Commit 540d540e by Marcus Efraimsson

fix: return id from api when creating new annotation/graphite annotation, fixes #9798

When creating a region annotation the response will include both
id (region start id) and endId (region end id), if not only id.
parent 9ea5af57
...@@ -89,7 +89,7 @@ Content-Type: application/json ...@@ -89,7 +89,7 @@ Content-Type: application/json
## Create Annotation ## Create Annotation
Creates an annotation in the Grafana database. The `dashboardId` and `panelId` fields are optional. If they are not specified then a global annotation is created and can be queried in any dashboard that adds the Grafana annotations data source. Creates an annotation in the Grafana database. The `dashboardId` and `panelId` fields are optional. If they are not specified then a global annotation is created and can be queried in any dashboard that adds the Grafana annotations data source. When creating a region annotation the response will include both `id` and `endId`, if not only `id`.
`POST /api/annotations` `POST /api/annotations`
...@@ -117,7 +117,11 @@ Content-Type: application/json ...@@ -117,7 +117,11 @@ Content-Type: application/json
HTTP/1.1 200 HTTP/1.1 200
Content-Type: application/json Content-Type: application/json
{"message":"Annotation added"} {
"message":"Annotation added",
"id": 1,
"endId": 2
}
``` ```
## Create Annotation in Graphite format ## Create Annotation in Graphite format
...@@ -148,7 +152,10 @@ Content-Type: application/json ...@@ -148,7 +152,10 @@ Content-Type: application/json
HTTP/1.1 200 HTTP/1.1 200
Content-Type: application/json Content-Type: application/json
{"message":"Graphite annotation added"} {
"message":"Graphite annotation added",
"id": 1
}
``` ```
## Update Annotation ## Update Annotation
......
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/middleware" "github.com/grafana/grafana/pkg/middleware"
"github.com/grafana/grafana/pkg/services/annotations" "github.com/grafana/grafana/pkg/services/annotations"
"github.com/grafana/grafana/pkg/util"
) )
func GetAnnotations(c *middleware.Context) Response { func GetAnnotations(c *middleware.Context) Response {
...@@ -48,12 +49,13 @@ func (e *CreateAnnotationError) Error() string { ...@@ -48,12 +49,13 @@ func (e *CreateAnnotationError) Error() string {
return e.message return e.message
} }
func PostAnnotation(c *middleware.Context, cmd dtos.PostAnnotationsCmd) Response { func PostAnnotation(c *middleware.Context, cmd dtos.PostAnnotationsCmd) {
repo := annotations.GetRepository() repo := annotations.GetRepository()
if cmd.Text == "" { if cmd.Text == "" {
err := &CreateAnnotationError{"text field should not be empty"} err := &CreateAnnotationError{"text field should not be empty"}
return ApiError(500, "Failed to save annotation", err) c.JsonApiErr(500, "Failed to save annotation", err)
return
} }
item := annotations.Item{ item := annotations.Item{
...@@ -72,30 +74,45 @@ func PostAnnotation(c *middleware.Context, cmd dtos.PostAnnotationsCmd) Response ...@@ -72,30 +74,45 @@ func PostAnnotation(c *middleware.Context, cmd dtos.PostAnnotationsCmd) Response
} }
if err := repo.Save(&item); err != nil { if err := repo.Save(&item); err != nil {
return ApiError(500, "Failed to save annotation", err) c.JsonApiErr(500, "Failed to save annotation", err)
return
} }
startID := item.Id
// handle regions // handle regions
if cmd.IsRegion { if cmd.IsRegion {
item.RegionId = item.Id item.RegionId = startID
if item.Data == nil { if item.Data == nil {
item.Data = simplejson.New() item.Data = simplejson.New()
} }
if err := repo.Update(&item); err != nil { if err := repo.Update(&item); err != nil {
return ApiError(500, "Failed set regionId on annotation", err) c.JsonApiErr(500, "Failed set regionId on annotation", err)
return
} }
item.Id = 0 item.Id = 0
item.Epoch = cmd.TimeEnd / 1000 item.Epoch = cmd.TimeEnd / 1000
if err := repo.Save(&item); err != nil { if err := repo.Save(&item); err != nil {
return ApiError(500, "Failed save annotation for region end time", err) c.JsonApiErr(500, "Failed save annotation for region end time", err)
return
} }
c.JSON(200, util.DynMap{
"message": "Annotation added",
"id": startID,
"endId": item.Id,
})
return
} }
return ApiSuccess("Annotation added") c.JSON(200, util.DynMap{
"message": "Annotation added",
"id": startID,
})
} }
func formatGraphiteAnnotation(what string, data string) string { func formatGraphiteAnnotation(what string, data string) string {
...@@ -106,12 +123,13 @@ func formatGraphiteAnnotation(what string, data string) string { ...@@ -106,12 +123,13 @@ func formatGraphiteAnnotation(what string, data string) string {
return text return text
} }
func PostGraphiteAnnotation(c *middleware.Context, cmd dtos.PostGraphiteAnnotationsCmd) Response { func PostGraphiteAnnotation(c *middleware.Context, cmd dtos.PostGraphiteAnnotationsCmd) {
repo := annotations.GetRepository() repo := annotations.GetRepository()
if cmd.What == "" { if cmd.What == "" {
err := &CreateAnnotationError{"what field should not be empty"} err := &CreateAnnotationError{"what field should not be empty"}
return ApiError(500, "Failed to save Graphite annotation", err) c.JsonApiErr(500, "Failed to save Graphite annotation", err)
return
} }
if cmd.When == 0 { if cmd.When == 0 {
...@@ -134,12 +152,14 @@ func PostGraphiteAnnotation(c *middleware.Context, cmd dtos.PostGraphiteAnnotati ...@@ -134,12 +152,14 @@ func PostGraphiteAnnotation(c *middleware.Context, cmd dtos.PostGraphiteAnnotati
tagsArray = append(tagsArray, tagStr) tagsArray = append(tagsArray, tagStr)
} else { } else {
err := &CreateAnnotationError{"tag should be a string"} err := &CreateAnnotationError{"tag should be a string"}
return ApiError(500, "Failed to save Graphite annotation", err) c.JsonApiErr(500, "Failed to save Graphite annotation", err)
return
} }
} }
default: default:
err := &CreateAnnotationError{"unsupported tags format"} err := &CreateAnnotationError{"unsupported tags format"}
return ApiError(500, "Failed to save Graphite annotation", err) c.JsonApiErr(500, "Failed to save Graphite annotation", err)
return
} }
item := annotations.Item{ item := annotations.Item{
...@@ -151,10 +171,14 @@ func PostGraphiteAnnotation(c *middleware.Context, cmd dtos.PostGraphiteAnnotati ...@@ -151,10 +171,14 @@ func PostGraphiteAnnotation(c *middleware.Context, cmd dtos.PostGraphiteAnnotati
} }
if err := repo.Save(&item); err != nil { if err := repo.Save(&item); err != nil {
return ApiError(500, "Failed to save Graphite annotation", err) c.JsonApiErr(500, "Failed to save Graphite annotation", err)
return
} }
return ApiSuccess("Graphite annotation added") c.JSON(200, util.DynMap{
"message": "Graphite annotation added",
"id": item.Id,
})
} }
func UpdateAnnotation(c *middleware.Context, cmd dtos.UpdateAnnotationsCmd) Response { func UpdateAnnotation(c *middleware.Context, cmd dtos.UpdateAnnotationsCmd) Response {
......
...@@ -288,11 +288,11 @@ func (hs *HttpServer) registerRoutes() { ...@@ -288,11 +288,11 @@ func (hs *HttpServer) registerRoutes() {
apiRoute.Post("/annotations/mass-delete", reqOrgAdmin, bind(dtos.DeleteAnnotationsCmd{}), wrap(DeleteAnnotations)) apiRoute.Post("/annotations/mass-delete", reqOrgAdmin, bind(dtos.DeleteAnnotationsCmd{}), wrap(DeleteAnnotations))
apiRoute.Group("/annotations", func(annotationsRoute RouteRegister) { apiRoute.Group("/annotations", func(annotationsRoute RouteRegister) {
annotationsRoute.Post("/", bind(dtos.PostAnnotationsCmd{}), wrap(PostAnnotation)) annotationsRoute.Post("/", bind(dtos.PostAnnotationsCmd{}), PostAnnotation)
annotationsRoute.Delete("/:annotationId", wrap(DeleteAnnotationById)) annotationsRoute.Delete("/:annotationId", wrap(DeleteAnnotationById))
annotationsRoute.Put("/:annotationId", bind(dtos.UpdateAnnotationsCmd{}), wrap(UpdateAnnotation)) annotationsRoute.Put("/:annotationId", bind(dtos.UpdateAnnotationsCmd{}), wrap(UpdateAnnotation))
annotationsRoute.Delete("/region/:regionId", wrap(DeleteAnnotationRegion)) annotationsRoute.Delete("/region/:regionId", wrap(DeleteAnnotationRegion))
annotationsRoute.Post("/graphite", bind(dtos.PostGraphiteAnnotationsCmd{}), wrap(PostGraphiteAnnotation)) annotationsRoute.Post("/graphite", bind(dtos.PostGraphiteAnnotationsCmd{}), PostGraphiteAnnotation)
}, reqEditorRole) }, reqEditorRole)
// error test // error test
......
...@@ -37,16 +37,18 @@ func TestAnnotations(t *testing.T) { ...@@ -37,16 +37,18 @@ func TestAnnotations(t *testing.T) {
repo := SqlAnnotationRepo{} repo := SqlAnnotationRepo{}
Convey("Can save annotation", func() { Convey("Can save annotation", func() {
err := repo.Save(&annotations.Item{ annotation := &annotations.Item{
OrgId: 1, OrgId: 1,
UserId: 1, UserId: 1,
DashboardId: 1, DashboardId: 1,
Text: "hello", Text: "hello",
Epoch: 10, Epoch: 10,
Tags: []string{"outage", "error", "type:outage", "server:server-1"}, Tags: []string{"outage", "error", "type:outage", "server:server-1"},
}) }
err := repo.Save(annotation)
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(annotation.Id, ShouldBeGreaterThan, 0)
Convey("Can query for annotation", func() { Convey("Can query for annotation", func() {
items, err := repo.Find(&annotations.ItemQuery{ items, err := repo.Find(&annotations.ItemQuery{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment