github.com/Tyktechnologies/tyk@v2.9.5+incompatible/gateway/coprocess_grpc.go (about)

     1  package gateway
     2  
     3  import (
     4  	"errors"
     5  	"net"
     6  	"net/url"
     7  	"time"
     8  
     9  	"github.com/sirupsen/logrus"
    10  	"golang.org/x/net/context"
    11  	"google.golang.org/grpc"
    12  
    13  	"github.com/TykTechnologies/tyk/apidef"
    14  	"github.com/TykTechnologies/tyk/config"
    15  	"github.com/TykTechnologies/tyk/coprocess"
    16  )
    17  
    18  var (
    19  	grpcConnection *grpc.ClientConn
    20  	grpcClient     coprocess.DispatcherClient
    21  )
    22  
    23  // GRPCDispatcher implements a coprocess.Dispatcher
    24  type GRPCDispatcher struct {
    25  	coprocess.Dispatcher
    26  }
    27  
    28  func dialer(addr string, timeout time.Duration) (net.Conn, error) {
    29  	grpcURL, err := url.Parse(config.Global().CoProcessOptions.CoProcessGRPCServer)
    30  	if err != nil {
    31  		log.WithFields(logrus.Fields{
    32  			"prefix": "coprocess-grpc",
    33  		}).Error(err)
    34  		return nil, err
    35  	}
    36  
    37  	if grpcURL == nil || config.Global().CoProcessOptions.CoProcessGRPCServer == "" {
    38  		errString := "No gRPC URL is set!"
    39  		log.WithFields(logrus.Fields{
    40  			"prefix": "coprocess-grpc",
    41  		}).Error(errString)
    42  		return nil, errors.New(errString)
    43  	}
    44  
    45  	grpcURLString := config.Global().CoProcessOptions.CoProcessGRPCServer[len(grpcURL.Scheme)+3:]
    46  	return net.DialTimeout(grpcURL.Scheme, grpcURLString, timeout)
    47  }
    48  
    49  // Dispatch takes a CoProcessMessage and sends it to the CP.
    50  func (d *GRPCDispatcher) Dispatch(object *coprocess.Object) (*coprocess.Object, error) {
    51  	return grpcClient.Dispatch(context.Background(), object)
    52  }
    53  
    54  // DispatchEvent dispatches a Tyk event.
    55  func (d *GRPCDispatcher) DispatchEvent(eventJSON []byte) {
    56  	eventObject := &coprocess.Event{
    57  		Payload: string(eventJSON),
    58  	}
    59  
    60  	_, err := grpcClient.DispatchEvent(context.Background(), eventObject)
    61  
    62  	if err != nil {
    63  		log.WithFields(logrus.Fields{
    64  			"prefix": "coprocess-grpc",
    65  		}).Error(err)
    66  	}
    67  }
    68  
    69  // Reload triggers a reload affecting CP middlewares and event handlers.
    70  func (d *GRPCDispatcher) Reload() {}
    71  
    72  // HandleMiddlewareCache isn't used by gRPC.
    73  func (d *GRPCDispatcher) HandleMiddlewareCache(b *apidef.BundleManifest, basePath string) {}
    74  
    75  func grpcCallOpts() grpc.DialOption {
    76  	recvSize := config.Global().CoProcessOptions.GRPCRecvMaxSize
    77  	sendSize := config.Global().CoProcessOptions.GRPCSendMaxSize
    78  	var opts []grpc.CallOption
    79  	if recvSize > 0 {
    80  		opts = append(opts, grpc.MaxCallRecvMsgSize(recvSize))
    81  	}
    82  	if sendSize > 0 {
    83  		opts = append(opts, grpc.MaxCallSendMsgSize(sendSize))
    84  	}
    85  	return grpc.WithDefaultCallOptions(opts...)
    86  }
    87  
    88  // NewGRPCDispatcher wraps all the actions needed for this CP.
    89  func NewGRPCDispatcher() (coprocess.Dispatcher, error) {
    90  	if config.Global().CoProcessOptions.CoProcessGRPCServer == "" {
    91  		return nil, errors.New("No gRPC URL is set")
    92  	}
    93  	var err error
    94  	grpcConnection, err = grpc.Dial("",
    95  		grpcCallOpts(),
    96  		grpc.WithInsecure(),
    97  		grpc.WithDialer(dialer),
    98  	)
    99  	grpcClient = coprocess.NewDispatcherClient(grpcConnection)
   100  
   101  	if err != nil {
   102  		log.WithFields(logrus.Fields{
   103  			"prefix": "coprocess-grpc",
   104  		}).Error(err)
   105  		return nil, err
   106  	}
   107  	return &GRPCDispatcher{}, nil
   108  }