|  | /* | 
|  | * 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) error | 
|  | } | 
|  |  | 
|  | // Call implements the TClient interface by calling and returning c.Wrapped. | 
|  | func (c WrappedTClient) Call(ctx context.Context, method string, args, result TStruct) 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 | 
|  | } |