func format(a *annotate.Annotation, w http.ResponseWriter, epochFmt bool) (e error) { if epochFmt { e = json.NewEncoder(w).Encode(a.AsEpochAnnotation()) } else { e = json.NewEncoder(w).Encode(a) } return }
func InsertAnnotation(w http.ResponseWriter, req *http.Request) { var a annotate.Annotation var ea annotate.EpochAnnotation epochFmt := false id := mux.Vars(req)["id"] // Need to read the request body twice to try both formats, so tee the b := bytes.NewBuffer(make([]byte, 0)) tee := io.TeeReader(req.Body, b) d := json.NewDecoder(tee) errRegFmt := d.Decode(&a) if errRegFmt != nil { d := json.NewDecoder(b) errEpochFmt := d.Decode(&ea) if errEpochFmt != nil { serveError(w, fmt.Errorf("Could not unmarhsal json in RFC3339 fmt or Epoch fmt: %v, %v", errRegFmt, errEpochFmt)) return } a = ea.AsAnnotation() epochFmt = true } if a.Id != "" && id != "" && a.Id != id { serveError(w, fmt.Errorf("conflicting ids in request: url id %v, body id %v", id, a.Id)) return } if id != "" { // If we got the id in the url a.Id = id } if a.IsOneTimeSet() { a.MatchTimes() } if a.IsTimeNotSet() { a.SetNow() } err := a.ValidateTime() if err != nil { serveError(w, err) return } if a.Id == "" { //if Id isn't set, this is a new Annotation a.Id = uuid.NewV4().String() } else { // Make sure annotation exists if not new for _, b := range backends { //TODO handle multiple backends _, found, err := b.GetAnnotation(a.Id) if err == nil && !found { serveError(w, fmt.Errorf("could not find annotation with id %v to update: %v", a.Id, err)) return } if err != nil { serveError(w, err) return } } } for _, b := range backends { log.Println("Inserting", a) err := b.InsertAnnotation(&a) //TODO Collect errors and insert into the backends that we can if err != nil { serveError(w, err) return } } if err = format(&a, w, epochFmt); err != nil { serveError(w, err) return } w.Header().Set("Content-Type", "application/json") return }