Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve runner #74

Merged
merged 4 commits into from
Aug 29, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions api/datastore/bolt/bolt.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,13 +208,13 @@ func (ds *BoltDatastore) StoreRoute(route *models.Route) (*models.Route, error)
return route, nil
}

func (ds *BoltDatastore) RemoveRoute(appName, routeName string) error {
func (ds *BoltDatastore) RemoveRoute(appName, routePath string) error {
if appName == "" {
return models.ErrDatastoreEmptyAppName
}

if routeName == "" {
return models.ErrDatastoreEmptyRouteName
if routePath == "" {
return models.ErrDatastoreEmptyRoutePath
}

err := ds.db.Update(func(tx *bolt.Tx) error {
Expand All @@ -223,7 +223,7 @@ func (ds *BoltDatastore) RemoveRoute(appName, routeName string) error {
return err
}

err = b.Delete([]byte(routeName))
err = b.Delete([]byte(routePath))
if err != nil {
return err
}
Expand All @@ -235,13 +235,13 @@ func (ds *BoltDatastore) RemoveRoute(appName, routeName string) error {
return nil
}

func (ds *BoltDatastore) GetRoute(appName, routeName string) (*models.Route, error) {
func (ds *BoltDatastore) GetRoute(appName, routePath string) (*models.Route, error) {
if appName == "" {
return nil, models.ErrDatastoreEmptyAppName
}

if routeName == "" {
return nil, models.ErrDatastoreEmptyRouteName
if routePath == "" {
return nil, models.ErrDatastoreEmptyRoutePath
}

var route *models.Route
Expand All @@ -251,7 +251,7 @@ func (ds *BoltDatastore) GetRoute(appName, routeName string) (*models.Route, err
return err
}

v := b.Get([]byte(routeName))
v := b.Get([]byte(routePath))
if v != nil {
err = json.Unmarshal(v, &route)
}
Expand Down
2 changes: 1 addition & 1 deletion api/datastore/bolt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ func TestBolt(t *testing.T) {
t.Fatalf("Test GetRoute: error: %s", err)
}
if route.Path != testRoute.Path {
t.Fatalf("Test GetRoute: expected `route.Name` to be `%s` but it was `%s`", route.Path, testRoute.Path)
t.Fatalf("Test GetRoute: expected `route.Path` to be `%s` but it was `%s`", route.Path, testRoute.Path)
}

// Testing list routes
Expand Down
39 changes: 33 additions & 6 deletions api/datastore/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,46 +9,73 @@ type Mock struct {
FakeRoutes []*models.Route
}

func (m *Mock) GetApp(app string) (*models.App, error) {
return m.FakeApp, nil
func (m *Mock) GetApp(appName string) (*models.App, error) {
app := m.FakeApp
if app == nil && m.FakeApps != nil {
for _, a := range m.FakeApps {
if a.Name == appName {
app = a
}
}
}

return app, nil
}

func (m *Mock) GetApps(appFilter *models.AppFilter) ([]*models.App, error) {
// TODO: improve this mock method
return m.FakeApps, nil
}

func (m *Mock) StoreApp(app *models.App) (*models.App, error) {
// TODO: improve this mock method
return m.FakeApp, nil
}

func (m *Mock) RemoveApp(app string) error {
func (m *Mock) RemoveApp(appName string) error {
// TODO: improve this mock method
return nil
}

func (m *Mock) GetRoute(app, route string) (*models.Route, error) {
return m.FakeRoute, nil
func (m *Mock) GetRoute(appName, routePath string) (*models.Route, error) {
route := m.FakeRoute
if route == nil && m.FakeRoutes != nil {
for _, r := range m.FakeRoutes {
if r.AppName == appName && r.Path == routePath {
route = r
}
}
}

return route, nil
}

func (m *Mock) GetRoutes(routeFilter *models.RouteFilter) ([]*models.Route, error) {
// TODO: improve this mock method
return m.FakeRoutes, nil
}

func (m *Mock) GetRoutesByApp(appName string, routeFilter *models.RouteFilter) ([]*models.Route, error) {
// TODO: improve this mock method
return m.FakeRoutes, nil
}

func (m *Mock) StoreRoute(route *models.Route) (*models.Route, error) {
// TODO: improve this mock method
return m.FakeRoute, nil
}

func (m *Mock) RemoveRoute(app, route string) error {
func (m *Mock) RemoveRoute(appName, routePath string) error {
// TODO: improve this mock method
return nil
}

func (m *Mock) Put(key, value []byte) error {
// TODO: improve this mock method
return nil
}

func (m *Mock) Get(key []byte) ([]byte, error) {
// TODO: improve this mock method
return []byte{}, nil
}
63 changes: 41 additions & 22 deletions api/datastore/postgres/postgres.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ CREATE TABLE IF NOT EXISTS routes (
path text NOT NULL,
image character varying(256) NOT NULL,
headers text NOT NULL,
config text NOT NULL,
PRIMARY KEY (app_name, path)
);`

const appsTableCreate = `CREATE TABLE IF NOT EXISTS apps (
name character varying(256) NOT NULL PRIMARY KEY
config text NOT NULL,
);`

const extrasTableCreate = `CREATE TABLE IF NOT EXISTS extras (
Expand Down Expand Up @@ -73,13 +75,20 @@ func New(url *url.URL) (models.Datastore, error) {
}

func (ds *PostgresDatastore) StoreApp(app *models.App) (*models.App, error) {
_, err := ds.db.Exec(`
INSERT INTO apps (name)
VALUES ($1)
ON CONFLICT (name) DO NOTHING
RETURNING name;
`, app.Name)
// todo: after we support headers, the conflict should update the headers.
cbyte, err := json.Marshal(app.Config)
if err != nil {
return nil, err
}

_, err = ds.db.Exec(`
INSERT INTO apps (name, config)
VALUES ($1, $2)
ON CONFLICT (app_name) DO UPDATE SET
config = $2;
`,
app.Name,
string(cbyte),
)

if err != nil {
return nil, err
Expand All @@ -105,12 +114,15 @@ func (ds *PostgresDatastore) GetApp(name string) (*models.App, error) {
row := ds.db.QueryRow("SELECT name FROM apps WHERE name=$1", name)

var resName string
err := row.Scan(&resName)
var config string
err := row.Scan(&resName, &config)

res := &models.App{
Name: resName,
}

json.Unmarshal([]byte(config), &res.Config)

if err != nil {
return nil, err
}
Expand Down Expand Up @@ -155,32 +167,36 @@ func (ds *PostgresDatastore) GetApps(filter *models.AppFilter) ([]*models.App, e
}

func (ds *PostgresDatastore) StoreRoute(route *models.Route) (*models.Route, error) {
var headers string

hbyte, err := json.Marshal(route.Headers)
if err != nil {
return nil, err
}

headers = string(hbyte)
cbyte, err := json.Marshal(route.Config)
if err != nil {
return nil, err
}

_, err = ds.db.Exec(`
INSERT INTO routes (
app_name,
path,
image,
headers
headers,
config
)
VALUES ($1, $2, $3, $4)
ON CONFLICT (app_name, path) DO UPDATE SET
path = $2,
image = $3,
headers = $4;
config = $5;
`,
route.AppName,
route.Path,
route.Image,
headers,
string(hbyte),
string(cbyte),
)

if err != nil {
Expand All @@ -189,11 +205,11 @@ func (ds *PostgresDatastore) StoreRoute(route *models.Route) (*models.Route, err
return route, nil
}

func (ds *PostgresDatastore) RemoveRoute(appName, routeName string) error {
func (ds *PostgresDatastore) RemoveRoute(appName, routePath string) error {
_, err := ds.db.Exec(`
DELETE FROM routes
WHERE name = $1
`, routeName)
WHERE path = $1
`, routePath)

if err != nil {
return err
Expand All @@ -203,27 +219,30 @@ func (ds *PostgresDatastore) RemoveRoute(appName, routeName string) error {

func scanRoute(scanner rowScanner, route *models.Route) error {
var headerStr string
var configStr string

err := scanner.Scan(
// &route.Name,
&route.AppName,
&route.Path,
&route.Image,
&headerStr,
&configStr,
)

if headerStr == "" {
return models.ErrRoutesNotFound
}

err = json.Unmarshal([]byte(headerStr), &route.Headers)
json.Unmarshal([]byte(headerStr), &route.Headers)
json.Unmarshal([]byte(configStr), &route.Config)

return err
}

func getRoute(qr rowQuerier, routeName string) (*models.Route, error) {
func getRoute(qr rowQuerier, routePath string) (*models.Route, error) {
var route models.Route

row := qr.QueryRow(fmt.Sprintf("%s WHERE name=$1", routeSelector), routeName)
row := qr.QueryRow(fmt.Sprintf("%s WHERE name=$1", routeSelector), routePath)
err := scanRoute(row, &route)

if err == sql.ErrNoRows {
Expand All @@ -234,8 +253,8 @@ func getRoute(qr rowQuerier, routeName string) (*models.Route, error) {
return &route, nil
}

func (ds *PostgresDatastore) GetRoute(appName, routeName string) (*models.Route, error) {
return getRoute(ds.db, routeName)
func (ds *PostgresDatastore) GetRoute(appName, routePath string) (*models.Route, error) {
return getRoute(ds.db, routePath)
}

func (ds *PostgresDatastore) GetRoutes(filter *models.RouteFilter) ([]*models.Route, error) {
Expand Down
1 change: 1 addition & 0 deletions api/models/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ var (
type App struct {
Name string `json:"name"`
Routes Routes `json:"routes,omitempty"`
Config `json:"config"`
}

const (
Expand Down
3 changes: 1 addition & 2 deletions api/models/config.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package models

type Config struct {
}
type Config map[string]string

func (c *Config) Validate() error {
return nil
Expand Down
6 changes: 3 additions & 3 deletions api/models/datastore.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ type Datastore interface {
StoreApp(*App) (*App, error)
RemoveApp(appName string) error

GetRoute(appName, routeName string) (*Route, error)
GetRoute(appName, routePath string) (*Route, error)
GetRoutes(*RouteFilter) (routes []*Route, err error)
GetRoutesByApp(string, *RouteFilter) (routes []*Route, err error)
StoreRoute(*Route) (*Route, error)
RemoveRoute(appName, routeName string) error
RemoveRoute(appName, routePath string) error

// The following provide a generic key value store for arbitrary data, can be used by extensions to store extra data
// todo: should we namespace these by app? Then when an app is deleted, it can delete any of this extra data too.
Expand All @@ -22,7 +22,7 @@ type Datastore interface {

var (
ErrDatastoreEmptyAppName = errors.New("Missing app name")
ErrDatastoreEmptyRouteName = errors.New("Missing route name")
ErrDatastoreEmptyRoutePath = errors.New("Missing route name")
ErrDatastoreEmptyApp = errors.New("Missing app")
ErrDatastoreEmptyRoute = errors.New("Missing route")
)
Expand Down
1 change: 1 addition & 0 deletions api/models/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type Route struct {
Path string `json:"path,omitempty"`
Image string `json:"image,omitempty"`
Headers http.Header `json:"headers,omitempty"`
Config `json:"config"`
}

var (
Expand Down
2 changes: 1 addition & 1 deletion api/server/apps_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,5 @@ func handleAppCreate(c *gin.Context) {
return
}

c.JSON(http.StatusCreated, appResponse{"App successfully created", wapp})
c.JSON(http.StatusCreated, appResponse{"App successfully created", wapp})
}
Loading