step_serialize.go 6.9 KB

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