src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

step_initialize.go (6691B)


      1 package middleware
      2 
      3 import "context"
      4 
      5 // InitializeInput wraps the input parameters for the InitializeMiddlewares to
      6 // consume. InitializeMiddleware may modify the parameter value before
      7 // forwarding it along to the next InitializeHandler.
      8 type InitializeInput struct {
      9 	Parameters interface{}
     10 }
     11 
     12 // InitializeOutput provides the result returned by the next InitializeHandler.
     13 type InitializeOutput struct {
     14 	Result interface{}
     15 }
     16 
     17 // InitializeHandler provides the interface for the next handler the
     18 // InitializeMiddleware will call in the middleware chain.
     19 type InitializeHandler interface {
     20 	HandleInitialize(ctx context.Context, in InitializeInput) (
     21 		out InitializeOutput, metadata Metadata, err error,
     22 	)
     23 }
     24 
     25 // InitializeMiddleware provides the interface for middleware specific to the
     26 // initialize step. Delegates to the next InitializeHandler for further
     27 // processing.
     28 type InitializeMiddleware interface {
     29 	// ID returns a unique ID for the middleware in the InitializeStep. The step does not
     30 	// allow duplicate IDs.
     31 	ID() string
     32 
     33 	// HandleInitialize invokes the middleware behavior which must delegate to the next handler
     34 	// for the middleware chain to continue. The method must return a result or
     35 	// error to its caller.
     36 	HandleInitialize(ctx context.Context, in InitializeInput, next InitializeHandler) (
     37 		out InitializeOutput, metadata Metadata, err error,
     38 	)
     39 }
     40 
     41 // InitializeMiddlewareFunc returns a InitializeMiddleware with the unique ID provided,
     42 // and the func to be invoked.
     43 func InitializeMiddlewareFunc(id string, fn func(context.Context, InitializeInput, InitializeHandler) (InitializeOutput, Metadata, error)) InitializeMiddleware {
     44 	return initializeMiddlewareFunc{
     45 		id: id,
     46 		fn: fn,
     47 	}
     48 }
     49 
     50 type initializeMiddlewareFunc struct {
     51 	// Unique ID for the middleware.
     52 	id string
     53 
     54 	// Middleware function to be called.
     55 	fn func(context.Context, InitializeInput, InitializeHandler) (
     56 		InitializeOutput, Metadata, error,
     57 	)
     58 }
     59 
     60 // ID returns the unique ID for the middleware.
     61 func (s initializeMiddlewareFunc) ID() string { return s.id }
     62 
     63 // HandleInitialize invokes the middleware Fn.
     64 func (s initializeMiddlewareFunc) HandleInitialize(ctx context.Context, in InitializeInput, next InitializeHandler) (
     65 	out InitializeOutput, metadata Metadata, err error,
     66 ) {
     67 	return s.fn(ctx, in, next)
     68 }
     69 
     70 var _ InitializeMiddleware = (initializeMiddlewareFunc{})
     71 
     72 // InitializeStep provides the ordered grouping of InitializeMiddleware to be
     73 // invoked on a handler.
     74 type InitializeStep struct {
     75 	ids *orderedIDs
     76 }
     77 
     78 // NewInitializeStep returns an InitializeStep ready to have middleware for
     79 // initialization added to it.
     80 func NewInitializeStep() *InitializeStep {
     81 	return &InitializeStep{
     82 		ids: newOrderedIDs(),
     83 	}
     84 }
     85 
     86 var _ Middleware = (*InitializeStep)(nil)
     87 
     88 // ID returns the unique ID of the step as a middleware.
     89 func (s *InitializeStep) ID() string {
     90 	return "Initialize stack step"
     91 }
     92 
     93 // HandleMiddleware invokes the middleware by decorating the next handler
     94 // provided. Returns the result of the middleware and handler being invoked.
     95 //
     96 // Implements Middleware interface.
     97 func (s *InitializeStep) HandleMiddleware(ctx context.Context, in interface{}, next Handler) (
     98 	out interface{}, metadata Metadata, err error,
     99 ) {
    100 	order := s.ids.GetOrder()
    101 
    102 	var h InitializeHandler = initializeWrapHandler{Next: next}
    103 	for i := len(order) - 1; i >= 0; i-- {
    104 		h = decoratedInitializeHandler{
    105 			Next: h,
    106 			With: order[i].(InitializeMiddleware),
    107 		}
    108 	}
    109 
    110 	sIn := InitializeInput{
    111 		Parameters: in,
    112 	}
    113 
    114 	res, metadata, err := h.HandleInitialize(ctx, sIn)
    115 	return res.Result, metadata, err
    116 }
    117 
    118 // Get retrieves the middleware identified by id. If the middleware is not present, returns false.
    119 func (s *InitializeStep) Get(id string) (InitializeMiddleware, bool) {
    120 	get, ok := s.ids.Get(id)
    121 	if !ok {
    122 		return nil, false
    123 	}
    124 	return get.(InitializeMiddleware), ok
    125 }
    126 
    127 // Add injects the middleware to the relative position of the middleware group.
    128 // Returns an error if the middleware already exists.
    129 func (s *InitializeStep) Add(m InitializeMiddleware, pos RelativePosition) error {
    130 	return s.ids.Add(m, pos)
    131 }
    132 
    133 // Insert injects the middleware relative to an existing middleware ID.
    134 // Returns error if the original middleware does not exist, or the middleware
    135 // being added already exists.
    136 func (s *InitializeStep) Insert(m InitializeMiddleware, relativeTo string, pos RelativePosition) error {
    137 	return s.ids.Insert(m, relativeTo, pos)
    138 }
    139 
    140 // Swap removes the middleware by id, replacing it with the new middleware.
    141 // Returns the middleware removed, or error if the middleware to be removed
    142 // doesn't exist.
    143 func (s *InitializeStep) Swap(id string, m InitializeMiddleware) (InitializeMiddleware, error) {
    144 	removed, err := s.ids.Swap(id, m)
    145 	if err != nil {
    146 		return nil, err
    147 	}
    148 
    149 	return removed.(InitializeMiddleware), nil
    150 }
    151 
    152 // Remove removes the middleware by id. Returns error if the middleware
    153 // doesn't exist.
    154 func (s *InitializeStep) Remove(id string) (InitializeMiddleware, error) {
    155 	removed, err := s.ids.Remove(id)
    156 	if err != nil {
    157 		return nil, err
    158 	}
    159 
    160 	return removed.(InitializeMiddleware), nil
    161 }
    162 
    163 // List returns a list of the middleware in the step.
    164 func (s *InitializeStep) List() []string {
    165 	return s.ids.List()
    166 }
    167 
    168 // Clear removes all middleware in the step.
    169 func (s *InitializeStep) Clear() {
    170 	s.ids.Clear()
    171 }
    172 
    173 type initializeWrapHandler struct {
    174 	Next Handler
    175 }
    176 
    177 var _ InitializeHandler = (*initializeWrapHandler)(nil)
    178 
    179 // HandleInitialize implements InitializeHandler, converts types and delegates to underlying
    180 // generic handler.
    181 func (w initializeWrapHandler) HandleInitialize(ctx context.Context, in InitializeInput) (
    182 	out InitializeOutput, metadata Metadata, err error,
    183 ) {
    184 	res, metadata, err := w.Next.Handle(ctx, in.Parameters)
    185 	return InitializeOutput{
    186 		Result: res,
    187 	}, metadata, err
    188 }
    189 
    190 type decoratedInitializeHandler struct {
    191 	Next InitializeHandler
    192 	With InitializeMiddleware
    193 }
    194 
    195 var _ InitializeHandler = (*decoratedInitializeHandler)(nil)
    196 
    197 func (h decoratedInitializeHandler) HandleInitialize(ctx context.Context, in InitializeInput) (
    198 	out InitializeOutput, metadata Metadata, err error,
    199 ) {
    200 	return h.With.HandleInitialize(ctx, in, h.Next)
    201 }
    202 
    203 // InitializeHandlerFunc provides a wrapper around a function to be used as an initialize middleware handler.
    204 type InitializeHandlerFunc func(context.Context, InitializeInput) (InitializeOutput, Metadata, error)
    205 
    206 // HandleInitialize calls the wrapped function with the provided arguments.
    207 func (i InitializeHandlerFunc) HandleInitialize(ctx context.Context, in InitializeInput) (InitializeOutput, Metadata, error) {
    208 	return i(ctx, in)
    209 }
    210 
    211 var _ InitializeHandler = InitializeHandlerFunc(nil)