Move all endpoints on v1 to be under apps

This commit is contained in:
James
2017-07-26 11:39:35 -07:00
parent 8ade75b868
commit 6ee7619b40
9 changed files with 119 additions and 86 deletions

View File

@@ -13,6 +13,7 @@ import (
"strings" "strings"
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
"github.com/fnproject/fn/api/models"
"github.com/go-sql-driver/mysql" "github.com/go-sql-driver/mysql"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx" "github.com/jmoiron/sqlx"
@@ -20,7 +21,6 @@ import (
_ "github.com/lib/pq" _ "github.com/lib/pq"
"github.com/mattn/go-sqlite3" "github.com/mattn/go-sqlite3"
_ "github.com/mattn/go-sqlite3" _ "github.com/mattn/go-sqlite3"
"github.com/fnproject/fn/api/models"
) )
// this aims to be an ANSI-SQL compliant package that uses only question // this aims to be an ANSI-SQL compliant package that uses only question
@@ -736,9 +736,12 @@ func buildFilterCallQuery(filter *models.CallFilter) (string, []interface{}) {
} }
} }
where("path=", filter.Path)
where("app_name=", filter.AppName) where("app_name=", filter.AppName)
if filter.Path != "" {
where("path=", filter.Path)
}
return b.String(), args return b.String(), args
} }

View File

@@ -3,38 +3,22 @@ package server
import ( import (
"net/http" "net/http"
"github.com/gin-gonic/gin"
"github.com/fnproject/fn/api" "github.com/fnproject/fn/api"
"github.com/fnproject/fn/api/models" "github.com/fnproject/fn/api/models"
"github.com/gin-gonic/gin"
) )
func (s *Server) handleCallList(c *gin.Context) { func (s *Server) handleCallList(c *gin.Context) {
ctx := c.Request.Context() ctx := c.Request.Context()
appName, ok := c.MustGet(api.AppName).(string) name, ok := c.Get(api.AppName)
if ok && appName == "" { appName, conv := name.(string)
if ok && conv && appName == "" {
handleErrorResponse(c, models.ErrRoutesValidationMissingAppName) handleErrorResponse(c, models.ErrRoutesValidationMissingAppName)
return return
} }
_, err := s.Datastore.GetApp(c, appName) filter := models.CallFilter{AppName: appName, Path: c.Query(api.CRoute)}
if err != nil {
handleErrorResponse(c, err)
return
}
appRoute, ok := c.MustGet(api.Path).(string)
if ok && appRoute == "" {
handleErrorResponse(c, models.ErrRoutesValidationMissingPath)
return
}
_, err = s.Datastore.GetRoute(c, appName, appRoute)
if err != nil {
handleErrorResponse(c, err)
return
}
filter := models.CallFilter{AppName: appName, Path: appRoute}
calls, err := s.Datastore.GetTasks(ctx, &filter) calls, err := s.Datastore.GetTasks(ctx, &filter)
if err != nil { if err != nil {
@@ -42,5 +26,21 @@ func (s *Server) handleCallList(c *gin.Context) {
return return
} }
if len(calls) == 0 {
_, err = s.Datastore.GetApp(c, appName)
if err != nil {
handleErrorResponse(c, err)
return
}
if filter.Path != "" {
_, err = s.Datastore.GetRoute(c, appName, filter.Path)
if err != nil {
handleErrorResponse(c, err)
return
}
}
}
c.JSON(http.StatusOK, fnCallsResponse{"Successfully listed calls", calls}) c.JSON(http.StatusOK, fnCallsResponse{"Successfully listed calls", calls})
} }

View File

@@ -14,12 +14,6 @@ import (
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
"github.com/ccirello/supervisor" "github.com/ccirello/supervisor"
"github.com/gin-gonic/gin"
"github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/ext"
"github.com/openzipkin/zipkin-go-opentracing"
"github.com/patrickmn/go-cache"
"github.com/spf13/viper"
"github.com/fnproject/fn/api" "github.com/fnproject/fn/api"
"github.com/fnproject/fn/api/datastore" "github.com/fnproject/fn/api/datastore"
"github.com/fnproject/fn/api/id" "github.com/fnproject/fn/api/id"
@@ -28,6 +22,12 @@ import (
"github.com/fnproject/fn/api/mqs" "github.com/fnproject/fn/api/mqs"
"github.com/fnproject/fn/api/runner" "github.com/fnproject/fn/api/runner"
"github.com/fnproject/fn/api/runner/common" "github.com/fnproject/fn/api/runner/common"
"github.com/gin-gonic/gin"
"github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/ext"
"github.com/openzipkin/zipkin-go-opentracing"
"github.com/patrickmn/go-cache"
"github.com/spf13/viper"
) )
const ( const (
@@ -350,12 +350,6 @@ func (s *Server) bindHandlers(ctx context.Context) {
v1.PATCH("/apps/:app", s.handleAppUpdate) v1.PATCH("/apps/:app", s.handleAppUpdate)
v1.DELETE("/apps/:app", s.handleAppDelete) v1.DELETE("/apps/:app", s.handleAppDelete)
v1.GET("/routes", s.handleRouteList)
v1.GET("/calls/:call", s.handleCallGet)
v1.GET("/calls/:call/log", s.handleCallLogGet)
v1.DELETE("/calls/:call/log", s.handleCallLogDelete)
apps := v1.Group("/apps/:app") apps := v1.Group("/apps/:app")
{ {
apps.GET("/routes", s.handleRouteList) apps.GET("/routes", s.handleRouteList)
@@ -364,7 +358,13 @@ func (s *Server) bindHandlers(ctx context.Context) {
apps.PATCH("/routes/*route", s.handleRouteCreateOrUpdate) apps.PATCH("/routes/*route", s.handleRouteCreateOrUpdate)
apps.PUT("/routes/*route", s.handleRouteCreateOrUpdate) apps.PUT("/routes/*route", s.handleRouteCreateOrUpdate)
apps.DELETE("/routes/*route", s.handleRouteDelete) apps.DELETE("/routes/*route", s.handleRouteDelete)
apps.GET("/calls/*route", s.handleCallList)
apps.GET("/calls", s.handleCallList)
apps.GET("/calls/:call", s.handleCallGet)
apps.GET("/calls/:call/log", s.handleCallLogGet)
apps.DELETE("/calls/:call/log", s.handleCallLogDelete)
} }
} }

View File

@@ -4,11 +4,11 @@ import (
"context" "context"
"fmt" "fmt"
client "github.com/fnproject/fn/cli/client"
fnclient "github.com/funcy/functions_go/client" fnclient "github.com/funcy/functions_go/client"
apicall "github.com/funcy/functions_go/client/call" apicall "github.com/funcy/functions_go/client/call"
"github.com/funcy/functions_go/models" "github.com/funcy/functions_go/models"
"github.com/urfave/cli" "github.com/urfave/cli"
client "github.com/fnproject/fn/cli/client"
) )
type callsCmd struct { type callsCmd struct {
@@ -20,20 +20,20 @@ func calls() cli.Command {
return cli.Command{ return cli.Command{
Name: "calls", Name: "calls",
Usage: "manage function calls", Usage: "manage function calls for apps",
Subcommands: []cli.Command{ Subcommands: []cli.Command{
{ {
Name: "get", Name: "get",
Aliases: []string{"g"}, Aliases: []string{"g"},
Usage: "get function call info", Usage: "get function call info per app",
ArgsUsage: "<call-id>", ArgsUsage: "<app> <call-id>",
Action: c.get, Action: c.get,
}, },
{ {
Name: "list", Name: "list",
Aliases: []string{"l"}, Aliases: []string{"l"},
Usage: "list all calls for specific route", Usage: "list all calls for specific app / route route is optional",
ArgsUsage: "<app> <route>", ArgsUsage: "<app> [route]",
Action: c.list, Action: c.list,
}, },
}, },
@@ -56,16 +56,17 @@ func printCalls(calls []*models.Call) {
} }
func (call *callsCmd) get(ctx *cli.Context) error { func (call *callsCmd) get(ctx *cli.Context) error {
callID := ctx.Args().Get(0) app, callID := ctx.Args().Get(0), ctx.Args().Get(1)
params := apicall.GetCallsCallParams{ params := apicall.GetAppsAppCallsCallParams{
Call: callID, Call: callID,
App: app,
Context: context.Background(), Context: context.Background(),
} }
resp, err := call.client.Call.GetCallsCall(&params) resp, err := call.client.Call.GetAppsAppCallsCall(&params)
if err != nil { if err != nil {
switch err.(type) { switch err.(type) {
case *apicall.GetCallsCallNotFound: case *apicall.GetAppsAppCallsCallNotFound:
return fmt.Errorf("error: %v", err.(*apicall.GetCallsCallNotFound).Payload.Error.Message) return fmt.Errorf("error: %v", err.(*apicall.GetAppsAppCallsCallNotFound).Payload.Error.Message)
} }
return fmt.Errorf("unexpected error: %v", err) return fmt.Errorf("unexpected error: %v", err)
@@ -75,13 +76,16 @@ func (call *callsCmd) get(ctx *cli.Context) error {
} }
func (call *callsCmd) list(ctx *cli.Context) error { func (call *callsCmd) list(ctx *cli.Context) error {
app, route := ctx.Args().Get(0), ctx.Args().Get(1) app := ctx.Args().Get(0)
params := apicall.GetAppsAppCallsRouteParams{ params := apicall.GetAppsAppCallsParams{
App: app, App: app,
Route: route,
Context: context.Background(), Context: context.Background(),
} }
resp, err := call.client.Call.GetAppsAppCallsRoute(&params) if ctx.Args().Get(1) != "" {
route := ctx.Args().Get(1)
params.Route = &route
}
resp, err := call.client.Call.GetAppsAppCalls(&params)
if err != nil { if err != nil {
switch err.(type) { switch err.(type) {
case *apicall.GetCallsCallNotFound: case *apicall.GetCallsCallNotFound:

View File

@@ -18,7 +18,7 @@ import:
subpackages: subpackages:
- semver - semver
- package: github.com/funcy/functions_go - package: github.com/funcy/functions_go
version: ^0.1.34 version: ^0.1.35
subpackages: subpackages:
- client - client
- client/apps - client/apps

View File

@@ -6,7 +6,7 @@ swagger: '2.0'
info: info:
title: Oracle Functions title: Oracle Functions
description: The open source serverless platform. description: The open source serverless platform.
version: "0.1.34" version: "0.1.35"
# the domain of the service # the domain of the service
host: "127.0.0.1:8080" host: "127.0.0.1:8080"
# array of all schemes that your API supports # array of all schemes that your API supports
@@ -352,7 +352,7 @@ paths:
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/Error'
/calls/{call}/log: /apps/{app}/calls/{call}/log:
get: get:
summary: Get call logs summary: Get call logs
description: Get call logs description: Get call logs
@@ -360,6 +360,11 @@ paths:
- Call - Call
- Log - Log
parameters: parameters:
- name: app
description: App Name
required: true
type: string
in: path
- name: call - name: call
description: Call ID. description: Call ID.
required: true required: true
@@ -386,6 +391,11 @@ paths:
required: true required: true
type: string type: string
in: path in: path
- name: app
description: App name.
required: true
type: string
in: path
responses: responses:
202: 202:
description: Log delete request accepted description: Log delete request accepted
@@ -398,13 +408,18 @@ paths:
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/Error'
/calls/{call}: /apps/{app}/calls/{call}:
get: get:
summary: Get call information summary: Get call information
description: Get call information description: Get call information
tags: tags:
- Call - Call
parameters: parameters:
- name: app
description: app name
required: true
type: string
in: path
- name: call - name: call
description: Call ID. description: Call ID.
required: true required: true
@@ -420,10 +435,10 @@ paths:
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/Error'
/apps/{app}/calls/{route}: /apps/{app}/calls/:
get: get:
summary: Get route-bound calls. summary: Get app-bound calls.
description: Get route-bound calls. description: Get app-bound calls can filter to route-bound calls.
tags: tags:
- Call - Call
parameters: parameters:
@@ -434,9 +449,9 @@ paths:
in: path in: path
- name: route - name: route
description: App route. description: App route.
required: true required: false
type: string type: string
in: path in: query
responses: responses:
200: 200:
description: Calls found description: Calls found

View File

@@ -4,6 +4,7 @@ excludeDirs:
import: import:
- package: code.cloudfoundry.org/bytefmt - package: code.cloudfoundry.org/bytefmt
- package: github.com/funcy/functions_go - package: github.com/funcy/functions_go
version: ^0.1.35
subpackages: subpackages:
- models - models
- package: github.com/Sirupsen/logrus - package: github.com/Sirupsen/logrus
@@ -28,7 +29,7 @@ import:
subpackages: subpackages:
- cli/config/configfile - cli/config/configfile
- package: github.com/docker/distribution - package: github.com/docker/distribution
branch: master branch: master
- package: github.com/fsouza/go-dockerclient - package: github.com/fsouza/go-dockerclient
- package: github.com/garyburd/redigo - package: github.com/garyburd/redigo
subpackages: subpackages:

View File

@@ -15,12 +15,12 @@ func TestCalls(t *testing.T) {
t.Run("list-calls-for-missing-app", func(t *testing.T) { t.Run("list-calls-for-missing-app", func(t *testing.T) {
t.Parallel() t.Parallel()
s := SetupDefaultSuite() s := SetupDefaultSuite()
cfg := &call.GetAppsAppCallsRouteParams{ cfg := &call.GetAppsAppCallsParams{
App: s.AppName, App: s.AppName,
Route: s.RoutePath, Route: &s.RoutePath,
Context: s.Context, Context: s.Context,
} }
_, err := s.Client.Call.GetAppsAppCallsRoute(cfg) _, err := s.Client.Call.GetAppsAppCalls(cfg)
if err == nil { if err == nil {
t.Errorf("Must fail with missing app error, but got %s", err) t.Errorf("Must fail with missing app error, but got %s", err)
} }
@@ -31,12 +31,12 @@ func TestCalls(t *testing.T) {
s := SetupDefaultSuite() s := SetupDefaultSuite()
CreateApp(t, s.Context, s.Client, s.AppName, map[string]string{}) CreateApp(t, s.Context, s.Client, s.AppName, map[string]string{})
cfg := &call.GetAppsAppCallsRouteParams{ cfg := &call.GetAppsAppCallsParams{
App: s.AppName, App: s.AppName,
Route: s.RoutePath, Route: &s.RoutePath,
Context: s.Context, Context: s.Context,
} }
_, err := s.Client.Call.GetAppsAppCallsRoute(cfg) _, err := s.Client.Call.GetAppsAppCalls(cfg)
if err == nil { if err == nil {
t.Errorf("Must fail with missing route error, but got %s", err) t.Errorf("Must fail with missing route error, but got %s", err)
} }
@@ -51,12 +51,13 @@ func TestCalls(t *testing.T) {
CreateRoute(t, s.Context, s.Client, s.AppName, s.RoutePath, s.Image, s.RouteType, CreateRoute(t, s.Context, s.Client, s.AppName, s.RoutePath, s.Image, s.RouteType,
s.RouteConfig, s.RouteHeaders) s.RouteConfig, s.RouteHeaders)
cfg := &call.GetCallsCallParams{ cfg := &call.GetAppsAppCallsCallParams{
Call: "dummy", Call: "dummy",
App: s.AppName,
Context: s.Context, Context: s.Context,
} }
cfg.WithTimeout(time.Second * 60) cfg.WithTimeout(time.Second * 60)
_, err := s.Client.Call.GetCallsCall(cfg) _, err := s.Client.Call.GetAppsAppCallsCall(cfg)
if err == nil { if err == nil {
t.Error("Must fail because `dummy` call does not exist.") t.Error("Must fail because `dummy` call does not exist.")
} }
@@ -85,7 +86,10 @@ func TestCalls(t *testing.T) {
Context: s.Context, Context: s.Context,
} }
cfg.WithTimeout(time.Second * 60) cfg.WithTimeout(time.Second * 60)
_, err := s.Client.Call.GetCallsCall(cfg) _, err := s.Client.Call.GetAppsAppCalls(&call.GetAppsAppCallsParams{
App: s.AppName,
Route: &s.RoutePath,
})
if err != nil { if err != nil {
switch err.(type) { switch err.(type) {
case *call.GetCallsCallNotFound: case *call.GetCallsCallNotFound:
@@ -113,17 +117,18 @@ func TestCalls(t *testing.T) {
CallAsync(t, u, &bytes.Buffer{}) CallAsync(t, u, &bytes.Buffer{})
time.Sleep(time.Second * 8) time.Sleep(time.Second * 8)
cfg := &call.GetAppsAppCallsRouteParams{ cfg := &call.GetAppsAppCallsParams{
App: s.AppName, App: s.AppName,
Route: s.RoutePath, Route: &s.RoutePath,
Context: s.Context, Context: s.Context,
} }
calls, err := s.Client.Call.GetAppsAppCallsRoute(cfg) calls, err := s.Client.Call.GetAppsAppCalls(cfg)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %s", err) t.Errorf("Unexpected error: %s", err)
} }
if len(calls.Payload.Calls) == 0 { if calls == nil || calls.Payload == nil || calls.Payload.Calls == nil || len(calls.Payload.Calls) == 0 {
t.Errorf("Must fail. There should be at least one call to `%v` route.", s.RoutePath) t.Errorf("Must fail. There should be at least one call to `%v` route.", s.RoutePath)
return
} }
for _, c := range calls.Payload.Calls { for _, c := range calls.Payload.Calls {
if c.Path != s.RoutePath { if c.Path != s.RoutePath {

View File

@@ -159,12 +159,13 @@ func TestRouteExecutions(t *testing.T) {
callID := CallAsync(t, u, &bytes.Buffer{}) callID := CallAsync(t, u, &bytes.Buffer{})
time.Sleep(time.Second * 10) time.Sleep(time.Second * 10)
cfg := &call.GetCallsCallParams{ cfg := &call.GetAppsAppCallsCallParams{
Call: callID, Call: callID,
App: s.AppName,
Context: s.Context, Context: s.Context,
} }
cfg.WithTimeout(time.Second * 60) cfg.WithTimeout(time.Second * 60)
callResponse, err := s.Client.Call.GetCallsCall(cfg) callResponse, err := s.Client.Call.GetAppsAppCallsCall(cfg)
if err != nil { if err != nil {
switch err.(type) { switch err.(type) {
case *call.GetCallsCallNotFound: case *call.GetCallsCallNotFound:
@@ -224,12 +225,13 @@ func TestRouteExecutions(t *testing.T) {
json.NewDecoder(output).Decode(tB) json.NewDecoder(output).Decode(tB)
cfg := &call.GetCallsCallParams{ cfg := &call.GetAppsAppCallsCallParams{
Call: tB.CallID, Call: tB.CallID,
App: s.AppName,
Context: s.Context, Context: s.Context,
} }
cfg.WithTimeout(time.Second * 60) cfg.WithTimeout(time.Second * 60)
callObj, err := s.Client.Call.GetCallsCall(cfg) callObj, err := s.Client.Call.GetAppsAppCallsCall(cfg)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %s", err) t.Errorf("Unexpected error: %s", err)
} }
@@ -262,12 +264,13 @@ func TestRouteExecutions(t *testing.T) {
callID := CallAsync(t, u, &bytes.Buffer{}) callID := CallAsync(t, u, &bytes.Buffer{})
time.Sleep(15 * time.Second) time.Sleep(15 * time.Second)
cfg := &operations.GetCallsCallLogParams{ cfg := &operations.GetAppsAppCallsCallLogParams{
Call: callID, Call: callID,
App: s.AppName,
Context: s.Context, Context: s.Context,
} }
logObj, err := s.Client.Operations.GetCallsCallLog(cfg) logObj, err := s.Client.Operations.GetAppsAppCallsCallLog(cfg)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %s", err) t.Errorf("Unexpected error: %s", err)
} }
@@ -312,7 +315,7 @@ func TestRouteExecutions(t *testing.T) {
res := output.String() res := output.String()
if !strings.Contains("application/xml, application/json; q=0.2", res) { if !strings.Contains("application/xml, application/json; q=0.2", res) {
t.Errorf("HEADER_ACCEPT='application/xml, application/json; q=0.2' "+ t.Errorf("HEADER_ACCEPT='application/xml, application/json; q=0.2' "+
"should be in output, have:\n%", res) "should be in output, have:%s\n", res)
} }
DeleteRoute(t, s.Context, s.Client, s.AppName, routePath) DeleteRoute(t, s.Context, s.Client, s.AppName, routePath)
DeleteApp(t, s.Context, s.Client, s.AppName) DeleteApp(t, s.Context, s.Client, s.AppName)
@@ -342,12 +345,13 @@ func TestRouteExecutions(t *testing.T) {
callID := CallAsync(t, u, content) callID := CallAsync(t, u, content)
time.Sleep(10 * time.Second) time.Sleep(10 * time.Second)
cfg := &operations.GetCallsCallLogParams{ cfg := &operations.GetAppsAppCallsCallLogParams{
Call: callID, Call: callID,
App: s.AppName,
Context: s.Context, Context: s.Context,
} }
_, err := s.Client.Operations.GetCallsCallLog(cfg) _, err := s.Client.Operations.GetAppsAppCallsCallLog(cfg)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %s", err) t.Errorf("Unexpected error: %s", err)
@@ -359,7 +363,7 @@ func TestRouteExecutions(t *testing.T) {
t.Run("exec-oversized-log-test", func(t *testing.T) { t.Run("exec-oversized-log-test", func(t *testing.T) {
t.Parallel() t.Parallel()
t.Skip("Skipped until fix for https://github.com/fnproject/fn/issues/86.") t.Skip("Skipped until fix for https://gitlab-odx.oracle.com/odx/functions/issues/86.")
s := SetupDefaultSuite() s := SetupDefaultSuite()
routePath := "/log" routePath := "/log"
@@ -384,12 +388,13 @@ func TestRouteExecutions(t *testing.T) {
callID := CallAsync(t, u, content) callID := CallAsync(t, u, content)
time.Sleep(5 * time.Second) time.Sleep(5 * time.Second)
cfg := &operations.GetCallsCallLogParams{ cfg := &operations.GetAppsAppCallsCallLogParams{
Call: callID, Call: callID,
App: s.AppName,
Context: s.Context, Context: s.Context,
} }
logObj, err := s.Client.Operations.GetCallsCallLog(cfg) logObj, err := s.Client.Operations.GetAppsAppCallsCallLog(cfg)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %s", err) t.Errorf("Unexpected error: %s", err)
} }