Skip to content

Commit

Permalink
De-couple shard and weaver packages
Browse files Browse the repository at this point in the history
  • Loading branch information
spy16 committed Feb 1, 2019
1 parent e7aba86 commit eb472d5
Show file tree
Hide file tree
Showing 17 changed files with 138 additions and 251 deletions.
31 changes: 6 additions & 25 deletions server/endpoint.go → endpoint.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,14 @@
package server
package weaver

import (
"encoding/json"
"fmt"
"net/http"

"github.com/gojektech/weaver"
"github.com/gojektech/weaver/pkg/matcher"
"github.com/gojektech/weaver/pkg/shard"
"github.com/pkg/errors"
)

var shardFuncTable = map[string]SharderGenerator{
"lookup": shard.NewLookupStrategy,
"prefix-lookup": shard.NewPrefixLookupStrategy,
"none": shard.NewNoStrategy,
"modulo": shard.NewModuloStrategy,
"hashring": shard.NewHashRingStrategy,
"s2": shard.NewS2Strategy,
}

// EndpointConfig - Defines a config for external service
type EndpointConfig struct {
Matcher string `json:"matcher"`
Expand All @@ -39,22 +28,14 @@ func (endpointConfig *EndpointConfig) genShardKeyFunc() (shardKeyFunc, error) {
}, nil
}

type SharderGenerator func(json.RawMessage) (shard.Sharder, error)

type Endpoint struct {
sharder shard.Sharder
sharder Sharder
shardKeyFunc shardKeyFunc
}

func NewEndpoint(endpointConfig *EndpointConfig) (*Endpoint, error) {
shardFunc, found := shardFuncTable[endpointConfig.ShardFunc]
if !found {
return nil, errors.WithStack(fmt.Errorf("failed to find ShardFunc for: %s", endpointConfig.ShardFunc))
}

sharder, err := shardFunc(endpointConfig.ShardConfig)
if err != nil {
return nil, errors.Wrapf(err, "failed to get sharder for %s", endpointConfig.ShardExpr)
func NewEndpoint(endpointConfig *EndpointConfig, sharder Sharder) (*Endpoint, error) {
if sharder == nil {
return nil, errors.New("nil sharder passed in")
}

shardKeyFunc, err := endpointConfig.genShardKeyFunc()
Expand All @@ -68,7 +49,7 @@ func NewEndpoint(endpointConfig *EndpointConfig) (*Endpoint, error) {
}, nil
}

func (endpoint *Endpoint) Shard(request *http.Request) (*weaver.Backend, error) {
func (endpoint *Endpoint) Shard(request *http.Request) (*Backend, error) {
shardKey, err := endpoint.shardKeyFunc(request)
if err != nil {
return nil, errors.Wrapf(err, "failed to find shardKey")
Expand Down
44 changes: 44 additions & 0 deletions endpoint_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package weaver

import (
"encoding/json"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestNewEndpoint(t *testing.T) {
endpointConfig := &EndpointConfig{
Matcher: "path",
ShardExpr: "/.*",
ShardFunc: "lookup",
ShardConfig: json.RawMessage(`{}`),
}
sharder := &stubSharder{}

endpoint, err := NewEndpoint(endpointConfig, sharder)
require.NoError(t, err, "should not fail to create an endpoint from endpointConfig")
assert.NotNil(t, endpoint, "should create an endpoint")
assert.Equal(t, sharder, endpoint.sharder)
}

func TestNewEndpoint_SharderIsNil(t *testing.T) {
endpointConfig := &EndpointConfig{
Matcher: "path",
ShardExpr: "/.*",
ShardFunc: "lookup",
ShardConfig: json.RawMessage(`{}`),
}

endpoint, err := NewEndpoint(endpointConfig, nil)
assert.Error(t, err, "should fail to create an endpoint when sharder is nil")
assert.Nil(t, endpoint)
}

type stubSharder struct {
}

func (stub *stubSharder) Shard(key string) (*Backend, error) {
return nil, nil
}
9 changes: 8 additions & 1 deletion etcd/routeloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/gojektech/weaver"
"github.com/gojektech/weaver/pkg/shard"
"sort"

etcd "github.com/coreos/etcd/client"
Expand Down Expand Up @@ -55,7 +57,12 @@ func (routeLoader *ETCDRouteLoader) GetACL(key ACLKey) (*server.ACL, error) {
return nil, err
}

acl.Endpoint, err = server.NewEndpoint(acl.EndpointConfig)
sharder, err := shard.New(acl.EndpointConfig.ShardFunc, acl.EndpointConfig.ShardConfig)
if err != nil {
return nil, errors.Wrapf(err, "failed to initialize sharder '%s'", acl.EndpointConfig.ShardFunc)
}

acl.Endpoint, err = weaver.NewEndpoint(acl.EndpointConfig, sharder)
if err != nil {
return nil, errors.Wrapf(err, "failed to create a new Endpoint for key: %s", key)
}
Expand Down
9 changes: 5 additions & 4 deletions etcd/routeloader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"errors"
"github.com/gojektech/weaver"
"reflect"
"testing"
"time"
Expand Down Expand Up @@ -46,7 +47,7 @@ func (es *ETCDRouteLoaderSuite) TestPutACL() {
aclPut := &server.ACL{
ID: "svc-01",
Criterion: "Method(`GET`) && Path(`/ping`)",
EndpointConfig: &server.EndpointConfig{
EndpointConfig: &weaver.EndpointConfig{
ShardFunc: "lookup",
Matcher: "path",
ShardExpr: "*",
Expand Down Expand Up @@ -76,7 +77,7 @@ func (es *ETCDRouteLoaderSuite) TestBootstrapRoutes() {
aclPut := &server.ACL{
ID: "svc-01",
Criterion: "Method(`GET`) && Path(`/ping`)",
EndpointConfig: &server.EndpointConfig{
EndpointConfig: &weaver.EndpointConfig{
ShardFunc: "lookup",
Matcher: "path",
ShardExpr: "*",
Expand All @@ -97,7 +98,7 @@ func (es *ETCDRouteLoaderSuite) TestBootstrapRoutesSucceedWhenARouteUpsertFails(
aclPut := &server.ACL{
ID: "svc-01",
Criterion: "Method(`GET`) && Path(`/ping`)",
EndpointConfig: &server.EndpointConfig{
EndpointConfig: &weaver.EndpointConfig{
ShardFunc: "lookup",
Matcher: "path",
ShardExpr: "*",
Expand Down Expand Up @@ -201,7 +202,7 @@ func newTestACL(matcher string) *server.ACL {
return &server.ACL{
ID: "svc-01",
Criterion: "Method(`GET`) && Path(`/ping`)",
EndpointConfig: &server.EndpointConfig{
EndpointConfig: &weaver.EndpointConfig{
ShardFunc: "lookup",
Matcher: matcher,
ShardExpr: "*",
Expand Down
2 changes: 1 addition & 1 deletion pkg/shard/hashring.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/pkg/errors"
)

func NewHashRingStrategy(data json.RawMessage) (Sharder, error) {
func NewHashRingStrategy(data json.RawMessage) (weaver.Sharder, error) {
cfg := HashRingStrategyConfig{}
if err := json.Unmarshal(data, &cfg); err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion pkg/shard/lookup.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"github.com/gojektech/weaver"
)

func NewLookupStrategy(data json.RawMessage) (Sharder, error) {
func NewLookupStrategy(data json.RawMessage) (weaver.Sharder, error) {
shardConfig := map[string]BackendDefinition{}
if err := json.Unmarshal(data, &shardConfig); err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion pkg/shard/modulo.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/pkg/errors"
)

func NewModuloStrategy(data json.RawMessage) (Sharder, error) {
func NewModuloStrategy(data json.RawMessage) (weaver.Sharder, error) {
shardConfig := map[string]BackendDefinition{}
if err := json.Unmarshal(data, &shardConfig); err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion pkg/shard/no.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/pkg/errors"
)

func NewNoStrategy(data json.RawMessage) (Sharder, error) {
func NewNoStrategy(data json.RawMessage) (weaver.Sharder, error) {
cfg := NoStrategyConfig{}
if err := json.Unmarshal(data, &cfg); err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion pkg/shard/prefix_lookup.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func (plg prefixLookupConfig) Validate() error {
return nil
}

func NewPrefixLookupStrategy(data json.RawMessage) (Sharder, error) {
func NewPrefixLookupStrategy(data json.RawMessage) (weaver.Sharder, error) {
prefixLookupConfig := &prefixLookupConfig{}

if err := json.Unmarshal(data, &prefixLookupConfig); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion pkg/shard/s2.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var (
defaultBackendS2id = "default"
)

func NewS2Strategy(data json.RawMessage) (Sharder, error) {
func NewS2Strategy(data json.RawMessage) (weaver.Sharder, error) {
cfg := S2StrategyConfig{}
if err := json.Unmarshal(data, &cfg); err != nil {
return nil, err
Expand Down
28 changes: 28 additions & 0 deletions pkg/shard/shard.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package shard

import (
"encoding/json"
"fmt"

"github.com/gojektech/weaver"
)

func New(name string, cfg json.RawMessage) (weaver.Sharder, error) {
newSharder, found := shardFuncTable[name]
if !found {
return nil, fmt.Errorf("failed to find sharder with name '%s'", name)
}

return newSharder(cfg)
}

type sharderGenerator func(json.RawMessage) (weaver.Sharder, error)

var shardFuncTable = map[string]sharderGenerator{
"lookup": NewLookupStrategy,
"prefix-lookup": NewPrefixLookupStrategy,
"none": NewNoStrategy,
"modulo": NewModuloStrategy,
"hashring": NewHashRingStrategy,
"s2": NewS2Strategy,
}
9 changes: 0 additions & 9 deletions pkg/shard/sharder.go

This file was deleted.

10 changes: 6 additions & 4 deletions server/acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ package server
import (
"encoding/json"
"fmt"

"github.com/gojektech/weaver"
)

// ACL - Connects to an external endpoint
type ACL struct {
ID string `json:"id"`
Criterion string `json:"criterion"`
EndpointConfig *EndpointConfig `json:"endpoint"`
ID string `json:"id"`
Criterion string `json:"criterion"`
EndpointConfig *weaver.EndpointConfig `json:"endpoint"`

Endpoint *Endpoint
Endpoint *weaver.Endpoint
}

// GenACL - Generates an ACL from JSON
Expand Down
Loading

0 comments on commit eb472d5

Please sign in to comment.