Merge branch v2.11 into v3.2
This commit is contained in:
commit
ca5b70e196
22 changed files with 190 additions and 68 deletions
|
@ -8,11 +8,6 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
type serviceManager interface {
|
||||
BuildHTTP(rootCtx context.Context, serviceName string) (http.Handler, error)
|
||||
LaunchHealthCheck(ctx context.Context)
|
||||
}
|
||||
|
||||
// InternalHandlers is the internal HTTP handlers builder.
|
||||
type InternalHandlers struct {
|
||||
api http.Handler
|
||||
|
@ -21,26 +16,24 @@ type InternalHandlers struct {
|
|||
prometheus http.Handler
|
||||
ping http.Handler
|
||||
acmeHTTP http.Handler
|
||||
serviceManager
|
||||
}
|
||||
|
||||
// NewInternalHandlers creates a new InternalHandlers.
|
||||
func NewInternalHandlers(next serviceManager, apiHandler, rest, metricsHandler, pingHandler, dashboard, acmeHTTP http.Handler) *InternalHandlers {
|
||||
func NewInternalHandlers(apiHandler, rest, metricsHandler, pingHandler, dashboard, acmeHTTP http.Handler) *InternalHandlers {
|
||||
return &InternalHandlers{
|
||||
api: apiHandler,
|
||||
dashboard: dashboard,
|
||||
rest: rest,
|
||||
prometheus: metricsHandler,
|
||||
ping: pingHandler,
|
||||
acmeHTTP: acmeHTTP,
|
||||
serviceManager: next,
|
||||
api: apiHandler,
|
||||
dashboard: dashboard,
|
||||
rest: rest,
|
||||
prometheus: metricsHandler,
|
||||
ping: pingHandler,
|
||||
acmeHTTP: acmeHTTP,
|
||||
}
|
||||
}
|
||||
|
||||
// BuildHTTP builds an HTTP handler.
|
||||
func (m *InternalHandlers) BuildHTTP(rootCtx context.Context, serviceName string) (http.Handler, error) {
|
||||
if !strings.HasSuffix(serviceName, "@internal") {
|
||||
return m.serviceManager.BuildHTTP(rootCtx, serviceName)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
internalHandler, err := m.get(serviceName)
|
||||
|
|
|
@ -74,13 +74,12 @@ func NewManagerFactory(staticConfiguration static.Configuration, routinesPool *s
|
|||
}
|
||||
|
||||
// Build creates a service manager.
|
||||
func (f *ManagerFactory) Build(configuration *runtime.Configuration) *InternalHandlers {
|
||||
svcManager := NewManager(configuration.Services, f.observabilityMgr, f.routinesPool, f.transportManager, f.proxyBuilder)
|
||||
|
||||
func (f *ManagerFactory) Build(configuration *runtime.Configuration) *Manager {
|
||||
var apiHandler http.Handler
|
||||
if f.api != nil {
|
||||
apiHandler = f.api(configuration)
|
||||
}
|
||||
|
||||
return NewInternalHandlers(svcManager, apiHandler, f.restHandler, f.metricsHandler, f.pingHandler, f.dashboardHandler, f.acmeHTTPHandler)
|
||||
internalHandlers := NewInternalHandlers(apiHandler, f.restHandler, f.metricsHandler, f.pingHandler, f.dashboardHandler, f.acmeHTTPHandler)
|
||||
return NewManager(configuration.Services, f.observabilityMgr, f.routinesPool, f.transportManager, f.proxyBuilder, internalHandlers)
|
||||
}
|
||||
|
|
|
@ -46,12 +46,18 @@ type ProxyBuilder interface {
|
|||
Update(configs map[string]*dynamic.ServersTransport)
|
||||
}
|
||||
|
||||
// ServiceBuilder is a Service builder.
|
||||
type ServiceBuilder interface {
|
||||
BuildHTTP(rootCtx context.Context, serviceName string) (http.Handler, error)
|
||||
}
|
||||
|
||||
// Manager The service manager.
|
||||
type Manager struct {
|
||||
routinePool *safe.Pool
|
||||
observabilityMgr *middleware.ObservabilityMgr
|
||||
transportManager httputil.TransportManager
|
||||
proxyBuilder ProxyBuilder
|
||||
serviceBuilders []ServiceBuilder
|
||||
|
||||
services map[string]http.Handler
|
||||
configs map[string]*runtime.ServiceInfo
|
||||
|
@ -60,12 +66,13 @@ type Manager struct {
|
|||
}
|
||||
|
||||
// NewManager creates a new Manager.
|
||||
func NewManager(configs map[string]*runtime.ServiceInfo, observabilityMgr *middleware.ObservabilityMgr, routinePool *safe.Pool, transportManager httputil.TransportManager, proxyBuilder ProxyBuilder) *Manager {
|
||||
func NewManager(configs map[string]*runtime.ServiceInfo, observabilityMgr *middleware.ObservabilityMgr, routinePool *safe.Pool, transportManager httputil.TransportManager, proxyBuilder ProxyBuilder, serviceBuilders ...ServiceBuilder) *Manager {
|
||||
return &Manager{
|
||||
routinePool: routinePool,
|
||||
observabilityMgr: observabilityMgr,
|
||||
transportManager: transportManager,
|
||||
proxyBuilder: proxyBuilder,
|
||||
serviceBuilders: serviceBuilders,
|
||||
services: make(map[string]http.Handler),
|
||||
configs: configs,
|
||||
healthCheckers: make(map[string]*healthcheck.ServiceHealthChecker),
|
||||
|
@ -85,6 +92,18 @@ func (m *Manager) BuildHTTP(rootCtx context.Context, serviceName string) (http.H
|
|||
return handler, nil
|
||||
}
|
||||
|
||||
// Must be before we get configs to handle services without config.
|
||||
for _, builder := range m.serviceBuilders {
|
||||
handler, err := builder.BuildHTTP(rootCtx, serviceName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if handler != nil {
|
||||
m.services[serviceName] = handler
|
||||
return handler, nil
|
||||
}
|
||||
}
|
||||
|
||||
conf, ok := m.configs[serviceName]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("the service %q does not exist", serviceName)
|
||||
|
|
|
@ -450,6 +450,48 @@ func Test1xxResponses(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
type serviceBuilderFunc func(ctx context.Context, serviceName string) (http.Handler, error)
|
||||
|
||||
func (s serviceBuilderFunc) BuildHTTP(ctx context.Context, serviceName string) (http.Handler, error) {
|
||||
return s(ctx, serviceName)
|
||||
}
|
||||
|
||||
type internalHandler struct{}
|
||||
|
||||
func (internalHandler) ServeHTTP(_ http.ResponseWriter, _ *http.Request) {}
|
||||
|
||||
func TestManager_ServiceBuilders(t *testing.T) {
|
||||
var internalHandler internalHandler
|
||||
|
||||
manager := NewManager(map[string]*runtime.ServiceInfo{
|
||||
"test@test": {
|
||||
Service: &dynamic.Service{
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{},
|
||||
},
|
||||
},
|
||||
}, nil, nil, &TransportManager{
|
||||
roundTrippers: map[string]http.RoundTripper{
|
||||
"default@internal": http.DefaultTransport,
|
||||
},
|
||||
}, nil, serviceBuilderFunc(func(rootCtx context.Context, serviceName string) (http.Handler, error) {
|
||||
if strings.HasSuffix(serviceName, "@internal") {
|
||||
return internalHandler, nil
|
||||
}
|
||||
return nil, nil
|
||||
}))
|
||||
|
||||
h, err := manager.BuildHTTP(context.Background(), "test@internal")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, internalHandler, h)
|
||||
|
||||
h, err = manager.BuildHTTP(context.Background(), "test@test")
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, h)
|
||||
|
||||
_, err = manager.BuildHTTP(context.Background(), "wrong@test")
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestManager_Build(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue