Merge branch 'resolves_issue_37' into 'master'

Resolves issue 37

Closes #37

See merge request !88
This commit is contained in:
Reed Allman
2017-07-06 14:10:31 -07:00
257 changed files with 36662 additions and 10902 deletions

View File

@@ -1,96 +0,0 @@
package server
import (
"context"
"net/http"
"github.com/gin-gonic/gin"
"gitlab-odx.oracle.com/odx/functions/api"
"gitlab-odx.oracle.com/odx/functions/api/models"
"gitlab-odx.oracle.com/odx/functions/api/runner/common"
)
func (s *Server) handleRouteCreate(c *gin.Context) {
ctx := c.MustGet("ctx").(context.Context)
log := common.Logger(ctx)
var wroute models.RouteWrapper
err := c.BindJSON(&wroute)
if err != nil {
log.WithError(err).Debug(models.ErrInvalidJSON)
c.JSON(http.StatusBadRequest, simpleError(models.ErrInvalidJSON))
return
}
if wroute.Route == nil {
log.WithError(err).Debug(models.ErrInvalidJSON)
c.JSON(http.StatusBadRequest, simpleError(models.ErrRoutesMissingNew))
return
}
wroute.Route.AppName = c.MustGet(api.AppName).(string)
wroute.Route.SetDefaults()
if err := wroute.Validate(false); err != nil {
log.WithError(err).Debug(models.ErrRoutesCreate)
c.JSON(http.StatusBadRequest, simpleError(err))
return
}
// err = s.Runner.EnsureImageExists(ctx, &task.Config{
// Image: wroute.Route.Image,
// })
// if err != nil {
// c.JSON(http.StatusBadRequest, simpleError(models.ErrUsableImage))
// return
// }
app, err := s.Datastore.GetApp(ctx, wroute.Route.AppName)
if err != nil && err != models.ErrAppsNotFound {
log.WithError(err).Error(models.ErrAppsGet)
c.JSON(http.StatusInternalServerError, simpleError(models.ErrAppsGet))
return
} else if app == nil {
// Create a new application and add the route to that new application
newapp := &models.App{Name: wroute.Route.AppName}
if err := newapp.Validate(); err != nil {
log.Error(err)
c.JSON(http.StatusInternalServerError, simpleError(err))
return
}
err = s.FireBeforeAppCreate(ctx, newapp)
if err != nil {
log.WithError(err).Error(models.ErrAppsCreate)
c.JSON(http.StatusInternalServerError, simpleError(ErrInternalServerError))
return
}
_, err = s.Datastore.InsertApp(ctx, newapp)
if err != nil {
log.WithError(err).Error(models.ErrRoutesCreate)
c.JSON(http.StatusInternalServerError, simpleError(ErrInternalServerError))
return
}
err = s.FireAfterAppCreate(ctx, newapp)
if err != nil {
log.WithError(err).Error(models.ErrRoutesCreate)
c.JSON(http.StatusInternalServerError, simpleError(ErrInternalServerError))
return
}
}
route, err := s.Datastore.InsertRoute(ctx, wroute.Route)
if err != nil {
handleErrorResponse(c, err)
return
}
s.cacheRefresh(route)
c.JSON(http.StatusOK, routeResponse{"Route successfully created", route})
}

View File

@@ -0,0 +1,150 @@
package server
import (
"context"
"net/http"
"path"
"strings"
"github.com/gin-gonic/gin"
"gitlab-odx.oracle.com/odx/functions/api"
"gitlab-odx.oracle.com/odx/functions/api/models"
"gitlab-odx.oracle.com/odx/functions/api/runner/common"
)
/* handleRouteCreateOrUpdate is used to handle POST PUT and PATCH for routes.
Post will only create route if its not there and create app if its not.
create only
Post does not skip validation of zero values
Put will create app if its not there and if route is there update if not it will create new route.
update if exists or create if not exists
Put does not skip validation of zero values
Patch will not create app if it does not exist since the route needs to exist as well...
update only
Patch accepts partial updates / skips validation of zero values.
*/
func (s *Server) handleRouteCreateOrUpdate(c *gin.Context) {
ctx := c.MustGet("ctx").(context.Context)
log := common.Logger(ctx)
method := strings.ToUpper(c.Request.Method)
var wroute models.RouteWrapper
err, resperr := s.bindAndValidate(ctx, c, method, &wroute)
if err != nil || resperr != nil {
log.WithError(err).Debug(resperr)
c.JSON(http.StatusBadRequest, simpleError(resperr))
return
}
// Create the app if it does not exist.
err, resperr = s.ensureApp(ctx, c, &wroute, method)
if err != nil || resperr != nil {
log.WithError(err).Debug(resperr)
handleErrorResponse(c, resperr)
return
}
resp, err := s.updateOrInsertRoute(ctx, method, wroute)
if err != nil {
handleErrorResponse(c, err)
return
}
s.cacheRefresh(resp.Route)
c.JSON(http.StatusOK, resp)
}
// ensureApp will only execute if it is on post or put. Patch is not allowed to create apps.
func (s *Server) ensureApp(ctx context.Context, c *gin.Context, wroute *models.RouteWrapper, method string) (error, error) {
if !(method == http.MethodPost || method == http.MethodPut) {
return nil, nil
}
var app *models.App
var err error
app, err = s.Datastore.GetApp(ctx, wroute.Route.AppName)
if err != nil && err != models.ErrAppsNotFound {
return err, models.ErrAppsGet
} else if app == nil {
// Create a new application
newapp := &models.App{Name: wroute.Route.AppName}
if err = newapp.Validate(); err != nil {
return err, err
}
err = s.FireBeforeAppCreate(ctx, newapp)
if err != nil {
return err, models.ErrAppsCreate
}
_, err = s.Datastore.InsertApp(ctx, newapp)
if err != nil {
return err, models.ErrAppsCreate
}
err = s.FireAfterAppCreate(ctx, newapp)
if err != nil {
return err, models.ErrAppsCreate
}
}
return nil, nil
}
/* bindAndValidate binds the RouteWrapper to the json from the request and validates that it is correct.
If it is a put or patch it makes sure that the path in the url matches the provideed one in the body.
Defaults are set and if patch skipZero is true for validating the RouteWrapper
*/
func (s *Server) bindAndValidate(ctx context.Context, c *gin.Context, method string, wroute *models.RouteWrapper) (error, error) {
err := c.BindJSON(wroute)
if err != nil {
return err, models.ErrInvalidJSON
}
if wroute.Route == nil {
return err, models.ErrRoutesMissingNew
}
wroute.Route.AppName = c.MustGet(api.AppName).(string)
if method == http.MethodPut || method == http.MethodPatch {
p := path.Clean(c.MustGet(api.Path).(string))
if wroute.Route.Path != "" && wroute.Route.Path != p {
return models.ErrRoutesPathImmutable, models.ErrRoutesPathImmutable
}
wroute.Route.Path = p
}
wroute.Route.SetDefaults()
if err = wroute.Validate(method == http.MethodPatch); err != nil {
return models.ErrRoutesCreate, err
}
return nil, nil
}
// updateOrInsertRoute will either update or insert the route respective the method.
func (s *Server) updateOrInsertRoute(ctx context.Context, method string, wroute models.RouteWrapper) (routeResponse, error) {
var route *models.Route
var err error
resp := routeResponse{"Route successfully created", nil}
up := routeResponse{"Route successfully updated", nil}
switch method {
case http.MethodPost:
route, err = s.Datastore.InsertRoute(ctx, wroute.Route)
case http.MethodPut:
route, err = s.Datastore.UpdateRoute(ctx, wroute.Route)
if err == models.ErrRoutesNotFound {
// try insert then
route, err = s.Datastore.InsertRoute(ctx, wroute.Route)
}
case http.MethodPatch:
// When patching if there is an error around the app we will return one and the update fails.
route, err = s.Datastore.UpdateRoute(ctx, wroute.Route)
resp = up
}
resp.Route = route
return resp, err
}

View File

@@ -7,60 +7,108 @@ import (
"testing"
"gitlab-odx.oracle.com/odx/functions/api/datastore"
"gitlab-odx.oracle.com/odx/functions/api/logs"
"gitlab-odx.oracle.com/odx/functions/api/models"
"gitlab-odx.oracle.com/odx/functions/api/mqs"
"gitlab-odx.oracle.com/odx/functions/api/logs"
)
type routeTestCase struct {
ds models.Datastore
logDB models.FnLog
method string
path string
body string
expectedCode int
expectedError error
}
func (test *routeTestCase) run(t *testing.T, i int, buf *bytes.Buffer) {
rnr, cancel := testRunner(t)
srv := testServer(test.ds, &mqs.Mock{}, test.logDB, rnr)
body := bytes.NewBuffer([]byte(test.body))
_, rec := routerRequest(t, srv.Router, test.method, test.path, body)
if rec.Code != test.expectedCode {
t.Log(buf.String())
t.Errorf("Test %d: Expected status code to be %d but was %d",
i, test.expectedCode, rec.Code)
}
if test.expectedError != nil {
resp := getErrorResponse(t, rec)
if resp.Error == nil {
t.Log(buf.String())
t.Errorf("Test %d: Expected error message to have `%s`, but it was nil",
i, test.expectedError)
} else if !strings.Contains(resp.Error.Message, test.expectedError.Error()) {
t.Log(buf.String())
t.Errorf("Test %d: Expected error message to have `%s`, but it was `%s`",
i, test.expectedError, resp.Error.Message)
}
}
cancel()
buf.Reset()
}
func TestRouteCreate(t *testing.T) {
buf := setLogBuffer()
for i, test := range []struct {
mock models.Datastore
logDB models.FnLog
path string
body string
expectedCode int
expectedError error
}{
for i, test := range []routeTestCase{
// errors
{datastore.NewMock(), logs.NewMock(),"/v1/apps/a/routes", ``, http.StatusBadRequest, models.ErrInvalidJSON},
{datastore.NewMock(), logs.NewMock(),"/v1/apps/a/routes", `{ }`, http.StatusBadRequest, models.ErrRoutesMissingNew},
{datastore.NewMock(), logs.NewMock(),"/v1/apps/a/routes", `{ "path": "/myroute" }`, http.StatusBadRequest, models.ErrRoutesMissingNew},
{datastore.NewMock(), logs.NewMock(),"/v1/apps/a/routes", `{ "route": { } }`, http.StatusBadRequest, models.ErrRoutesValidationMissingPath},
{datastore.NewMock(), logs.NewMock(),"/v1/apps/a/routes", `{ "route": { "path": "/myroute" } }`, http.StatusBadRequest, models.ErrRoutesValidationMissingImage},
{datastore.NewMock(), logs.NewMock(),"/v1/apps/a/routes", `{ "route": { "image": "funcy/hello" } }`, http.StatusBadRequest, models.ErrRoutesValidationMissingPath},
{datastore.NewMock(), logs.NewMock(),"/v1/apps/a/routes", `{ "route": { "image": "funcy/hello", "path": "myroute" } }`, http.StatusBadRequest, models.ErrRoutesValidationInvalidPath},
{datastore.NewMock(), logs.NewMock(),"/v1/apps/$/routes", `{ "route": { "image": "funcy/hello", "path": "/myroute" } }`, http.StatusInternalServerError, models.ErrAppsValidationInvalidName},
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", ``, http.StatusBadRequest, models.ErrInvalidJSON},
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ }`, http.StatusBadRequest, models.ErrRoutesMissingNew},
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "path": "/myroute" }`, http.StatusBadRequest, models.ErrRoutesMissingNew},
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { } }`, http.StatusBadRequest, models.ErrRoutesValidationMissingPath},
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { "path": "/myroute" } }`, http.StatusBadRequest, models.ErrRoutesValidationMissingImage},
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { "image": "funcy/hello" } }`, http.StatusBadRequest, models.ErrRoutesValidationMissingPath},
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { "image": "funcy/hello", "path": "myroute" } }`, http.StatusBadRequest, models.ErrRoutesValidationInvalidPath},
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/$/routes", `{ "route": { "image": "funcy/hello", "path": "/myroute" } }`, http.StatusInternalServerError, models.ErrAppsValidationInvalidName},
{datastore.NewMockInit(nil,
[]*models.Route{
{
AppName: "a",
Path: "/myroute",
},
}, nil, nil,
), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { "image": "funcy/hello", "path": "/myroute" } }`, http.StatusConflict, models.ErrRoutesAlreadyExists},
// success
{datastore.NewMock(), logs.NewMock(),"/v1/apps/a/routes", `{ "route": { "image": "funcy/hello", "path": "/myroute" } }`, http.StatusOK, nil},
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { "image": "funcy/hello", "path": "/myroute" } }`, http.StatusOK, nil},
} {
rnr, cancel := testRunner(t)
srv := testServer(test.mock, &mqs.Mock{}, test.logDB, rnr)
test.run(t, i, buf)
}
}
body := bytes.NewBuffer([]byte(test.body))
_, rec := routerRequest(t, srv.Router, "POST", test.path, body)
func TestRoutePut(t *testing.T) {
buf := setLogBuffer()
if rec.Code != test.expectedCode {
t.Log(buf.String())
t.Errorf("Test %d: Expected status code to be %d but was %d",
i, test.expectedCode, rec.Code)
}
for i, test := range []routeTestCase{
// errors
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ }`, http.StatusBadRequest, models.ErrRoutesMissingNew},
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "path": "/myroute" }`, http.StatusBadRequest, models.ErrRoutesMissingNew},
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { } }`, http.StatusBadRequest, models.ErrRoutesValidationMissingImage},
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "path": "/myroute" } }`, http.StatusBadRequest, models.ErrRoutesValidationMissingImage},
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "image": "funcy/hello", "path": "myroute" } }`, http.StatusBadRequest, models.ErrRoutesPathImmutable},
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "image": "funcy/hello", "path": "diffRoute" } }`, http.StatusBadRequest, models.ErrRoutesPathImmutable},
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/$/routes/myroute", `{ "route": { "image": "funcy/hello", "path": "/myroute" } }`, http.StatusInternalServerError, models.ErrAppsValidationInvalidName},
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "type": "invalid-type" } }`, http.StatusBadRequest, models.ErrRoutesValidationInvalidType},
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "format": "invalid-format" } }`, http.StatusBadRequest, models.ErrRoutesValidationInvalidFormat},
if test.expectedError != nil {
resp := getErrorResponse(t, rec)
if resp.Error == nil {
t.Log(buf.String())
t.Errorf("Test %d: Expected error message to have `%s`, but it was nil",
i, test.expectedError)
} else if !strings.Contains(resp.Error.Message, test.expectedError.Error()) {
t.Log(buf.String())
t.Errorf("Test %d: Expected error message to have `%s`, but it was `%s`",
i, test.expectedError, resp.Error.Message)
}
}
cancel()
// success
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "image": "funcy/hello", "path": "/myroute" } }`, http.StatusOK, nil},
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "image": "funcy/hello" } }`, http.StatusOK, nil},
} {
test.run(t, i, buf)
test.ds = datastore.NewMockInit(nil,
[]*models.Route{
{
AppName: "a",
Path: "/myroute",
},
}, nil, nil,
)
test.run(t, i, buf)
}
}
@@ -75,12 +123,12 @@ func TestRouteDelete(t *testing.T) {
expectedCode int
expectedError error
}{
{datastore.NewMock(), logs.NewMock(),"/v1/apps/a/routes/missing", "", http.StatusNotFound, nil},
{datastore.NewMock(), logs.NewMock(), "/v1/apps/a/routes/missing", "", http.StatusNotFound, models.ErrRoutesNotFound},
{datastore.NewMockInit(nil,
[]*models.Route{
{Path: "/myroute", AppName: "a"},
}, nil, nil,
), logs.NewMock(),"/v1/apps/a/routes/myroute", "", http.StatusOK, nil},
), logs.NewMock(), "/v1/apps/a/routes/myroute", "", http.StatusOK, nil},
} {
rnr, cancel := testRunner(t)
srv := testServer(test.ds, &mqs.Mock{}, test.logDB, rnr)
@@ -186,19 +234,12 @@ func TestRouteGet(t *testing.T) {
func TestRouteUpdate(t *testing.T) {
buf := setLogBuffer()
for i, test := range []struct {
ds models.Datastore
logDB models.FnLog
path string
body string
expectedCode int
expectedError error
}{
for i, test := range []routeTestCase{
// errors
{datastore.NewMock(), logs.NewMock(),"/v1/apps/a/routes/myroute/do", ``, http.StatusBadRequest, models.ErrInvalidJSON},
{datastore.NewMock(), logs.NewMock(),"/v1/apps/a/routes/myroute/do", `{}`, http.StatusBadRequest, models.ErrRoutesMissingNew},
{datastore.NewMock(), logs.NewMock(),"/v1/apps/a/routes/myroute/do", `{ "route": { "type": "invalid-type" } }`, http.StatusBadRequest, nil},
{datastore.NewMock(), logs.NewMock(),"/v1/apps/a/routes/myroute/do", `{ "route": { "format": "invalid-format" } }`, http.StatusBadRequest, nil},
{datastore.NewMock(), logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/do", ``, http.StatusBadRequest, models.ErrInvalidJSON},
{datastore.NewMock(), logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/do", `{}`, http.StatusBadRequest, models.ErrRoutesMissingNew},
{datastore.NewMock(), logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/do", `{ "route": { "type": "invalid-type" } }`, http.StatusBadRequest, models.ErrRoutesValidationInvalidType},
{datastore.NewMock(), logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/do", `{ "route": { "format": "invalid-format" } }`, http.StatusBadRequest, models.ErrRoutesValidationInvalidFormat},
// success
{datastore.NewMockInit(nil,
@@ -208,7 +249,7 @@ func TestRouteUpdate(t *testing.T) {
Path: "/myroute/do",
},
}, nil, nil,
), logs.NewMock(),"/v1/apps/a/routes/myroute/do", `{ "route": { "image": "funcy/hello" } }`, http.StatusOK, nil},
), logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/do", `{ "route": { "image": "funcy/hello" } }`, http.StatusOK, nil},
// Addresses #381
{datastore.NewMockInit(nil,
@@ -218,31 +259,8 @@ func TestRouteUpdate(t *testing.T) {
Path: "/myroute/do",
},
}, nil, nil,
), logs.NewMock(),"/v1/apps/a/routes/myroute/do", `{ "route": { "path": "/otherpath" } }`, http.StatusBadRequest, nil},
), logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/do", `{ "route": { "path": "/otherpath" } }`, http.StatusBadRequest, models.ErrRoutesPathImmutable},
} {
rnr, cancel := testRunner(t)
srv := testServer(test.ds, &mqs.Mock{}, test.logDB, rnr)
body := bytes.NewBuffer([]byte(test.body))
_, rec := routerRequest(t, srv.Router, "PATCH", test.path, body)
if rec.Code != test.expectedCode {
t.Log(buf.String())
t.Errorf("Test %d: Expected status code to be %d but was %d: %s",
i, test.expectedCode, rec.Code, rec.Body.String())
}
if test.expectedError != nil {
resp := getErrorResponse(t, rec)
if !strings.Contains(resp.Error.Message, test.expectedError.Error()) {
t.Log(buf.String())
t.Errorf("Test %d: Expected error message to have `%s`",
i, test.expectedError.Error())
}
}
cancel()
test.run(t, i, buf)
}
}

View File

@@ -1,77 +0,0 @@
package server
import (
"context"
"net/http"
"path"
"github.com/gin-gonic/gin"
"gitlab-odx.oracle.com/odx/functions/api"
"gitlab-odx.oracle.com/odx/functions/api/models"
"gitlab-odx.oracle.com/odx/functions/api/runner/common"
)
func (s *Server) handleRouteUpdate(c *gin.Context) {
ctx := c.MustGet("ctx").(context.Context)
log := common.Logger(ctx)
var wroute models.RouteWrapper
err := c.BindJSON(&wroute)
if err != nil {
log.WithError(err).Debug(models.ErrInvalidJSON)
c.JSON(http.StatusBadRequest, simpleError(models.ErrInvalidJSON))
return
}
if wroute.Route == nil {
log.Debug(models.ErrRoutesMissingNew)
c.JSON(http.StatusBadRequest, simpleError(models.ErrRoutesMissingNew))
return
}
if wroute.Route.Path != "" {
log.Debug(models.ErrRoutesPathImmutable)
c.JSON(http.StatusBadRequest, simpleError(models.ErrRoutesPathImmutable))
return
}
// fmt.Printf("ROUTE BOUND: %+v", *wroute.Route)
wroute.Route.AppName = c.MustGet(api.AppName).(string)
wroute.Route.Path = path.Clean(c.MustGet(api.Path).(string))
wroute.Route.SetDefaults()
if err := wroute.Validate(true); err != nil {
log.WithError(err).Debug(models.ErrRoutesUpdate)
c.JSON(http.StatusBadRequest, simpleError(err))
return
}
if wroute.Route.Image != "" {
// This was checking that an image exists, but it's too slow of an operation. Checks at runtime now.
// err = s.Runner.EnsureImageExists(ctx, &task.Config{
// Image: wroute.Route.Image,
// })
// if err != nil {
// log.WithError(err).Debug(models.ErrRoutesUpdate)
// c.JSON(http.StatusBadRequest, simpleError(models.ErrUsableImage))
// return
// }
}
route, err := s.Datastore.UpdateRoute(ctx, wroute.Route)
if err == models.ErrRoutesNotFound {
// try insert then
route, err = s.Datastore.InsertRoute(ctx, wroute.Route)
}
if err != nil {
handleErrorResponse(c, err)
return
}
s.cacheRefresh(route)
c.JSON(http.StatusOK, routeResponse{"Route successfully updated", route})
}

View File

@@ -19,30 +19,30 @@ import (
"gitlab-odx.oracle.com/odx/functions/api"
"gitlab-odx.oracle.com/odx/functions/api/datastore"
"gitlab-odx.oracle.com/odx/functions/api/id"
"gitlab-odx.oracle.com/odx/functions/api/logs"
"gitlab-odx.oracle.com/odx/functions/api/models"
"gitlab-odx.oracle.com/odx/functions/api/mqs"
"gitlab-odx.oracle.com/odx/functions/api/runner"
"gitlab-odx.oracle.com/odx/functions/api/runner/common"
"gitlab-odx.oracle.com/odx/functions/api/server/internal/routecache"
"gitlab-odx.oracle.com/odx/functions/api/logs"
)
const (
EnvLogLevel = "log_level"
EnvMQURL = "mq_url"
EnvDBURL = "db_url"
EnvLOGDBURL = "logstore_url"
EnvLOGDBURL = "logstore_url"
EnvPort = "port" // be careful, Gin expects this variable to be "port"
EnvAPIURL = "api_url"
)
type Server struct {
Datastore models.Datastore
Runner *runner.Runner
Router *gin.Engine
MQ models.MessageQueue
Enqueue models.Enqueue
LogDB models.FnLog
Datastore models.Datastore
Runner *runner.Runner
Router *gin.Engine
MQ models.MessageQueue
Enqueue models.Enqueue
LogDB models.FnLog
apiURL string
@@ -317,9 +317,10 @@ func (s *Server) bindHandlers(ctx context.Context) {
apps := v1.Group("/apps/:app")
{
apps.GET("/routes", s.handleRouteList)
apps.POST("/routes", s.handleRouteCreate)
apps.POST("/routes", s.handleRouteCreateOrUpdate)
apps.GET("/routes/*route", s.handleRouteGet)
apps.PATCH("/routes/*route", s.handleRouteUpdate)
apps.PATCH("/routes/*route", s.handleRouteCreateOrUpdate)
apps.PUT("/routes/*route", s.handleRouteCreateOrUpdate)
apps.DELETE("/routes/*route", s.handleRouteDelete)
apps.GET("/calls/*route", s.handleCallList)
}
@@ -369,6 +370,6 @@ type fnCallsResponse struct {
}
type fnCallLogResponse struct {
Message string `json:"message"`
Log *models.FnCallLog `json:"log"`
Message string `json:"message"`
Log *models.FnCallLog `json:"log"`
}