func (server *Server) execTemplate(writer http.ResponseWriter, status int, data interface{}, files ...string) error { var err error tmpl := template.New(path.Base(files[0])).Funcs(template.FuncMap{ "asset": server.templateAsset, "dump": templateDumpMap, "eq": templateEqual, "hl": templateHighlight, "ne": templateNotEqual, "substr": templateSubstr, }) // Execute template tmpl, err = tmpl.ParseFiles(files...) if err != nil { return err } tmplData := bytes.NewBuffer(nil) err = tmpl.Execute(tmplData, data) if err != nil { return err } writer.WriteHeader(status) if utils.HTTPGetContentType(writer) == "text/xml" { writer.Write([]byte("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")) } writer.Write(tmplData.Bytes()) return err }
func kairosdbCheckBackendResponse(r *http.Response) error { if r.StatusCode != 200 { return fmt.Errorf("got HTTP status code %d, expected 200", r.StatusCode) } if utils.HTTPGetContentType(r) != "application/json" { return fmt.Errorf("got HTTP content type `%s', expected `application/json'", r.Header["Content-Type"]) } return nil }
func (server *Server) parseStoreRequest(writer http.ResponseWriter, request *http.Request, id string) (*serverResponse, int) { if request.Method == "POST" && id != "" || request.Method == "PUT" && id == "" { return &serverResponse{mesgMethodNotAllowed}, http.StatusMethodNotAllowed } else if utils.HTTPGetContentType(request) != "application/json" { return &serverResponse{mesgUnsupportedMediaType}, http.StatusUnsupportedMediaType } return nil, http.StatusOK }
func (server *Server) servePlots(writer http.ResponseWriter, request *http.Request) { var ( err error graph *library.Graph item interface{} ) if request.Method != "POST" && request.Method != "HEAD" { server.serveResponse(writer, serverResponse{mesgMethodNotAllowed}, http.StatusMethodNotAllowed) return } else if utils.HTTPGetContentType(request) != "application/json" { server.serveResponse(writer, serverResponse{mesgUnsupportedMediaType}, http.StatusUnsupportedMediaType) return } // Check for requests loop if request.Header.Get("X-Facette-Requestor") == server.ID { logger.Log(logger.LevelWarning, "server", "request loop detected, cancelled") server.serveResponse(writer, serverResponse{mesgEmptyData}, http.StatusBadRequest) return } // Parse plots request plotReq, err := parsePlotRequest(request) if err != nil { logger.Log(logger.LevelError, "server", "%s", err) server.serveResponse(writer, serverResponse{mesgResourceInvalid}, http.StatusBadRequest) return } // Get graph definition from the plot request graph = plotReq.Graph // If a Graph ID has been provided in the plot request, fetch the graph definition from the library instead if plotReq.ID != "" { graph = &library.Graph{} if item, err = server.Library.GetItem(plotReq.ID, library.LibraryItemGraph); err == nil { utils.Clone(item.(*library.Graph), graph) } } if graph == nil { err = os.ErrNotExist } // Stop if an error was encountered if err != nil { if os.IsNotExist(err) { server.serveResponse(writer, serverResponse{mesgResourceNotFound}, http.StatusNotFound) } else { logger.Log(logger.LevelError, "server", "%s", err) server.serveResponse(writer, serverResponse{mesgUnhandledError}, http.StatusInternalServerError) } return } // If linked graph, expand its template if graph.Link != "" || graph.ID == "" && len(graph.Attributes) > 0 { if graph.Link != "" { // Get graph template from library item, err := server.Library.GetItem(graph.Link, library.LibraryItemGraph) if err != nil { logger.Log(logger.LevelError, "server", "graph template not found: %s", graph.Link) return } utils.Clone(item.(*library.Graph), graph) } if err = server.expandGraphTemplate(graph); err != nil { logger.Log(logger.LevelError, "server", "unable to apply graph template: %s", err) server.serveResponse(writer, serverResponse{mesgUnhandledError}, http.StatusInternalServerError) } } // Prepare queries to be executed by the providers providerQueries, err := server.prepareProviderQueries(plotReq, graph) if err != nil { if os.IsNotExist(err) { server.serveResponse(writer, serverResponse{mesgResourceNotFound}, http.StatusNotFound) } else { logger.Log(logger.LevelError, "server", "%s", err) server.serveResponse(writer, serverResponse{mesgUnhandledError}, http.StatusInternalServerError) } return } plotSeries, err := executeQueries(providerQueries) if err != nil { logger.Log(logger.LevelError, "server", "unable to execute provider queries: %s", err) server.serveResponse(writer, serverResponse{mesgProviderQueryError}, http.StatusInternalServerError) return } if len(plotSeries) == 0 { server.serveResponse(writer, serverResponse{mesgEmptyData}, http.StatusOK) return } response, err := makePlotsResponse(plotSeries, plotReq, graph) if err != nil { logger.Log(logger.LevelError, "server", "unable to make plots response: %s", err) server.serveResponse(writer, serverResponse{mesgPlotOperationError}, http.StatusInternalServerError) return } server.serveResponse(writer, response, http.StatusOK) }
func (server *Server) serveGraphPlots(writer http.ResponseWriter, request *http.Request) { var ( err error graph *library.Graph item interface{} startTime, endTime time.Time ) if request.Method != "POST" && request.Method != "HEAD" { server.serveResponse(writer, serverResponse{mesgMethodNotAllowed}, http.StatusMethodNotAllowed) return } else if utils.HTTPGetContentType(request) != "application/json" { server.serveResponse(writer, serverResponse{mesgUnsupportedMediaType}, http.StatusUnsupportedMediaType) return } // Parse input JSON for graph data body, _ := ioutil.ReadAll(request.Body) plotReq := PlotRequest{} if err := json.Unmarshal(body, &plotReq); err != nil { logger.Log(logger.LevelError, "server", "%s", err) server.serveResponse(writer, serverResponse{mesgResourceInvalid}, http.StatusBadRequest) return } if plotReq.Time == "" { endTime = time.Now() } else if strings.HasPrefix(strings.Trim(plotReq.Range, " "), "-") { if endTime, err = time.Parse(time.RFC3339, plotReq.Time); err != nil { logger.Log(logger.LevelError, "server", "%s", err) server.serveResponse(writer, serverResponse{mesgResourceInvalid}, http.StatusBadRequest) return } } else { if startTime, err = time.Parse(time.RFC3339, plotReq.Time); err != nil { logger.Log(logger.LevelError, "server", "%s", err) server.serveResponse(writer, serverResponse{mesgResourceInvalid}, http.StatusBadRequest) return } } if startTime.IsZero() { if startTime, err = utils.TimeApplyRange(endTime, plotReq.Range); err != nil { logger.Log(logger.LevelError, "server", "%s", err) server.serveResponse(writer, serverResponse{mesgResourceInvalid}, http.StatusBadRequest) return } } else if endTime, err = utils.TimeApplyRange(startTime, plotReq.Range); err != nil { logger.Log(logger.LevelError, "server", "%s", err) server.serveResponse(writer, serverResponse{mesgResourceInvalid}, http.StatusBadRequest) return } if plotReq.Sample == 0 { plotReq.Sample = config.DefaultPlotSample } // Get graph from library graph = plotReq.Graph if plotReq.ID != "" { if item, err = server.Library.GetItem(plotReq.ID, library.LibraryItemGraph); err == nil { graph = item.(*library.Graph) } } if graph == nil { err = os.ErrNotExist } if err != nil { if os.IsNotExist(err) { server.serveResponse(writer, serverResponse{mesgResourceNotFound}, http.StatusNotFound) } else { logger.Log(logger.LevelError, "server", "%s", err) server.serveResponse(writer, serverResponse{mesgUnhandledError}, http.StatusInternalServerError) } return } step := endTime.Sub(startTime) / time.Duration(plotReq.Sample) // Get plots data groupOptions := make(map[string]map[string]interface{}) data := make([][]*types.PlotResult, 0) for _, groupItem := range graph.Groups { groupOptions[groupItem.Name] = groupItem.Options query, providerConnector, err := server.preparePlotQuery(&plotReq, groupItem) if err != nil { if err != os.ErrInvalid { logger.Log(logger.LevelError, "server", "%s", err) } data = append(data, nil) continue } plotResults, err := providerConnector.GetPlots(&types.PlotQuery{query, startTime, endTime, step, plotReq.Percentiles}) if err != nil { logger.Log(logger.LevelError, "server", "%s", err) } if len(plotResults) > 1 { for index, entry := range plotResults { entry.Name = fmt.Sprintf("%s (%s)", groupItem.Name, query.Series[index].Metric.Name) } } else if len(plotResults) == 1 { plotResults[0].Name = groupItem.Name } data = append(data, plotResults) } response := &PlotResponse{ ID: graph.ID, Start: startTime.Format(time.RFC3339), End: endTime.Format(time.RFC3339), Step: step.Seconds(), Name: graph.Name, Description: graph.Description, Type: graph.Type, StackMode: graph.StackMode, UnitLabel: graph.UnitLabel, UnitType: graph.UnitType, Modified: graph.Modified, } if len(data) == 0 { server.serveResponse(writer, serverResponse{mesgEmptyData}, http.StatusOK) return } plotMax := 0 for _, groupItem := range graph.Groups { var plotResult []*types.PlotResult plotResult, data = data[0], data[1:] for _, serieResult := range plotResult { if len(serieResult.Plots) > plotMax { plotMax = len(serieResult.Plots) } response.Series = append(response.Series, &SerieResponse{ Name: serieResult.Name, Plots: serieResult.Plots, Info: serieResult.Info, Options: groupOptions[groupItem.Name], }) } } if plotMax > 0 { response.Step = (endTime.Sub(startTime) / time.Duration(plotMax)).Seconds() } server.serveResponse(writer, response, http.StatusOK) }