diff options
Diffstat (limited to 'src/jobCheckin/jobCheckin.go')
| -rw-r--r-- | src/jobCheckin/jobCheckin.go | 114 |
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) +} |
