diff --git a/backend/api/api.go b/backend/api/api.go new file mode 100644 index 00000000000..a0dca45c1b8 --- /dev/null +++ b/backend/api/api.go @@ -0,0 +1,72 @@ +package api + +import ( + "html/template" + + log "github.com/alecthomas/log4go" + "github.com/gin-gonic/gin" + "github.com/torkelo/grafana-pro/backend/components" + "github.com/torkelo/grafana-pro/backend/stores" +) + +type HttpServer struct { + port string + shutdown chan bool + store stores.Store + renderer *components.PhantomRenderer + router *gin.Engine +} + +func NewHttpServer(port string, store stores.Store) *HttpServer { + self := &HttpServer{} + self.port = port + self.store = store + self.renderer = &components.PhantomRenderer{ImagesDir: "data/png", PhantomDir: "_vendor/phantomjs"} + + return self +} + +func CacheHeadersMiddleware() gin.HandlerFunc { + return func(c *gin.Context) { + c.Writer.Header().Add("Cache-Control", "max-age=0, public, must-revalidate, proxy-revalidate") + } +} + +func (self *HttpServer) ListenAndServe() { + log.Info("Starting Http Listener on port %v", self.port) + defer func() { self.shutdown <- true }() + + self.router = gin.Default() + self.router.Use(CacheHeadersMiddleware()) + + // register & parse templates + templates := template.New("templates") + templates.Delims("[[", "]]") + templates.ParseFiles("./views/index.html") + self.router.SetHTMLTemplate(templates) + + // register default route + self.router.GET("/", self.index) + for _, fn := range routeHandlers { + fn(self) + } + + self.router.Static("/public", "./public") + self.router.Static("/app", "./public/app") + self.router.Static("/img", "./public/img") + + self.router.Run(":" + self.port) +} + +func (self *HttpServer) index(c *gin.Context) { + c.HTML(200, "index.html", &indexViewModel{title: "hello from go"}) +} + +// Api Handler Registration +var routeHandlers = make([]routeHandlerRegisterFn, 0) + +type routeHandlerRegisterFn func(self *HttpServer) + +func addRoutes(fn routeHandlerRegisterFn) { + routeHandlers = append(routeHandlers, fn) +} diff --git a/backend/api/api_dashboard.go b/backend/api/api_dashboard.go new file mode 100644 index 00000000000..7c1f9614233 --- /dev/null +++ b/backend/api/api_dashboard.go @@ -0,0 +1,52 @@ +package api + +import ( + "github.com/gin-gonic/gin" + "github.com/torkelo/grafana-pro/backend/models" +) + +func init() { + addRoutes(func(self *HttpServer) { + self.router.GET("/api/dashboards/:id", self.getDashboard) + self.router.GET("/api/search/", self.search) + self.router.POST("/api/dashboard", self.postDashboard) + }) +} + +func (self *HttpServer) getDashboard(c *gin.Context) { + id := c.Params.ByName("id") + + dash, err := self.store.GetById(id) + if err != nil { + c.JSON(404, newErrorResponse("Dashboard not found")) + return + } + + c.JSON(200, dash.Data) +} + +func (self *HttpServer) search(c *gin.Context) { + query := c.Params.ByName("q") + + results, err := self.store.Query(query) + if err != nil { + c.JSON(500, newErrorResponse("Failed")) + return + } + + c.JSON(200, results) +} + +func (self *HttpServer) postDashboard(c *gin.Context) { + var command saveDashboardCommand + + if c.EnsureBody(&command) { + err := self.store.Save(&models.Dashboard{Data: command.dashboard}) + if err == nil { + c.JSON(200, gin.H{"status": "saved"}) + return + } + } + + c.JSON(500, gin.H{"error": "bad request"}) +} diff --git a/backend/api/api_models.go b/backend/api/api_models.go new file mode 100644 index 00000000000..9d57a6b5fa2 --- /dev/null +++ b/backend/api/api_models.go @@ -0,0 +1,19 @@ +package api + +type saveDashboardCommand struct { + id string `json:"id"` + title string `json:"title"` + dashboard map[string]interface{} +} + +type errorResponse struct { + message string `json:"message"` +} + +type indexViewModel struct { + title string +} + +func newErrorResponse(message string) *errorResponse { + return &errorResponse{message: message} +} diff --git a/backend/api/api_render.go b/backend/api/api_render.go new file mode 100644 index 00000000000..ec03254938d --- /dev/null +++ b/backend/api/api_render.go @@ -0,0 +1,20 @@ +package api + +import "github.com/gin-gonic/gin" + +func init() { + addRoutes(func(self *HttpServer) { + self.router.GET("/api/render", self.renderToPng) + }) +} + +func (self *HttpServer) renderToPng(c *gin.Context) { + qs := c.Request.URL.Query() + url := qs["url"][0] + pngPath, err := self.renderer.RenderToPng(url) + if err != nil { + c.HTML(500, "error.html", nil) + } + + c.File(pngPath) +} diff --git a/backend/api/api_test.go b/backend/api/api_test.go new file mode 100644 index 00000000000..778f64ec17c --- /dev/null +++ b/backend/api/api_test.go @@ -0,0 +1 @@ +package api diff --git a/backend/httpApi/api.go b/backend/httpApi/api.go deleted file mode 100644 index 5b609aa159e..00000000000 --- a/backend/httpApi/api.go +++ /dev/null @@ -1,122 +0,0 @@ -package httpApi - -import ( - "html/template" - - log "github.com/alecthomas/log4go" - "github.com/gin-gonic/gin" - "github.com/torkelo/grafana-pro/backend/components" - "github.com/torkelo/grafana-pro/backend/models" - "github.com/torkelo/grafana-pro/backend/stores" -) - -type HttpServer struct { - port string - shutdown chan bool - store stores.Store - renderer *components.PhantomRenderer -} - -func NewHttpServer(port string, store stores.Store) *HttpServer { - self := &HttpServer{} - self.port = port - self.store = store - self.renderer = &components.PhantomRenderer{ImagesDir: "data/png", PhantomDir: "_vendor/phantomjs"} - - return self -} - -func CacheHeadersMiddleware() gin.HandlerFunc { - return func(c *gin.Context) { - c.Writer.Header().Add("Cache-Control", "max-age=0, public, must-revalidate, proxy-revalidate") - } -} - -func (self *HttpServer) ListenAndServe() { - log.Info("Starting Http Listener on port %v", self.port) - - defer func() { self.shutdown <- true }() - - r := gin.Default() - r.Use(CacheHeadersMiddleware()) - - templates := template.New("templates") - templates.Delims("[[", "]]") - templates.ParseFiles("./views/index.html") - - r.SetHTMLTemplate(templates) - - r.GET("/", self.index) - r.GET("/api/dashboards/:id", self.getDashboard) - r.GET("/api/search/", self.search) - r.POST("/api/dashboard", self.postDashboard) - - r.GET("/api/render", self.renderToPng) - - r.Static("/public", "./public") - r.Static("/app", "./public/app") - r.Static("/img", "./public/img") - - r.Run(":" + self.port) -} - -type IndexViewModel struct { - Title string -} - -func (self *HttpServer) index(c *gin.Context) { - c.HTML(200, "index.html", &IndexViewModel{Title: "hello from go"}) -} - -type ErrorRsp struct { - Message string `json:"message"` -} - -func (self *HttpServer) getDashboard(c *gin.Context) { - id := c.Params.ByName("id") - - dash, err := self.store.GetById(id) - if err != nil { - c.JSON(404, &ErrorRsp{Message: "Dashboard not found"}) - return - } - - c.JSON(200, dash.Data) -} - -func (self *HttpServer) renderToPng(c *gin.Context) { - qs := c.Request.URL.Query() - url := qs["url"][0] - pngPath, err := self.renderer.RenderToPng(url) - if err != nil { - c.HTML(500, "error.html", nil) - } - - c.File(pngPath) -} - -func (self *HttpServer) search(c *gin.Context) { - query := c.Params.ByName("q") - - results, err := self.store.Query(query) - if err != nil { - c.JSON(500, &ErrorRsp{Message: "Search error"}) - return - } - - c.JSON(200, results) -} - -func (self *HttpServer) postDashboard(c *gin.Context) { - var command saveDashboardCommand - - if c.EnsureBody(&command) { - err := self.store.Save(&models.Dashboard{Data: command.Dashboard}) - if err == nil { - c.JSON(200, gin.H{"status": "saved"}) - return - } - } - - c.JSON(500, gin.H{"error": "bad request"}) -} diff --git a/backend/httpApi/api_test.go b/backend/httpApi/api_test.go deleted file mode 100644 index 6daae4e93fa..00000000000 --- a/backend/httpApi/api_test.go +++ /dev/null @@ -1 +0,0 @@ -package httpApi diff --git a/backend/httpApi/commands.go b/backend/httpApi/commands.go deleted file mode 100644 index 922d2607621..00000000000 --- a/backend/httpApi/commands.go +++ /dev/null @@ -1,7 +0,0 @@ -package httpApi - -type saveDashboardCommand struct { - Id string `json:"id"` - Title string `json:"title"` - Dashboard map[string]interface{} -} diff --git a/backend/server/server.go b/backend/server/server.go index b3fcaf37779..089ccc9ed4f 100644 --- a/backend/server/server.go +++ b/backend/server/server.go @@ -1,18 +1,18 @@ package server import ( - "github.com/torkelo/grafana-pro/backend/httpApi" + "github.com/torkelo/grafana-pro/backend/api" "github.com/torkelo/grafana-pro/backend/stores" ) type Server struct { - HttpServer *httpApi.HttpServer + HttpServer *api.HttpServer Store stores.Store } func NewServer(port string) (*Server, error) { store := stores.New() - httpServer := httpApi.NewHttpServer(port, store) + httpServer := api.NewHttpServer(port, store) return &Server{ HttpServer: httpServer,