aboutsummaryrefslogtreecommitdiff
path: root/src/jobCheckin/jobCheckin.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/jobCheckin/jobCheckin.go')
-rw-r--r--src/jobCheckin/jobCheckin.go114
1 files changed, 114 insertions, 0 deletions
diff --git a/src/jobCheckin/jobCheckin.go b/src/jobCheckin/jobCheckin.go
new file mode 100644
index 0000000..0a1dd1b
--- /dev/null
+++ b/src/jobCheckin/jobCheckin.go
@@ -0,0 +1,114 @@
+package jobCheckin
+
+import (
+ "app/common"
+ "encoding/json"
+ client "github.com/influxdata/influxdb1-client/v2"
+ "log"
+ "net/http"
+ "os"
+ "regexp"
+ "strings"
+)
+
+type Job struct {
+ Source string
+}
+
+// Validates the incomming request and writes an appropriate response.
+// 405: when not POST request
+// 401: when body is not given, or 'source' field missing
+// 500: failed to complete
+// 202: successfully complete
+func jobCheckinHandler(w http.ResponseWriter, r *http.Request) {
+ log.Println("New request ===== ")
+
+ if r.Method != "POST" {
+ common.JsonRespond(&w, http.StatusMethodNotAllowed, "This end-point only accepts POST requests.")
+ return
+ }
+
+ var j Job
+ err := json.NewDecoder(r.Body).Decode(&j)
+ if err != nil {
+ common.JsonRespond(&w, http.StatusBadRequest, err.Error())
+ return
+ }
+ if j.Source == "" {
+ common.JsonRespond(&w, http.StatusBadRequest, "no 'source' field in body. Try sending a json such as {'source': 'job_name'} in the body.")
+ return
+ }
+ log.Println("source:", j.Source)
+
+ measurement, err := chekinJob(j.Source)
+ if err != nil {
+ common.JsonRespond(&w, http.StatusInternalServerError, "Error while writing to Influx.")
+ return
+ }
+
+ common.JsonRespond(&w, http.StatusAccepted, measurement)
+ return
+}
+
+// Write job check-in to influx.
+func chekinJob(jobName string) (string, error) {
+ jobNameClean, err := sanitizeJobName(jobName)
+ if err != nil {
+ return "", err
+ }
+
+ // Make client
+ c, err := client.NewHTTPClient(client.HTTPConfig{
+ Addr: "http://" + os.Getenv("INFLUX_HOST") + ":" + os.Getenv("INFLUX_PORT"),
+ })
+ if err != nil {
+ return "", err
+ }
+ defer c.Close()
+
+ // Create a new point batch
+ bp, _ := client.NewBatchPoints(client.BatchPointsConfig{
+ Database: os.Getenv("INFLUX_DB"),
+ Precision: "s",
+ RetentionPolicy: os.Getenv("INFLUX_RP"),
+ })
+
+ measurement := jobNameClean + "_checkins"
+ // Create a point and add to batch
+ tags := map[string]string{}
+ fields := map[string]interface{}{"check-in": 1}
+ pt, err := client.NewPoint(measurement, tags, fields)
+ if err != nil {
+ return "", err
+ }
+ bp.AddPoint(pt)
+
+ // Write the batch
+ err = c.Write(bp)
+ if err != nil {
+ return "", err
+ }
+ return measurement, nil
+}
+
+// Sanitize jobname - we only want letters, numbers, and underscores
+func sanitizeJobName(jobName string) (string, error) {
+ // remove any non-alphanumeric chars, and non-space chars
+ reg1, err := regexp.Compile("[^ _a-zA-Z0-9]+")
+ if err != nil {
+ return "", nil
+ }
+ jobName = reg1.ReplaceAllString(jobName, "")
+ // replace spaces with _
+ reg2, err := regexp.Compile("[ ]+")
+ if err != nil {
+ return "", nil
+ }
+ jobName = reg2.ReplaceAllString(jobName, "_")
+ return strings.ToLower(jobName), nil
+}
+
+// Every new endpoint/package MUST implement this function like so...
+func MakeHTTPHandler(endpoint string) http.Handler {
+ return common.MakeHTTPHandler(endpoint, jobCheckinHandler)
+}