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)