mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
route filter improvement
This commit is contained in:
@@ -260,10 +260,10 @@ func (ds *BoltDatastore) GetRoute(appName, routeName string) (*models.Route, err
|
|||||||
return route, err
|
return route, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *BoltDatastore) GetRoutes(filter *models.RouteFilter) ([]*models.Route, error) {
|
func (ds *BoltDatastore) GetRoutesByApp(appName string, filter *models.RouteFilter) ([]*models.Route, error) {
|
||||||
res := []*models.Route{}
|
res := []*models.Route{}
|
||||||
err := ds.db.View(func(tx *bolt.Tx) error {
|
err := ds.db.View(func(tx *bolt.Tx) error {
|
||||||
b, err := ds.getRouteBucketForApp(tx, filter.AppName)
|
b, err := ds.getRouteBucketForApp(tx, appName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -294,6 +294,43 @@ func (ds *BoltDatastore) GetRoutes(filter *models.RouteFilter) ([]*models.Route,
|
|||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ds *BoltDatastore) GetRoutes(filter *models.RouteFilter) ([]*models.Route, error) {
|
||||||
|
res := []*models.Route{}
|
||||||
|
err := ds.db.View(func(tx *bolt.Tx) error {
|
||||||
|
i := 0
|
||||||
|
rbucket := tx.Bucket(ds.routesBucket)
|
||||||
|
|
||||||
|
b := rbucket.Cursor()
|
||||||
|
var k, v []byte
|
||||||
|
k, v = b.First()
|
||||||
|
|
||||||
|
// Iterates all buckets
|
||||||
|
for ; k != nil && v == nil; k, v = b.Next() {
|
||||||
|
bucket := rbucket.Bucket(k)
|
||||||
|
r := bucket.Cursor()
|
||||||
|
var k2, v2 []byte
|
||||||
|
k2, v2 = r.Last()
|
||||||
|
// Iterate all routes
|
||||||
|
for ; k2 != nil; k2, v2 = r.Prev() {
|
||||||
|
var route models.Route
|
||||||
|
err := json.Unmarshal(v2, &route)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if models.ApplyRouteFilter(&route, filter) {
|
||||||
|
i++
|
||||||
|
res = append(res, &route)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ds *BoltDatastore) Put(key, value []byte) error {
|
func (ds *BoltDatastore) Put(key, value []byte) error {
|
||||||
ds.db.Update(func(tx *bolt.Tx) error {
|
ds.db.Update(func(tx *bolt.Tx) error {
|
||||||
b := tx.Bucket(ds.extrasBucket) // todo: maybe namespace by app?
|
b := tx.Bucket(ds.extrasBucket) // todo: maybe namespace by app?
|
||||||
|
|||||||
@@ -122,7 +122,19 @@ func TestBolt(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Testing list routes
|
// Testing list routes
|
||||||
routes, err := ds.GetRoutes(&models.RouteFilter{AppName: testApp.Name})
|
routes, err := ds.GetRoutesByApp(testApp.Name, &models.RouteFilter{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Test GetRoutes: error: %s", err)
|
||||||
|
}
|
||||||
|
if len(routes) == 0 {
|
||||||
|
t.Fatal("Test GetRoutes: expected result count to be greater than 0")
|
||||||
|
}
|
||||||
|
if routes[0].Path != testRoute.Path {
|
||||||
|
t.Fatalf("Test GetRoutes: expected `app.Name` to be `%s` but it was `%s`", testRoute.Path, routes[0].Path)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing list routes
|
||||||
|
routes, err = ds.GetRoutes(&models.RouteFilter{Image: testRoute.Image})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Test GetRoutes: error: %s", err)
|
t.Fatalf("Test GetRoutes: error: %s", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ func (m *Mock) GetRoutes(routeFilter *models.RouteFilter) ([]*models.Route, erro
|
|||||||
return m.FakeRoutes, nil
|
return m.FakeRoutes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Mock) GetRoutesByApp(appName string, routeFilter *models.RouteFilter) ([]*models.Route, error) {
|
||||||
|
return m.FakeRoutes, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Mock) StoreRoute(route *models.Route) (*models.Route, error) {
|
func (m *Mock) StoreRoute(route *models.Route) (*models.Route, error) {
|
||||||
return m.FakeRoute, nil
|
return m.FakeRoute, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -263,6 +263,32 @@ func (ds *PostgresDatastore) GetRoutes(filter *models.RouteFilter) ([]*models.Ro
|
|||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ds *PostgresDatastore) GetRoutesByApp(appName string, filter *models.RouteFilter) ([]*models.Route, error) {
|
||||||
|
res := []*models.Route{}
|
||||||
|
filter.AppName = appName
|
||||||
|
filterQuery := buildFilterQuery(filter)
|
||||||
|
rows, err := ds.db.Query(fmt.Sprintf("%s %s", routeSelector, filterQuery))
|
||||||
|
// todo: check for no rows so we don't respond with a sql 500 err
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
var route models.Route
|
||||||
|
err := scanRoute(rows, &route)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
res = append(res, &route)
|
||||||
|
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
func buildFilterQuery(filter *models.RouteFilter) string {
|
func buildFilterQuery(filter *models.RouteFilter) string {
|
||||||
filterQuery := ""
|
filterQuery := ""
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ type Datastore interface {
|
|||||||
|
|
||||||
GetRoute(appName, routeName string) (*Route, error)
|
GetRoute(appName, routeName string) (*Route, error)
|
||||||
GetRoutes(*RouteFilter) (routes []*Route, err error)
|
GetRoutes(*RouteFilter) (routes []*Route, err error)
|
||||||
|
GetRoutesByApp(string, *RouteFilter) (routes []*Route, err error)
|
||||||
StoreRoute(*Route) (*Route, error)
|
StoreRoute(*Route) (*Route, error)
|
||||||
RemoveRoute(appName, routeName string) error
|
RemoveRoute(appName, routeName string) error
|
||||||
|
|
||||||
|
|||||||
@@ -15,17 +15,20 @@ func handleRouteList(c *gin.Context) {
|
|||||||
ctx := c.MustGet("ctx").(context.Context)
|
ctx := c.MustGet("ctx").(context.Context)
|
||||||
log := titancommon.Logger(ctx)
|
log := titancommon.Logger(ctx)
|
||||||
|
|
||||||
appName := c.Param("app")
|
filter := &models.RouteFilter{}
|
||||||
|
|
||||||
filter := &models.RouteFilter{
|
|
||||||
AppName: appName,
|
|
||||||
}
|
|
||||||
|
|
||||||
if img := c.Query("image"); img != "" {
|
if img := c.Query("image"); img != "" {
|
||||||
filter.Image = img
|
filter.Image = img
|
||||||
}
|
}
|
||||||
|
|
||||||
routes, err := Api.Datastore.GetRoutes(filter)
|
var routes []*models.Route
|
||||||
|
var err error
|
||||||
|
if app := c.Param("app"); app != "" {
|
||||||
|
routes, err = Api.Datastore.GetRoutesByApp(app, filter)
|
||||||
|
} else {
|
||||||
|
routes, err = Api.Datastore.GetRoutes(filter)
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Error(models.ErrRoutesGet)
|
log.WithError(err).Error(models.ErrRoutesGet)
|
||||||
c.JSON(http.StatusInternalServerError, simpleError(models.ErrRoutesGet))
|
c.JSON(http.StatusInternalServerError, simpleError(models.ErrRoutesGet))
|
||||||
|
|||||||
@@ -88,13 +88,12 @@ func handleRunner(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
filter := &models.RouteFilter{
|
filter := &models.RouteFilter{
|
||||||
Path: route,
|
Path: route,
|
||||||
AppName: appName,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.WithFields(logrus.Fields{"app": appName, "path": route}).Debug("Finding route on datastore")
|
log.WithFields(logrus.Fields{"app": appName, "path": route}).Debug("Finding route on datastore")
|
||||||
|
|
||||||
routes, err := Api.Datastore.GetRoutes(filter)
|
routes, err := Api.Datastore.GetRoutesByApp(appName, filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Error(models.ErrRoutesList)
|
log.WithError(err).Error(models.ErrRoutesList)
|
||||||
c.JSON(http.StatusInternalServerError, simpleError(models.ErrRoutesList))
|
c.JSON(http.StatusInternalServerError, simpleError(models.ErrRoutesList))
|
||||||
|
|||||||
@@ -113,6 +113,8 @@ func bindHandlers(engine *gin.Engine) {
|
|||||||
v1.PUT("/apps/:app", handleAppUpdate)
|
v1.PUT("/apps/:app", handleAppUpdate)
|
||||||
v1.DELETE("/apps/:app", handleAppDelete)
|
v1.DELETE("/apps/:app", handleAppDelete)
|
||||||
|
|
||||||
|
v1.GET("/routes", handleRouteList)
|
||||||
|
|
||||||
apps := v1.Group("/apps/:app")
|
apps := v1.Group("/apps/:app")
|
||||||
{
|
{
|
||||||
apps.GET("/routes", handleRouteList)
|
apps.GET("/routes", handleRouteList)
|
||||||
|
|||||||
Reference in New Issue
Block a user