| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package thrift |
| |
| import "context" |
| |
| // ProcessorMiddleware is a function that can be passed to WrapProcessor to wrap the |
| // TProcessorFunctions for that TProcessor. |
| // |
| // Middlewares are passed in the name of the function as set in the processor |
| // map of the TProcessor. |
| type ProcessorMiddleware func(name string, next TProcessorFunction) TProcessorFunction |
| |
| // WrapProcessor takes an existing TProcessor and wraps each of its inner |
| // TProcessorFunctions with the middlewares passed in and returns it. |
| // |
| // Middlewares will be called in the order that they are defined: |
| // |
| // 1. Middlewares[0] |
| // 2. Middlewares[1] |
| // ... |
| // N. Middlewares[n] |
| func WrapProcessor(processor TProcessor, middlewares ...ProcessorMiddleware) TProcessor { |
| for name, processorFunc := range processor.ProcessorMap() { |
| wrapped := processorFunc |
| // Add middlewares in reverse so the first in the list is the outermost. |
| for i := len(middlewares) - 1; i >= 0; i-- { |
| wrapped = middlewares[i](name, wrapped) |
| } |
| processor.AddToProcessorMap(name, wrapped) |
| } |
| return processor |
| } |
| |
| // WrappedTProcessorFunction is a convenience struct that implements the |
| // TProcessorFunction interface that can be used when implementing custom |
| // Middleware. |
| type WrappedTProcessorFunction struct { |
| // Wrapped is called by WrappedTProcessorFunction.Process and should be a |
| // "wrapped" call to a base TProcessorFunc.Process call. |
| Wrapped func(ctx context.Context, seqId int32, in, out TProtocol) (bool, TException) |
| } |
| |
| // Process implements the TProcessorFunction interface using p.Wrapped. |
| func (p WrappedTProcessorFunction) Process(ctx context.Context, seqID int32, in, out TProtocol) (bool, TException) { |
| return p.Wrapped(ctx, seqID, in, out) |
| } |
| |
| // verify that WrappedTProcessorFunction implements TProcessorFunction |
| var ( |
| _ TProcessorFunction = WrappedTProcessorFunction{} |
| _ TProcessorFunction = (*WrappedTProcessorFunction)(nil) |
| ) |
| |
| // ClientMiddleware can be passed to WrapClient in order to wrap TClient calls |
| // with custom middleware. |
| type ClientMiddleware func(TClient) TClient |
| |
| // WrappedTClient is a convenience struct that implements the TClient interface |
| // using inner Wrapped function. |
| // |
| // This is provided to aid in developing ClientMiddleware. |
| type WrappedTClient struct { |
| Wrapped func(ctx context.Context, method string, args, result TStruct) (ResponseMeta, error) |
| } |
| |
| // Call implements the TClient interface by calling and returning c.Wrapped. |
| func (c WrappedTClient) Call(ctx context.Context, method string, args, result TStruct) (ResponseMeta, error) { |
| return c.Wrapped(ctx, method, args, result) |
| } |
| |
| // verify that WrappedTClient implements TClient |
| var ( |
| _ TClient = WrappedTClient{} |
| _ TClient = (*WrappedTClient)(nil) |
| ) |
| |
| // WrapClient wraps the given TClient in the given middlewares. |
| // |
| // Middlewares will be called in the order that they are defined: |
| // |
| // 1. Middlewares[0] |
| // 2. Middlewares[1] |
| // ... |
| // N. Middlewares[n] |
| func WrapClient(client TClient, middlewares ...ClientMiddleware) TClient { |
| // Add middlewares in reverse so the first in the list is the outermost. |
| for i := len(middlewares) - 1; i >= 0; i-- { |
| client = middlewares[i](client) |
| } |
| return client |
| } |