2019-07-25 10:30:25 +00:00
package http
import (
"context"
"encoding/json"
"fmt"
2019-12-18 04:54:23 +00:00
"io/ioutil"
2019-07-25 10:30:25 +00:00
"net/http"
2019-11-25 14:22:19 +00:00
"github.com/influxdata/httprouter"
2019-07-25 10:30:25 +00:00
"github.com/influxdata/influxdb"
2019-08-16 04:00:55 +00:00
pctx "github.com/influxdata/influxdb/context"
2019-07-25 10:30:25 +00:00
"github.com/influxdata/influxdb/notification/check"
"go.uber.org/zap"
)
// CheckBackend is all services and associated parameters required to construct
// the CheckBackendHandler.
type CheckBackend struct {
influxdb . HTTPErrorHandler
2019-12-04 23:10:23 +00:00
log * zap . Logger
2019-07-25 10:30:25 +00:00
2019-09-18 20:19:51 +00:00
TaskService influxdb . TaskService
2019-07-25 10:30:25 +00:00
CheckService influxdb . CheckService
UserResourceMappingService influxdb . UserResourceMappingService
LabelService influxdb . LabelService
UserService influxdb . UserService
OrganizationService influxdb . OrganizationService
}
// NewCheckBackend returns a new instance of CheckBackend.
2019-12-04 23:10:23 +00:00
func NewCheckBackend ( log * zap . Logger , b * APIBackend ) * CheckBackend {
2019-07-25 10:30:25 +00:00
return & CheckBackend {
HTTPErrorHandler : b . HTTPErrorHandler ,
2019-12-04 23:10:23 +00:00
log : log ,
2019-07-25 10:30:25 +00:00
2019-09-18 20:19:51 +00:00
TaskService : b . TaskService ,
2019-07-25 10:30:25 +00:00
CheckService : b . CheckService ,
UserResourceMappingService : b . UserResourceMappingService ,
LabelService : b . LabelService ,
UserService : b . UserService ,
OrganizationService : b . OrganizationService ,
}
}
// CheckHandler is the handler for the check service
type CheckHandler struct {
* httprouter . Router
influxdb . HTTPErrorHandler
2019-12-04 23:10:23 +00:00
log * zap . Logger
2019-07-25 10:30:25 +00:00
2019-09-18 20:19:51 +00:00
TaskService influxdb . TaskService
2019-07-25 10:30:25 +00:00
CheckService influxdb . CheckService
UserResourceMappingService influxdb . UserResourceMappingService
LabelService influxdb . LabelService
UserService influxdb . UserService
OrganizationService influxdb . OrganizationService
}
const (
2019-12-09 23:54:16 +00:00
prefixChecks = "/api/v2/checks"
2019-07-25 10:30:25 +00:00
checksIDPath = "/api/v2/checks/:id"
2019-08-22 16:18:02 +00:00
checksIDQueryPath = "/api/v2/checks/:id/query"
2019-07-25 10:30:25 +00:00
checksIDMembersPath = "/api/v2/checks/:id/members"
checksIDMembersIDPath = "/api/v2/checks/:id/members/:userID"
checksIDOwnersPath = "/api/v2/checks/:id/owners"
checksIDOwnersIDPath = "/api/v2/checks/:id/owners/:userID"
checksIDLabelsPath = "/api/v2/checks/:id/labels"
checksIDLabelsIDPath = "/api/v2/checks/:id/labels/:lid"
)
// NewCheckHandler returns a new instance of CheckHandler.
2019-12-04 23:10:23 +00:00
func NewCheckHandler ( log * zap . Logger , b * CheckBackend ) * CheckHandler {
2019-07-25 10:30:25 +00:00
h := & CheckHandler {
Router : NewRouter ( b . HTTPErrorHandler ) ,
HTTPErrorHandler : b . HTTPErrorHandler ,
2019-12-04 23:10:23 +00:00
log : log ,
2019-07-25 10:30:25 +00:00
CheckService : b . CheckService ,
UserResourceMappingService : b . UserResourceMappingService ,
LabelService : b . LabelService ,
UserService : b . UserService ,
2019-09-18 20:19:51 +00:00
TaskService : b . TaskService ,
2019-07-25 10:30:25 +00:00
OrganizationService : b . OrganizationService ,
}
2019-12-09 23:54:16 +00:00
h . HandlerFunc ( "POST" , prefixChecks , h . handlePostCheck )
h . HandlerFunc ( "GET" , prefixChecks , h . handleGetChecks )
2019-07-25 10:30:25 +00:00
h . HandlerFunc ( "GET" , checksIDPath , h . handleGetCheck )
2019-08-22 16:18:02 +00:00
h . HandlerFunc ( "GET" , checksIDQueryPath , h . handleGetCheckQuery )
2019-07-25 10:30:25 +00:00
h . HandlerFunc ( "DELETE" , checksIDPath , h . handleDeleteCheck )
h . HandlerFunc ( "PUT" , checksIDPath , h . handlePutCheck )
h . HandlerFunc ( "PATCH" , checksIDPath , h . handlePatchCheck )
memberBackend := MemberBackend {
HTTPErrorHandler : b . HTTPErrorHandler ,
2019-12-04 23:10:23 +00:00
log : b . log . With ( zap . String ( "handler" , "member" ) ) ,
2019-07-25 10:30:25 +00:00
ResourceType : influxdb . ChecksResourceType ,
UserType : influxdb . Member ,
UserResourceMappingService : b . UserResourceMappingService ,
UserService : b . UserService ,
}
h . HandlerFunc ( "POST" , checksIDMembersPath , newPostMemberHandler ( memberBackend ) )
h . HandlerFunc ( "GET" , checksIDMembersPath , newGetMembersHandler ( memberBackend ) )
h . HandlerFunc ( "DELETE" , checksIDMembersIDPath , newDeleteMemberHandler ( memberBackend ) )
ownerBackend := MemberBackend {
HTTPErrorHandler : b . HTTPErrorHandler ,
2019-12-04 23:10:23 +00:00
log : b . log . With ( zap . String ( "handler" , "member" ) ) ,
2019-07-25 10:30:25 +00:00
ResourceType : influxdb . ChecksResourceType ,
UserType : influxdb . Owner ,
UserResourceMappingService : b . UserResourceMappingService ,
UserService : b . UserService ,
}
h . HandlerFunc ( "POST" , checksIDOwnersPath , newPostMemberHandler ( ownerBackend ) )
h . HandlerFunc ( "GET" , checksIDOwnersPath , newGetMembersHandler ( ownerBackend ) )
h . HandlerFunc ( "DELETE" , checksIDOwnersIDPath , newDeleteMemberHandler ( ownerBackend ) )
labelBackend := & LabelBackend {
HTTPErrorHandler : b . HTTPErrorHandler ,
2019-12-04 23:10:23 +00:00
log : b . log . With ( zap . String ( "handler" , "label" ) ) ,
2019-07-25 10:30:25 +00:00
LabelService : b . LabelService ,
ResourceType : influxdb . TelegrafsResourceType ,
}
2019-09-25 07:07:24 +00:00
h . HandlerFunc ( "GET" , checksIDLabelsPath , newGetLabelsHandler ( labelBackend ) )
2019-07-25 10:30:25 +00:00
h . HandlerFunc ( "POST" , checksIDLabelsPath , newPostLabelHandler ( labelBackend ) )
h . HandlerFunc ( "DELETE" , checksIDLabelsIDPath , newDeleteLabelHandler ( labelBackend ) )
return h
}
type checkLinks struct {
Self string ` json:"self" `
Labels string ` json:"labels" `
Members string ` json:"members" `
Owners string ` json:"owners" `
2019-11-08 16:23:38 +00:00
Query string ` json:"query" `
2019-07-25 10:30:25 +00:00
}
type checkResponse struct {
influxdb . Check
2019-09-18 20:19:51 +00:00
Status string ` json:"status" `
2019-07-25 10:30:25 +00:00
Labels [ ] influxdb . Label ` json:"labels" `
Links checkLinks ` json:"links" `
}
2019-09-30 23:15:14 +00:00
type postCheckRequest struct {
influxdb . CheckCreate
Labels [ ] string ` json:"labels" `
}
type decodeLabels struct {
Labels [ ] string ` json:"labels" `
}
2019-07-25 10:30:25 +00:00
func ( resp checkResponse ) MarshalJSON ( ) ( [ ] byte , error ) {
b1 , err := json . Marshal ( resp . Check )
if err != nil {
return nil , err
}
b2 , err := json . Marshal ( struct {
Labels [ ] influxdb . Label ` json:"labels" `
Links checkLinks ` json:"links" `
2019-09-18 20:19:51 +00:00
Status string ` json:"status" `
2019-07-25 10:30:25 +00:00
} {
Links : resp . Links ,
Labels : resp . Labels ,
2019-09-18 20:19:51 +00:00
Status : resp . Status ,
2019-07-25 10:30:25 +00:00
} )
if err != nil {
return nil , err
}
return [ ] byte ( string ( b1 [ : len ( b1 ) - 1 ] ) + ", " + string ( b2 [ 1 : ] ) ) , nil
}
type checksResponse struct {
Checks [ ] * checkResponse ` json:"checks" `
Links * influxdb . PagingLinks ` json:"links" `
}
2019-09-18 20:19:51 +00:00
func ( h * CheckHandler ) newCheckResponse ( ctx context . Context , chk influxdb . Check , labels [ ] * influxdb . Label ) ( * checkResponse , error ) {
2019-09-24 19:48:36 +00:00
// TODO(desa): this should be handled in the check and not exposed in http land, but is currently blocking the FE. https://github.com/influxdata/influxdb/issues/15259
task , err := h . TaskService . FindTaskByID ( ctx , chk . GetTaskID ( ) )
if err != nil {
return nil , err
}
2019-08-07 22:34:07 +00:00
// Ensure that we don't expose that this creates a task behind the scene
chk . ClearPrivateData ( )
2019-07-25 10:30:25 +00:00
res := & checkResponse {
Check : chk ,
Links : checkLinks {
Self : fmt . Sprintf ( "/api/v2/checks/%s" , chk . GetID ( ) ) ,
Labels : fmt . Sprintf ( "/api/v2/checks/%s/labels" , chk . GetID ( ) ) ,
Members : fmt . Sprintf ( "/api/v2/checks/%s/members" , chk . GetID ( ) ) ,
Owners : fmt . Sprintf ( "/api/v2/checks/%s/owners" , chk . GetID ( ) ) ,
2019-11-08 16:23:38 +00:00
Query : fmt . Sprintf ( "/api/v2/checks/%s/query" , chk . GetID ( ) ) ,
2019-07-25 10:30:25 +00:00
} ,
Labels : [ ] influxdb . Label { } ,
}
for _ , l := range labels {
res . Labels = append ( res . Labels , * l )
}
2019-09-18 20:19:51 +00:00
res . Status = task . Status
return res , nil
2019-07-25 10:30:25 +00:00
}
2019-09-18 20:19:51 +00:00
func ( h * CheckHandler ) newChecksResponse ( ctx context . Context , chks [ ] influxdb . Check , labelService influxdb . LabelService , f influxdb . PagingFilter , opts influxdb . FindOptions ) * checksResponse {
2019-07-25 10:30:25 +00:00
resp := & checksResponse {
2019-09-18 20:19:51 +00:00
Checks : [ ] * checkResponse { } ,
2019-12-09 23:54:16 +00:00
Links : newPagingLinks ( prefixChecks , opts , f , len ( chks ) ) ,
2019-07-25 10:30:25 +00:00
}
2019-09-18 20:19:51 +00:00
for _ , chk := range chks {
2019-07-25 10:30:25 +00:00
labels , _ := labelService . FindResourceLabels ( ctx , influxdb . LabelMappingFilter { ResourceID : chk . GetID ( ) } )
2019-09-18 20:19:51 +00:00
cr , err := h . newCheckResponse ( ctx , chk , labels )
if err != nil {
2019-12-04 23:10:23 +00:00
h . log . Info ( "Failed to retrieve task associated with check" , zap . String ( "checkID" , chk . GetID ( ) . String ( ) ) )
2019-09-18 20:19:51 +00:00
continue
}
resp . Checks = append ( resp . Checks , cr )
2019-07-25 10:30:25 +00:00
}
return resp
}
func decodeGetCheckRequest ( ctx context . Context , r * http . Request ) ( i influxdb . ID , err error ) {
params := httprouter . ParamsFromContext ( ctx )
id := params . ByName ( "id" )
if id == "" {
return i , & influxdb . Error {
Code : influxdb . EInvalid ,
Msg : "url missing id" ,
}
}
if err := i . DecodeFromString ( id ) ; err != nil {
return i , err
}
return i , nil
}
func ( h * CheckHandler ) handleGetChecks ( w http . ResponseWriter , r * http . Request ) {
ctx := r . Context ( )
filter , opts , err := decodeCheckFilter ( ctx , r )
if err != nil {
2019-12-04 23:10:23 +00:00
h . log . Debug ( "Failed to decode request" , zap . Error ( err ) )
2019-07-25 10:30:25 +00:00
h . HandleHTTPError ( ctx , err , w )
return
}
chks , _ , err := h . CheckService . FindChecks ( ctx , * filter , * opts )
if err != nil {
h . HandleHTTPError ( ctx , err , w )
return
}
2019-12-04 23:10:23 +00:00
h . log . Debug ( "Checks retrieved" , zap . String ( "checks" , fmt . Sprint ( chks ) ) )
2019-07-25 10:30:25 +00:00
2019-09-18 20:19:51 +00:00
if err := encodeResponse ( ctx , w , http . StatusOK , h . newChecksResponse ( ctx , chks , h . LabelService , filter , * opts ) ) ; err != nil {
2019-12-04 23:10:23 +00:00
logEncodingError ( h . log , r , err )
2019-07-25 10:30:25 +00:00
return
}
}
2019-08-22 16:18:02 +00:00
func ( h * CheckHandler ) handleGetCheckQuery ( w http . ResponseWriter , r * http . Request ) {
ctx := r . Context ( )
id , err := decodeGetCheckRequest ( ctx , r )
if err != nil {
h . HandleHTTPError ( ctx , err , w )
return
}
chk , err := h . CheckService . FindCheckByID ( ctx , id )
if err != nil {
h . HandleHTTPError ( ctx , err , w )
return
}
flux , err := chk . GenerateFlux ( )
if err != nil {
h . HandleHTTPError ( ctx , err , w )
return
}
2019-12-04 23:10:23 +00:00
h . log . Debug ( "Check query retrieved" , zap . String ( "check query" , flux ) )
2019-08-22 16:18:02 +00:00
if err := encodeResponse ( ctx , w , http . StatusOK , newFluxResponse ( flux ) ) ; err != nil {
2019-12-04 23:10:23 +00:00
logEncodingError ( h . log , r , err )
2019-08-22 16:18:02 +00:00
return
}
}
type fluxResp struct {
Flux string ` json:"flux" `
}
func newFluxResponse ( flux string ) fluxResp {
return fluxResp {
Flux : flux ,
}
}
2019-07-25 10:30:25 +00:00
func ( h * CheckHandler ) handleGetCheck ( w http . ResponseWriter , r * http . Request ) {
ctx := r . Context ( )
id , err := decodeGetCheckRequest ( ctx , r )
if err != nil {
h . HandleHTTPError ( ctx , err , w )
return
}
chk , err := h . CheckService . FindCheckByID ( ctx , id )
if err != nil {
h . HandleHTTPError ( ctx , err , w )
return
}
2019-12-04 23:10:23 +00:00
h . log . Debug ( "Check retrieved" , zap . String ( "check" , fmt . Sprint ( chk ) ) )
2019-07-25 10:30:25 +00:00
labels , err := h . LabelService . FindResourceLabels ( ctx , influxdb . LabelMappingFilter { ResourceID : chk . GetID ( ) } )
if err != nil {
h . HandleHTTPError ( ctx , err , w )
return
}
2019-09-18 20:19:51 +00:00
cr , err := h . newCheckResponse ( ctx , chk , labels )
if err != nil {
h . HandleHTTPError ( ctx , err , w )
return
}
if err := encodeResponse ( ctx , w , http . StatusOK , cr ) ; err != nil {
2019-12-04 23:10:23 +00:00
logEncodingError ( h . log , r , err )
2019-07-25 10:30:25 +00:00
return
}
}
func decodeCheckFilter ( ctx context . Context , r * http . Request ) ( * influxdb . CheckFilter , * influxdb . FindOptions , error ) {
2019-10-21 18:11:08 +00:00
auth , err := pctx . GetAuthorizer ( ctx )
if err != nil {
return nil , nil , err
}
f := & influxdb . CheckFilter {
UserResourceMappingFilter : influxdb . UserResourceMappingFilter {
UserID : auth . GetUserID ( ) ,
ResourceType : influxdb . ChecksResourceType ,
} ,
}
2019-07-25 10:30:25 +00:00
opts , err := decodeFindOptions ( ctx , r )
if err != nil {
return f , nil , err
}
q := r . URL . Query ( )
if orgIDStr := q . Get ( "orgID" ) ; orgIDStr != "" {
orgID , err := influxdb . IDFromString ( orgIDStr )
if err != nil {
return f , opts , & influxdb . Error {
Code : influxdb . EInvalid ,
Msg : "orgID is invalid" ,
Err : err ,
}
}
f . OrgID = orgID
} else if orgNameStr := q . Get ( "org" ) ; orgNameStr != "" {
* f . Org = orgNameStr
}
return f , opts , err
}
2019-09-18 20:19:51 +00:00
type decodeStatus struct {
Status influxdb . Status ` json:"status" `
}
2019-12-18 04:54:23 +00:00
func decodePostCheckRequest ( r * http . Request ) ( postCheckRequest , error ) {
b , err := ioutil . ReadAll ( r . Body )
2019-07-25 10:30:25 +00:00
if err != nil {
2019-12-18 04:54:23 +00:00
return postCheckRequest { } , & influxdb . Error {
2019-07-25 10:30:25 +00:00
Code : influxdb . EInvalid ,
Err : err ,
}
}
defer r . Body . Close ( )
2019-12-18 04:54:23 +00:00
chk , err := check . UnmarshalJSON ( b )
2019-07-25 10:30:25 +00:00
if err != nil {
2019-12-18 04:54:23 +00:00
return postCheckRequest { } , & influxdb . Error {
2019-07-25 10:30:25 +00:00
Code : influxdb . EInvalid ,
Err : err ,
}
}
2019-08-16 11:12:28 +00:00
2019-09-18 20:19:51 +00:00
var ds decodeStatus
2019-12-18 04:54:23 +00:00
err = json . Unmarshal ( b , & ds )
2019-09-18 20:19:51 +00:00
if err != nil {
2019-12-18 04:54:23 +00:00
return postCheckRequest { } , & influxdb . Error {
2019-09-18 20:19:51 +00:00
Code : influxdb . EInvalid ,
Err : err ,
}
}
2019-09-30 23:15:14 +00:00
var dl decodeLabels
2019-12-18 04:54:23 +00:00
err = json . Unmarshal ( b , & dl )
2019-09-30 23:15:14 +00:00
if err != nil {
2019-12-18 04:54:23 +00:00
return postCheckRequest { } , & influxdb . Error {
2019-09-30 23:15:14 +00:00
Code : influxdb . EInvalid ,
Err : err ,
}
}
2019-09-18 20:19:51 +00:00
2019-12-18 04:54:23 +00:00
return postCheckRequest {
CheckCreate : influxdb . CheckCreate {
Check : chk ,
Status : ds . Status ,
} ,
Labels : dl . Labels ,
} , nil
2019-07-25 10:30:25 +00:00
}
2019-09-18 20:19:51 +00:00
func decodePutCheckRequest ( ctx context . Context , r * http . Request ) ( influxdb . CheckCreate , error ) {
2019-09-10 14:23:54 +00:00
params := httprouter . ParamsFromContext ( ctx )
id := params . ByName ( "id" )
if id == "" {
2019-12-18 04:54:23 +00:00
return influxdb . CheckCreate { } , & influxdb . Error {
2019-07-25 10:30:25 +00:00
Code : influxdb . EInvalid ,
2019-09-10 14:23:54 +00:00
Msg : "url missing id" ,
2019-07-25 10:30:25 +00:00
}
}
2019-09-10 14:23:54 +00:00
i := new ( influxdb . ID )
if err := i . DecodeFromString ( id ) ; err != nil {
2019-12-18 04:54:23 +00:00
return influxdb . CheckCreate { } , & influxdb . Error {
2019-09-10 14:23:54 +00:00
Code : influxdb . EInvalid ,
Msg : "invalid check id format" ,
}
}
2019-12-18 04:54:23 +00:00
b , err := ioutil . ReadAll ( r . Body )
2019-07-25 10:30:25 +00:00
if err != nil {
2019-12-18 04:54:23 +00:00
return influxdb . CheckCreate { } , & influxdb . Error {
2019-07-25 10:30:25 +00:00
Code : influxdb . EInvalid ,
2019-09-10 14:23:54 +00:00
Msg : "unable to read HTTP body" ,
2019-07-25 10:30:25 +00:00
Err : err ,
}
}
2019-12-18 04:54:23 +00:00
defer r . Body . Close ( )
2019-09-10 14:23:54 +00:00
2019-12-18 04:54:23 +00:00
chk , err := check . UnmarshalJSON ( b )
2019-09-10 14:23:54 +00:00
if err != nil {
2019-12-18 04:54:23 +00:00
return influxdb . CheckCreate { } , & influxdb . Error {
2019-07-25 10:30:25 +00:00
Code : influxdb . EInvalid ,
2019-09-10 14:23:54 +00:00
Msg : "malformed check body" ,
Err : err ,
2019-07-25 10:30:25 +00:00
}
}
2019-09-10 14:23:54 +00:00
chk . SetID ( * i )
if err := chk . Valid ( ) ; err != nil {
2019-12-18 04:54:23 +00:00
return influxdb . CheckCreate { } , err
2019-07-25 10:30:25 +00:00
}
2019-09-10 14:23:54 +00:00
2019-09-18 20:19:51 +00:00
var ds decodeStatus
2019-12-18 04:54:23 +00:00
err = json . Unmarshal ( b , & ds )
2019-09-18 20:19:51 +00:00
if err != nil {
2019-12-18 04:54:23 +00:00
return influxdb . CheckCreate { } , & influxdb . Error {
2019-09-18 20:19:51 +00:00
Code : influxdb . EInvalid ,
Err : err ,
}
}
2019-12-18 04:54:23 +00:00
return influxdb . CheckCreate {
Check : chk ,
Status : ds . Status ,
} , nil
2019-07-25 10:30:25 +00:00
}
type patchCheckRequest struct {
influxdb . ID
Update influxdb . CheckUpdate
}
func decodePatchCheckRequest ( ctx context . Context , r * http . Request ) ( * patchCheckRequest , error ) {
2019-12-18 04:54:23 +00:00
id := httprouter . ParamsFromContext ( ctx ) . ByName ( "id" )
2019-07-25 10:30:25 +00:00
if id == "" {
return nil , & influxdb . Error {
Code : influxdb . EInvalid ,
Msg : "url missing id" ,
}
}
var i influxdb . ID
if err := i . DecodeFromString ( id ) ; err != nil {
return nil , err
}
2019-12-18 04:54:23 +00:00
var upd influxdb . CheckUpdate
if err := json . NewDecoder ( r . Body ) . Decode ( & upd ) ; err != nil {
2019-07-25 10:30:25 +00:00
return nil , & influxdb . Error {
Code : influxdb . EInvalid ,
Msg : err . Error ( ) ,
}
}
if err := upd . Valid ( ) ; err != nil {
return nil , & influxdb . Error {
Code : influxdb . EInvalid ,
Msg : err . Error ( ) ,
}
}
2019-12-18 04:54:23 +00:00
return & patchCheckRequest {
ID : i ,
Update : upd ,
} , nil
2019-07-25 10:30:25 +00:00
}
// handlePostCheck is the HTTP handler for the POST /api/v2/checks route.
func ( h * CheckHandler ) handlePostCheck ( w http . ResponseWriter , r * http . Request ) {
ctx := r . Context ( )
2019-12-18 04:54:23 +00:00
chk , err := decodePostCheckRequest ( r )
2019-07-25 10:30:25 +00:00
if err != nil {
2019-12-04 23:10:23 +00:00
h . log . Debug ( "Failed to decode request" , zap . Error ( err ) )
2019-07-25 10:30:25 +00:00
h . HandleHTTPError ( ctx , err , w )
return
}
2019-08-16 04:00:55 +00:00
auth , err := pctx . GetAuthorizer ( ctx )
if err != nil {
h . HandleHTTPError ( ctx , err , w )
return
}
2019-09-30 23:15:14 +00:00
if err := h . CheckService . CreateCheck ( ctx , chk . CheckCreate , auth . GetUserID ( ) ) ; err != nil {
2019-07-25 10:30:25 +00:00
h . HandleHTTPError ( ctx , err , w )
return
}
2019-12-04 23:10:23 +00:00
h . log . Debug ( "Check created" , zap . String ( "check" , fmt . Sprint ( chk ) ) )
2019-07-25 10:30:25 +00:00
2019-09-30 23:15:14 +00:00
labels := h . mapNewCheckLabels ( ctx , chk . CheckCreate , chk . Labels )
cr , err := h . newCheckResponse ( ctx , chk , labels )
2019-09-18 20:19:51 +00:00
if err != nil {
h . HandleHTTPError ( ctx , err , w )
2019-09-24 19:48:36 +00:00
return
2019-09-18 20:19:51 +00:00
}
if err := encodeResponse ( ctx , w , http . StatusCreated , cr ) ; err != nil {
2019-12-04 23:10:23 +00:00
logEncodingError ( h . log , r , err )
2019-07-25 10:30:25 +00:00
return
}
}
2019-09-30 23:15:14 +00:00
// mapNewCheckLabels takes label ids from create check and maps them to the newly created check
func ( h * CheckHandler ) mapNewCheckLabels ( ctx context . Context , chk influxdb . CheckCreate , labels [ ] string ) [ ] * influxdb . Label {
var ls [ ] * influxdb . Label
for _ , sid := range labels {
var lid influxdb . ID
err := lid . DecodeFromString ( sid )
if err != nil {
continue
}
label , err := h . LabelService . FindLabelByID ( ctx , lid )
if err != nil {
continue
}
mapping := influxdb . LabelMapping {
LabelID : label . ID ,
ResourceID : chk . GetID ( ) ,
ResourceType : influxdb . ChecksResourceType ,
}
err = h . LabelService . CreateLabelMapping ( ctx , & mapping )
if err != nil {
continue
}
ls = append ( ls , label )
}
return ls
}
2019-07-25 10:30:25 +00:00
// handlePutCheck is the HTTP handler for the PUT /api/v2/checks route.
func ( h * CheckHandler ) handlePutCheck ( w http . ResponseWriter , r * http . Request ) {
ctx := r . Context ( )
chk , err := decodePutCheckRequest ( ctx , r )
if err != nil {
2019-12-04 23:10:23 +00:00
h . log . Debug ( "Failed to decode request" , zap . Error ( err ) )
2019-07-25 10:30:25 +00:00
h . HandleHTTPError ( ctx , err , w )
return
}
2019-09-18 20:19:51 +00:00
c , err := h . CheckService . UpdateCheck ( ctx , chk . GetID ( ) , chk )
2019-07-25 10:30:25 +00:00
if err != nil {
h . HandleHTTPError ( ctx , err , w )
return
}
2019-09-18 20:19:51 +00:00
labels , err := h . LabelService . FindResourceLabels ( ctx , influxdb . LabelMappingFilter { ResourceID : c . GetID ( ) } )
2019-07-25 10:30:25 +00:00
if err != nil {
h . HandleHTTPError ( ctx , err , w )
return
}
2019-12-04 23:10:23 +00:00
h . log . Debug ( "Check replaced" , zap . String ( "check" , fmt . Sprint ( c ) ) )
2019-07-25 10:30:25 +00:00
2019-09-18 20:19:51 +00:00
cr , err := h . newCheckResponse ( ctx , c , labels )
if err != nil {
h . HandleHTTPError ( ctx , err , w )
return
}
if err := encodeResponse ( ctx , w , http . StatusOK , cr ) ; err != nil {
2019-12-04 23:10:23 +00:00
logEncodingError ( h . log , r , err )
2019-07-25 10:30:25 +00:00
return
}
}
// handlePatchCheck is the HTTP handler for the PATCH /api/v2/checks/:id route.
func ( h * CheckHandler ) handlePatchCheck ( w http . ResponseWriter , r * http . Request ) {
ctx := r . Context ( )
req , err := decodePatchCheckRequest ( ctx , r )
if err != nil {
2019-12-04 23:10:23 +00:00
h . log . Debug ( "Failed to decode request" , zap . Error ( err ) )
2019-07-25 10:30:25 +00:00
h . HandleHTTPError ( ctx , err , w )
return
}
chk , err := h . CheckService . PatchCheck ( ctx , req . ID , req . Update )
if err != nil {
h . HandleHTTPError ( ctx , err , w )
return
}
labels , err := h . LabelService . FindResourceLabels ( ctx , influxdb . LabelMappingFilter { ResourceID : chk . GetID ( ) } )
if err != nil {
h . HandleHTTPError ( ctx , err , w )
return
}
2019-12-04 23:10:23 +00:00
h . log . Debug ( "Check patch" , zap . String ( "check" , fmt . Sprint ( chk ) ) )
2019-07-25 10:30:25 +00:00
2019-09-18 20:19:51 +00:00
cr , err := h . newCheckResponse ( ctx , chk , labels )
if err != nil {
h . HandleHTTPError ( ctx , err , w )
return
}
if err := encodeResponse ( ctx , w , http . StatusOK , cr ) ; err != nil {
2019-12-04 23:10:23 +00:00
logEncodingError ( h . log , r , err )
2019-07-25 10:30:25 +00:00
return
}
}
func ( h * CheckHandler ) handleDeleteCheck ( w http . ResponseWriter , r * http . Request ) {
ctx := r . Context ( )
i , err := decodeGetCheckRequest ( ctx , r )
if err != nil {
h . HandleHTTPError ( ctx , err , w )
return
}
if err = h . CheckService . DeleteCheck ( ctx , i ) ; err != nil {
h . HandleHTTPError ( ctx , err , w )
return
}
2019-12-04 23:10:23 +00:00
h . log . Debug ( "Check deleted" , zap . String ( "checkID" , fmt . Sprint ( i ) ) )
2019-07-25 10:30:25 +00:00
w . WriteHeader ( http . StatusNoContent )
}