Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc-gcp / build / src / index.js
1 "use strict";
2 Object.defineProperty(exports, "__esModule", { value: true });
3 /**
4  * @license
5  * Copyright 2018 gRPC authors.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20 const grpc = require("grpc");
21 const util = require("util");
22 const gcp_channel_factory_1 = require("./gcp_channel_factory");
23 exports.GcpChannelFactory = gcp_channel_factory_1.GcpChannelFactory;
24 const protoRoot = require("./generated/grpc_gcp");
25 var ApiConfig = protoRoot.grpc.gcp.ApiConfig;
26 var AffinityConfig = protoRoot.grpc.gcp.AffinityConfig;
27 /**
28  * Create ApiConfig proto message from config object.
29  * @param apiDefinition Api object that specifies channel pool configuation.
30  * @return A protobuf message type.
31  */
32 function createGcpApiConfig(apiDefinition) {
33     return ApiConfig.fromObject(apiDefinition);
34 }
35 exports.createGcpApiConfig = createGcpApiConfig;
36 /**
37  * Function for creating a gcp channel factory.
38  * @memberof grpc-gcp
39  * @param address The address of the server to connect to.
40  * @param credentials Channel credentials to use when connecting
41  * @param options A map of channel options that will be passed to the core.
42  * @return {GcpChannelFactory} A GcpChannelFactory instance.
43  */
44 function gcpChannelFactoryOverride(address, credentials, options) {
45     return new gcp_channel_factory_1.GcpChannelFactory(address, credentials, options);
46 }
47 exports.gcpChannelFactoryOverride = gcpChannelFactoryOverride;
48 /**
49  * Pass in call properties and return a new object with modified values.
50  * This function will be used together with gcpChannelFactoryOverride
51  * when constructing a grpc Client.
52  * @memberof grpc-gcp
53  * @param callProperties Call properties with channel factory object.
54  * @return Modified call properties with selected grpc channel object.
55  */
56 function gcpCallInvocationTransformer(callProperties) {
57     const channelFactory = callProperties.channel;
58     if (!channelFactory || !(channelFactory instanceof gcp_channel_factory_1.GcpChannelFactory)) {
59         // The gcpCallInvocationTransformer needs to use gcp channel factory.
60         return callProperties;
61     }
62     const argument = callProperties.argument;
63     const metadata = callProperties.metadata;
64     const call = callProperties.call;
65     const methodDefinition = callProperties.methodDefinition;
66     const path = methodDefinition.path;
67     const callOptions = callProperties.callOptions;
68     const callback = callProperties.callback;
69     const preProcessResult = preProcess(channelFactory, path, argument);
70     const channelRef = preProcessResult.channelRef;
71     const boundKey = preProcessResult.boundKey;
72     const postProcessInterceptor = (
73     // tslint:disable-next-line:no-any options can be any object
74     options, nextCall) => {
75         // tslint:disable-next-line:no-any protobuf message
76         let firstMessage;
77         const requester = {
78             start: (metadata, listener, next) => {
79                 const newListener = {
80                     onReceiveMetadata: (metadata, next) => {
81                         next(metadata);
82                     },
83                     // tslint:disable-next-line:no-any protobuf message
84                     onReceiveMessage: (message, next) => {
85                         if (!firstMessage)
86                             firstMessage = message;
87                         next(message);
88                     },
89                     onReceiveStatus: (status, next) => {
90                         if (status.code === grpc.status.OK) {
91                             postProcess(channelFactory, channelRef, path, boundKey, firstMessage);
92                         }
93                         next(status);
94                     },
95                 };
96                 next(metadata, newListener);
97             },
98             // tslint:disable-next-line:no-any protobuf message
99             sendMessage: (message, next) => {
100                 next(message);
101             },
102             halfClose: (next) => {
103                 next();
104             },
105             cancel: (next) => {
106                 next();
107             },
108         };
109         return new grpc.InterceptingCall(nextCall(options), requester);
110     };
111     // Append interceptor to existing interceptors list.
112     const newCallOptions = Object.assign({}, callOptions);
113     const interceptors = callOptions.interceptors ? callOptions.interceptors : [];
114     newCallOptions.interceptors = interceptors.concat([postProcessInterceptor]);
115     return {
116         argument,
117         metadata,
118         call,
119         channel: channelRef.getChannel(),
120         methodDefinition,
121         callOptions: newCallOptions,
122         callback,
123     };
124 }
125 exports.gcpCallInvocationTransformer = gcpCallInvocationTransformer;
126 /**
127  * Handle channel affinity and pick a channel before call starts.
128  * @param channelFactory The channel management factory.
129  * @param path Method path.
130  * @param argument The request arguments object.
131  * @return Result containing bound affinity key and the chosen channel ref
132  * object.
133  */
134 function preProcess(channelFactory, path, 
135 // tslint:disable-next-line:no-any protobuf message
136 argument) {
137     const affinityConfig = channelFactory.getAffinityConfig(path);
138     let boundKey;
139     if (argument && affinityConfig) {
140         const command = affinityConfig.command;
141         if (command === AffinityConfig.Command.BOUND ||
142             command === AffinityConfig.Command.UNBIND) {
143             boundKey = getAffinityKeyFromMessage(affinityConfig.affinityKey, argument);
144         }
145     }
146     const channelRef = channelFactory.getChannelRef(boundKey);
147     channelRef.activeStreamsCountIncr();
148     return {
149         boundKey,
150         channelRef,
151     };
152 }
153 /**
154  * Handle channel affinity and streams count after call is done.
155  * @param channelFactory The channel management factory.
156  * @param channelRef ChannelRef instance that contains a real grpc channel.
157  * @param path Method path.
158  * @param boundKey Affinity key bound to a channel.
159  * @param responseMsg Response proto message.
160  */
161 function postProcess(channelFactory, channelRef, path, boundKey, 
162 // tslint:disable-next-line:no-any protobuf message
163 responseMsg) {
164     if (!channelFactory || !responseMsg)
165         return;
166     const affinityConfig = channelFactory.getAffinityConfig(path);
167     if (affinityConfig && affinityConfig.command) {
168         const command = affinityConfig.command;
169         if (command === AffinityConfig.Command.BIND) {
170             const affinityKey = getAffinityKeyFromMessage(affinityConfig.affinityKey, responseMsg);
171             channelFactory.bind(channelRef, affinityKey);
172         }
173         else if (command === AffinityConfig.Command.UNBIND) {
174             channelFactory.unbind(boundKey);
175         }
176     }
177     channelRef.activeStreamsCountDecr();
178 }
179 /**
180  * Retrieve affinity key specified in the proto message.
181  * @param affinityKeyName affinity key locator.
182  * @param message proto message that contains affinity info.
183  * @return Affinity key string.
184  */
185 function getAffinityKeyFromMessage(affinityKeyName, 
186 // tslint:disable-next-line:no-any protobuf message
187 message) {
188     if (affinityKeyName) {
189         let currMessage = message;
190         const names = affinityKeyName.split('.');
191         let i = 0;
192         for (; i < names.length; i++) {
193             if (currMessage[names[i]]) {
194                 // check if the proto message is generated by protobufjs.
195                 currMessage = currMessage[names[i]];
196             }
197             else {
198                 // otherwise use jspb format.
199                 const getter = 'get' + names[i].charAt(0).toUpperCase() + names[i].substr(1);
200                 if (!currMessage || typeof currMessage[getter] !== 'function')
201                     break;
202                 currMessage = currMessage[getter]();
203             }
204         }
205         if (i !== 0 && i === names.length)
206             return currMessage;
207     }
208     console.error(util.format('Cannot find affinity value from proto message using affinity_key: %s.', affinityKeyName));
209     return '';
210 }
211 //# sourceMappingURL=index.js.map