infinispan 0.12.0 → 0.14.0
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/Dockerfile.server +8 -0
- package/README.md +5 -11
- package/docker-compose.yml +272 -0
- package/gen-asciidoc.sh +46 -0
- package/lib/codec.js +358 -27
- package/lib/functional.js +40 -7
- package/lib/infinispan.js +503 -52
- package/lib/io.js +399 -43
- package/lib/listeners.js +50 -3
- package/lib/near-cache.js +99 -0
- package/lib/protocols.js +560 -75
- package/lib/sasl/digest.js +22 -17
- package/lib/sasl/external.js +7 -4
- package/lib/sasl/factory.js +6 -5
- package/lib/sasl/oauthbearer.js +7 -5
- package/lib/sasl/plain.js +6 -4
- package/lib/sasl/scram.js +19 -11
- package/lib/utils.js +89 -24
- package/package.json +8 -7
- package/run-docker-testsuite.sh +72 -0
- package/types/index.d.ts +192 -1
- package/.eslintrc +0 -25
- package/.flowconfig +0 -6
- package/Jenkinsfile +0 -50
- package/Jenkinsfile-release +0 -63
- package/documentation/asciidoc/stories/assembly_client_usage_examples.adoc +0 -10
- package/documentation/asciidoc/stories/assembly_installation_configuration.adoc +0 -20
- package/documentation/asciidoc/titles/js_client.asciidoc +0 -28
- package/documentation/asciidoc/titles/stories.adoc +0 -5
- package/documentation/asciidoc/topics/attributes/community-attributes.adoc +0 -9
- package/documentation/asciidoc/topics/attributes/downstream-attributes.adoc +0 -2
- package/documentation/asciidoc/topics/code_examples/authentication-digest.js +0 -12
- package/documentation/asciidoc/topics/code_examples/authentication-external.js +0 -15
- package/documentation/asciidoc/topics/code_examples/authentication-oauthbearer.js +0 -10
- package/documentation/asciidoc/topics/code_examples/authentication-plain.js +0 -11
- package/documentation/asciidoc/topics/code_examples/authentication-scram.js +0 -11
- package/documentation/asciidoc/topics/code_examples/await-multiple-entries.js +0 -36
- package/documentation/asciidoc/topics/code_examples/await-single-entries.js +0 -29
- package/documentation/asciidoc/topics/code_examples/conditional-operations.js +0 -57
- package/documentation/asciidoc/topics/code_examples/connection-multiple-servers.js +0 -23
- package/documentation/asciidoc/topics/code_examples/connection-xsite-cluster-switch.js +0 -39
- package/documentation/asciidoc/topics/code_examples/connection-xsite.js +0 -13
- package/documentation/asciidoc/topics/code_examples/data-types.js +0 -30
- package/documentation/asciidoc/topics/code_examples/encryption-crypto-store.js +0 -11
- package/documentation/asciidoc/topics/code_examples/encryption-private-key.js +0 -13
- package/documentation/asciidoc/topics/code_examples/encryption-sni-hostname.js +0 -9
- package/documentation/asciidoc/topics/code_examples/encryption-trust-certs.js +0 -8
- package/documentation/asciidoc/topics/code_examples/ephemeral-data.js +0 -52
- package/documentation/asciidoc/topics/code_examples/hello-world.js +0 -42
- package/documentation/asciidoc/topics/code_examples/key-value-converter.js +0 -67
- package/documentation/asciidoc/topics/code_examples/logging-configuration.js +0 -2
- package/documentation/asciidoc/topics/code_examples/multiple-entries.js +0 -64
- package/documentation/asciidoc/topics/code_examples/queries.js +0 -92
- package/documentation/asciidoc/topics/code_examples/register-event-listener.js +0 -64
- package/documentation/asciidoc/topics/code_examples/sample-script-execute.js +0 -33
- package/documentation/asciidoc/topics/code_examples/sample-script.js +0 -3
- package/documentation/asciidoc/topics/code_examples/single-entries.js +0 -49
- package/documentation/asciidoc/topics/config_examples/logging.json +0 -14
- package/documentation/asciidoc/topics/proc_configuring_authentication.adoc +0 -16
- package/documentation/asciidoc/topics/proc_configuring_connections.adoc +0 -25
- package/documentation/asciidoc/topics/proc_configuring_connections_xsite.adoc +0 -18
- package/documentation/asciidoc/topics/proc_configuring_data_formats.adoc +0 -30
- package/documentation/asciidoc/topics/proc_configuring_encryption.adoc +0 -15
- package/documentation/asciidoc/topics/proc_configuring_logging.adoc +0 -28
- package/documentation/asciidoc/topics/proc_installing_clients.adoc +0 -58
- package/documentation/asciidoc/topics/proc_switching_clusters.adoc +0 -17
- package/documentation/asciidoc/topics/ref_authentication_mechanisms.adoc +0 -68
- package/documentation/asciidoc/topics/ref_client_usage.adoc +0 -128
- package/documentation/asciidoc/topics/ref_encryption.adoc +0 -71
- package/gen-jsdoc.sh +0 -6
- package/make-ssl.sh +0 -335
- package/memory-profiling/helper.js +0 -9
- package/memory-profiling/infinispan_memory_many_get.js +0 -50
- package/memory-profiling/infinispan_memory_one_get.js +0 -56
- package/release.sh +0 -19
- package/run-servers.sh +0 -171
- package/run-testsuite.sh +0 -6
- package/server/.keep +0 -0
- package/set-npm-auth-token.sh +0 -4
- package/smoke-tests.sh +0 -21
- package/spec/codec_spec.js +0 -224
- package/spec/configs/clean/infinispan.xml +0 -55
- package/spec/configs/infinispan-clustered.xml +0 -63
- package/spec/configs/infinispan-ssl.xml +0 -115
- package/spec/configs/infinispan-xsite-EARTH.xml +0 -187
- package/spec/configs/infinispan-xsite-MOON.xml +0 -189
- package/spec/configs/infinispan.xml +0 -77
- package/spec/functional_spec.js +0 -73
- package/spec/infinispan_auth_spec.js +0 -19
- package/spec/infinispan_cluster_spec.js +0 -176
- package/spec/infinispan_expiry_spec.js +0 -218
- package/spec/infinispan_failover_listener_spec.js +0 -52
- package/spec/infinispan_failover_spec.js +0 -63
- package/spec/infinispan_json_spec.js +0 -182
- package/spec/infinispan_local_spec.js +0 -354
- package/spec/infinispan_ssl_spec.js +0 -442
- package/spec/infinispan_stress_spec.js +0 -32
- package/spec/infinispan_xsite_spec.js +0 -99
- package/spec/protocols_spec.js +0 -82
- package/spec/protostream_spec.js +0 -237
- package/spec/tests.js +0 -28
- package/spec/utils/test-log4js.json +0 -14
- package/spec/utils/testing.js +0 -762
- package/spec/utils/typed-cachemanager-put-get.js +0 -3
- package/spec/utils/typed-null-return-dist.js +0 -2
- package/spec/utils/typed-null-return.js +0 -2
- package/spec/utils/typed-put-get-dist.js +0 -3
- package/spec/utils/typed-put-get-unicode.js +0 -3
- package/spec/utils/typed-put-get.js +0 -3
- package/spec/utils/typed-size.js +0 -2
- package/spec/utils_spec.js +0 -154
- package/spec-manual/infinispan_manual_stress_get_spec.js +0 -50
- package/spec-manual/infinispan_manual_stress_iterate_spec.js +0 -86
package/lib/protocols.js
CHANGED
|
@@ -23,6 +23,12 @@
|
|
|
23
23
|
var INFINITE_LIFESPAN = 0x01, INFINITE_MAXIDLE = 0x02; // Duration flag masks
|
|
24
24
|
var MAGIC = 0xA0;
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Creates decode actions for a key-value pair.
|
|
28
|
+
* @param {Object} decoderKey Key decoder descriptor.
|
|
29
|
+
* @param {Object} decoderValue Value decoder descriptor.
|
|
30
|
+
* @returns {Function} Action function that decodes a key-value pair from a byte buffer.
|
|
31
|
+
*/
|
|
26
32
|
function decodePairActions(decoderKey, decoderValue) {
|
|
27
33
|
return f.actions(
|
|
28
34
|
[
|
|
@@ -31,7 +37,7 @@
|
|
|
31
37
|
]
|
|
32
38
|
, function(values) {
|
|
33
39
|
if (values.length < 2) {
|
|
34
|
-
logger.tracef(
|
|
40
|
+
logger.tracef('Not enough to read (not array): %s', values);
|
|
35
41
|
return undefined;
|
|
36
42
|
}
|
|
37
43
|
|
|
@@ -43,7 +49,7 @@
|
|
|
43
49
|
[codec.decodeString(), codec.decodeString()],
|
|
44
50
|
function(values) {
|
|
45
51
|
if (values.length < 2) {
|
|
46
|
-
logger.tracef(
|
|
52
|
+
logger.tracef('Not enough to read (not array): %s', values);
|
|
47
53
|
return undefined;
|
|
48
54
|
}
|
|
49
55
|
|
|
@@ -57,9 +63,28 @@
|
|
|
57
63
|
var DECODE_VINT = f.actions([codec.decodeVInt()], codec.lastDecoded);
|
|
58
64
|
var DECODE_SHORT = f.actions([codec.decodeShort()], codec.lastDecoded);
|
|
59
65
|
|
|
66
|
+
/**
|
|
67
|
+
* Checks whether an option is present and truthy.
|
|
68
|
+
* @param {Object} opts Options object.
|
|
69
|
+
* @param {string} name Option name to check.
|
|
70
|
+
* @returns {boolean} True if the option exists and is truthy.
|
|
71
|
+
*/
|
|
60
72
|
function hasOpt(opts, name) { return _.has(opts, name) && f.truthy(opts[name]); }
|
|
73
|
+
/**
|
|
74
|
+
* Checks whether the 'previous' option is present and truthy.
|
|
75
|
+
* @param {Object} opts Options object.
|
|
76
|
+
* @returns {boolean} True if the 'previous' option exists and is truthy.
|
|
77
|
+
*/
|
|
61
78
|
function hasOptPrev(opts) { return hasOpt(opts, 'previous'); }
|
|
62
79
|
|
|
80
|
+
/**
|
|
81
|
+
* Decodes a timestamp (created/lifespan or lastUsed/maxIdle) from a byte buffer.
|
|
82
|
+
* @param {number} flags Metadata flags byte.
|
|
83
|
+
* @param {number} mask Bitmask for infinite duration check.
|
|
84
|
+
* @param {string[]} headers Header names for the decoded values.
|
|
85
|
+
* @param {Object} bytebuf Byte buffer to decode from.
|
|
86
|
+
* @returns {Object|undefined} Object with header-keyed timestamp values, or undefined if not enough data.
|
|
87
|
+
*/
|
|
63
88
|
function decodeTimestamp(flags, mask, headers, bytebuf) {
|
|
64
89
|
var timestamp;
|
|
65
90
|
if (((flags & mask) != mask)) {
|
|
@@ -75,10 +100,20 @@
|
|
|
75
100
|
return _.object(headers, timestamp);
|
|
76
101
|
}
|
|
77
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Creates a decode action for a single value.
|
|
105
|
+
* @param {Object} decoder Decoder descriptor with fun and obj properties.
|
|
106
|
+
* @returns {Function} Action function that decodes a single value from a byte buffer.
|
|
107
|
+
*/
|
|
78
108
|
function decodeSingle(decoder) {
|
|
79
109
|
return f.actions([decoder.fun(decoder.obj)], codec.lastDecoded);
|
|
80
110
|
}
|
|
81
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Creates a media decoder descriptor from a media type object.
|
|
114
|
+
* @param {Object} obj Media type object with a decodeMedia method.
|
|
115
|
+
* @returns {Object} Decoder descriptor with obj and fun properties.
|
|
116
|
+
*/
|
|
82
117
|
function decoderMedia(obj) {
|
|
83
118
|
return {
|
|
84
119
|
obj: obj
|
|
@@ -89,10 +124,21 @@
|
|
|
89
124
|
var EncodeMixin = (function() {
|
|
90
125
|
var logger = u.logger('encoder');
|
|
91
126
|
|
|
127
|
+
var VERSION_BYTE_TO_STRING = {
|
|
128
|
+
22: '2.2', 25: '2.5', 29: '2.9', 30: '3.0', 31: '3.1', 40: '4.0', 41: '4.1'
|
|
129
|
+
};
|
|
130
|
+
|
|
92
131
|
return {
|
|
93
132
|
buildFlags: function (opts) { // TODO: Move out to a Mixin (similar to expiry)
|
|
94
133
|
return hasOptPrev(opts) ? 0x01 : 0;
|
|
95
134
|
},
|
|
135
|
+
/**
|
|
136
|
+
* Returns the protocol version as a human-readable string (e.g. '3.1').
|
|
137
|
+
* @returns {string} Protocol version string.
|
|
138
|
+
*/
|
|
139
|
+
getVersionString: function() {
|
|
140
|
+
return VERSION_BYTE_TO_STRING[this.version] || String(this.version);
|
|
141
|
+
},
|
|
96
142
|
encodeHeader: function (op, topologyId, opts) {
|
|
97
143
|
logger.tracef('Encode operation with topology id %d', topologyId);
|
|
98
144
|
var protocolVersion = this.version;
|
|
@@ -110,24 +156,24 @@
|
|
|
110
156
|
codec.encodeUByte(clientIntelligence), // basic client intelligence
|
|
111
157
|
codec.encodeVInt(topologyId) // client topology id
|
|
112
158
|
];
|
|
113
|
-
}
|
|
159
|
+
};
|
|
114
160
|
},
|
|
115
161
|
encodeKey: function (k) {
|
|
116
162
|
var outer = this;
|
|
117
163
|
return function() {
|
|
118
164
|
return [outer.encodeMediaKey(k)]; // key
|
|
119
|
-
}
|
|
165
|
+
};
|
|
120
166
|
},
|
|
121
167
|
encodeQuery: function (q) {
|
|
122
168
|
return function() {
|
|
123
169
|
return [codec.encodeQuery(q)]; // query
|
|
124
|
-
}
|
|
170
|
+
};
|
|
125
171
|
},
|
|
126
172
|
encodeKeyVersion: function (k, version) {
|
|
127
173
|
var outer = this;
|
|
128
174
|
return function() {
|
|
129
175
|
return [outer.encodeMediaKey(k), codec.encodeBytes(version)]; // key + version
|
|
130
|
-
}
|
|
176
|
+
};
|
|
131
177
|
},
|
|
132
178
|
encodeKeyValue: function (k, v) {
|
|
133
179
|
var outer = this;
|
|
@@ -137,7 +183,7 @@
|
|
|
137
183
|
outer.encodeExpiry(opts), // lifespan & max idle
|
|
138
184
|
[outer.encodeMediaValue(v)] // value
|
|
139
185
|
);
|
|
140
|
-
}
|
|
186
|
+
};
|
|
141
187
|
},
|
|
142
188
|
encodeKeyValueVersion: function (k, v, version) {
|
|
143
189
|
var outer = this;
|
|
@@ -148,7 +194,7 @@
|
|
|
148
194
|
[codec.encodeBytes(version), // version
|
|
149
195
|
outer.encodeMediaValue(v)] // value
|
|
150
196
|
);
|
|
151
|
-
}
|
|
197
|
+
};
|
|
152
198
|
},
|
|
153
199
|
encodeMultiKey: function (keys) {
|
|
154
200
|
var outer = this;
|
|
@@ -170,7 +216,7 @@
|
|
|
170
216
|
return [
|
|
171
217
|
outer.encodeMediaKey(pair.key), // key
|
|
172
218
|
outer.encodeMediaValue(pair.value) // value
|
|
173
|
-
]
|
|
219
|
+
];
|
|
174
220
|
});
|
|
175
221
|
|
|
176
222
|
return f.cat(
|
|
@@ -203,6 +249,11 @@
|
|
|
203
249
|
}());
|
|
204
250
|
|
|
205
251
|
var ExpiryEncodeMixin = (function() {
|
|
252
|
+
/**
|
|
253
|
+
* Parses a duration string into a numeric value and time unit byte.
|
|
254
|
+
* @param {string|number|undefined} d Duration string (e.g. '1h'), number, or undefined.
|
|
255
|
+
* @returns {Array} Two-element array of [value, unitByte].
|
|
256
|
+
*/
|
|
206
257
|
function parseDuration(d) {
|
|
207
258
|
if (!f.existy(d)) {
|
|
208
259
|
return [undefined, 7];
|
|
@@ -210,17 +261,22 @@
|
|
|
210
261
|
// Numeric durations only allowed to describe infinite (negative) or default durations (0)
|
|
211
262
|
if (d < 0) return [undefined, 8];
|
|
212
263
|
else if (d == 0) return [undefined, 7];
|
|
213
|
-
else throw new Error(
|
|
264
|
+
else throw new Error(`Positive duration provided without time unit: ${ d}`);
|
|
214
265
|
} else {
|
|
215
266
|
var splitter = /(\d+)[\s,]*([a-zμ]+)/g;
|
|
216
267
|
var matches = splitter.exec(d);
|
|
217
268
|
if (f.existy(matches))
|
|
218
269
|
return [parseInt(matches[1]), timeUnitToByte(matches[2])];
|
|
219
270
|
else
|
|
220
|
-
throw new Error(
|
|
271
|
+
throw new Error(`Unknown duration format for ${ d}`);
|
|
221
272
|
}
|
|
222
273
|
}
|
|
223
274
|
|
|
275
|
+
/**
|
|
276
|
+
* Converts a time unit string to its protocol byte representation.
|
|
277
|
+
* @param {string} unit Time unit character (e.g. 's', 'ms', 'h').
|
|
278
|
+
* @returns {number} Byte value representing the time unit.
|
|
279
|
+
*/
|
|
224
280
|
function timeUnitToByte(unit) {
|
|
225
281
|
switch (unit) {
|
|
226
282
|
case 's': return 0;
|
|
@@ -231,7 +287,7 @@
|
|
|
231
287
|
case 'h': return 5;
|
|
232
288
|
case 'd': return 6;
|
|
233
289
|
default: // TODO: Could it be caught in regular expression?
|
|
234
|
-
throw new Error(
|
|
290
|
+
throw new Error(`Unknown duration unit in ${ unit}`);
|
|
235
291
|
}
|
|
236
292
|
}
|
|
237
293
|
|
|
@@ -248,7 +304,7 @@
|
|
|
248
304
|
}
|
|
249
305
|
return [codec.encodeUByte(0x77)]; // default lifespan & max idle
|
|
250
306
|
}
|
|
251
|
-
}
|
|
307
|
+
};
|
|
252
308
|
}());
|
|
253
309
|
|
|
254
310
|
var DecodeMixin = (function() {
|
|
@@ -262,14 +318,14 @@
|
|
|
262
318
|
codec.decodeUByte() // topology change marker
|
|
263
319
|
], function(values) {
|
|
264
320
|
if (values.length < 5) {
|
|
265
|
-
logger.tracef(
|
|
321
|
+
logger.tracef('Not enough to read (not array): %s', values);
|
|
266
322
|
return undefined;
|
|
267
323
|
}
|
|
268
324
|
|
|
269
325
|
return {
|
|
270
326
|
msgId: values[1], opCode: values[2],
|
|
271
327
|
status: values[3], hasNewTopology: values[4] == 1
|
|
272
|
-
}
|
|
328
|
+
};
|
|
273
329
|
});
|
|
274
330
|
// var DECODE_VERSIONED = f.actions([codec.decodeFixedBytes(8), codec.decodeObject()],
|
|
275
331
|
// function(values) { return {version: values[0], value: values[1]}; });
|
|
@@ -279,7 +335,7 @@
|
|
|
279
335
|
[codec.decodeVInt(), codec.decodeVInt()],
|
|
280
336
|
function(values) {
|
|
281
337
|
if (values.length < 2) {
|
|
282
|
-
logger.tracef(
|
|
338
|
+
logger.tracef('Not enough to read (not array): %s', values);
|
|
283
339
|
return undefined;
|
|
284
340
|
}
|
|
285
341
|
|
|
@@ -289,7 +345,7 @@
|
|
|
289
345
|
[codec.decodeUByte(), codec.decodeVInt()],
|
|
290
346
|
function(values) {
|
|
291
347
|
if (values.length < 2) {
|
|
292
|
-
logger.tracef(
|
|
348
|
+
logger.tracef('Not enough to read (not array): %s', values);
|
|
293
349
|
return undefined;
|
|
294
350
|
}
|
|
295
351
|
|
|
@@ -298,23 +354,43 @@
|
|
|
298
354
|
var DECODE_HOST_PORT = f.actions([codec.decodeString(), codec.decodeShort()],
|
|
299
355
|
function(values) { return {host: values[0], port: values[1]}; });
|
|
300
356
|
|
|
301
|
-
var SUCCESS = 0x00, NOT_EXECUTED = 0x01,
|
|
357
|
+
var SUCCESS = 0x00, NOT_EXECUTED = 0x01, // Status codes
|
|
302
358
|
SUCCESS_WITH_PREV = 0x03, NOT_EXECUTED_WITH_PREV = 0x04; // Status codes
|
|
303
359
|
|
|
360
|
+
/**
|
|
361
|
+
* Checks whether a status code indicates success.
|
|
362
|
+
* @param {number} status Response status code.
|
|
363
|
+
* @returns {boolean} True if status is SUCCESS or SUCCESS_WITH_PREV.
|
|
364
|
+
*/
|
|
304
365
|
function isSuccess(status) {
|
|
305
366
|
return status == SUCCESS || status == SUCCESS_WITH_PREV;
|
|
306
367
|
}
|
|
307
368
|
|
|
369
|
+
/**
|
|
370
|
+
* Checks whether a status code indicates the operation was not executed.
|
|
371
|
+
* @param {number} status Response status code.
|
|
372
|
+
* @returns {boolean} True if status is NOT_EXECUTED or NOT_EXECUTED_WITH_PREV.
|
|
373
|
+
*/
|
|
308
374
|
function isNotExecuted(status) {
|
|
309
375
|
return status == NOT_EXECUTED || status == NOT_EXECUTED_WITH_PREV;
|
|
310
376
|
}
|
|
311
377
|
|
|
378
|
+
/**
|
|
379
|
+
* Checks whether a status code includes a previous value.
|
|
380
|
+
* @param {number} status Response status code.
|
|
381
|
+
* @returns {boolean} True if status is SUCCESS_WITH_PREV or NOT_EXECUTED_WITH_PREV.
|
|
382
|
+
*/
|
|
312
383
|
function hasPrevious(status) {
|
|
313
384
|
return status == SUCCESS_WITH_PREV || status == NOT_EXECUTED_WITH_PREV;
|
|
314
385
|
}
|
|
315
386
|
|
|
316
|
-
|
|
317
|
-
|
|
387
|
+
/**
|
|
388
|
+
* Decodes a previous value from the byte buffer.
|
|
389
|
+
* @param {Object} header Response header.
|
|
390
|
+
* @param {Object} bytebuf Byte buffer to decode from.
|
|
391
|
+
* @param {Object} decoder Value decoder descriptor.
|
|
392
|
+
* @returns {Object} Result object with decoded previous value and continue flag.
|
|
393
|
+
*/
|
|
318
394
|
function decodePrev(header, bytebuf, decoder) {
|
|
319
395
|
var decodeActions = decodeSingle(decoder);
|
|
320
396
|
var prev = decodeActions(bytebuf);
|
|
@@ -324,6 +400,13 @@
|
|
|
324
400
|
return {continue: false};
|
|
325
401
|
}
|
|
326
402
|
|
|
403
|
+
/**
|
|
404
|
+
* Decodes an object from the byte buffer on success status.
|
|
405
|
+
* @param {Object} header Response header with status field.
|
|
406
|
+
* @param {Object} bytebuf Byte buffer to decode from.
|
|
407
|
+
* @param {Function} action Decode action function to apply.
|
|
408
|
+
* @returns {Object} Result object with decoded value and continue flag.
|
|
409
|
+
*/
|
|
327
410
|
function decodeObject(header, bytebuf, action) {
|
|
328
411
|
if (isSuccess(header.status)) {
|
|
329
412
|
var obj = action(bytebuf);
|
|
@@ -338,7 +421,7 @@
|
|
|
338
421
|
try {
|
|
339
422
|
var header = DECODE_HEADER(bytebuf);
|
|
340
423
|
if (f.existy(header)) {
|
|
341
|
-
logger.tracef(
|
|
424
|
+
logger.tracef('Read header(msgId=%d): opCode=%s, status=%s, hasNewTopology=%d',
|
|
342
425
|
header.msgId, header.opCode, header.status, header.hasNewTopology);
|
|
343
426
|
return {continue: true, result: header};
|
|
344
427
|
}
|
|
@@ -365,13 +448,13 @@
|
|
|
365
448
|
return function(header, bytebuf) {
|
|
366
449
|
var decodeAction = decodeSingle(decoderValue);
|
|
367
450
|
return decodeObject(header, bytebuf, decodeAction);
|
|
368
|
-
}
|
|
451
|
+
};
|
|
369
452
|
},
|
|
370
453
|
decodeQuery: function() {
|
|
371
454
|
return function(header, bytebuf) {
|
|
372
455
|
var decodeAction = f.actions([f.partial2(codec.decodeQuery,ProtostreamType.lookupProtostreamTypeById,ProtobufRoot.findRootByTypeName)()],codec.lastDecoded);
|
|
373
456
|
return decodeObject(header, bytebuf, decodeAction);
|
|
374
|
-
}
|
|
457
|
+
};
|
|
375
458
|
},
|
|
376
459
|
decodeWithMeta: function() {
|
|
377
460
|
var decoderValue = decoderMedia(this.valueMediaType);
|
|
@@ -403,7 +486,7 @@
|
|
|
403
486
|
}
|
|
404
487
|
|
|
405
488
|
return {result: undefined, continue: true};
|
|
406
|
-
}
|
|
489
|
+
};
|
|
407
490
|
},
|
|
408
491
|
decodePrevOrElse: function(opts, cond, orElse) {
|
|
409
492
|
var decoderValue = decoderMedia(this.valueMediaType);
|
|
@@ -415,7 +498,7 @@
|
|
|
415
498
|
: {result: undefined, continue: true};
|
|
416
499
|
|
|
417
500
|
return orElse(header);
|
|
418
|
-
}
|
|
501
|
+
};
|
|
419
502
|
},
|
|
420
503
|
decodeCountValues: function() {
|
|
421
504
|
var decoderKey = decoderMedia(this.keyMediaType);
|
|
@@ -430,7 +513,7 @@
|
|
|
430
513
|
}
|
|
431
514
|
|
|
432
515
|
return {result: pairs, continue: true};
|
|
433
|
-
}
|
|
516
|
+
};
|
|
434
517
|
},
|
|
435
518
|
decodeStringPairs: function(header, bytebuf) {
|
|
436
519
|
var count = DECODE_VINT(bytebuf);
|
|
@@ -503,9 +586,9 @@
|
|
|
503
586
|
complete: function(f) {
|
|
504
587
|
return function(header) {
|
|
505
588
|
return {result: f(header), continue: true};
|
|
506
|
-
}
|
|
589
|
+
};
|
|
507
590
|
}
|
|
508
|
-
}
|
|
591
|
+
};
|
|
509
592
|
}());
|
|
510
593
|
|
|
511
594
|
var ListenersMixin = (function() {
|
|
@@ -517,13 +600,20 @@
|
|
|
517
600
|
codec.decodeUByte()], // event is retried
|
|
518
601
|
function(values) {
|
|
519
602
|
if (values.length < 3) {
|
|
520
|
-
logger.tracef(
|
|
603
|
+
logger.tracef('Not enough to read (not array): %s', values);
|
|
521
604
|
return undefined;
|
|
522
605
|
}
|
|
523
606
|
|
|
524
|
-
return {listenerId: values[0], isCustom: values[1] == 1, isRetried: values[2] == 1}
|
|
607
|
+
return {listenerId: values[0], isCustom: values[1] == 1, isRetried: values[2] == 1};
|
|
525
608
|
});
|
|
526
609
|
|
|
610
|
+
/**
|
|
611
|
+
* Returns an emit function for custom events or falls back to an alternative emitter.
|
|
612
|
+
* @param {boolean} isCustom Whether the event uses a custom converter.
|
|
613
|
+
* @param {Object} decoderBytes Decoder descriptor for byte decoding.
|
|
614
|
+
* @param {Function} alternativeEmit Fallback emit function factory.
|
|
615
|
+
* @returns {Function} Emit function that dispatches the event.
|
|
616
|
+
*/
|
|
527
617
|
function emitCustomOr(isCustom, decoderBytes, alternativeEmit) {
|
|
528
618
|
if (isCustom) {
|
|
529
619
|
return function(event, emitter, bytebuf, listenerId) {
|
|
@@ -553,6 +643,11 @@
|
|
|
553
643
|
return alternativeEmit(decoderBytes);
|
|
554
644
|
}
|
|
555
645
|
|
|
646
|
+
/**
|
|
647
|
+
* Creates an emit function that decodes and emits a key-version event.
|
|
648
|
+
* @param {Object} decoderKey Key decoder descriptor.
|
|
649
|
+
* @returns {Function} Emit function for key-version events.
|
|
650
|
+
*/
|
|
556
651
|
function emitKeyVersion(decoderKey) {
|
|
557
652
|
return function(event, emitter, bytebuf, listenerId) {
|
|
558
653
|
var decoder = f.actions(
|
|
@@ -572,6 +667,11 @@
|
|
|
572
667
|
};
|
|
573
668
|
}
|
|
574
669
|
|
|
670
|
+
/**
|
|
671
|
+
* Creates an emit function that decodes and emits a key-only event.
|
|
672
|
+
* @param {Object} decodeFn Decoder descriptor for the key.
|
|
673
|
+
* @returns {Function} Emit function for key-only events.
|
|
674
|
+
*/
|
|
575
675
|
function emitKey(decodeFn) {
|
|
576
676
|
return function(event, emitter, bytebuf, listenerId) {
|
|
577
677
|
var decodeActions = decodeSingle(decodeFn);
|
|
@@ -579,7 +679,7 @@
|
|
|
579
679
|
logger.tracef('Emit %s event for key=%s', event, key);
|
|
580
680
|
emitter.emit(event, key, listenerId);
|
|
581
681
|
return true;
|
|
582
|
-
}
|
|
682
|
+
};
|
|
583
683
|
}
|
|
584
684
|
|
|
585
685
|
return {
|
|
@@ -603,7 +703,7 @@
|
|
|
603
703
|
codec.encodeUByte(0) // TODO filter factory name
|
|
604
704
|
];
|
|
605
705
|
|
|
606
|
-
if (_.has(opts,
|
|
706
|
+
if (_.has(opts, 'converterFactory') && _.has(opts.converterFactory, 'name')) {
|
|
607
707
|
steps.push(codec.encodeString(opts.converterFactory.name));
|
|
608
708
|
steps.push(codec.encodeUByte(0)); // TODO add converter parameter support
|
|
609
709
|
} else {
|
|
@@ -614,12 +714,12 @@
|
|
|
614
714
|
|
|
615
715
|
return function() {
|
|
616
716
|
return steps;
|
|
617
|
-
}
|
|
717
|
+
};
|
|
618
718
|
},
|
|
619
719
|
encodeListenerId: function(listenerId) {
|
|
620
720
|
return function() {
|
|
621
721
|
return [codec.encodeString(listenerId)]; // listener id
|
|
622
|
-
}
|
|
722
|
+
};
|
|
623
723
|
},
|
|
624
724
|
decodeEvent: function(header, bytebuf, listeners) {
|
|
625
725
|
var common = DECODE_EVENT_COMMON(bytebuf);
|
|
@@ -639,7 +739,7 @@
|
|
|
639
739
|
}
|
|
640
740
|
return true;
|
|
641
741
|
}
|
|
642
|
-
}
|
|
742
|
+
};
|
|
643
743
|
}());
|
|
644
744
|
|
|
645
745
|
var IteratorMixin = (function() { // protocol 2.3+
|
|
@@ -650,11 +750,11 @@
|
|
|
650
750
|
codec.decodeVInt()], // number of entries
|
|
651
751
|
function(values) {
|
|
652
752
|
if (values.length < 2) {
|
|
653
|
-
logger.tracef(
|
|
753
|
+
logger.tracef('Not enough to read (not array): %s', values);
|
|
654
754
|
return undefined;
|
|
655
755
|
}
|
|
656
756
|
|
|
657
|
-
return {segments: values[0], count: values[1]}
|
|
757
|
+
return {segments: values[0], count: values[1]};
|
|
658
758
|
});
|
|
659
759
|
var DECODE_VERSION = f.actions(
|
|
660
760
|
[codec.decodeFixedBytes(8)],
|
|
@@ -671,12 +771,12 @@
|
|
|
671
771
|
codec.encodeVInt(batchSize), // batch size
|
|
672
772
|
codec.encodeUByte(meta) // metadata
|
|
673
773
|
];
|
|
674
|
-
}
|
|
774
|
+
};
|
|
675
775
|
},
|
|
676
776
|
encodeIterId: function(iterId) {
|
|
677
777
|
return function() {
|
|
678
778
|
return [codec.encodeString(iterId)];
|
|
679
|
-
}
|
|
779
|
+
};
|
|
680
780
|
},
|
|
681
781
|
decodeIterId: function(header, bytebuf, conn) {
|
|
682
782
|
var iterId = DECODE_STRING(bytebuf);
|
|
@@ -733,30 +833,35 @@
|
|
|
733
833
|
}
|
|
734
834
|
|
|
735
835
|
return {result: [], continue: true};
|
|
736
|
-
}
|
|
836
|
+
};
|
|
737
837
|
}
|
|
738
|
-
}
|
|
838
|
+
};
|
|
739
839
|
}());
|
|
740
840
|
|
|
741
841
|
var NoListenerInterestsMixin = (function() {
|
|
742
842
|
return {
|
|
743
|
-
encodeListenerInterests: function (
|
|
843
|
+
encodeListenerInterests: function (_) {
|
|
744
844
|
return [codec.encodeUByte(0x0F)]; // interested in all
|
|
745
845
|
}
|
|
746
|
-
}
|
|
846
|
+
};
|
|
747
847
|
}());
|
|
748
848
|
|
|
749
849
|
var ListenerInterestsMixin = (function() {
|
|
750
850
|
return {
|
|
751
|
-
encodeListenerInterests: function (
|
|
851
|
+
encodeListenerInterests: function (_) {
|
|
752
852
|
return [codec.encodeUByte(0x0F)]; // interested in all
|
|
753
853
|
}
|
|
754
|
-
}
|
|
854
|
+
};
|
|
755
855
|
}());
|
|
756
856
|
|
|
757
857
|
var MediaType = function(mediaType) {
|
|
758
858
|
var mediaCodecs = resolveEncoders(mediaType);
|
|
759
859
|
|
|
860
|
+
/**
|
|
861
|
+
* Resolves encoder and decoder functions for a given media type.
|
|
862
|
+
* @param {string} mediaType Media type string (e.g. 'application/json').
|
|
863
|
+
* @returns {Array} Three-element array of [idByte, encoderFn, decoderFn].
|
|
864
|
+
*/
|
|
760
865
|
function resolveEncoders(mediaType) {
|
|
761
866
|
return f.dispatch(
|
|
762
867
|
f.isa('application/json', encoder(2, encoderJson, decoderJson()))
|
|
@@ -765,30 +870,64 @@
|
|
|
765
870
|
)(mediaType);
|
|
766
871
|
}
|
|
767
872
|
|
|
873
|
+
/**
|
|
874
|
+
* Encodes a value as JSON.
|
|
875
|
+
* @param {*} json Value to encode as JSON.
|
|
876
|
+
* @returns {Buffer} Encoded JSON bytes.
|
|
877
|
+
*/
|
|
768
878
|
function encoderJson(json) {
|
|
769
879
|
return codec.encodeJSON(json);
|
|
770
880
|
}
|
|
771
881
|
|
|
882
|
+
/**
|
|
883
|
+
* Creates a JSON decoder function.
|
|
884
|
+
* @returns {Function} Decoder function for JSON values.
|
|
885
|
+
*/
|
|
772
886
|
function decoderJson() {
|
|
773
887
|
return codec.decodeJSON();
|
|
774
888
|
}
|
|
775
889
|
|
|
890
|
+
/**
|
|
891
|
+
* Encodes a value as a string.
|
|
892
|
+
* @param {string} str String value to encode.
|
|
893
|
+
* @returns {Buffer} Encoded string bytes.
|
|
894
|
+
*/
|
|
776
895
|
function encoderString(str) {
|
|
777
896
|
return codec.encodeString(str);
|
|
778
897
|
}
|
|
779
898
|
|
|
899
|
+
/**
|
|
900
|
+
* Creates a string decoder function.
|
|
901
|
+
* @returns {Function} Decoder function for string values.
|
|
902
|
+
*/
|
|
780
903
|
function decoderString() {
|
|
781
904
|
return codec.decodeString();
|
|
782
905
|
}
|
|
783
906
|
|
|
907
|
+
/**
|
|
908
|
+
* Encodes a value as Protobuf.
|
|
909
|
+
* @param {Object} message Protobuf message to encode.
|
|
910
|
+
* @returns {Buffer} Encoded Protobuf bytes.
|
|
911
|
+
*/
|
|
784
912
|
function encoderProtobuf(message){
|
|
785
913
|
return codec.encodeProtobuf(message,ProtostreamType.lookupProtostreamTypeByName);
|
|
786
914
|
}
|
|
787
915
|
|
|
916
|
+
/**
|
|
917
|
+
* Creates a Protobuf decoder function.
|
|
918
|
+
* @returns {Function} Decoder function for Protobuf values.
|
|
919
|
+
*/
|
|
788
920
|
function decoderProtobuf(){
|
|
789
921
|
return f.partial2(codec.decodeProtobuf,ProtostreamType.lookupProtostreamTypeById,ProtobufRoot.findRootByTypeName)();
|
|
790
922
|
}
|
|
791
923
|
|
|
924
|
+
/**
|
|
925
|
+
* Creates a media type encoder tuple with id, encoder, and decoder.
|
|
926
|
+
* @param {number} id Media type identifier byte.
|
|
927
|
+
* @param {Function} mediaEncoder Encoder function for this media type.
|
|
928
|
+
* @param {Function} mediaDecoder Decoder function for this media type.
|
|
929
|
+
* @returns {Function} Factory function returning [id, encoder, decoder] array.
|
|
930
|
+
*/
|
|
792
931
|
function encoder(id, mediaEncoder, mediaDecoder) {
|
|
793
932
|
return function() {
|
|
794
933
|
return [
|
|
@@ -796,7 +935,7 @@
|
|
|
796
935
|
, mediaEncoder
|
|
797
936
|
, mediaDecoder
|
|
798
937
|
];
|
|
799
|
-
}
|
|
938
|
+
};
|
|
800
939
|
}
|
|
801
940
|
|
|
802
941
|
return {
|
|
@@ -817,7 +956,7 @@
|
|
|
817
956
|
|
|
818
957
|
var NoMediaTypesMixin = (function() {
|
|
819
958
|
return {
|
|
820
|
-
init: function(
|
|
959
|
+
init: function(_) {
|
|
821
960
|
this.keyMediaType = new MediaType('text/plain');
|
|
822
961
|
this.valueMediaType = new MediaType('text/plain');
|
|
823
962
|
},
|
|
@@ -830,10 +969,15 @@
|
|
|
830
969
|
encodeMediaValue: function(v) {
|
|
831
970
|
return codec.encodeString(v);
|
|
832
971
|
}
|
|
833
|
-
}
|
|
972
|
+
};
|
|
834
973
|
}());
|
|
835
974
|
|
|
836
975
|
var MediaTypesMixin = (function() {
|
|
976
|
+
/**
|
|
977
|
+
* Encodes a media type into protocol bytes.
|
|
978
|
+
* @param {Object} mediaType MediaType instance to encode.
|
|
979
|
+
* @returns {Array} Array of encoded media type bytes.
|
|
980
|
+
*/
|
|
837
981
|
function encodeMediaType(mediaType) {
|
|
838
982
|
return [
|
|
839
983
|
codec.encodeUByte(1)
|
|
@@ -842,6 +986,11 @@
|
|
|
842
986
|
];
|
|
843
987
|
}
|
|
844
988
|
|
|
989
|
+
/**
|
|
990
|
+
* Decodes a server media type from the byte buffer.
|
|
991
|
+
* @param {Object} bytebuf Byte buffer to decode from.
|
|
992
|
+
* @returns {Object} Result object with continue flag.
|
|
993
|
+
*/
|
|
845
994
|
function decodeServerMediaType(bytebuf) {
|
|
846
995
|
var mediaType = DECODE_UBYTE(bytebuf);
|
|
847
996
|
if (!f.existy(mediaType))
|
|
@@ -860,7 +1009,7 @@
|
|
|
860
1009
|
|
|
861
1010
|
return {
|
|
862
1011
|
init: function(clientOpts) {
|
|
863
|
-
logger.debugf(
|
|
1012
|
+
logger.debugf('Before init, key media type was: %s'
|
|
864
1013
|
, f.existy(this.keyMediaType) ? this.keyMediaType.getMediaType() : 'undefined'
|
|
865
1014
|
);
|
|
866
1015
|
|
|
@@ -868,7 +1017,7 @@
|
|
|
868
1017
|
this.valueMediaType = new MediaType(clientOpts.dataFormat.valueType);
|
|
869
1018
|
this.authOpts = clientOpts.authentication;
|
|
870
1019
|
|
|
871
|
-
logger.debugf(
|
|
1020
|
+
logger.debugf('After init, key media type is: %s'
|
|
872
1021
|
, f.existy(this.keyMediaType) ? this.keyMediaType.getMediaType() : 'undefined'
|
|
873
1022
|
);
|
|
874
1023
|
},
|
|
@@ -899,7 +1048,7 @@
|
|
|
899
1048
|
}
|
|
900
1049
|
return {continue: false};
|
|
901
1050
|
}
|
|
902
|
-
}
|
|
1051
|
+
};
|
|
903
1052
|
}());
|
|
904
1053
|
|
|
905
1054
|
var SASLMixin = (function() {
|
|
@@ -913,7 +1062,7 @@
|
|
|
913
1062
|
if (f.existy(authMech)) {
|
|
914
1063
|
authMechs.push(authMech);
|
|
915
1064
|
} else {
|
|
916
|
-
return {result:
|
|
1065
|
+
return {result: `Unexpected error decoding auth mechanism ${ i}`, continue: false};
|
|
917
1066
|
}
|
|
918
1067
|
}
|
|
919
1068
|
logger.tracef(authMechs);
|
|
@@ -938,7 +1087,7 @@
|
|
|
938
1087
|
response = '';
|
|
939
1088
|
}
|
|
940
1089
|
} else {
|
|
941
|
-
logger.tracef(
|
|
1090
|
+
logger.tracef('SASL server challenge response [%s]', holder.mech.name);
|
|
942
1091
|
response = holder.mech.challenge(holder.challenge).response({
|
|
943
1092
|
username: authOpts.userName,
|
|
944
1093
|
password: authOpts.password,
|
|
@@ -948,9 +1097,9 @@
|
|
|
948
1097
|
host: 'infinispan'
|
|
949
1098
|
});
|
|
950
1099
|
}
|
|
951
|
-
logger.tracef(
|
|
1100
|
+
logger.tracef('SASL client response [%s]', holder.mech.name);
|
|
952
1101
|
return [codec.encodeString(authOpts.saslMechanism), codec.encodeString(response)];
|
|
953
|
-
}
|
|
1102
|
+
};
|
|
954
1103
|
},
|
|
955
1104
|
decodeSasl: function(header, bytebuf) {
|
|
956
1105
|
var authDone = DECODE_UBYTE(bytebuf);
|
|
@@ -961,23 +1110,23 @@
|
|
|
961
1110
|
return {result: {response: DECODE_STRING(bytebuf)}, continue: true};
|
|
962
1111
|
}
|
|
963
1112
|
}
|
|
964
|
-
}
|
|
1113
|
+
};
|
|
965
1114
|
}());
|
|
966
1115
|
|
|
967
1116
|
var Ping29Mixin = (function() {
|
|
968
1117
|
return {
|
|
969
1118
|
decodePingResponse: function(header,bytebuf){
|
|
970
|
-
logger.debugf(
|
|
1119
|
+
logger.debugf('header and bytebuf %s %s',header,bytebuf);
|
|
971
1120
|
return MediaTypesMixin.decodeServerMediaTypes(header,bytebuf);
|
|
972
1121
|
}
|
|
973
|
-
}
|
|
1122
|
+
};
|
|
974
1123
|
}());
|
|
975
1124
|
|
|
976
1125
|
var Ping30Mixin = (function() {
|
|
977
1126
|
return {
|
|
978
1127
|
decodePingResponse: function(header,bytebuf){
|
|
979
1128
|
var serverMediaTypes= MediaTypesMixin.decodeServerMediaTypes(header,bytebuf);
|
|
980
|
-
|
|
1129
|
+
DECODE_UBYTE(bytebuf);
|
|
981
1130
|
var opCount=DECODE_VINT(bytebuf);
|
|
982
1131
|
var opRequestCodes=[];
|
|
983
1132
|
for(let i=0;i<opCount;i++){
|
|
@@ -985,7 +1134,242 @@
|
|
|
985
1134
|
}
|
|
986
1135
|
return serverMediaTypes;
|
|
987
1136
|
}
|
|
1137
|
+
};
|
|
1138
|
+
}());
|
|
1139
|
+
|
|
1140
|
+
var CounterMixin = (function() {
|
|
1141
|
+
var DECODE_LONG = f.actions([codec.decodeLong()], codec.lastDecoded);
|
|
1142
|
+
|
|
1143
|
+
// Counter status codes
|
|
1144
|
+
var COUNTER_SUCCESS = 0x00;
|
|
1145
|
+
var COUNTER_NOT_DEFINED = 0x02;
|
|
1146
|
+
|
|
1147
|
+
/**
|
|
1148
|
+
* Encodes only the counter name as the request body.
|
|
1149
|
+
* @param {string} name Counter name.
|
|
1150
|
+
* @returns {Function} Body encoder function.
|
|
1151
|
+
*/
|
|
1152
|
+
function encodeCounterName(name) {
|
|
1153
|
+
return function() {
|
|
1154
|
+
return [codec.encodeString(name)];
|
|
1155
|
+
};
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
/**
|
|
1159
|
+
* Encodes a counter name followed by a long value.
|
|
1160
|
+
* @param {string} name Counter name.
|
|
1161
|
+
* @param {number} value Long value.
|
|
1162
|
+
* @returns {Function} Body encoder function.
|
|
1163
|
+
*/
|
|
1164
|
+
function encodeCounterNameValue(name, value) {
|
|
1165
|
+
return function() {
|
|
1166
|
+
return [codec.encodeString(name), codec.encodeLong(value)];
|
|
1167
|
+
};
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
/**
|
|
1171
|
+
* Encodes a counter name followed by two long values (expect, update).
|
|
1172
|
+
* @param {string} name Counter name.
|
|
1173
|
+
* @param {number} expect Expected value.
|
|
1174
|
+
* @param {number} update New value.
|
|
1175
|
+
* @returns {Function} Body encoder function.
|
|
1176
|
+
*/
|
|
1177
|
+
function encodeCounterNameTwoLongs(name, expect, update) {
|
|
1178
|
+
return function() {
|
|
1179
|
+
return [codec.encodeString(name), codec.encodeLong(expect), codec.encodeLong(update)];
|
|
1180
|
+
};
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
/**
|
|
1184
|
+
* Encodes a counter create request body (name + configuration).
|
|
1185
|
+
* @param {string} name Counter name.
|
|
1186
|
+
* @param {Object} config Counter configuration.
|
|
1187
|
+
* @returns {Function} Body encoder function.
|
|
1188
|
+
*/
|
|
1189
|
+
function encodeCounterCreate(name, config) {
|
|
1190
|
+
return function() {
|
|
1191
|
+
var isWeak = config.type === 'weak';
|
|
1192
|
+
var isBounded = config.type === 'strong' && (typeof config.lowerBound === 'number' || typeof config.upperBound === 'number');
|
|
1193
|
+
var isPersistent = config.storage === 'persistent';
|
|
1194
|
+
var flags = (isWeak ? 0x01 : 0x00)
|
|
1195
|
+
| (isBounded ? 0x02 : 0x00)
|
|
1196
|
+
| (isPersistent ? 0x04 : 0x00);
|
|
1197
|
+
|
|
1198
|
+
var steps = [
|
|
1199
|
+
codec.encodeString(name),
|
|
1200
|
+
codec.encodeUByte(flags)
|
|
1201
|
+
];
|
|
1202
|
+
|
|
1203
|
+
if (isWeak) {
|
|
1204
|
+
steps.push(codec.encodeVInt(config.concurrencyLevel || 16));
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
if (isBounded) {
|
|
1208
|
+
steps.push(codec.encodeLong(typeof config.lowerBound === 'number' ? config.lowerBound : 0));
|
|
1209
|
+
steps.push(codec.encodeLong(typeof config.upperBound === 'number' ? config.upperBound : 0));
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
steps.push(codec.encodeLong(config.initialValue || 0));
|
|
1213
|
+
|
|
1214
|
+
return steps;
|
|
1215
|
+
};
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
/**
|
|
1219
|
+
* Decodes a counter long value from the response.
|
|
1220
|
+
* @param {Object} header Response header.
|
|
1221
|
+
* @param {Object} bytebuf Byte buffer to decode from.
|
|
1222
|
+
* @returns {Object} Result object with decoded long value.
|
|
1223
|
+
*/
|
|
1224
|
+
function decodeCounterValue(header, bytebuf) {
|
|
1225
|
+
if (header.status === COUNTER_SUCCESS) {
|
|
1226
|
+
var value = DECODE_LONG(bytebuf);
|
|
1227
|
+
if (!f.existy(value) && value !== 0)
|
|
1228
|
+
return {continue: false};
|
|
1229
|
+
return {result: value, continue: true};
|
|
1230
|
+
}
|
|
1231
|
+
if (header.status === COUNTER_NOT_DEFINED)
|
|
1232
|
+
return {result: undefined, continue: true};
|
|
1233
|
+
// Status 0x04 = boundary reached — still has a value
|
|
1234
|
+
if (header.status === 0x04) {
|
|
1235
|
+
var boundValue = DECODE_LONG(bytebuf);
|
|
1236
|
+
if (!f.existy(boundValue) && boundValue !== 0)
|
|
1237
|
+
return {continue: false};
|
|
1238
|
+
return {result: boundValue, continue: true};
|
|
1239
|
+
}
|
|
1240
|
+
return {result: undefined, continue: true};
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
/**
|
|
1244
|
+
* Decodes a counter configuration from the response.
|
|
1245
|
+
* @param {Object} header Response header.
|
|
1246
|
+
* @param {Object} bytebuf Byte buffer to decode from.
|
|
1247
|
+
* @returns {Object} Result object with decoded configuration.
|
|
1248
|
+
*/
|
|
1249
|
+
function decodeCounterConfig(header, bytebuf) {
|
|
1250
|
+
if (header.status !== COUNTER_SUCCESS)
|
|
1251
|
+
return {result: undefined, continue: true};
|
|
1252
|
+
|
|
1253
|
+
var flags = DECODE_UBYTE(bytebuf);
|
|
1254
|
+
if (!f.existy(flags))
|
|
1255
|
+
return {continue: false};
|
|
1256
|
+
|
|
1257
|
+
var isWeak = (flags & 0x01) !== 0;
|
|
1258
|
+
var isBounded = (flags & 0x02) !== 0;
|
|
1259
|
+
var isPersistent = (flags & 0x04) !== 0;
|
|
1260
|
+
|
|
1261
|
+
var config = {
|
|
1262
|
+
type: isWeak ? 'weak' : 'strong',
|
|
1263
|
+
storage: isPersistent ? 'persistent' : 'volatile'
|
|
1264
|
+
};
|
|
1265
|
+
|
|
1266
|
+
if (isWeak) {
|
|
1267
|
+
var concurrencyLevel = DECODE_VINT(bytebuf);
|
|
1268
|
+
if (!f.existy(concurrencyLevel))
|
|
1269
|
+
return {continue: false};
|
|
1270
|
+
config.concurrencyLevel = concurrencyLevel;
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
if (isBounded) {
|
|
1274
|
+
var lowerBound = DECODE_LONG(bytebuf);
|
|
1275
|
+
if (!f.existy(lowerBound) && lowerBound !== 0)
|
|
1276
|
+
return {continue: false};
|
|
1277
|
+
config.lowerBound = lowerBound;
|
|
1278
|
+
|
|
1279
|
+
var upperBound = DECODE_LONG(bytebuf);
|
|
1280
|
+
if (!f.existy(upperBound) && upperBound !== 0)
|
|
1281
|
+
return {continue: false};
|
|
1282
|
+
config.upperBound = upperBound;
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
var initialValue = DECODE_LONG(bytebuf);
|
|
1286
|
+
if (!f.existy(initialValue) && initialValue !== 0)
|
|
1287
|
+
return {continue: false};
|
|
1288
|
+
config.initialValue = initialValue;
|
|
1289
|
+
|
|
1290
|
+
return {result: config, continue: true};
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
/**
|
|
1294
|
+
* Decodes a success/failure status for counter operations.
|
|
1295
|
+
* @param {Object} header Response header.
|
|
1296
|
+
* @returns {Object} Result object with boolean success.
|
|
1297
|
+
*/
|
|
1298
|
+
function decodeCounterStatus(header) {
|
|
1299
|
+
return {result: header.status === COUNTER_SUCCESS, continue: true};
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
return {
|
|
1303
|
+
encodeCounterCreate: encodeCounterCreate,
|
|
1304
|
+
encodeCounterName: encodeCounterName,
|
|
1305
|
+
encodeCounterNameValue: encodeCounterNameValue,
|
|
1306
|
+
encodeCounterNameTwoLongs: encodeCounterNameTwoLongs,
|
|
1307
|
+
decodeCounterValue: decodeCounterValue,
|
|
1308
|
+
decodeCounterConfig: decodeCounterConfig,
|
|
1309
|
+
decodeCounterStatus: decodeCounterStatus
|
|
1310
|
+
};
|
|
1311
|
+
}());
|
|
1312
|
+
|
|
1313
|
+
/**
|
|
1314
|
+
* Protocol 4.0+ requires an 'otherParams' map after media types in the header.
|
|
1315
|
+
* This mixin overrides stepsHeader to append the count (0 = no params).
|
|
1316
|
+
*/
|
|
1317
|
+
var OtherParamsMixin = {
|
|
1318
|
+
stepsHeader: function(ctx, op, opts) {
|
|
1319
|
+
var header = this.encodeHeader(op, ctx.topologyId, opts)(ctx.id);
|
|
1320
|
+
var mediaType = this.encodeMediaTypes();
|
|
1321
|
+
return f.cat(header, mediaType, [codec.encodeVInt(0)]);
|
|
1322
|
+
}
|
|
1323
|
+
};
|
|
1324
|
+
|
|
1325
|
+
var DecodePrevWithMetaMixin = (function() {
|
|
1326
|
+
/**
|
|
1327
|
+
* Decodes a previous value with metadata from the response buffer.
|
|
1328
|
+
* @param {Object} header - Response header.
|
|
1329
|
+
* @param {Object} bytebuf - Byte buffer to decode from.
|
|
1330
|
+
* @param {Function} decoderValue - Value decoder function.
|
|
1331
|
+
* @returns {Object} Result object with decoded previous value and metadata.
|
|
1332
|
+
*/
|
|
1333
|
+
function decodePrevWithMeta(header, bytebuf, decoderValue) {
|
|
1334
|
+
var flags = DECODE_UBYTE(bytebuf);
|
|
1335
|
+
if (!f.existy(flags))
|
|
1336
|
+
return {continue: false};
|
|
1337
|
+
|
|
1338
|
+
var lifespan = decodeTimestamp(flags, INFINITE_LIFESPAN, ['created', 'lifespan'], bytebuf);
|
|
1339
|
+
if (!f.existy(lifespan))
|
|
1340
|
+
return {continue: false};
|
|
1341
|
+
|
|
1342
|
+
var idle = decodeTimestamp(flags, INFINITE_MAXIDLE, ['lastUsed', 'maxIdle'], bytebuf);
|
|
1343
|
+
if (!f.existy(idle))
|
|
1344
|
+
return {continue: false};
|
|
1345
|
+
|
|
1346
|
+
var decoder = f.actions(
|
|
1347
|
+
[codec.decodeFixedBytes(8), decoderValue.fun(decoderValue.obj)]
|
|
1348
|
+
, function(values) {
|
|
1349
|
+
return {version: values[0], value: values[1]};
|
|
1350
|
+
});
|
|
1351
|
+
var versioned = decoder(bytebuf);
|
|
1352
|
+
if (f.existy(versioned)) {
|
|
1353
|
+
var result = f.merge(versioned, lifespan, idle);
|
|
1354
|
+
return {result: _.isEmpty(result.value) ? undefined : result, continue: true};
|
|
1355
|
+
}
|
|
1356
|
+
return {continue: false};
|
|
988
1357
|
}
|
|
1358
|
+
|
|
1359
|
+
return {
|
|
1360
|
+
decodePrevOrElse: function(opts, cond, orElse) {
|
|
1361
|
+
var decoderValue = decoderMedia(this.valueMediaType);
|
|
1362
|
+
var shouldReturnPrev = hasOptPrev(opts);
|
|
1363
|
+
return function(header, bytebuf) {
|
|
1364
|
+
if (shouldReturnPrev)
|
|
1365
|
+
return cond(header)
|
|
1366
|
+
? decodePrevWithMeta(header, bytebuf, decoderValue)
|
|
1367
|
+
: {result: undefined, continue: true};
|
|
1368
|
+
|
|
1369
|
+
return orElse(header);
|
|
1370
|
+
};
|
|
1371
|
+
}
|
|
1372
|
+
};
|
|
989
1373
|
}());
|
|
990
1374
|
|
|
991
1375
|
var ProtostreamType = (function() {
|
|
@@ -1001,15 +1385,15 @@
|
|
|
1001
1385
|
},
|
|
1002
1386
|
lookupProtostreamTypeByName: function (protostreamTypeName) {
|
|
1003
1387
|
return _.find(protostreamTypes,function(protostreamType){
|
|
1004
|
-
return _.isEqual(protostreamType.protostreamTypeName,protostreamTypeName)
|
|
1388
|
+
return _.isEqual(protostreamType.protostreamTypeName,protostreamTypeName);
|
|
1005
1389
|
}).protostreamDescriptorId;
|
|
1006
1390
|
},
|
|
1007
1391
|
lookupProtostreamTypeById: function(protostreamDescriptorId){
|
|
1008
1392
|
return _.find(protostreamTypes,function(protostreamType){
|
|
1009
|
-
return _.isEqual(protostreamType.protostreamDescriptorId,protostreamDescriptorId)
|
|
1393
|
+
return _.isEqual(protostreamType.protostreamDescriptorId,protostreamDescriptorId);
|
|
1010
1394
|
}).protostreamTypeName;
|
|
1011
1395
|
}
|
|
1012
|
-
}
|
|
1396
|
+
};
|
|
1013
1397
|
}());
|
|
1014
1398
|
|
|
1015
1399
|
var ProtobufRoot = (function() {
|
|
@@ -1024,13 +1408,20 @@
|
|
|
1024
1408
|
var root= protobufRoot.lookupType(typeName);
|
|
1025
1409
|
return root;
|
|
1026
1410
|
}catch(err){
|
|
1027
|
-
throw new Error(
|
|
1411
|
+
throw new Error('Protobuf root not found');
|
|
1028
1412
|
}
|
|
1029
1413
|
}
|
|
1030
|
-
}
|
|
1414
|
+
};
|
|
1031
1415
|
}());
|
|
1032
1416
|
|
|
1033
1417
|
|
|
1418
|
+
/**
|
|
1419
|
+
* Constructs a Hot Rod protocol instance for the given version.
|
|
1420
|
+
* @param {number} v Protocol version number.
|
|
1421
|
+
* @param {Object} clientOpts Client options.
|
|
1422
|
+
* @constructs Protocol
|
|
1423
|
+
* @returns {void}
|
|
1424
|
+
*/
|
|
1034
1425
|
function Protocol(v, clientOpts) {
|
|
1035
1426
|
this.version = v;
|
|
1036
1427
|
this.clientOpts = clientOpts;
|
|
@@ -1055,11 +1446,23 @@
|
|
|
1055
1446
|
Protocol.call(this, 30, clientOpts);
|
|
1056
1447
|
};
|
|
1057
1448
|
|
|
1449
|
+
var Protocol31 = function(clientOpts) {
|
|
1450
|
+
Protocol.call(this, 31, clientOpts);
|
|
1451
|
+
};
|
|
1452
|
+
|
|
1453
|
+
var Protocol40 = function(clientOpts) {
|
|
1454
|
+
Protocol.call(this, 40, clientOpts);
|
|
1455
|
+
};
|
|
1456
|
+
|
|
1457
|
+
var Protocol41 = function(clientOpts) {
|
|
1458
|
+
Protocol.call(this, 41, clientOpts);
|
|
1459
|
+
};
|
|
1460
|
+
|
|
1058
1461
|
// TODO: Missing operations, just for reference
|
|
1059
1462
|
var IdsMixin = {
|
|
1060
|
-
queryId: function() { return 0x1F },
|
|
1061
|
-
authMechId: function() { return 0x21 },
|
|
1062
|
-
authReqId: function() { return 0x23 }
|
|
1463
|
+
queryId: function() { return 0x1F; },
|
|
1464
|
+
authMechId: function() { return 0x21; },
|
|
1465
|
+
authReqId: function() { return 0x23; }
|
|
1063
1466
|
};
|
|
1064
1467
|
|
|
1065
1468
|
_.extend(Protocol22.prototype
|
|
@@ -1122,14 +1525,61 @@
|
|
|
1122
1525
|
, Ping30Mixin
|
|
1123
1526
|
, ProtostreamType
|
|
1124
1527
|
, ProtobufRoot
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1528
|
+
);
|
|
1529
|
+
|
|
1530
|
+
_.extend(Protocol31.prototype
|
|
1531
|
+
, EncodeMixin
|
|
1532
|
+
, ExpiryEncodeMixin
|
|
1533
|
+
, DecodeMixin
|
|
1534
|
+
, IdsMixin
|
|
1535
|
+
, ListenersMixin
|
|
1536
|
+
, ListenerInterestsMixin
|
|
1537
|
+
, IteratorMixin
|
|
1538
|
+
, MediaTypesMixin
|
|
1539
|
+
, SASLMixin
|
|
1540
|
+
, Ping30Mixin
|
|
1541
|
+
, CounterMixin
|
|
1542
|
+
, ProtostreamType
|
|
1543
|
+
, ProtobufRoot
|
|
1544
|
+
// TODO 3.1 new ops: bloom filter near-cache
|
|
1545
|
+
);
|
|
1546
|
+
|
|
1547
|
+
_.extend(Protocol40.prototype
|
|
1548
|
+
, EncodeMixin
|
|
1549
|
+
, ExpiryEncodeMixin
|
|
1550
|
+
, OtherParamsMixin
|
|
1551
|
+
, DecodeMixin
|
|
1552
|
+
, DecodePrevWithMetaMixin
|
|
1553
|
+
, IdsMixin
|
|
1554
|
+
, ListenersMixin
|
|
1555
|
+
, ListenerInterestsMixin
|
|
1556
|
+
, IteratorMixin
|
|
1557
|
+
, MediaTypesMixin
|
|
1558
|
+
, SASLMixin
|
|
1559
|
+
, Ping30Mixin
|
|
1560
|
+
, CounterMixin
|
|
1561
|
+
, ProtostreamType
|
|
1562
|
+
, ProtobufRoot
|
|
1563
|
+
);
|
|
1564
|
+
|
|
1565
|
+
_.extend(Protocol41.prototype
|
|
1566
|
+
, EncodeMixin
|
|
1567
|
+
, ExpiryEncodeMixin
|
|
1568
|
+
, OtherParamsMixin
|
|
1569
|
+
, DecodeMixin
|
|
1570
|
+
, DecodePrevWithMetaMixin
|
|
1571
|
+
, IdsMixin
|
|
1572
|
+
, ListenersMixin
|
|
1573
|
+
, ListenerInterestsMixin
|
|
1574
|
+
, IteratorMixin
|
|
1575
|
+
, MediaTypesMixin
|
|
1576
|
+
, SASLMixin
|
|
1577
|
+
, Ping30Mixin
|
|
1578
|
+
, CounterMixin
|
|
1579
|
+
, ProtostreamType
|
|
1580
|
+
, ProtobufRoot
|
|
1581
|
+
// TODO 4.1 new ops: chunked streaming (GetStreamStart/Next/End, PutStreamStart/Next/End)
|
|
1582
|
+
);
|
|
1133
1583
|
|
|
1134
1584
|
exports.version22 = function(clientOpts) {
|
|
1135
1585
|
return new Protocol22(clientOpts);
|
|
@@ -1147,4 +1597,39 @@
|
|
|
1147
1597
|
return new Protocol30(clientOpts);
|
|
1148
1598
|
};
|
|
1149
1599
|
|
|
1600
|
+
exports.version31 = function(clientOpts) {
|
|
1601
|
+
return new Protocol31(clientOpts);
|
|
1602
|
+
};
|
|
1603
|
+
|
|
1604
|
+
exports.version40 = function(clientOpts) {
|
|
1605
|
+
return new Protocol40(clientOpts);
|
|
1606
|
+
};
|
|
1607
|
+
|
|
1608
|
+
exports.version41 = function(clientOpts) {
|
|
1609
|
+
return new Protocol41(clientOpts);
|
|
1610
|
+
};
|
|
1611
|
+
|
|
1612
|
+
var VERSION_ORDER = ['4.1', '4.0', '3.1', '3.0', '2.9', '2.5', '2.2'];
|
|
1613
|
+
|
|
1614
|
+
exports.VERSION_ORDER = VERSION_ORDER;
|
|
1615
|
+
|
|
1616
|
+
/**
|
|
1617
|
+
* Creates a protocol instance for the given version string.
|
|
1618
|
+
* @param {string} version Protocol version (e.g. '3.1', '4.0').
|
|
1619
|
+
* @param {Object} clientOpts Client configuration options.
|
|
1620
|
+
* @returns {Object} Protocol instance.
|
|
1621
|
+
*/
|
|
1622
|
+
exports.resolve = function(version, clientOpts) {
|
|
1623
|
+
switch (version) {
|
|
1624
|
+
case '4.1': return new Protocol41(clientOpts);
|
|
1625
|
+
case '4.0': return new Protocol40(clientOpts);
|
|
1626
|
+
case '3.1': return new Protocol31(clientOpts);
|
|
1627
|
+
case '3.0': return new Protocol30(clientOpts);
|
|
1628
|
+
case '2.9': return new Protocol29(clientOpts);
|
|
1629
|
+
case '2.5': return new Protocol25(clientOpts);
|
|
1630
|
+
case '2.2': return new Protocol22(clientOpts);
|
|
1631
|
+
default: throw new Error(`Unknown protocol version: ${version}`);
|
|
1632
|
+
}
|
|
1633
|
+
};
|
|
1634
|
+
|
|
1150
1635
|
}.call(this));
|