HTTP Triggers hookup (#1086)

* Initial suypport for invoking tiggers

* dupe method

* tighten server constraints

* runner tests not working yet

* basic route tests passing

* post rebase fixes

* add hybrid support for trigger invoke and tests

* consoloidate all hybrid evil into one place

* cleanup and make triggers unique by source

* fix oops with Agent

* linting

* review fixes
This commit is contained in:
Owen Cliffe
2018-07-05 18:56:07 +01:00
committed by Reed Allman
parent b07a000a18
commit b8b544ed25
38 changed files with 2208 additions and 865 deletions

View File

@@ -5,9 +5,14 @@ import (
"strings"
"time"
"errors"
"fmt"
"github.com/fnproject/fn/api"
"github.com/fnproject/fn/api/common"
"github.com/fnproject/fn/api/models"
"github.com/gin-gonic/gin"
"net/http"
"path"
)
func (s *Server) handleRunnerEnqueue(c *gin.Context) {
@@ -18,9 +23,9 @@ func (s *Server) handleRunnerEnqueue(c *gin.Context) {
err := c.BindJSON(&call)
if err != nil {
if models.IsAPIError(err) {
handleV1ErrorResponse(c, err)
handleErrorResponse(c, err)
} else {
handleV1ErrorResponse(c, models.ErrInvalidJSON)
handleErrorResponse(c, models.ErrInvalidJSON)
}
return
}
@@ -39,7 +44,7 @@ func (s *Server) handleRunnerEnqueue(c *gin.Context) {
call.Status = "queued"
_, err = s.mq.Push(ctx, &call)
if err != nil {
handleV1ErrorResponse(c, err)
handleErrorResponse(c, err)
return
}
@@ -50,9 +55,7 @@ func (s *Server) handleRunnerEnqueue(c *gin.Context) {
// will ensure the call exists in the db in 'running' state there.
// s.datastore.InsertCall(ctx, &call)
c.JSON(200, struct {
M string `json:"msg"`
}{M: "enqueued call"})
c.String(http.StatusNoContent, "")
}
func (s *Server) handleRunnerDequeue(c *gin.Context) {
@@ -70,7 +73,7 @@ func (s *Server) handleRunnerDequeue(c *gin.Context) {
for {
call, err := s.mq.Reserve(ctx)
if err != nil {
handleV1ErrorResponse(c, err)
handleErrorResponse(c, err)
return
}
if call != nil {
@@ -97,9 +100,9 @@ func (s *Server) handleRunnerStart(c *gin.Context) {
err := c.BindJSON(&call)
if err != nil {
if models.IsAPIError(err) {
handleV1ErrorResponse(c, err)
handleErrorResponse(c, err)
} else {
handleV1ErrorResponse(c, models.ErrInvalidJSON)
handleErrorResponse(c, models.ErrInvalidJSON)
}
return
}
@@ -129,7 +132,7 @@ func (s *Server) handleRunnerStart(c *gin.Context) {
// TODO change this to only delete message if the status change fails b/c it already ran
// after messaging semantics change
if err := s.mq.Delete(ctx, &call); err != nil { // TODO change this to take some string(s), not a whole call
handleV1ErrorResponse(c, err)
handleErrorResponse(c, err)
return
}
//}
@@ -137,9 +140,7 @@ func (s *Server) handleRunnerStart(c *gin.Context) {
//return
//}
c.JSON(200, struct {
M string `json:"msg"`
}{M: "slingshot: engage"})
c.String(http.StatusNoContent, "")
}
func (s *Server) handleRunnerFinish(c *gin.Context) {
@@ -152,9 +153,9 @@ func (s *Server) handleRunnerFinish(c *gin.Context) {
err := c.BindJSON(&body)
if err != nil {
if models.IsAPIError(err) {
handleV1ErrorResponse(c, err)
handleErrorResponse(c, err)
} else {
handleV1ErrorResponse(c, models.ErrInvalidJSON)
handleErrorResponse(c, models.ErrInvalidJSON)
}
return
}
@@ -184,7 +185,49 @@ func (s *Server) handleRunnerFinish(c *gin.Context) {
//// note: Not returning err here since the job could have already finished successfully.
//}
c.JSON(200, struct {
M string `json:"msg"`
}{M: "good night, sweet prince"})
c.String(http.StatusNoContent, "")
}
// This is a sort of interim route that is V2 API style but due for deprectation
func (s *Server) handleRunnerGetRoute(c *gin.Context) {
ctx := c.Request.Context()
routePath := path.Clean("/" + c.MustGet(api.Path).(string))
route, err := s.datastore.GetRoute(ctx, c.MustGet(api.AppID).(string), routePath)
if err != nil {
handleErrorResponse(c, err)
return
}
c.JSON(http.StatusOK, route)
}
func (s *Server) handleRunnerGetTriggerBySource(c *gin.Context) {
ctx := c.Request.Context()
appId := c.MustGet(api.AppID).(string)
triggerType := c.Param(api.ParamTriggerType)
if triggerType == "" {
handleErrorResponse(c, errors.New("no trigger type in request"))
return
}
triggerSource := strings.TrimPrefix(c.Param(api.ParamTriggerSource), "/")
trigger, err := s.datastore.GetTriggerBySource(ctx, appId, triggerType, triggerSource)
if err != nil {
handleErrorResponse(c, err)
return
}
// Not clear that we really need to annotate the trigger here but ... lets do it just in case.
app, err := s.datastore.GetAppByID(ctx, trigger.AppID)
if err != nil {
handleErrorResponse(c, fmt.Errorf("unexpected error - trigger app not available: %s", err))
}
s.triggerAnnotator.AnnotateTrigger(c, app, trigger)
c.JSON(http.StatusOK, trigger)
}