forked from Arrim/http-api-mock
-
Notifications
You must be signed in to change notification settings - Fork 1
/
request_router.go
85 lines (73 loc) · 2.19 KB
/
request_router.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package route
import (
"bytes"
"encoding/gob"
"sync"
"github.com/kolesa-team/http-api-mock/definition"
"github.com/kolesa-team/http-api-mock/logging"
"github.com/kolesa-team/http-api-mock/match"
)
//NewRouter returns a pointer to new RequestRouter
func NewRouter(mocks []definition.Mock, matcher match.Matcher, dUpdates chan []definition.Mock) *RequestRouter {
return &RequestRouter{
Mocks: mocks,
Matcher: match.MockMatch{},
DUpdates: dUpdates,
}
}
//RequestRouter checks http requesta and try to figure out what is the best mock for each one.
type RequestRouter struct {
Mocks []definition.Mock
Matcher match.Matcher
DUpdates chan []definition.Mock
sync.Mutex
}
func (rr *RequestRouter) Copy(src, dst *definition.Mock) {
var mod bytes.Buffer
enc := gob.NewEncoder(&mod)
dec := gob.NewDecoder(&mod)
err := enc.Encode(src)
if err != nil {
logging.Fatal("encode error:", err)
}
err = dec.Decode(dst)
if err != nil {
logging.Fatal("decode error:", err)
}
}
//Route checks the request with all available mock definitions and return the matching mock for it.
func (rr *RequestRouter) Route(req *definition.Request) (*definition.Mock, map[string]string) {
errors := make(map[string]string)
rr.Lock()
defer rr.Unlock()
for _, mock := range rr.Mocks {
m, err := rr.Matcher.Match(req, &mock.Request)
if m {
//we return a copy of it, not the definition itself because we will working on it.
md := definition.Mock{}
rr.Copy(&mock, &md)
return &md, nil
}
errors[mock.Name] = err.Error()
if err != match.ErrPathNotMatch {
logging.Printf("Discarding mock: %s Reason: %s\n", mock.Name, err.Error())
}
}
return &definition.Mock{Response: definition.Response{StatusCode: 404}}, errors
}
//SetMockDefinitions allows replace the current mock definitions for new ones.
func (rr *RequestRouter) SetMockDefinitions(mocks []definition.Mock) {
rr.Lock()
rr.Mocks = mocks
rr.Unlock()
}
//MockChangeWatch monitors the mock configuration dir and loads again all the mocks it something change.
func (rr *RequestRouter) MockChangeWatch() {
go func() {
for {
mocks := <-rr.DUpdates
rr.SetMockDefinitions(mocks)
logging.Println("New mock definitions loaded")
}
}()
}