step_serialize.go

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