Skip to content

Commit

Permalink
updated Transformer to use injectors, responded to reviews
Browse files Browse the repository at this point in the history
  • Loading branch information
tenczar committed Aug 25, 2018
1 parent 8137f69 commit 3d98365
Show file tree
Hide file tree
Showing 9 changed files with 475 additions and 127 deletions.
5 changes: 4 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ func main() {
funky.NewYAMLHTTPMessageConverter(),
funky.NewBase64HTTPMessageConverter(),
funky.NewPlainTextHTTPMessageConverter())
reqTransformer := funky.NewDefaultRequestTransformer(funcTimeout, secrets, rw)

injectors := []funky.ContextInjector{funky.NewTimeoutInjector(funcTimeout),
funky.NewEnvVarSecretInjector(secrets...), funky.NewRequestMetadataInjector()}
reqTransformer := funky.NewDefaultRequestTransformer(rw, injectors)

router, err := funky.NewRouter(numServers, serverFactory)
if err != nil {
Expand Down
7 changes: 7 additions & 0 deletions pkg/funky/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ func (e IllegalArgumentError) Error() string {
return fmt.Sprintf("The argument is illegal or inappropriate: %s", string(e))
}

// IllegalStateError An error indicating that the application or method is in an illegal state.
type IllegalStateError string

func (e IllegalStateError) Error() string {
return string(e)
}

// TimeoutError An error indicating that a timeout has been exceeded
type TimeoutError string

Expand Down
96 changes: 96 additions & 0 deletions pkg/funky/injector.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
///////////////////////////////////////////////////////////////////////
// Copyright (c) 2018 VMware, Inc. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
///////////////////////////////////////////////////////////////////////

package funky

import (
"net/http"
"os"
)

type ContextInjector interface {
Inject(req *Request) error
}

type HTTPRequestAware interface {
SetHTTPRequest(req *http.Request)
}

type EnvVarSecretInjector struct {
secrets []string
}

func NewEnvVarSecretInjector(secrets ...string) *EnvVarSecretInjector {
return &EnvVarSecretInjector{
secrets: secrets,
}
}

func (i *EnvVarSecretInjector) Inject(req *Request) error {
if _, ok := req.Context["secrets"]; ok {
return IllegalArgumentError("Context[\"secrets\"] already exists.")
}

secrets := map[string]string{}
for _, v := range i.secrets {
secrets[v] = os.Getenv("d_secret_" + v)
}

req.Context["secrets"] = secrets

return nil
}

type TimeoutInjector struct {
timeout int
}

func NewTimeoutInjector(timeout ...int) *TimeoutInjector {
var t int
if len(timeout) == 0 {
t = 0
} else {
t = timeout[0]
}
return &TimeoutInjector{
timeout: t,
}
}

func (i *TimeoutInjector) Inject(req *Request) error {
if _, ok := req.Context["timeout"]; ok {
return IllegalStateError("Context[\"timeout\"] already exists.")
}

req.Context["timeout"] = i.timeout

return nil
}

type RequestMetadataInjector struct {
r *http.Request
}

func NewRequestMetadataInjector() *RequestMetadataInjector {
return &RequestMetadataInjector{}
}

func (i *RequestMetadataInjector) Inject(req *Request) error {
if _, ok := req.Context["request"]; ok {
return IllegalStateError("Context[\"request\"] already exists.")
}

req.Context["request"] = map[string]interface{}{
"uri": i.r.RequestURI,
"method": i.r.Method,
"header": i.r.Header,
}

return nil
}

func (i *RequestMetadataInjector) SetHTTPRequest(req *http.Request) {
i.r = req
}
141 changes: 141 additions & 0 deletions pkg/funky/injector_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
///////////////////////////////////////////////////////////////////////
// Copyright (c) 2018 VMware, Inc. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
///////////////////////////////////////////////////////////////////////

package funky_test

import (
"net/http/httptest"
"testing"

"github.com/stretchr/testify/assert"

"github.com/dispatchframework/funky/pkg/funky"
)

func TestEnvVarSecretInjectorInjectSecretsAlreadyExists(t *testing.T) {
injector := funky.NewEnvVarSecretInjector("username", "password")

var body funky.Request
body.Context = map[string]interface{}{}
body.Context["secrets"] = map[string]string{}

err := injector.Inject(&body)

assert.Errorf(t, err, "Injector should have failed with 'Context[\"secrets\"] already exists', instead got %+v", err)
}

func TestTimeoutInjectorTimeoutAlreadyExists(t *testing.T) {
injector := funky.NewTimeoutInjector()

body := funky.Request{
Context: map[string]interface{}{
"timeout": 0,
},
}

err := injector.Inject(&body)

assert.Error(t, err)
}

func TestTimeoutInjectorEmptyConstructor(t *testing.T) {
injector := funky.NewTimeoutInjector()

body := funky.Request{
Context: map[string]interface{}{},
}

err := injector.Inject(&body)

expected := funky.Request{
Context: map[string]interface{}{
"timeout": 0,
},
}

assert.NoError(t, err)
assert.Equal(t, expected, body)
}

func TestTimeoutInjectorSingleTimeout(t *testing.T) {
injector := funky.NewTimeoutInjector(5000)

body := funky.Request{
Context: map[string]interface{}{},
}

err := injector.Inject(&body)

expected := funky.Request{
Context: map[string]interface{}{
"timeout": 5000,
},
}

assert.NoError(t, err)
assert.Equal(t, expected, body)
}

func TestTimeoutInjectorMoreThanOneTimeout(t *testing.T) {
injector := funky.NewTimeoutInjector(5000, 6000, 7000)

body := funky.Request{
Context: map[string]interface{}{},
}

err := injector.Inject(&body)

expected := funky.Request{
Context: map[string]interface{}{
"timeout": 5000,
},
}

assert.NoError(t, err)
assert.Equal(t, expected, body)
}

func TestRequestMetadataInjectorRequestAlreadyExists(t *testing.T) {
req := httptest.NewRequest("GET", "/", nil)

injector := funky.NewRequestMetadataInjector()
injector.SetHTTPRequest(req)

body := funky.Request{
Context: map[string]interface{}{
"request": map[string]string{},
},
}

err := injector.Inject(&body)

assert.Errorf(t, err, "Injector should have failed with 'Context[\"request\"] already exists, instead got %+v", err)
}

func TestRequestMetadataInjectorRequestSuccess(t *testing.T) {
req := httptest.NewRequest("GET", "/", nil)

injector := funky.NewRequestMetadataInjector()
injector.SetHTTPRequest(req)

body := funky.Request{
Context: map[string]interface{}{},
}

err := injector.Inject(&body)

expected := funky.Request{
Context: map[string]interface{}{
"request": map[string]interface{}{
"uri": req.RequestURI,
"method": req.Method,
"header": req.Header,
},
},
}

assert.NoError(t, err)
assert.Equal(t, expected, body)
}
24 changes: 24 additions & 0 deletions pkg/funky/mocks/context_injector.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions pkg/funky/mocks/http_request_aware.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 32 additions & 0 deletions pkg/funky/mocks/request_aware_context_injector.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package mocks

import (
http "net/http"

funky "github.com/dispatchframework/funky/pkg/funky"
mock "github.com/stretchr/testify/mock"
)

// HTTPRequestAwareContextInjector is mock type for HTTPRequestAware and ContextInjector types
type HTTPRequestAwareContextInjector struct {
mock.Mock
}

// SetHTTPRequest provides a mock function with given fields: req
func (_m *HTTPRequestAwareContextInjector) SetHTTPRequest(req *http.Request) {
_m.Called(req)
}

// Inject provides a mock function with given fields: req
func (_m *HTTPRequestAwareContextInjector) Inject(req *funky.Request) error {
ret := _m.Called(req)

var r0 error
if rf, ok := ret.Get(0).(func(*funky.Request) error); ok {
r0 = rf(req)
} else {
r0 = ret.Error(0)
}

return r0
}
Loading

0 comments on commit 3d98365

Please sign in to comment.