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 }