mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
Add annotation to trigger on create if endpoints are enabled (#1177)
* Add annotations for creation of triggers and fns along with the test for them fixes #1178 * Log errors and still return created resource for annotation failures
This commit is contained in:
committed by
Tom Coupland
parent
24f41c29b2
commit
d336035678
@@ -3,12 +3,14 @@ package server
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/fnproject/fn/api/common"
|
||||||
"github.com/fnproject/fn/api/models"
|
"github.com/fnproject/fn/api/models"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) handleFnCreate(c *gin.Context) {
|
func (s *Server) handleFnCreate(c *gin.Context) {
|
||||||
ctx := c.Request.Context()
|
ctx := c.Request.Context()
|
||||||
|
log := common.Logger(ctx)
|
||||||
|
|
||||||
fn := &models.Fn{}
|
fn := &models.Fn{}
|
||||||
err := c.BindJSON(fn)
|
err := c.BindJSON(fn)
|
||||||
@@ -24,7 +26,22 @@ func (s *Server) handleFnCreate(c *gin.Context) {
|
|||||||
fnCreated, err := s.datastore.InsertFn(ctx, fn)
|
fnCreated, err := s.datastore.InsertFn(ctx, fn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
handleErrorResponse(c, err)
|
handleErrorResponse(c, err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, fnCreated)
|
app, err := s.datastore.GetAppByID(ctx, fnCreated.AppID)
|
||||||
|
if err != nil {
|
||||||
|
log.Debugln("Failed to lookup app.")
|
||||||
|
c.JSON(http.StatusOK, fnCreated)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fnAnnotated, err := s.fnAnnotator.AnnotateFn(c, app, fnCreated)
|
||||||
|
if err != nil {
|
||||||
|
log.Debugln("Failed to annotate fn")
|
||||||
|
c.JSON(http.StatusOK, fnCreated)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, fnAnnotated)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -361,29 +361,52 @@ func TestFnGet(t *testing.T) {
|
|||||||
|
|
||||||
func TestFnInvokeEndpointAnnotations(t *testing.T) {
|
func TestFnInvokeEndpointAnnotations(t *testing.T) {
|
||||||
a := &models.App{ID: "app_id", Name: "myapp"}
|
a := &models.App{ID: "app_id", Name: "myapp"}
|
||||||
fn := &models.Fn{ID: "fnid", AppID: a.ID, Name: "fnname"}
|
fn := &models.Fn{AppID: a.ID, Name: "fnname", Image: "fnproject/image"}
|
||||||
|
|
||||||
commonDS := datastore.NewMockInit([]*models.App{a}, []*models.Fn{fn})
|
commonDS := datastore.NewMockInit([]*models.App{a})
|
||||||
|
|
||||||
srv := testServer(commonDS, &mqs.Mock{}, logs.NewMock(), nil, ServerTypeAPI)
|
srv := testServer(commonDS, &mqs.Mock{}, logs.NewMock(), nil, ServerTypeAPI)
|
||||||
|
body, err := json.Marshal(fn)
|
||||||
_, rec := routerRequest(t, srv.Router, "GET", "/v2/fns/fnid", bytes.NewBuffer([]byte("")))
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to marshal json to create fn %s", err)
|
||||||
if rec.Code != http.StatusOK {
|
|
||||||
t.Fatalf("expected code %d != 200", rec.Code)
|
|
||||||
}
|
}
|
||||||
var fnGet models.Fn
|
|
||||||
err := json.NewDecoder(rec.Body).Decode(&fnGet)
|
_, createFN := routerRequest(t, srv.Router, "POST", "/v2/fns", bytes.NewReader(body))
|
||||||
|
if createFN.Code != http.StatusOK {
|
||||||
|
t.Fatalf("expected code %d != 200 %s", createFN.Code, createFN.Body.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
var fnCreate models.Fn
|
||||||
|
err = json.NewDecoder(createFN.Body).Decode(&fnCreate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Invalid json from server %s", err)
|
t.Fatalf("Invalid json from server %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
const fnEndpoint = "fnproject.io/fn/invokeEndpoint"
|
const fnEndpoint = "fnproject.io/fn/invokeEndpoint"
|
||||||
v, err := fnGet.Annotations.GetString(fnEndpoint)
|
v, err := fnCreate.Annotations.GetString(fnEndpoint)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to get fn %s", err)
|
||||||
|
}
|
||||||
|
if v != "http://127.0.0.1:8080/invoke/"+fnCreate.ID {
|
||||||
|
t.Errorf("unexpected fn val %s", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, rec := routerRequest(t, srv.Router, "GET", "/v2/fns/"+fnCreate.ID, bytes.NewBuffer([]byte("")))
|
||||||
|
|
||||||
|
if rec.Code != http.StatusOK {
|
||||||
|
t.Fatalf("expected code %d != 200", rec.Code)
|
||||||
|
}
|
||||||
|
var fnGet models.Fn
|
||||||
|
err = json.NewDecoder(rec.Body).Decode(&fnGet)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Invalid json from server %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
v, err = fnGet.Annotations.GetString(fnEndpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to get fn %s", err)
|
t.Fatalf("failed to get fn %s", err)
|
||||||
}
|
}
|
||||||
if v != "http://127.0.0.1:8080/invoke/fnid" {
|
if v != "http://127.0.0.1:8080/invoke/"+fnCreate.ID {
|
||||||
t.Errorf("unexpected fn val %s", v)
|
t.Errorf("unexpected fn val %s", v)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,7 +427,7 @@ func TestFnInvokeEndpointAnnotations(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
v, err = resp.Items[0].Annotations.GetString(fnEndpoint)
|
v, err = resp.Items[0].Annotations.GetString(fnEndpoint)
|
||||||
if v != "http://127.0.0.1:8080/invoke/fnid" {
|
if v != "http://127.0.0.1:8080/invoke/"+fnCreate.ID {
|
||||||
t.Errorf("unexpected fn val %s", v)
|
t.Errorf("unexpected fn val %s", v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/fnproject/fn/api/common"
|
||||||
"github.com/fnproject/fn/api/models"
|
"github.com/fnproject/fn/api/models"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
@@ -10,6 +12,7 @@ import (
|
|||||||
func (s *Server) handleTriggerCreate(c *gin.Context) {
|
func (s *Server) handleTriggerCreate(c *gin.Context) {
|
||||||
ctx := c.Request.Context()
|
ctx := c.Request.Context()
|
||||||
trigger := &models.Trigger{}
|
trigger := &models.Trigger{}
|
||||||
|
log := common.Logger(ctx)
|
||||||
|
|
||||||
err := c.BindJSON(trigger)
|
err := c.BindJSON(trigger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -27,5 +30,19 @@ func (s *Server) handleTriggerCreate(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, triggerCreated)
|
app, err := s.datastore.GetAppByID(ctx, triggerCreated.AppID)
|
||||||
|
if err != nil {
|
||||||
|
log.Debugln(fmt.Errorf("unexpected error - trigger app not available: %s", err))
|
||||||
|
c.JSON(http.StatusOK, triggerCreated)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
triggerAnnotated, err := s.triggerAnnotator.AnnotateTrigger(c, app, triggerCreated)
|
||||||
|
if err != nil {
|
||||||
|
log.Debugln("Failed to annotate trigger on cration")
|
||||||
|
c.JSON(http.StatusOK, triggerCreated)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, triggerAnnotated)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -315,24 +315,47 @@ func TestHTTPTriggerEndpointAnnotations(t *testing.T) {
|
|||||||
a := &models.App{ID: "appid", Name: "myapp"}
|
a := &models.App{ID: "appid", Name: "myapp"}
|
||||||
fn := &models.Fn{ID: "fnid", AppID: a.ID}
|
fn := &models.Fn{ID: "fnid", AppID: a.ID}
|
||||||
fn.SetDefaults()
|
fn.SetDefaults()
|
||||||
trig := &models.Trigger{ID: "triggerid", FnID: fn.ID, AppID: a.ID, Type: "http", Source: "/myt"}
|
trig := &models.Trigger{Name: "thetrigger", FnID: fn.ID, AppID: a.ID, Type: "http", Source: "/myt"}
|
||||||
commonDS := datastore.NewMockInit([]*models.App{a}, []*models.Fn{fn}, []*models.Trigger{trig})
|
commonDS := datastore.NewMockInit([]*models.App{a}, []*models.Fn{fn})
|
||||||
|
triggerBody, err := json.Marshal(trig)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to marshal triggerbody: %s", err)
|
||||||
|
}
|
||||||
srv := testServer(commonDS, &mqs.Mock{}, logs.NewMock(), nil, ServerTypeAPI)
|
srv := testServer(commonDS, &mqs.Mock{}, logs.NewMock(), nil, ServerTypeAPI)
|
||||||
|
|
||||||
_, rec := routerRequest(t, srv.Router, "GET", "/v2/triggers/triggerid", bytes.NewBuffer([]byte("")))
|
_, createTrigger := routerRequest(t, srv.Router, "POST", BaseRoute, bytes.NewReader(triggerBody))
|
||||||
|
|
||||||
|
if createTrigger.Code != http.StatusOK {
|
||||||
|
t.Fatalf("expected code %d != 200 %s", createTrigger.Code, createTrigger.Body.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
var triggerCreate models.Trigger
|
||||||
|
err = json.NewDecoder(createTrigger.Body).Decode(&triggerCreate)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Invalid json from server on trigger create: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
const triggerEndpoint = "fnproject.io/trigger/httpEndpoint"
|
||||||
|
v, err := triggerCreate.Annotations.GetString(triggerEndpoint)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to get trigger %s", err)
|
||||||
|
}
|
||||||
|
if v != "http://127.0.0.1:8080/t/myapp/myt" {
|
||||||
|
t.Errorf("unexpected trigger val %s", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, rec := routerRequest(t, srv.Router, "GET", "/v2/triggers/"+triggerCreate.ID, bytes.NewBuffer([]byte("")))
|
||||||
|
|
||||||
if rec.Code != http.StatusOK {
|
if rec.Code != http.StatusOK {
|
||||||
t.Fatalf("expected code %d != 200", rec.Code)
|
t.Fatalf("expected code %d != 200", rec.Code)
|
||||||
}
|
}
|
||||||
var triggerGet models.Trigger
|
var triggerGet models.Trigger
|
||||||
err := json.NewDecoder(rec.Body).Decode(&triggerGet)
|
err = json.NewDecoder(rec.Body).Decode(&triggerGet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Invalid json from server %s", err)
|
t.Fatalf("Invalid json from server %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
const triggerEndpoint = "fnproject.io/trigger/httpEndpoint"
|
v, err = triggerGet.Annotations.GetString(triggerEndpoint)
|
||||||
v, err := triggerGet.Annotations.GetString(triggerEndpoint)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to get trigger %s", err)
|
t.Fatalf("failed to get trigger %s", err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user