// SetWriteConsistency sets cluster consistency level func (c *CommandLine) SetWriteConsistency(cmd string) { // Remove the "consistency" keyword if it exists cmd = strings.TrimSpace(strings.Replace(cmd, "consistency", "", -1)) // normalize cmd cmd = strings.ToLower(cmd) _, err := models.ParseConsistencyLevel(cmd) if err != nil { fmt.Printf("Unknown consistency level %q. Please use any, one, quorum, or all.\n", cmd) return } c.WriteConsistency = cmd }
// serveWrite receives incoming series data in line protocol format and writes it to the database. func (h *Handler) serveWrite(w http.ResponseWriter, r *http.Request, user *meta.UserInfo) { atomic.AddInt64(&h.stats.WriteRequests, 1) atomic.AddInt64(&h.stats.ActiveWriteRequests, 1) defer func(start time.Time) { atomic.AddInt64(&h.stats.ActiveWriteRequests, -1) atomic.AddInt64(&h.stats.WriteRequestDuration, time.Since(start).Nanoseconds()) }(time.Now()) database := r.URL.Query().Get("db") if database == "" { h.resultError(w, influxql.Result{Err: fmt.Errorf("database is required")}, http.StatusBadRequest) return } if di := h.MetaClient.Database(database); di == nil { h.resultError(w, influxql.Result{Err: fmt.Errorf("database not found: %q", database)}, http.StatusNotFound) return } if h.Config.AuthEnabled && user == nil { h.resultError(w, influxql.Result{Err: fmt.Errorf("user is required to write to database %q", database)}, http.StatusUnauthorized) return } if h.Config.AuthEnabled { if err := h.WriteAuthorizer.AuthorizeWrite(user.Name, database); err != nil { h.resultError(w, influxql.Result{Err: fmt.Errorf("%q user is not authorized to write to database %q", user.Name, database)}, http.StatusUnauthorized) return } } // Handle gzip decoding of the body body := r.Body if r.Header.Get("Content-Encoding") == "gzip" { b, err := gzip.NewReader(r.Body) if err != nil { h.resultError(w, influxql.Result{Err: err}, http.StatusBadRequest) return } defer b.Close() body = b } var bs []byte if clStr := r.Header.Get("Content-Length"); clStr != "" { if length, err := strconv.Atoi(clStr); err == nil { // This will just be an initial hint for the gzip reader, as the // bytes.Buffer will grow as needed when ReadFrom is called bs = make([]byte, 0, length) } } buf := bytes.NewBuffer(bs) _, err := buf.ReadFrom(body) if err != nil { if h.Config.WriteTracing { h.Logger.Print("Write handler unable to read bytes from request body") } h.resultError(w, influxql.Result{Err: err}, http.StatusBadRequest) return } atomic.AddInt64(&h.stats.WriteRequestBytesReceived, int64(buf.Len())) if h.Config.WriteTracing { h.Logger.Printf("Write body received by handler: %s", buf.Bytes()) } points, parseError := models.ParsePointsWithPrecision(buf.Bytes(), time.Now().UTC(), r.URL.Query().Get("precision")) // Not points parsed correctly so return the error now if parseError != nil && len(points) == 0 { if parseError.Error() == "EOF" { h.writeHeader(w, http.StatusOK) return } h.resultError(w, influxql.Result{Err: parseError}, http.StatusBadRequest) return } // Determine required consistency level. level := r.URL.Query().Get("consistency") consistency := models.ConsistencyLevelOne if level != "" { var err error consistency, err = models.ParseConsistencyLevel(level) if err != nil { h.resultError(w, influxql.Result{Err: err}, http.StatusBadRequest) return } } // Write points. if err := h.PointsWriter.WritePoints(database, r.URL.Query().Get("rp"), consistency, points); influxdb.IsClientError(err) { atomic.AddInt64(&h.stats.PointsWrittenFail, int64(len(points))) h.resultError(w, influxql.Result{Err: err}, http.StatusBadRequest) return } else if err != nil { atomic.AddInt64(&h.stats.PointsWrittenFail, int64(len(points))) h.resultError(w, influxql.Result{Err: err}, http.StatusInternalServerError) return } else if parseError != nil { // We wrote some of the points atomic.AddInt64(&h.stats.PointsWrittenOK, int64(len(points))) // The other points failed to parse which means the client sent invalid line protocol. We return a 400 // response code as well as the lines that failed to parse. h.resultError(w, influxql.Result{Err: fmt.Errorf("partial write:\n%v", parseError)}, http.StatusBadRequest) return } atomic.AddInt64(&h.stats.PointsWrittenOK, int64(len(points))) h.writeHeader(w, http.StatusNoContent) }