@tdxvolt/volt-client-grpc 0.11.0 → 0.11.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/grpc-call.js CHANGED
@@ -6,280 +6,281 @@ import { VoltCredential } from "./volt-credential.js";
6
6
  const log = debug("volt-client-grpc:grpc-call");
7
7
 
8
8
  function _prepareInvokeRequest(
9
- request,
10
- method,
11
- methodType = "METHOD_TYPE_UNARY",
9
+ request,
10
+ method,
11
+ methodType = "METHOD_TYPE_UNARY",
12
12
  ) {
13
- const meta = this._voltClient.credential.getIdentityMetadata(
14
- this._voltClient.grpc,
15
- this._voltClient.voltConfig.id,
16
- this._voltClient.isRemote,
17
- );
18
- let invokeRequest;
19
- let callMethod = method;
20
-
21
- if (this._voltClient.isVoltRelay) {
22
- let requestPayload;
23
- if (request) {
24
- requestPayload = this._grpcClient[method].requestSerialize(request);
25
- } else if (request !== null) {
26
- log("****************LOOKOUT****************** - empty request");
27
- } else {
28
- log("explicit empty request payload");
29
- }
30
-
31
- const tunnelMethod = this._grpcClient.Tunnel;
32
-
33
- const tunnelResp = {
34
- method_invoke: {
35
- method_name: this._grpcClient[method].path,
36
- method_type: methodType,
37
- token: meta.token,
38
- request: requestPayload,
39
- },
40
- };
41
-
42
- const invokePayload = VoltCredential.aesEncrypt(
43
- tunnelMethod.responseSerialize(tunnelResp),
44
- meta.sharedKey.key,
45
- meta.sharedKey.iv,
46
- );
47
-
48
- log("target volt is %s", this._voltClient.credential.voltFingerprint);
49
-
50
- invokeRequest = {
51
- identity_fingerprint: this._voltClient.credential.voltFingerprint,
52
- payload: invokePayload,
53
- };
54
-
55
- callMethod = "Invoke";
56
- } else if (this._voltClient.isRemote && meta.sharedKey.key) {
57
- const requestPayload =
58
- this._grpcClient[method].requestSerializeOriginal(request);
59
- invokeRequest = VoltCredential.aesEncrypt(
60
- requestPayload,
61
- meta.sharedKey.key,
62
- meta.sharedKey.iv,
63
- );
64
- } else {
65
- invokeRequest = request;
66
- }
67
-
68
- return {
69
- meta,
70
- method: callMethod,
71
- methodName: method,
72
- request: invokeRequest,
73
- };
13
+ const meta = this._voltClient.credential.getIdentityMetadata(
14
+ this._voltClient.grpc,
15
+ this._voltClient.voltConfig.id,
16
+ this._voltClient.isRemote,
17
+ );
18
+ let invokeRequest;
19
+ let callMethod = method;
20
+
21
+ if (this._voltClient.isVoltRelay) {
22
+ let requestPayload;
23
+ if (request) {
24
+ requestPayload = this._grpcClient[method].requestSerialize(request);
25
+ } else if (request !== null) {
26
+ log("****************LOOKOUT****************** - empty request");
27
+ } else {
28
+ log("explicit empty request payload");
29
+ }
30
+
31
+ const tunnelMethod = this._grpcClient.Tunnel;
32
+
33
+ const tunnelResp = {
34
+ method_invoke: {
35
+ method_name: this._grpcClient[method].path,
36
+ method_type: methodType,
37
+ token: meta.token,
38
+ request: requestPayload,
39
+ },
40
+ };
41
+
42
+ const invokePayload = VoltCredential.aesEncrypt(
43
+ tunnelMethod.responseSerialize(tunnelResp),
44
+ meta.sharedKey.key,
45
+ meta.sharedKey.iv,
46
+ );
47
+
48
+ log("target volt is %s", this._voltClient.credential.voltFingerprint);
49
+
50
+ invokeRequest = {
51
+ identity_fingerprint: this._voltClient.credential.voltFingerprint,
52
+ payload: invokePayload,
53
+ };
54
+
55
+ callMethod = "Invoke";
56
+ } else if (this._voltClient.isRemote && meta.sharedKey.key) {
57
+ const requestPayload =
58
+ this._grpcClient[method].requestSerializeOriginal(request);
59
+ invokeRequest = VoltCredential.aesEncrypt(
60
+ requestPayload,
61
+ meta.sharedKey.key,
62
+ meta.sharedKey.iv,
63
+ );
64
+ } else {
65
+ invokeRequest = request;
66
+ }
67
+
68
+ return {
69
+ meta,
70
+ method: callMethod,
71
+ methodName: method,
72
+ request: invokeRequest,
73
+ };
74
74
  }
75
75
 
76
76
  function _preparePayloadRequest(request, invokeInfo) {
77
- let payloadRequest;
78
-
79
- if (this._voltClient.isVoltRelay) {
80
- const requestPayload =
81
- this._grpcClient[invokeInfo.methodName].requestSerialize(request);
82
- const tunnelMethod = this._grpcClient.Tunnel;
83
-
84
- const tunnelResp = {
85
- method_payload: {
86
- payload: requestPayload,
87
- },
88
- };
89
-
90
- const invokePayload = VoltCredential.aesEncrypt(
91
- tunnelMethod.responseSerialize(tunnelResp),
92
- invokeInfo.meta.sharedKey.key,
93
- invokeInfo.meta.sharedKey.iv,
94
- );
95
-
96
- payloadRequest = {
97
- payload: invokePayload,
98
- };
99
- } else if (this._voltClient.isRemote && invokeInfo.meta.sharedKey.key) {
100
- const requestPayload =
101
- this._grpcClient[invokeInfo.methodName].requestSerializeOriginal(request);
102
- payloadRequest = VoltCredential.aesEncrypt(
103
- requestPayload,
104
- invokeInfo.meta.sharedKey.key,
105
- invokeInfo.meta.sharedKey.iv,
106
- );
107
- } else {
108
- payloadRequest = request;
109
- }
110
-
111
- return payloadRequest;
77
+ let payloadRequest;
78
+
79
+ if (this._voltClient.isVoltRelay) {
80
+ const requestPayload =
81
+ this._grpcClient[invokeInfo.methodName].requestSerialize(request);
82
+ const tunnelMethod = this._grpcClient.Tunnel;
83
+
84
+ const tunnelResp = {
85
+ method_payload: {
86
+ payload: requestPayload,
87
+ },
88
+ };
89
+
90
+ const invokePayload = VoltCredential.aesEncrypt(
91
+ tunnelMethod.responseSerialize(tunnelResp),
92
+ invokeInfo.meta.sharedKey.key,
93
+ invokeInfo.meta.sharedKey.iv,
94
+ );
95
+
96
+ payloadRequest = {
97
+ payload: invokePayload,
98
+ };
99
+ } else if (this._voltClient.isRemote && invokeInfo.meta.sharedKey.key) {
100
+ const requestPayload =
101
+ this._grpcClient[invokeInfo.methodName].requestSerializeOriginal(request);
102
+ payloadRequest = VoltCredential.aesEncrypt(
103
+ requestPayload,
104
+ invokeInfo.meta.sharedKey.key,
105
+ invokeInfo.meta.sharedKey.iv,
106
+ );
107
+ } else {
108
+ payloadRequest = request;
109
+ }
110
+
111
+ return payloadRequest;
112
112
  }
113
113
 
114
114
  function _parseResponse(method, meta, response) {
115
- let invokeResponse = {};
116
-
117
- if (this._voltClient.isVoltRelay) {
118
- if (response.payload) {
119
- const decryptedPayload = VoltCredential.aesDecrypt(
120
- response.payload,
121
- meta.sharedKey.key,
122
- meta.sharedKey.iv,
123
- );
124
- const tunnelMethod = this._grpcClient.Tunnel;
125
- const responsePayload = tunnelMethod.requestDeserialize(decryptedPayload);
126
- if (responsePayload.payload === "method_payload") {
127
- invokeResponse.payload = this._grpcClient[method].responseDeserialize(
128
- responsePayload.method_payload.payload,
129
- );
130
- } else if (responsePayload.payload === "method_end") {
131
- invokeResponse = responsePayload.method_end;
132
- } else {
133
- log("unexpected tunnel payload type: %s", responsePayload.payload);
134
- }
135
- } else if (response.status?.message) {
136
- // There's been an error in the tunnel.
137
- log(
138
- "Tunnel status received: %s, code %d, description: %s",
139
- response.status.message,
140
- response.status.code,
141
- response.status.description || "n/a",
142
- );
143
- invokeResponse = {
144
- ended: true,
145
- error: `Error in tunnel: ${response.status.message}`,
146
- };
147
- } else {
148
- invokeResponse.methodId = response.invoke_id;
149
- log("started method %d for %s", invokeResponse.methodId, method);
150
- }
151
- } else if (this._voltClient.isRemote && meta.sharedKey.key) {
152
- const decryptedPayload = VoltCredential.aesDecrypt(
153
- response,
154
- meta.sharedKey.key,
155
- meta.sharedKey.iv,
156
- );
157
- invokeResponse = {
158
- payload:
159
- this._grpcClient[method].responseDeserializeOriginal(decryptedPayload),
160
- };
161
- } else {
162
- invokeResponse = { payload: response };
163
- }
164
-
165
- return invokeResponse;
115
+ let invokeResponse = {};
116
+
117
+ if (this._voltClient.isVoltRelay) {
118
+ if (response.payload) {
119
+ const decryptedPayload = VoltCredential.aesDecrypt(
120
+ response.payload,
121
+ meta.sharedKey.key,
122
+ meta.sharedKey.iv,
123
+ );
124
+ const tunnelMethod = this._grpcClient.Tunnel;
125
+ const responsePayload = tunnelMethod.requestDeserialize(decryptedPayload);
126
+ if (responsePayload.payload === "method_payload") {
127
+ invokeResponse.payload = this._grpcClient[method].responseDeserialize(
128
+ responsePayload.method_payload.payload,
129
+ );
130
+ } else if (responsePayload.payload === "method_end") {
131
+ invokeResponse = responsePayload.method_end;
132
+ } else {
133
+ log("unexpected tunnel payload type: %s", responsePayload.payload);
134
+ }
135
+ } else if (response.status?.message) {
136
+ // There's been an error in the tunnel.
137
+ log(
138
+ "Tunnel status received: %s, code %d, description: %s",
139
+ response.status.message,
140
+ response.status.code,
141
+ response.status.description || "n/a",
142
+ );
143
+ invokeResponse = {
144
+ ended: true,
145
+ error: `Error in tunnel: ${response.status.message}`,
146
+ };
147
+ } else {
148
+ invokeResponse.methodId = response.invoke_id;
149
+ log("started method %d for %s", invokeResponse.methodId, method);
150
+ }
151
+ } else if (this._voltClient.isRemote && meta.sharedKey.key) {
152
+ const decryptedPayload = VoltCredential.aesDecrypt(
153
+ response,
154
+ meta.sharedKey.key,
155
+ meta.sharedKey.iv,
156
+ );
157
+ invokeResponse = {
158
+ payload:
159
+ this._grpcClient[method].responseDeserializeOriginal(decryptedPayload),
160
+ };
161
+ } else {
162
+ invokeResponse = { payload: response };
163
+ }
164
+
165
+ return invokeResponse;
166
166
  }
167
167
 
168
168
  export default class GRPCCall extends EventEmitter {
169
- constructor(voltClient, methodName, methodType) {
170
- super();
171
- this._methodName = methodName;
172
- this._methodType = methodType;
173
- this._call = null;
174
- this._voltClient = voltClient;
175
- }
176
-
177
- start(grpcClient, request) {
178
- this._grpcClient = grpcClient;
179
-
180
- this._initialRequest = _prepareInvokeRequest.call(
181
- this,
182
- request,
183
- this._methodName,
184
- this._methodType,
185
- );
186
-
187
- if (!this._grpcClient[this._initialRequest.method]) {
188
- return reject(
189
- new Error(`method not found: '${this._initialRequest.method}'`),
190
- );
191
- }
192
-
193
- this._call = this._grpcClient[this._initialRequest.method](
194
- this._initialRequest.meta.metadata,
195
- );
196
-
197
- this._call.on("data", (streamResponse) => {
198
- try {
199
- const parsedResponse = _parseResponse.call(
200
- this,
201
- this._methodName,
202
- this._initialRequest.meta,
203
- streamResponse,
204
- );
205
- if (parsedResponse.payload) {
206
- this.emit("data", parsedResponse.payload);
207
- } else if (parsedResponse.ended) {
208
- if (parsedResponse.error) {
209
- this.emit("error", new Error(parsedResponse.error));
210
- } else {
211
- // Not sure this is necessary - we should receive "end" from grpc soon...
212
- this.emit("end");
213
- }
214
- } else {
215
- log("method id is %s", parsedResponse.methodId);
216
- }
217
- } catch (err) {
218
- log("failure processing connect response: %s", err.message);
219
- this.emit("error", err);
220
- }
221
- });
222
-
223
- this._call.on("error", (err) => {
224
- log("ERROR - intercepted stream error %s", err.message);
225
- this.emit("error", err);
226
- });
227
-
228
- this._call.on("finish", () => {
229
- // The read side has ended (i.e. we called end()).
230
- log("finished call %s", this._methodName);
231
- this.emit("finish");
232
- });
233
-
234
- this._call.on("end", () => {
235
- // The remote peer ended the stream.
236
- log(
237
- "ended call %s, method id: %s",
238
- this._methodName,
239
- this._initialRequest.methodId || "n/a - not tunnelling",
240
- );
241
- this.emit("end");
242
- });
243
-
244
- if (this._initialRequest.request) {
245
- this._call.write(this._initialRequest.request);
246
- }
247
-
248
- return this;
249
- }
250
-
251
- end() {
252
- if (this._call) {
253
- return this._call.end();
254
- } else {
255
- throw new Error("call not initialised");
256
- }
257
- }
258
-
259
- get writable() {
260
- return this._call?.writable;
261
- }
262
-
263
- write(request) {
264
- if (!this._call) {
265
- log("ERROR - call not initialised");
266
- throw new Error("call not initialised");
267
- } else if (this._initialRequest) {
268
- const payloadRequest = _preparePayloadRequest.call(
269
- this,
270
- request,
271
- this._initialRequest,
272
- );
273
- return this._call.write(payloadRequest);
274
- } else {
275
- this._initialRequest = _prepareInvokeRequest.call(
276
- this,
277
- request,
278
- this._methodName,
279
- this._methodType,
280
- );
281
-
282
- return this._call.write(this._initialRequest.request);
283
- }
284
- }
169
+ constructor(voltClient, methodName, methodType) {
170
+ super();
171
+ this._methodName = methodName;
172
+ this._methodType = methodType;
173
+ this._call = null;
174
+ this._voltClient = voltClient;
175
+ }
176
+
177
+ start(grpcClient, request) {
178
+ this._grpcClient = grpcClient;
179
+
180
+ this._initialRequest = _prepareInvokeRequest.call(
181
+ this,
182
+ request,
183
+ this._methodName,
184
+ this._methodType,
185
+ );
186
+
187
+ if (!this._grpcClient[this._initialRequest.method]) {
188
+ return reject(
189
+ new Error(`method not found: '${this._initialRequest.method}'`),
190
+ );
191
+ }
192
+
193
+ this._call = this._grpcClient[this._initialRequest.method](
194
+ this._initialRequest.meta.metadata,
195
+ );
196
+
197
+ this._call.on("data", (streamResponse) => {
198
+ try {
199
+ const parsedResponse = _parseResponse.call(
200
+ this,
201
+ this._methodName,
202
+ this._initialRequest.meta,
203
+ streamResponse,
204
+ );
205
+ if (parsedResponse.payload) {
206
+ this.emit("data", parsedResponse.payload);
207
+ } else if (parsedResponse.ended) {
208
+ if (parsedResponse.error) {
209
+ this.emit("error", new Error(parsedResponse.error));
210
+ } else {
211
+ // Not sure this is necessary - we should receive "end" from grpc soon...
212
+ this.emit("end");
213
+ }
214
+ } else {
215
+ log("method id is %s", parsedResponse.methodId);
216
+ }
217
+ } catch (err) {
218
+ log("failure processing connect response: %s", err.message);
219
+ this.emit("error", err);
220
+ }
221
+ });
222
+
223
+ this._call.on("error", (err) => {
224
+ log("ERROR - intercepted stream error %s", err.message);
225
+ this.emit("error", err);
226
+ });
227
+
228
+ this._call.on("finish", () => {
229
+ // The read side has ended (i.e. we called end()).
230
+ log("finished call %s", this._methodName);
231
+ this.emit("finish");
232
+ });
233
+
234
+ this._call.on("end", () => {
235
+ // The remote peer ended the stream.
236
+ log(
237
+ "ended call %s, method id: %s",
238
+ this._methodName,
239
+ this._initialRequest.methodId || "n/a - not tunnelling",
240
+ );
241
+ this.emit("end");
242
+ });
243
+
244
+ if (this._initialRequest.request) {
245
+ // Allow callee to attach event handlers before we actually send the initial payload.
246
+ process.nextTick(() => this._call.write(this._initialRequest.request));
247
+ }
248
+
249
+ return this;
250
+ }
251
+
252
+ end() {
253
+ if (this._call) {
254
+ return this._call.end();
255
+ } else {
256
+ throw new Error("call not initialised");
257
+ }
258
+ }
259
+
260
+ get writable() {
261
+ return this._call?.writable;
262
+ }
263
+
264
+ write(request) {
265
+ if (!this._call) {
266
+ log("ERROR - call not initialised");
267
+ throw new Error("call not initialised");
268
+ } else if (this._initialRequest) {
269
+ const payloadRequest = _preparePayloadRequest.call(
270
+ this,
271
+ request,
272
+ this._initialRequest,
273
+ );
274
+ return this._call.write(payloadRequest);
275
+ } else {
276
+ this._initialRequest = _prepareInvokeRequest.call(
277
+ this,
278
+ request,
279
+ this._methodName,
280
+ this._methodType,
281
+ );
282
+
283
+ return this._call.write(this._initialRequest.request);
284
+ }
285
+ }
285
286
  }