forked from NETCRACKER-P2P-Streaming/krakend
/
factory.go
92 lines (78 loc) · 3.14 KB
/
factory.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
86
87
88
89
90
91
92
package proxy
import (
"github.com/devopsfaith/krakend/config"
"github.com/devopsfaith/krakend/logging"
"github.com/devopsfaith/krakend/sd"
)
// Factory creates proxies based on the received endpoint configuration.
//
// Both, factories and backend factories, create proxies but factories are designed as a stack makers
// because they are intended to generate the complete proxy stack for a given frontend endpoint
// the app would expose and they could wrap several proxies provided by a backend factory
type Factory interface {
New(cfg *config.EndpointConfig) (Proxy, error)
}
// FactoryFunc type is an adapter to allow the use of ordinary functions as proxy factories.
// If f is a function with the appropriate signature, FactoryFunc(f) is a Factory that calls f.
type FactoryFunc func(*config.EndpointConfig) (Proxy, error)
// New implements the Factory interface
func (f FactoryFunc) New(cfg *config.EndpointConfig) (Proxy, error) { return f(cfg) }
// DefaultFactory returns a default http proxy factory with the injected logger
func DefaultFactory(logger logging.Logger) Factory {
return NewDefaultFactory(httpProxy, logger)
}
// DefaultFactoryWithSubscriber returns a default proxy factory with the injected logger and subscriber factory
func DefaultFactoryWithSubscriber(logger logging.Logger, sF sd.SubscriberFactory) Factory {
return NewDefaultFactoryWithSubscriber(httpProxy, logger, sF)
}
// NewDefaultFactory returns a default proxy factory with the injected proxy builder and logger
func NewDefaultFactory(backendFactory BackendFactory, logger logging.Logger) Factory {
return NewDefaultFactoryWithSubscriber(backendFactory, logger, sd.GetSubscriber)
}
// NewDefaultFactoryWithSubscriber returns a default proxy factory with the injected proxy builder,
// logger and subscriber factory
func NewDefaultFactoryWithSubscriber(backendFactory BackendFactory, logger logging.Logger, sF sd.SubscriberFactory) Factory {
return defaultFactory{backendFactory, logger, sF}
}
type defaultFactory struct {
backendFactory BackendFactory
logger logging.Logger
subscriberFactory sd.SubscriberFactory
}
// New implements the Factory interface
func (pf defaultFactory) New(cfg *config.EndpointConfig) (p Proxy, err error) {
switch len(cfg.Backend) {
case 0:
err = ErrNoBackends
case 1:
p, err = pf.newSingle(cfg)
default:
p, err = pf.newMulti(cfg)
}
if err != nil {
return
}
p = NewStaticMiddleware(cfg)(p)
return
}
func (pf defaultFactory) newMulti(cfg *config.EndpointConfig) (p Proxy, err error) {
backendProxy := make([]Proxy, len(cfg.Backend))
for i, backend := range cfg.Backend {
backendProxy[i] = pf.newStack(backend)
}
p = NewMergeDataMiddleware(cfg)(backendProxy...)
p = NewFlatmapMiddleware(cfg)(p)
return
}
func (pf defaultFactory) newSingle(cfg *config.EndpointConfig) (Proxy, error) {
return pf.newStack(cfg.Backend[0]), nil
}
func (pf defaultFactory) newStack(backend *config.Backend) (p Proxy) {
p = pf.backendFactory(backend)
p = NewLoadBalancedMiddlewareWithSubscriber(pf.subscriberFactory(backend))(p)
if backend.ConcurrentCalls > 1 {
p = NewConcurrentMiddleware(backend)(p)
}
p = NewRequestBuilderMiddleware(backend)(p)
return
}