-
Notifications
You must be signed in to change notification settings - Fork 66
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
794 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package backend | ||
|
||
import "context" | ||
|
||
// Handler interface for all handlers. | ||
type Handler interface { | ||
QueryDataHandler | ||
CheckHealthHandler | ||
StreamHandler | ||
AdmissionHandler | ||
CallResourceHandler | ||
CollectMetricsHandler | ||
} | ||
|
||
var _ = Handler(&BaseHandler{}) | ||
|
||
// BaseHandler base handler provides a base implementation of Handler interface | ||
// passing the request down the chain to next Handler. | ||
// This allows handlers to avoid implementing the full Handler interface. | ||
type BaseHandler struct { | ||
next Handler | ||
} | ||
|
||
// NewBaseHandler creates a new BaseHandler. | ||
func NewBaseHandler(next Handler) BaseHandler { | ||
return BaseHandler{ | ||
next: next, | ||
} | ||
} | ||
|
||
func (m BaseHandler) QueryData(ctx context.Context, req *QueryDataRequest) (*QueryDataResponse, error) { | ||
return m.next.QueryData(ctx, req) | ||
} | ||
|
||
func (m BaseHandler) CallResource(ctx context.Context, req *CallResourceRequest, sender CallResourceResponseSender) error { | ||
return m.next.CallResource(ctx, req, sender) | ||
} | ||
|
||
func (m BaseHandler) CheckHealth(ctx context.Context, req *CheckHealthRequest) (*CheckHealthResult, error) { | ||
return m.next.CheckHealth(ctx, req) | ||
} | ||
|
||
func (m BaseHandler) CollectMetrics(ctx context.Context, req *CollectMetricsRequest) (*CollectMetricsResult, error) { | ||
return m.next.CollectMetrics(ctx, req) | ||
} | ||
|
||
func (m BaseHandler) SubscribeStream(ctx context.Context, req *SubscribeStreamRequest) (*SubscribeStreamResponse, error) { | ||
return m.next.SubscribeStream(ctx, req) | ||
} | ||
|
||
func (m BaseHandler) PublishStream(ctx context.Context, req *PublishStreamRequest) (*PublishStreamResponse, error) { | ||
return m.next.PublishStream(ctx, req) | ||
} | ||
|
||
func (m BaseHandler) RunStream(ctx context.Context, req *RunStreamRequest, sender *StreamSender) error { | ||
return m.next.RunStream(ctx, req, sender) | ||
} | ||
|
||
func (m BaseHandler) ValidateAdmission(ctx context.Context, req *AdmissionRequest) (*ValidationResponse, error) { | ||
return m.next.ValidateAdmission(ctx, req) | ||
} | ||
|
||
func (m *BaseHandler) MutateAdmission(ctx context.Context, req *AdmissionRequest) (*MutationResponse, error) { | ||
return m.next.MutateAdmission(ctx, req) | ||
} | ||
|
||
func (m *BaseHandler) ConvertObject(ctx context.Context, req *ConversionRequest) (*ConversionResponse, error) { | ||
return m.next.ConvertObject(ctx, req) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
package backend | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
) | ||
|
||
var ( | ||
errNilRequest = errors.New("req cannot be nil") | ||
errNilSender = errors.New("sender cannot be nil") | ||
) | ||
|
||
// HandlerMiddleware is an interface representing the ability to create a middleware | ||
// that implements the Handler interface. | ||
type HandlerMiddleware interface { | ||
// CreateHandlerMiddleware creates a new Handler by decorating next Handler. | ||
CreateHandlerMiddleware(next Handler) Handler | ||
} | ||
|
||
// The HandlerMiddlewareFunc type is an adapter to allow the use of ordinary | ||
// functions as HandlerMiddleware's. If f is a function with the appropriate | ||
// signature, HandlerMiddlewareFunc(f) is a HandlerMiddleware that calls f. | ||
type HandlerMiddlewareFunc func(next Handler) Handler | ||
|
||
// CreateHandlerMiddleware implements the HandlerMiddleware interface. | ||
func (fn HandlerMiddlewareFunc) CreateHandlerMiddleware(next Handler) Handler { | ||
return fn(next) | ||
} | ||
|
||
// MiddlewareHandler decorates a Handler with HandlerMiddleware's. | ||
type MiddlewareHandler struct { | ||
handler Handler | ||
} | ||
|
||
// HandlerFromMiddlewares creates a new MiddlewareHandler implementing Handler that decorates finalHandler with middlewares. | ||
func HandlerFromMiddlewares(finalHandler Handler, middlewares ...HandlerMiddleware) (*MiddlewareHandler, error) { | ||
if finalHandler == nil { | ||
return nil, errors.New("finalHandler cannot be nil") | ||
} | ||
|
||
return &MiddlewareHandler{ | ||
handler: handlerFromMiddlewares(middlewares, finalHandler), | ||
}, nil | ||
} | ||
|
||
func (h *MiddlewareHandler) QueryData(ctx context.Context, req *QueryDataRequest) (*QueryDataResponse, error) { | ||
if req == nil { | ||
return nil, errNilRequest | ||
} | ||
|
||
return h.handler.QueryData(ctx, req) | ||
} | ||
|
||
func (h MiddlewareHandler) CallResource(ctx context.Context, req *CallResourceRequest, sender CallResourceResponseSender) error { | ||
if req == nil { | ||
return errNilRequest | ||
} | ||
|
||
if sender == nil { | ||
return errNilSender | ||
} | ||
|
||
return h.handler.CallResource(ctx, req, sender) | ||
} | ||
|
||
func (h MiddlewareHandler) CollectMetrics(ctx context.Context, req *CollectMetricsRequest) (*CollectMetricsResult, error) { | ||
if req == nil { | ||
return nil, errNilRequest | ||
} | ||
|
||
return h.handler.CollectMetrics(ctx, req) | ||
} | ||
|
||
func (h MiddlewareHandler) CheckHealth(ctx context.Context, req *CheckHealthRequest) (*CheckHealthResult, error) { | ||
if req == nil { | ||
return nil, errNilRequest | ||
} | ||
|
||
return h.handler.CheckHealth(ctx, req) | ||
} | ||
|
||
func (h MiddlewareHandler) SubscribeStream(ctx context.Context, req *SubscribeStreamRequest) (*SubscribeStreamResponse, error) { | ||
if req == nil { | ||
return nil, errNilRequest | ||
} | ||
|
||
return h.handler.SubscribeStream(ctx, req) | ||
} | ||
|
||
func (h MiddlewareHandler) PublishStream(ctx context.Context, req *PublishStreamRequest) (*PublishStreamResponse, error) { | ||
if req == nil { | ||
return nil, errNilRequest | ||
} | ||
|
||
return h.handler.PublishStream(ctx, req) | ||
} | ||
|
||
func (h MiddlewareHandler) RunStream(ctx context.Context, req *RunStreamRequest, sender *StreamSender) error { | ||
if req == nil { | ||
return errNilRequest | ||
} | ||
|
||
if sender == nil { | ||
return errors.New("sender cannot be nil") | ||
} | ||
|
||
return h.handler.RunStream(ctx, req, sender) | ||
} | ||
|
||
func (h MiddlewareHandler) ValidateAdmission(ctx context.Context, req *AdmissionRequest) (*ValidationResponse, error) { | ||
if req == nil { | ||
return nil, errNilRequest | ||
} | ||
|
||
return h.handler.ValidateAdmission(ctx, req) | ||
} | ||
|
||
func (h MiddlewareHandler) MutateAdmission(ctx context.Context, req *AdmissionRequest) (*MutationResponse, error) { | ||
if req == nil { | ||
return nil, errNilRequest | ||
} | ||
|
||
return h.handler.MutateAdmission(ctx, req) | ||
} | ||
|
||
func (h MiddlewareHandler) ConvertObject(ctx context.Context, req *ConversionRequest) (*ConversionResponse, error) { | ||
if req == nil { | ||
return nil, errNilRequest | ||
} | ||
|
||
return h.handler.ConvertObject(ctx, req) | ||
} | ||
|
||
func handlerFromMiddlewares(middlewares []HandlerMiddleware, finalHandler Handler) Handler { | ||
if len(middlewares) == 0 { | ||
return finalHandler | ||
} | ||
|
||
reversed := reverseMiddlewares(middlewares) | ||
next := finalHandler | ||
|
||
for _, m := range reversed { | ||
next = m.CreateHandlerMiddleware(next) | ||
} | ||
|
||
return next | ||
} | ||
|
||
func reverseMiddlewares(middlewares []HandlerMiddleware) []HandlerMiddleware { | ||
reversed := make([]HandlerMiddleware, len(middlewares)) | ||
copy(reversed, middlewares) | ||
|
||
for i, j := 0, len(reversed)-1; i < j; i, j = i+1, j-1 { | ||
reversed[i], reversed[j] = reversed[j], reversed[i] | ||
} | ||
|
||
return reversed | ||
} |
Oops, something went wrong.