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)