infinispan 0.13.0 → 0.15.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/.githooks/commit-msg +9 -0
- package/.githooks/configure-hooks +7 -0
- package/.githooks/configure-hooks.bat +15 -0
- package/.gitmessage +7 -0
- package/AI-CODE.md +86 -0
- package/README.md +52 -80
- package/lib/codec.js +396 -28
- package/lib/functional.js +65 -7
- package/lib/infinispan.js +591 -69
- package/lib/io.js +402 -44
- package/lib/listeners.js +166 -5
- package/lib/near-cache.js +99 -0
- package/lib/protocols.js +580 -82
- 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/uri.js +206 -0
- package/lib/utils.js +89 -24
- package/package.json +10 -4
- package/server/.keep +0 -0
- package/types/index.d.ts +236 -1
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 {
|
|
@@ -599,27 +699,40 @@
|
|
|
599
699
|
|
|
600
700
|
var steps = [
|
|
601
701
|
codec.encodeString(listenerId), // listener id
|
|
602
|
-
codec.encodeUByte(includeState)
|
|
603
|
-
codec.encodeUByte(0) // TODO filter factory name
|
|
702
|
+
codec.encodeUByte(includeState) // include state
|
|
604
703
|
];
|
|
605
704
|
|
|
606
|
-
|
|
705
|
+
// Filter factory
|
|
706
|
+
if (_.has(opts, 'filterFactory') && _.has(opts.filterFactory, 'name')) {
|
|
707
|
+
steps.push(codec.encodeString(opts.filterFactory.name));
|
|
708
|
+
var filterParams = opts.filterFactory.params || [];
|
|
709
|
+
steps.push(codec.encodeUByte(filterParams.length));
|
|
710
|
+
filterParams.forEach(function(p) { steps.push(codec.encodeBytesWithLength(p)); });
|
|
711
|
+
} else {
|
|
712
|
+
steps.push(codec.encodeUByte(0));
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
// Converter factory
|
|
716
|
+
if (_.has(opts, 'converterFactory') && _.has(opts.converterFactory, 'name')) {
|
|
607
717
|
steps.push(codec.encodeString(opts.converterFactory.name));
|
|
608
|
-
|
|
718
|
+
var converterParams = opts.converterFactory.params || [];
|
|
719
|
+
steps.push(codec.encodeUByte(converterParams.length));
|
|
720
|
+
converterParams.forEach(function(p) { steps.push(codec.encodeBytesWithLength(p)); });
|
|
609
721
|
} else {
|
|
610
|
-
steps.push(codec.encodeUByte(0));
|
|
722
|
+
steps.push(codec.encodeUByte(0));
|
|
611
723
|
}
|
|
612
724
|
|
|
613
|
-
|
|
725
|
+
// Raw data
|
|
726
|
+
steps.push(codec.encodeUByte(hasOpt(opts, 'useRawData') ? 1 : 0));
|
|
614
727
|
|
|
615
728
|
return function() {
|
|
616
729
|
return steps;
|
|
617
|
-
}
|
|
730
|
+
};
|
|
618
731
|
},
|
|
619
732
|
encodeListenerId: function(listenerId) {
|
|
620
733
|
return function() {
|
|
621
734
|
return [codec.encodeString(listenerId)]; // listener id
|
|
622
|
-
}
|
|
735
|
+
};
|
|
623
736
|
},
|
|
624
737
|
decodeEvent: function(header, bytebuf, listeners) {
|
|
625
738
|
var common = DECODE_EVENT_COMMON(bytebuf);
|
|
@@ -639,7 +752,7 @@
|
|
|
639
752
|
}
|
|
640
753
|
return true;
|
|
641
754
|
}
|
|
642
|
-
}
|
|
755
|
+
};
|
|
643
756
|
}());
|
|
644
757
|
|
|
645
758
|
var IteratorMixin = (function() { // protocol 2.3+
|
|
@@ -650,11 +763,11 @@
|
|
|
650
763
|
codec.decodeVInt()], // number of entries
|
|
651
764
|
function(values) {
|
|
652
765
|
if (values.length < 2) {
|
|
653
|
-
logger.tracef(
|
|
766
|
+
logger.tracef('Not enough to read (not array): %s', values);
|
|
654
767
|
return undefined;
|
|
655
768
|
}
|
|
656
769
|
|
|
657
|
-
return {segments: values[0], count: values[1]}
|
|
770
|
+
return {segments: values[0], count: values[1]};
|
|
658
771
|
});
|
|
659
772
|
var DECODE_VERSION = f.actions(
|
|
660
773
|
[codec.decodeFixedBytes(8)],
|
|
@@ -671,12 +784,12 @@
|
|
|
671
784
|
codec.encodeVInt(batchSize), // batch size
|
|
672
785
|
codec.encodeUByte(meta) // metadata
|
|
673
786
|
];
|
|
674
|
-
}
|
|
787
|
+
};
|
|
675
788
|
},
|
|
676
789
|
encodeIterId: function(iterId) {
|
|
677
790
|
return function() {
|
|
678
791
|
return [codec.encodeString(iterId)];
|
|
679
|
-
}
|
|
792
|
+
};
|
|
680
793
|
},
|
|
681
794
|
decodeIterId: function(header, bytebuf, conn) {
|
|
682
795
|
var iterId = DECODE_STRING(bytebuf);
|
|
@@ -733,30 +846,35 @@
|
|
|
733
846
|
}
|
|
734
847
|
|
|
735
848
|
return {result: [], continue: true};
|
|
736
|
-
}
|
|
849
|
+
};
|
|
737
850
|
}
|
|
738
|
-
}
|
|
851
|
+
};
|
|
739
852
|
}());
|
|
740
853
|
|
|
741
854
|
var NoListenerInterestsMixin = (function() {
|
|
742
855
|
return {
|
|
743
|
-
encodeListenerInterests: function (
|
|
856
|
+
encodeListenerInterests: function (_) {
|
|
744
857
|
return [codec.encodeUByte(0x0F)]; // interested in all
|
|
745
858
|
}
|
|
746
|
-
}
|
|
859
|
+
};
|
|
747
860
|
}());
|
|
748
861
|
|
|
749
862
|
var ListenerInterestsMixin = (function() {
|
|
750
863
|
return {
|
|
751
|
-
encodeListenerInterests: function (
|
|
864
|
+
encodeListenerInterests: function (_) {
|
|
752
865
|
return [codec.encodeUByte(0x0F)]; // interested in all
|
|
753
866
|
}
|
|
754
|
-
}
|
|
867
|
+
};
|
|
755
868
|
}());
|
|
756
869
|
|
|
757
870
|
var MediaType = function(mediaType) {
|
|
758
871
|
var mediaCodecs = resolveEncoders(mediaType);
|
|
759
872
|
|
|
873
|
+
/**
|
|
874
|
+
* Resolves encoder and decoder functions for a given media type.
|
|
875
|
+
* @param {string} mediaType Media type string (e.g. 'application/json').
|
|
876
|
+
* @returns {Array} Three-element array of [idByte, encoderFn, decoderFn].
|
|
877
|
+
*/
|
|
760
878
|
function resolveEncoders(mediaType) {
|
|
761
879
|
return f.dispatch(
|
|
762
880
|
f.isa('application/json', encoder(2, encoderJson, decoderJson()))
|
|
@@ -765,30 +883,64 @@
|
|
|
765
883
|
)(mediaType);
|
|
766
884
|
}
|
|
767
885
|
|
|
886
|
+
/**
|
|
887
|
+
* Encodes a value as JSON.
|
|
888
|
+
* @param {*} json Value to encode as JSON.
|
|
889
|
+
* @returns {Buffer} Encoded JSON bytes.
|
|
890
|
+
*/
|
|
768
891
|
function encoderJson(json) {
|
|
769
892
|
return codec.encodeJSON(json);
|
|
770
893
|
}
|
|
771
894
|
|
|
895
|
+
/**
|
|
896
|
+
* Creates a JSON decoder function.
|
|
897
|
+
* @returns {Function} Decoder function for JSON values.
|
|
898
|
+
*/
|
|
772
899
|
function decoderJson() {
|
|
773
900
|
return codec.decodeJSON();
|
|
774
901
|
}
|
|
775
902
|
|
|
903
|
+
/**
|
|
904
|
+
* Encodes a value as a string.
|
|
905
|
+
* @param {string} str String value to encode.
|
|
906
|
+
* @returns {Buffer} Encoded string bytes.
|
|
907
|
+
*/
|
|
776
908
|
function encoderString(str) {
|
|
777
909
|
return codec.encodeString(str);
|
|
778
910
|
}
|
|
779
911
|
|
|
912
|
+
/**
|
|
913
|
+
* Creates a string decoder function.
|
|
914
|
+
* @returns {Function} Decoder function for string values.
|
|
915
|
+
*/
|
|
780
916
|
function decoderString() {
|
|
781
917
|
return codec.decodeString();
|
|
782
918
|
}
|
|
783
919
|
|
|
920
|
+
/**
|
|
921
|
+
* Encodes a value as Protobuf.
|
|
922
|
+
* @param {Object} message Protobuf message to encode.
|
|
923
|
+
* @returns {Buffer} Encoded Protobuf bytes.
|
|
924
|
+
*/
|
|
784
925
|
function encoderProtobuf(message){
|
|
785
926
|
return codec.encodeProtobuf(message,ProtostreamType.lookupProtostreamTypeByName);
|
|
786
927
|
}
|
|
787
928
|
|
|
929
|
+
/**
|
|
930
|
+
* Creates a Protobuf decoder function.
|
|
931
|
+
* @returns {Function} Decoder function for Protobuf values.
|
|
932
|
+
*/
|
|
788
933
|
function decoderProtobuf(){
|
|
789
934
|
return f.partial2(codec.decodeProtobuf,ProtostreamType.lookupProtostreamTypeById,ProtobufRoot.findRootByTypeName)();
|
|
790
935
|
}
|
|
791
936
|
|
|
937
|
+
/**
|
|
938
|
+
* Creates a media type encoder tuple with id, encoder, and decoder.
|
|
939
|
+
* @param {number} id Media type identifier byte.
|
|
940
|
+
* @param {Function} mediaEncoder Encoder function for this media type.
|
|
941
|
+
* @param {Function} mediaDecoder Decoder function for this media type.
|
|
942
|
+
* @returns {Function} Factory function returning [id, encoder, decoder] array.
|
|
943
|
+
*/
|
|
792
944
|
function encoder(id, mediaEncoder, mediaDecoder) {
|
|
793
945
|
return function() {
|
|
794
946
|
return [
|
|
@@ -796,7 +948,7 @@
|
|
|
796
948
|
, mediaEncoder
|
|
797
949
|
, mediaDecoder
|
|
798
950
|
];
|
|
799
|
-
}
|
|
951
|
+
};
|
|
800
952
|
}
|
|
801
953
|
|
|
802
954
|
return {
|
|
@@ -817,7 +969,7 @@
|
|
|
817
969
|
|
|
818
970
|
var NoMediaTypesMixin = (function() {
|
|
819
971
|
return {
|
|
820
|
-
init: function(
|
|
972
|
+
init: function(_) {
|
|
821
973
|
this.keyMediaType = new MediaType('text/plain');
|
|
822
974
|
this.valueMediaType = new MediaType('text/plain');
|
|
823
975
|
},
|
|
@@ -830,10 +982,15 @@
|
|
|
830
982
|
encodeMediaValue: function(v) {
|
|
831
983
|
return codec.encodeString(v);
|
|
832
984
|
}
|
|
833
|
-
}
|
|
985
|
+
};
|
|
834
986
|
}());
|
|
835
987
|
|
|
836
988
|
var MediaTypesMixin = (function() {
|
|
989
|
+
/**
|
|
990
|
+
* Encodes a media type into protocol bytes.
|
|
991
|
+
* @param {Object} mediaType MediaType instance to encode.
|
|
992
|
+
* @returns {Array} Array of encoded media type bytes.
|
|
993
|
+
*/
|
|
837
994
|
function encodeMediaType(mediaType) {
|
|
838
995
|
return [
|
|
839
996
|
codec.encodeUByte(1)
|
|
@@ -842,6 +999,11 @@
|
|
|
842
999
|
];
|
|
843
1000
|
}
|
|
844
1001
|
|
|
1002
|
+
/**
|
|
1003
|
+
* Decodes a server media type from the byte buffer.
|
|
1004
|
+
* @param {Object} bytebuf Byte buffer to decode from.
|
|
1005
|
+
* @returns {Object} Result object with continue flag.
|
|
1006
|
+
*/
|
|
845
1007
|
function decodeServerMediaType(bytebuf) {
|
|
846
1008
|
var mediaType = DECODE_UBYTE(bytebuf);
|
|
847
1009
|
if (!f.existy(mediaType))
|
|
@@ -860,7 +1022,7 @@
|
|
|
860
1022
|
|
|
861
1023
|
return {
|
|
862
1024
|
init: function(clientOpts) {
|
|
863
|
-
logger.debugf(
|
|
1025
|
+
logger.debugf('Before init, key media type was: %s'
|
|
864
1026
|
, f.existy(this.keyMediaType) ? this.keyMediaType.getMediaType() : 'undefined'
|
|
865
1027
|
);
|
|
866
1028
|
|
|
@@ -868,7 +1030,7 @@
|
|
|
868
1030
|
this.valueMediaType = new MediaType(clientOpts.dataFormat.valueType);
|
|
869
1031
|
this.authOpts = clientOpts.authentication;
|
|
870
1032
|
|
|
871
|
-
logger.debugf(
|
|
1033
|
+
logger.debugf('After init, key media type is: %s'
|
|
872
1034
|
, f.existy(this.keyMediaType) ? this.keyMediaType.getMediaType() : 'undefined'
|
|
873
1035
|
);
|
|
874
1036
|
},
|
|
@@ -899,7 +1061,7 @@
|
|
|
899
1061
|
}
|
|
900
1062
|
return {continue: false};
|
|
901
1063
|
}
|
|
902
|
-
}
|
|
1064
|
+
};
|
|
903
1065
|
}());
|
|
904
1066
|
|
|
905
1067
|
var SASLMixin = (function() {
|
|
@@ -913,7 +1075,7 @@
|
|
|
913
1075
|
if (f.existy(authMech)) {
|
|
914
1076
|
authMechs.push(authMech);
|
|
915
1077
|
} else {
|
|
916
|
-
return {result:
|
|
1078
|
+
return {result: `Unexpected error decoding auth mechanism ${ i}`, continue: false};
|
|
917
1079
|
}
|
|
918
1080
|
}
|
|
919
1081
|
logger.tracef(authMechs);
|
|
@@ -938,7 +1100,7 @@
|
|
|
938
1100
|
response = '';
|
|
939
1101
|
}
|
|
940
1102
|
} else {
|
|
941
|
-
logger.tracef(
|
|
1103
|
+
logger.tracef('SASL server challenge response [%s]', holder.mech.name);
|
|
942
1104
|
response = holder.mech.challenge(holder.challenge).response({
|
|
943
1105
|
username: authOpts.userName,
|
|
944
1106
|
password: authOpts.password,
|
|
@@ -948,36 +1110,36 @@
|
|
|
948
1110
|
host: 'infinispan'
|
|
949
1111
|
});
|
|
950
1112
|
}
|
|
951
|
-
logger.tracef(
|
|
1113
|
+
logger.tracef('SASL client response [%s]', holder.mech.name);
|
|
952
1114
|
return [codec.encodeString(authOpts.saslMechanism), codec.encodeString(response)];
|
|
953
|
-
}
|
|
1115
|
+
};
|
|
954
1116
|
},
|
|
955
1117
|
decodeSasl: function(header, bytebuf) {
|
|
956
1118
|
var authDone = DECODE_UBYTE(bytebuf);
|
|
957
1119
|
if(authDone == 1) {
|
|
958
1120
|
logger.tracef('SASL authentication complete');
|
|
959
|
-
return {result: {response: DECODE_UBYTE(bytebuf)}, continue: true};
|
|
1121
|
+
return {result: {response: DECODE_UBYTE(bytebuf), complete: true}, continue: true};
|
|
960
1122
|
} else {
|
|
961
|
-
return {result: {response: DECODE_STRING(bytebuf)}, continue: true};
|
|
1123
|
+
return {result: {response: DECODE_STRING(bytebuf), complete: false}, continue: true};
|
|
962
1124
|
}
|
|
963
1125
|
}
|
|
964
|
-
}
|
|
1126
|
+
};
|
|
965
1127
|
}());
|
|
966
1128
|
|
|
967
1129
|
var Ping29Mixin = (function() {
|
|
968
1130
|
return {
|
|
969
1131
|
decodePingResponse: function(header,bytebuf){
|
|
970
|
-
logger.debugf(
|
|
1132
|
+
logger.debugf('header and bytebuf %s %s',header,bytebuf);
|
|
971
1133
|
return MediaTypesMixin.decodeServerMediaTypes(header,bytebuf);
|
|
972
1134
|
}
|
|
973
|
-
}
|
|
1135
|
+
};
|
|
974
1136
|
}());
|
|
975
1137
|
|
|
976
1138
|
var Ping30Mixin = (function() {
|
|
977
1139
|
return {
|
|
978
1140
|
decodePingResponse: function(header,bytebuf){
|
|
979
1141
|
var serverMediaTypes= MediaTypesMixin.decodeServerMediaTypes(header,bytebuf);
|
|
980
|
-
|
|
1142
|
+
DECODE_UBYTE(bytebuf);
|
|
981
1143
|
var opCount=DECODE_VINT(bytebuf);
|
|
982
1144
|
var opRequestCodes=[];
|
|
983
1145
|
for(let i=0;i<opCount;i++){
|
|
@@ -985,7 +1147,242 @@
|
|
|
985
1147
|
}
|
|
986
1148
|
return serverMediaTypes;
|
|
987
1149
|
}
|
|
1150
|
+
};
|
|
1151
|
+
}());
|
|
1152
|
+
|
|
1153
|
+
var CounterMixin = (function() {
|
|
1154
|
+
var DECODE_LONG = f.actions([codec.decodeLong()], codec.lastDecoded);
|
|
1155
|
+
|
|
1156
|
+
// Counter status codes
|
|
1157
|
+
var COUNTER_SUCCESS = 0x00;
|
|
1158
|
+
var COUNTER_NOT_DEFINED = 0x02;
|
|
1159
|
+
|
|
1160
|
+
/**
|
|
1161
|
+
* Encodes only the counter name as the request body.
|
|
1162
|
+
* @param {string} name Counter name.
|
|
1163
|
+
* @returns {Function} Body encoder function.
|
|
1164
|
+
*/
|
|
1165
|
+
function encodeCounterName(name) {
|
|
1166
|
+
return function() {
|
|
1167
|
+
return [codec.encodeString(name)];
|
|
1168
|
+
};
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
/**
|
|
1172
|
+
* Encodes a counter name followed by a long value.
|
|
1173
|
+
* @param {string} name Counter name.
|
|
1174
|
+
* @param {number} value Long value.
|
|
1175
|
+
* @returns {Function} Body encoder function.
|
|
1176
|
+
*/
|
|
1177
|
+
function encodeCounterNameValue(name, value) {
|
|
1178
|
+
return function() {
|
|
1179
|
+
return [codec.encodeString(name), codec.encodeLong(value)];
|
|
1180
|
+
};
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
/**
|
|
1184
|
+
* Encodes a counter name followed by two long values (expect, update).
|
|
1185
|
+
* @param {string} name Counter name.
|
|
1186
|
+
* @param {number} expect Expected value.
|
|
1187
|
+
* @param {number} update New value.
|
|
1188
|
+
* @returns {Function} Body encoder function.
|
|
1189
|
+
*/
|
|
1190
|
+
function encodeCounterNameTwoLongs(name, expect, update) {
|
|
1191
|
+
return function() {
|
|
1192
|
+
return [codec.encodeString(name), codec.encodeLong(expect), codec.encodeLong(update)];
|
|
1193
|
+
};
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
/**
|
|
1197
|
+
* Encodes a counter create request body (name + configuration).
|
|
1198
|
+
* @param {string} name Counter name.
|
|
1199
|
+
* @param {Object} config Counter configuration.
|
|
1200
|
+
* @returns {Function} Body encoder function.
|
|
1201
|
+
*/
|
|
1202
|
+
function encodeCounterCreate(name, config) {
|
|
1203
|
+
return function() {
|
|
1204
|
+
var isWeak = config.type === 'weak';
|
|
1205
|
+
var isBounded = config.type === 'strong' && (typeof config.lowerBound === 'number' || typeof config.upperBound === 'number');
|
|
1206
|
+
var isPersistent = config.storage === 'persistent';
|
|
1207
|
+
var flags = (isWeak ? 0x01 : 0x00)
|
|
1208
|
+
| (isBounded ? 0x02 : 0x00)
|
|
1209
|
+
| (isPersistent ? 0x04 : 0x00);
|
|
1210
|
+
|
|
1211
|
+
var steps = [
|
|
1212
|
+
codec.encodeString(name),
|
|
1213
|
+
codec.encodeUByte(flags)
|
|
1214
|
+
];
|
|
1215
|
+
|
|
1216
|
+
if (isWeak) {
|
|
1217
|
+
steps.push(codec.encodeVInt(config.concurrencyLevel || 16));
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
if (isBounded) {
|
|
1221
|
+
steps.push(codec.encodeLong(typeof config.lowerBound === 'number' ? config.lowerBound : 0));
|
|
1222
|
+
steps.push(codec.encodeLong(typeof config.upperBound === 'number' ? config.upperBound : 0));
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
steps.push(codec.encodeLong(config.initialValue || 0));
|
|
1226
|
+
|
|
1227
|
+
return steps;
|
|
1228
|
+
};
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
/**
|
|
1232
|
+
* Decodes a counter long value from the response.
|
|
1233
|
+
* @param {Object} header Response header.
|
|
1234
|
+
* @param {Object} bytebuf Byte buffer to decode from.
|
|
1235
|
+
* @returns {Object} Result object with decoded long value.
|
|
1236
|
+
*/
|
|
1237
|
+
function decodeCounterValue(header, bytebuf) {
|
|
1238
|
+
if (header.status === COUNTER_SUCCESS) {
|
|
1239
|
+
var value = DECODE_LONG(bytebuf);
|
|
1240
|
+
if (!f.existy(value) && value !== 0)
|
|
1241
|
+
return {continue: false};
|
|
1242
|
+
return {result: value, continue: true};
|
|
1243
|
+
}
|
|
1244
|
+
if (header.status === COUNTER_NOT_DEFINED)
|
|
1245
|
+
return {result: undefined, continue: true};
|
|
1246
|
+
// Status 0x04 = boundary reached — still has a value
|
|
1247
|
+
if (header.status === 0x04) {
|
|
1248
|
+
var boundValue = DECODE_LONG(bytebuf);
|
|
1249
|
+
if (!f.existy(boundValue) && boundValue !== 0)
|
|
1250
|
+
return {continue: false};
|
|
1251
|
+
return {result: boundValue, continue: true};
|
|
1252
|
+
}
|
|
1253
|
+
return {result: undefined, continue: true};
|
|
988
1254
|
}
|
|
1255
|
+
|
|
1256
|
+
/**
|
|
1257
|
+
* Decodes a counter configuration from the response.
|
|
1258
|
+
* @param {Object} header Response header.
|
|
1259
|
+
* @param {Object} bytebuf Byte buffer to decode from.
|
|
1260
|
+
* @returns {Object} Result object with decoded configuration.
|
|
1261
|
+
*/
|
|
1262
|
+
function decodeCounterConfig(header, bytebuf) {
|
|
1263
|
+
if (header.status !== COUNTER_SUCCESS)
|
|
1264
|
+
return {result: undefined, continue: true};
|
|
1265
|
+
|
|
1266
|
+
var flags = DECODE_UBYTE(bytebuf);
|
|
1267
|
+
if (!f.existy(flags))
|
|
1268
|
+
return {continue: false};
|
|
1269
|
+
|
|
1270
|
+
var isWeak = (flags & 0x01) !== 0;
|
|
1271
|
+
var isBounded = (flags & 0x02) !== 0;
|
|
1272
|
+
var isPersistent = (flags & 0x04) !== 0;
|
|
1273
|
+
|
|
1274
|
+
var config = {
|
|
1275
|
+
type: isWeak ? 'weak' : 'strong',
|
|
1276
|
+
storage: isPersistent ? 'persistent' : 'volatile'
|
|
1277
|
+
};
|
|
1278
|
+
|
|
1279
|
+
if (isWeak) {
|
|
1280
|
+
var concurrencyLevel = DECODE_VINT(bytebuf);
|
|
1281
|
+
if (!f.existy(concurrencyLevel))
|
|
1282
|
+
return {continue: false};
|
|
1283
|
+
config.concurrencyLevel = concurrencyLevel;
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
if (isBounded) {
|
|
1287
|
+
var lowerBound = DECODE_LONG(bytebuf);
|
|
1288
|
+
if (!f.existy(lowerBound) && lowerBound !== 0)
|
|
1289
|
+
return {continue: false};
|
|
1290
|
+
config.lowerBound = lowerBound;
|
|
1291
|
+
|
|
1292
|
+
var upperBound = DECODE_LONG(bytebuf);
|
|
1293
|
+
if (!f.existy(upperBound) && upperBound !== 0)
|
|
1294
|
+
return {continue: false};
|
|
1295
|
+
config.upperBound = upperBound;
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
var initialValue = DECODE_LONG(bytebuf);
|
|
1299
|
+
if (!f.existy(initialValue) && initialValue !== 0)
|
|
1300
|
+
return {continue: false};
|
|
1301
|
+
config.initialValue = initialValue;
|
|
1302
|
+
|
|
1303
|
+
return {result: config, continue: true};
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
/**
|
|
1307
|
+
* Decodes a success/failure status for counter operations.
|
|
1308
|
+
* @param {Object} header Response header.
|
|
1309
|
+
* @returns {Object} Result object with boolean success.
|
|
1310
|
+
*/
|
|
1311
|
+
function decodeCounterStatus(header) {
|
|
1312
|
+
return {result: header.status === COUNTER_SUCCESS, continue: true};
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
return {
|
|
1316
|
+
encodeCounterCreate: encodeCounterCreate,
|
|
1317
|
+
encodeCounterName: encodeCounterName,
|
|
1318
|
+
encodeCounterNameValue: encodeCounterNameValue,
|
|
1319
|
+
encodeCounterNameTwoLongs: encodeCounterNameTwoLongs,
|
|
1320
|
+
decodeCounterValue: decodeCounterValue,
|
|
1321
|
+
decodeCounterConfig: decodeCounterConfig,
|
|
1322
|
+
decodeCounterStatus: decodeCounterStatus
|
|
1323
|
+
};
|
|
1324
|
+
}());
|
|
1325
|
+
|
|
1326
|
+
/**
|
|
1327
|
+
* Protocol 4.0+ requires an 'otherParams' map after media types in the header.
|
|
1328
|
+
* This mixin overrides stepsHeader to append the count (0 = no params).
|
|
1329
|
+
*/
|
|
1330
|
+
var OtherParamsMixin = {
|
|
1331
|
+
stepsHeader: function(ctx, op, opts) {
|
|
1332
|
+
var header = this.encodeHeader(op, ctx.topologyId, opts)(ctx.id);
|
|
1333
|
+
var mediaType = this.encodeMediaTypes();
|
|
1334
|
+
return f.cat(header, mediaType, [codec.encodeVInt(0)]);
|
|
1335
|
+
}
|
|
1336
|
+
};
|
|
1337
|
+
|
|
1338
|
+
var DecodePrevWithMetaMixin = (function() {
|
|
1339
|
+
/**
|
|
1340
|
+
* Decodes a previous value with metadata from the response buffer.
|
|
1341
|
+
* @param {Object} header - Response header.
|
|
1342
|
+
* @param {Object} bytebuf - Byte buffer to decode from.
|
|
1343
|
+
* @param {Function} decoderValue - Value decoder function.
|
|
1344
|
+
* @returns {Object} Result object with decoded previous value and metadata.
|
|
1345
|
+
*/
|
|
1346
|
+
function decodePrevWithMeta(header, bytebuf, decoderValue) {
|
|
1347
|
+
var flags = DECODE_UBYTE(bytebuf);
|
|
1348
|
+
if (!f.existy(flags))
|
|
1349
|
+
return {continue: false};
|
|
1350
|
+
|
|
1351
|
+
var lifespan = decodeTimestamp(flags, INFINITE_LIFESPAN, ['created', 'lifespan'], bytebuf);
|
|
1352
|
+
if (!f.existy(lifespan))
|
|
1353
|
+
return {continue: false};
|
|
1354
|
+
|
|
1355
|
+
var idle = decodeTimestamp(flags, INFINITE_MAXIDLE, ['lastUsed', 'maxIdle'], bytebuf);
|
|
1356
|
+
if (!f.existy(idle))
|
|
1357
|
+
return {continue: false};
|
|
1358
|
+
|
|
1359
|
+
var decoder = f.actions(
|
|
1360
|
+
[codec.decodeFixedBytes(8), decoderValue.fun(decoderValue.obj)]
|
|
1361
|
+
, function(values) {
|
|
1362
|
+
return {version: values[0], value: values[1]};
|
|
1363
|
+
});
|
|
1364
|
+
var versioned = decoder(bytebuf);
|
|
1365
|
+
if (f.existy(versioned)) {
|
|
1366
|
+
var result = f.merge(versioned, lifespan, idle);
|
|
1367
|
+
return {result: _.isEmpty(result.value) ? undefined : result, continue: true};
|
|
1368
|
+
}
|
|
1369
|
+
return {continue: false};
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
return {
|
|
1373
|
+
decodePrevOrElse: function(opts, cond, orElse) {
|
|
1374
|
+
var decoderValue = decoderMedia(this.valueMediaType);
|
|
1375
|
+
var shouldReturnPrev = hasOptPrev(opts);
|
|
1376
|
+
return function(header, bytebuf) {
|
|
1377
|
+
if (shouldReturnPrev)
|
|
1378
|
+
return cond(header)
|
|
1379
|
+
? decodePrevWithMeta(header, bytebuf, decoderValue)
|
|
1380
|
+
: {result: undefined, continue: true};
|
|
1381
|
+
|
|
1382
|
+
return orElse(header);
|
|
1383
|
+
};
|
|
1384
|
+
}
|
|
1385
|
+
};
|
|
989
1386
|
}());
|
|
990
1387
|
|
|
991
1388
|
var ProtostreamType = (function() {
|
|
@@ -1001,15 +1398,15 @@
|
|
|
1001
1398
|
},
|
|
1002
1399
|
lookupProtostreamTypeByName: function (protostreamTypeName) {
|
|
1003
1400
|
return _.find(protostreamTypes,function(protostreamType){
|
|
1004
|
-
return _.isEqual(protostreamType.protostreamTypeName,protostreamTypeName)
|
|
1401
|
+
return _.isEqual(protostreamType.protostreamTypeName,protostreamTypeName);
|
|
1005
1402
|
}).protostreamDescriptorId;
|
|
1006
1403
|
},
|
|
1007
1404
|
lookupProtostreamTypeById: function(protostreamDescriptorId){
|
|
1008
1405
|
return _.find(protostreamTypes,function(protostreamType){
|
|
1009
|
-
return _.isEqual(protostreamType.protostreamDescriptorId,protostreamDescriptorId)
|
|
1406
|
+
return _.isEqual(protostreamType.protostreamDescriptorId,protostreamDescriptorId);
|
|
1010
1407
|
}).protostreamTypeName;
|
|
1011
1408
|
}
|
|
1012
|
-
}
|
|
1409
|
+
};
|
|
1013
1410
|
}());
|
|
1014
1411
|
|
|
1015
1412
|
var ProtobufRoot = (function() {
|
|
@@ -1024,13 +1421,20 @@
|
|
|
1024
1421
|
var root= protobufRoot.lookupType(typeName);
|
|
1025
1422
|
return root;
|
|
1026
1423
|
}catch(err){
|
|
1027
|
-
throw new Error(
|
|
1424
|
+
throw new Error('Protobuf root not found');
|
|
1028
1425
|
}
|
|
1029
1426
|
}
|
|
1030
|
-
}
|
|
1427
|
+
};
|
|
1031
1428
|
}());
|
|
1032
1429
|
|
|
1033
1430
|
|
|
1431
|
+
/**
|
|
1432
|
+
* Constructs a Hot Rod protocol instance for the given version.
|
|
1433
|
+
* @param {number} v Protocol version number.
|
|
1434
|
+
* @param {Object} clientOpts Client options.
|
|
1435
|
+
* @constructs Protocol
|
|
1436
|
+
* @returns {void}
|
|
1437
|
+
*/
|
|
1034
1438
|
function Protocol(v, clientOpts) {
|
|
1035
1439
|
this.version = v;
|
|
1036
1440
|
this.clientOpts = clientOpts;
|
|
@@ -1055,11 +1459,23 @@
|
|
|
1055
1459
|
Protocol.call(this, 30, clientOpts);
|
|
1056
1460
|
};
|
|
1057
1461
|
|
|
1462
|
+
var Protocol31 = function(clientOpts) {
|
|
1463
|
+
Protocol.call(this, 31, clientOpts);
|
|
1464
|
+
};
|
|
1465
|
+
|
|
1466
|
+
var Protocol40 = function(clientOpts) {
|
|
1467
|
+
Protocol.call(this, 40, clientOpts);
|
|
1468
|
+
};
|
|
1469
|
+
|
|
1470
|
+
var Protocol41 = function(clientOpts) {
|
|
1471
|
+
Protocol.call(this, 41, clientOpts);
|
|
1472
|
+
};
|
|
1473
|
+
|
|
1058
1474
|
// TODO: Missing operations, just for reference
|
|
1059
1475
|
var IdsMixin = {
|
|
1060
|
-
queryId: function() { return 0x1F },
|
|
1061
|
-
authMechId: function() { return 0x21 },
|
|
1062
|
-
authReqId: function() { return 0x23 }
|
|
1476
|
+
queryId: function() { return 0x1F; },
|
|
1477
|
+
authMechId: function() { return 0x21; },
|
|
1478
|
+
authReqId: function() { return 0x23; }
|
|
1063
1479
|
};
|
|
1064
1480
|
|
|
1065
1481
|
_.extend(Protocol22.prototype
|
|
@@ -1122,14 +1538,61 @@
|
|
|
1122
1538
|
, Ping30Mixin
|
|
1123
1539
|
, ProtostreamType
|
|
1124
1540
|
, ProtobufRoot
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1541
|
+
);
|
|
1542
|
+
|
|
1543
|
+
_.extend(Protocol31.prototype
|
|
1544
|
+
, EncodeMixin
|
|
1545
|
+
, ExpiryEncodeMixin
|
|
1546
|
+
, DecodeMixin
|
|
1547
|
+
, IdsMixin
|
|
1548
|
+
, ListenersMixin
|
|
1549
|
+
, ListenerInterestsMixin
|
|
1550
|
+
, IteratorMixin
|
|
1551
|
+
, MediaTypesMixin
|
|
1552
|
+
, SASLMixin
|
|
1553
|
+
, Ping30Mixin
|
|
1554
|
+
, CounterMixin
|
|
1555
|
+
, ProtostreamType
|
|
1556
|
+
, ProtobufRoot
|
|
1557
|
+
// TODO 3.1 new ops: bloom filter near-cache
|
|
1558
|
+
);
|
|
1559
|
+
|
|
1560
|
+
_.extend(Protocol40.prototype
|
|
1561
|
+
, EncodeMixin
|
|
1562
|
+
, ExpiryEncodeMixin
|
|
1563
|
+
, OtherParamsMixin
|
|
1564
|
+
, DecodeMixin
|
|
1565
|
+
, DecodePrevWithMetaMixin
|
|
1566
|
+
, IdsMixin
|
|
1567
|
+
, ListenersMixin
|
|
1568
|
+
, ListenerInterestsMixin
|
|
1569
|
+
, IteratorMixin
|
|
1570
|
+
, MediaTypesMixin
|
|
1571
|
+
, SASLMixin
|
|
1572
|
+
, Ping30Mixin
|
|
1573
|
+
, CounterMixin
|
|
1574
|
+
, ProtostreamType
|
|
1575
|
+
, ProtobufRoot
|
|
1576
|
+
);
|
|
1577
|
+
|
|
1578
|
+
_.extend(Protocol41.prototype
|
|
1579
|
+
, EncodeMixin
|
|
1580
|
+
, ExpiryEncodeMixin
|
|
1581
|
+
, OtherParamsMixin
|
|
1582
|
+
, DecodeMixin
|
|
1583
|
+
, DecodePrevWithMetaMixin
|
|
1584
|
+
, IdsMixin
|
|
1585
|
+
, ListenersMixin
|
|
1586
|
+
, ListenerInterestsMixin
|
|
1587
|
+
, IteratorMixin
|
|
1588
|
+
, MediaTypesMixin
|
|
1589
|
+
, SASLMixin
|
|
1590
|
+
, Ping30Mixin
|
|
1591
|
+
, CounterMixin
|
|
1592
|
+
, ProtostreamType
|
|
1593
|
+
, ProtobufRoot
|
|
1594
|
+
// TODO 4.1 new ops: chunked streaming (GetStreamStart/Next/End, PutStreamStart/Next/End)
|
|
1595
|
+
);
|
|
1133
1596
|
|
|
1134
1597
|
exports.version22 = function(clientOpts) {
|
|
1135
1598
|
return new Protocol22(clientOpts);
|
|
@@ -1147,4 +1610,39 @@
|
|
|
1147
1610
|
return new Protocol30(clientOpts);
|
|
1148
1611
|
};
|
|
1149
1612
|
|
|
1613
|
+
exports.version31 = function(clientOpts) {
|
|
1614
|
+
return new Protocol31(clientOpts);
|
|
1615
|
+
};
|
|
1616
|
+
|
|
1617
|
+
exports.version40 = function(clientOpts) {
|
|
1618
|
+
return new Protocol40(clientOpts);
|
|
1619
|
+
};
|
|
1620
|
+
|
|
1621
|
+
exports.version41 = function(clientOpts) {
|
|
1622
|
+
return new Protocol41(clientOpts);
|
|
1623
|
+
};
|
|
1624
|
+
|
|
1625
|
+
var VERSION_ORDER = ['4.1', '4.0', '3.1', '3.0', '2.9', '2.5', '2.2'];
|
|
1626
|
+
|
|
1627
|
+
exports.VERSION_ORDER = VERSION_ORDER;
|
|
1628
|
+
|
|
1629
|
+
/**
|
|
1630
|
+
* Creates a protocol instance for the given version string.
|
|
1631
|
+
* @param {string} version Protocol version (e.g. '3.1', '4.0').
|
|
1632
|
+
* @param {Object} clientOpts Client configuration options.
|
|
1633
|
+
* @returns {Object} Protocol instance.
|
|
1634
|
+
*/
|
|
1635
|
+
exports.resolve = function(version, clientOpts) {
|
|
1636
|
+
switch (version) {
|
|
1637
|
+
case '4.1': return new Protocol41(clientOpts);
|
|
1638
|
+
case '4.0': return new Protocol40(clientOpts);
|
|
1639
|
+
case '3.1': return new Protocol31(clientOpts);
|
|
1640
|
+
case '3.0': return new Protocol30(clientOpts);
|
|
1641
|
+
case '2.9': return new Protocol29(clientOpts);
|
|
1642
|
+
case '2.5': return new Protocol25(clientOpts);
|
|
1643
|
+
case '2.2': return new Protocol22(clientOpts);
|
|
1644
|
+
default: throw new Error(`Unknown protocol version: ${version}`);
|
|
1645
|
+
}
|
|
1646
|
+
};
|
|
1647
|
+
|
|
1150
1648
|
}.call(this));
|