src

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

step_finalize.go (6553B)


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