infinispan 0.9.0 → 0.10.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/documentation/asciidoc/stories/assembly_client_usage_examples.adoc +2 -8
- package/documentation/asciidoc/stories/{assembly_configuration.adoc → assembly_installation_configuration.adoc} +6 -4
- package/documentation/asciidoc/titles/js_client.asciidoc +1 -0
- package/documentation/asciidoc/titles/stories.adoc +1 -2
- package/documentation/asciidoc/topics/attributes/community-attributes.adoc +1 -1
- package/documentation/asciidoc/topics/attributes/downstream-attributes.adoc +0 -2
- package/documentation/asciidoc/topics/code_examples/authentication-digest.js +3 -2
- package/documentation/asciidoc/topics/code_examples/authentication-external.js +3 -2
- package/documentation/asciidoc/topics/code_examples/authentication-oauthbearer.js +3 -2
- package/documentation/asciidoc/topics/code_examples/authentication-plain.js +3 -2
- package/documentation/asciidoc/topics/code_examples/authentication-scram.js +3 -2
- package/documentation/asciidoc/topics/code_examples/await-single-entries.js +1 -1
- package/documentation/asciidoc/topics/code_examples/conditional-operations.js +7 -1
- package/documentation/asciidoc/topics/code_examples/connection-multiple-servers.js +5 -1
- package/documentation/asciidoc/topics/code_examples/data-types.js +2 -2
- package/documentation/asciidoc/topics/code_examples/ephemeral-data.js +11 -6
- package/documentation/asciidoc/topics/code_examples/hello-world.js +13 -1
- package/documentation/asciidoc/topics/code_examples/key-value-converter.js +3 -4
- package/documentation/asciidoc/topics/code_examples/multiple-entries.js +13 -2
- package/documentation/asciidoc/topics/code_examples/register-event-listener.js +8 -4
- package/documentation/asciidoc/topics/code_examples/sample-script-execute.js +6 -1
- package/documentation/asciidoc/topics/code_examples/single-entries.js +13 -2
- package/documentation/asciidoc/topics/proc_configuring_connections.adoc +8 -9
- package/documentation/asciidoc/topics/proc_installing_clients.adoc +23 -5
- package/documentation/asciidoc/topics/ref_client_usage.adoc +116 -0
- package/lib/codec.js +153 -2
- package/lib/infinispan.js +27 -1
- package/lib/io.js +14 -8
- package/lib/protocols.js +129 -4
- package/lib/protostream/message-wrapping.proto +134 -0
- package/lib/protostream/query.proto +122 -0
- package/lib/sasl/bitops.js +5 -7
- package/lib/sasl/factory.js +71 -0
- package/lib/utils.js +1 -1
- package/memory-profiling/helper.js +9 -0
- package/memory-profiling/infinispan_memory_many_get.js +1 -3
- package/memory-profiling/infinispan_memory_one_get.js +6 -4
- package/package.json +7 -12
- package/run-servers.sh +1 -1
- package/spec/codec_spec.js +7 -7
- package/spec/configs/infinispan-clustered.xml +17 -14
- package/spec/configs/infinispan-ssl.xml +25 -22
- package/spec/configs/infinispan-xsite-EARTH.xml +17 -14
- package/spec/configs/infinispan-xsite-MOON.xml +14 -11
- package/spec/configs/infinispan.xml +22 -13
- package/spec/protostream_spec.js +237 -0
- package/spec/utils/testing.js +1 -3
- package/documentation/asciidoc/stories/assembly_getting_started.adoc +0 -11
- package/documentation/asciidoc/topics/community-attributes.adoc +0 -10
- package/documentation/asciidoc/topics/downstream-attributes.adoc +0 -10
- package/documentation/asciidoc/topics/proc_executing_scripts.adoc +0 -16
- package/documentation/asciidoc/topics/proc_registering_event_listeners.adoc +0 -31
- package/documentation/asciidoc/topics/proc_using_async_await.adoc +0 -23
- package/documentation/asciidoc/topics/proc_using_conditional_operations.adoc +0 -7
- package/documentation/asciidoc/topics/proc_working_ephemeral_data.adoc +0 -7
- package/documentation/asciidoc/topics/proc_working_multiple_entries.adoc +0 -7
- package/documentation/asciidoc/topics/proc_working_single_entries_statistics.adoc +0 -7
- package/documentation/asciidoc/topics/ref_basic_usage.adoc +0 -8
package/lib/codec.js
CHANGED
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
, INT = Math.pow(2, 31);
|
|
7
7
|
|
|
8
8
|
var _ = require('underscore');
|
|
9
|
+
var protobuf = require('protobufjs');
|
|
10
|
+
var path = require('path');
|
|
11
|
+
|
|
9
12
|
var f = require('./functional');
|
|
10
13
|
var utils = require('./utils');
|
|
11
14
|
|
|
@@ -16,8 +19,11 @@
|
|
|
16
19
|
exports.encodeVLong = f.lift(doEncodeVLong, _.identity);
|
|
17
20
|
exports.encodeJSON = f.lift(doEncodeJSON, _.identity);
|
|
18
21
|
exports.encodeBytes = f.lift(doEncodeBytes, _.identity);
|
|
22
|
+
exports.encodeBytesWithLength = f.lift(doEncodeBytesWithLength, _.identity);
|
|
19
23
|
exports.encodeString = f.lift(doEncodeString, _.identity);
|
|
20
24
|
exports.encodeSignedInt = f.lift(doEncodeSignedInt, _.identity);
|
|
25
|
+
exports.encodeProtobuf = f.lift(doEncodeProtobuf, _.identity);
|
|
26
|
+
exports.encodeQuery = f.lift(doEncodeQuery,_.identity);
|
|
21
27
|
|
|
22
28
|
exports.decodeUByte = f.lift(doDecodeUByte, _.identity);
|
|
23
29
|
exports.decodeVInt = f.lift(doDecodeVInt, _.identity);
|
|
@@ -29,6 +35,8 @@
|
|
|
29
35
|
exports.decodeSignedInt = f.lift(doDecodeSignedInt, _.identity);
|
|
30
36
|
exports.decodeVariableBytes = f.lift(doDecodeVariableBytes, _.identity);
|
|
31
37
|
exports.decodeShort = f.lift(doDecodeShort, _.identity);
|
|
38
|
+
exports.decodeProtobuf = f.lift(doDecodeProtobuf, _.identity);
|
|
39
|
+
exports.decodeQuery = f.lift(doDecodeQuery,_.identity);
|
|
32
40
|
|
|
33
41
|
exports.lastDecoded = function(values) {
|
|
34
42
|
return values[0];
|
|
@@ -79,10 +87,54 @@
|
|
|
79
87
|
return _.compose(updateEncOffset(bytebuf), checkedWriteBytes(bytebuf))(bytes);
|
|
80
88
|
}
|
|
81
89
|
|
|
90
|
+
function doEncodeBytesWithLength(bytebuf, bytes) {
|
|
91
|
+
return _.compose(updateEncOffset(bytebuf), checkedWriteBytesWithLength(bytebuf))(bytes);
|
|
92
|
+
}
|
|
93
|
+
|
|
82
94
|
function doEncodeSignedInt(bytebuf, num) {
|
|
83
95
|
return _.compose(updateEncOffset(bytebuf), checkedWriteSignedInt(bytebuf), zigZag)(num);
|
|
84
96
|
}
|
|
85
97
|
|
|
98
|
+
function doEncodeProtobuf(bytebuf, message, typeId) {
|
|
99
|
+
return doEncodeBytesWithLength(bytebuf,encodeProtobuf(message,typeId));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function encodeProtobufInstance(root){
|
|
103
|
+
return function(obj){
|
|
104
|
+
return root.encode(obj).finish();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function encodeProtobuf(message,typeId){
|
|
109
|
+
return _.compose(encodeProtobufInstance(WrappedMessage), createWrappedMessage)(message,typeId);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function doEncodeQuery(bytebuf,query){
|
|
113
|
+
return doEncodeBytesWithLength(bytebuf,encodeProtobufInstance(Query.QueryRequest)(query));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function createWrappedMessage(message,typeId){
|
|
117
|
+
var wrappedMessage={};
|
|
118
|
+
if(_.isNumber(message)){
|
|
119
|
+
return f.merge(wrappedMessage,{'wrappedDouble':message});
|
|
120
|
+
}
|
|
121
|
+
if(_.isString(message)){
|
|
122
|
+
return f.merge(wrappedMessage,{'wrappedString':message});
|
|
123
|
+
}
|
|
124
|
+
if(_.isBoolean(message)){
|
|
125
|
+
return f.merge(wrappedMessage,{'wrappedBool':message});
|
|
126
|
+
}
|
|
127
|
+
if(_.isArrayBuffer(message)){
|
|
128
|
+
return f.merge(wrappedMessage,{'wrappedBytes':message});
|
|
129
|
+
}
|
|
130
|
+
if(f.existy(message.$type)){
|
|
131
|
+
var encodedMessage = encodeProtobufInstance(message.$type)(message);
|
|
132
|
+
var messageTypeId = typeId(message.$type.fullName);
|
|
133
|
+
return f.merge(wrappedMessage,{'wrappedMessage':encodedMessage},{'wrappedTypeId':messageTypeId});
|
|
134
|
+
}
|
|
135
|
+
throw new Error("Provide valid data types.");
|
|
136
|
+
}
|
|
137
|
+
|
|
86
138
|
function zigZag(num) {
|
|
87
139
|
return (num << 1) ^ (num >> 31);
|
|
88
140
|
}
|
|
@@ -90,8 +142,8 @@
|
|
|
90
142
|
var nullCheck = f.validator('must not be null', f.existy);
|
|
91
143
|
var number = f.validator('must be a number', _.isNumber);
|
|
92
144
|
var positiveOrZero = f.validator('must be >= 0', f.greaterThan(-1));
|
|
93
|
-
var intTooBig = f.validator('must be less than 2^
|
|
94
|
-
var shortTooBig = f.validator('must be less than 2^
|
|
145
|
+
var intTooBig = f.validator('must be less than 2^32', f.lessThan(Math.pow(2, 32)));
|
|
146
|
+
var shortTooBig = f.validator('must be less than 2^16', f.lessThan(Math.pow(2, 16)));
|
|
95
147
|
var longTooBig = f.validator('must be less than 2^53 (javascript safe integer limitation)',
|
|
96
148
|
f.lessThan(Math.pow(2, 53)));
|
|
97
149
|
var stringOrNullCheck = f.validator('must be a String or null', stringOrNull);
|
|
@@ -124,6 +176,10 @@
|
|
|
124
176
|
return f.partial1(f.condition1(nullCheck), uncheckedWriteBytes(bytebuf));
|
|
125
177
|
}
|
|
126
178
|
|
|
179
|
+
function checkedWriteBytesWithLength(bytebuf) {
|
|
180
|
+
return f.partial1(f.condition1(nullCheck), uncheckedWriteBytesWithLength(bytebuf));
|
|
181
|
+
}
|
|
182
|
+
|
|
127
183
|
function checkedWriteSignedInt(bytebuf) {
|
|
128
184
|
return f.partial1(f.condition1(number, intTooBig), uncheckedWriteVNum(bytebuf));
|
|
129
185
|
}
|
|
@@ -209,6 +265,19 @@
|
|
|
209
265
|
}
|
|
210
266
|
}
|
|
211
267
|
|
|
268
|
+
function uncheckedWriteBytesWithLength(bytebuf) {
|
|
269
|
+
return function(bytes) {
|
|
270
|
+
var buffNumBytes = f.existy(bytes) ? Buffer.byteLength(bytes) : 0;
|
|
271
|
+
var offsetAfterBytes = doEncodeVInt(bytebuf, buffNumBytes);
|
|
272
|
+
if (buffNumBytes > 0) {
|
|
273
|
+
bytebuf = bytebufOverflowProtect(bytebuf, bytes.length);
|
|
274
|
+
var targetStart = bytebuf.offset;
|
|
275
|
+
bytes.copy(bytebuf.buf, targetStart);
|
|
276
|
+
}
|
|
277
|
+
return targetStart + buffNumBytes;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
212
281
|
function doDecodeUByte(bytebuf) {
|
|
213
282
|
return uncheckedReadUByte(bytebuf)();
|
|
214
283
|
}
|
|
@@ -253,6 +322,68 @@
|
|
|
253
322
|
return uncheckedReadShort(bytebuf)();
|
|
254
323
|
}
|
|
255
324
|
|
|
325
|
+
function doDecodeProtobuf(bytebuf,protostreamTypename,root){
|
|
326
|
+
var wrappedObject = _.compose(decodeProtobufMessage(WrappedMessage),trimBytebuf)(bytebuf);
|
|
327
|
+
return unwrapWrappedMessage(wrappedObject,protostreamTypename,root);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function unwrapWrappedMessage(wrappedObject,protostreamTypename,root){
|
|
331
|
+
switch(true){
|
|
332
|
+
case _.has(wrappedObject,'wrappedDouble'):
|
|
333
|
+
return wrappedObject.wrappedDouble;
|
|
334
|
+
case _.has(wrappedObject,'wrappedString'):
|
|
335
|
+
return wrappedObject.wrappedString;
|
|
336
|
+
case _.has(wrappedObject,'wrappedBool'):
|
|
337
|
+
return wrappedObject.wrappedBool;
|
|
338
|
+
case _.has(wrappedObject,'wrappedBytes'):
|
|
339
|
+
return wrappedObject.wrappedBytes;
|
|
340
|
+
case _.has(wrappedObject,'wrappedMessage'):
|
|
341
|
+
var messageBytes= wrappedObject.wrappedMessage;
|
|
342
|
+
var protobufRoot = findRootByTypeId(protostreamTypename,root)(wrappedObject.wrappedTypeId);
|
|
343
|
+
return decodeProtobufMessage(protobufRoot)(messageBytes);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function decodeProtobufMessage(root){
|
|
348
|
+
return function(bytebuf){
|
|
349
|
+
return root.decode(bytebuf);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
function findRootByTypeId(protostreamTypename,root){
|
|
354
|
+
return function(wrappedTypeId){
|
|
355
|
+
return _.compose(root,protostreamTypename)(wrappedTypeId);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
function trimBytebuf(bytebuf,length){
|
|
360
|
+
if(!f.existy(length)) length = doDecodeVInt(bytebuf);
|
|
361
|
+
var retBuf = bytebuf.buf.slice(bytebuf.offset, bytebuf.offset + length);
|
|
362
|
+
bytebuf.offset += length;
|
|
363
|
+
return retBuf;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
function doDecodeQuery(bytebuf,protostreamTypename,root){
|
|
367
|
+
var queryResponse = decodeProtobufMessage(Query.QueryResponse)(trimBytebuf(bytebuf));
|
|
368
|
+
var queryResults = queryResponse.results;
|
|
369
|
+
var projectionSize = queryResponse.projectionSize;
|
|
370
|
+
return f.greaterThan(0)(projectionSize) ? unwrapQueryWithProj(queryResults,projectionSize) : unwrapQueryWithoutProj(queryResults,protostreamTypename,root);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
function decodeWrappedBytes(result,protostreamTypename,root){
|
|
374
|
+
return _.compose(f.curry3(unwrapWrappedMessage)(root)(protostreamTypename),decodeProtobufMessage(WrappedMessage))(result.wrappedBytes);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
function unwrapQueryWithoutProj(queryResults,protostreamTypeName,root){
|
|
378
|
+
return queryResults.map(f.curry3(decodeWrappedBytes)(root)(protostreamTypeName));
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
function unwrapQueryWithProj(queryResults,projectionSize){
|
|
382
|
+
return _.reduce(queryResults,function(acc,cur,i){
|
|
383
|
+
return ((i%projectionSize) ? acc[acc.length-1].push(_.values(cur)[0]) : acc.push([_.values(cur)[0]])) && acc;
|
|
384
|
+
},[]);
|
|
385
|
+
}
|
|
386
|
+
|
|
256
387
|
function uncheckedReadUByte(bytebuf) {
|
|
257
388
|
return function() {
|
|
258
389
|
if (1 > bytebuf.buf.length - bytebuf.offset) {
|
|
@@ -346,4 +477,24 @@
|
|
|
346
477
|
}
|
|
347
478
|
}
|
|
348
479
|
|
|
480
|
+
var WrappedMessage = (function() {
|
|
481
|
+
var root=protobuf.loadSync(path.join(__dirname+'/protostream/message-wrapping.proto'));
|
|
482
|
+
|
|
483
|
+
var wrappedMessage = root.lookupType('org.infinispan.protostream.WrappedMessage');
|
|
484
|
+
|
|
485
|
+
return wrappedMessage;
|
|
486
|
+
}());
|
|
487
|
+
|
|
488
|
+
var Query = (function() {
|
|
489
|
+
var root=protobuf.loadSync(path.join(__dirname+'/protostream/query.proto'));
|
|
490
|
+
protobuf.loadSync(path.join(__dirname+'/protostream/message-wrapping.proto'),root); //loaded the wrappedMessage.proto to the root
|
|
491
|
+
var QueryRequest = root.lookupType('org.infinispan.query.remote.client.QueryRequest');
|
|
492
|
+
var QueryResponse = root.lookupType('org.infinispan.query.remote.client.QueryResponse');
|
|
493
|
+
|
|
494
|
+
return {
|
|
495
|
+
QueryRequest,
|
|
496
|
+
QueryResponse
|
|
497
|
+
};
|
|
498
|
+
}());
|
|
499
|
+
|
|
349
500
|
}.call(this));
|
package/lib/infinispan.js
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
logger.debugf('Using protocol version: %s', version);
|
|
25
25
|
|
|
26
26
|
switch (version) {
|
|
27
|
+
case '3.0': return protocols.version30(clientOpts);
|
|
27
28
|
case '2.9': return protocols.version29(clientOpts);
|
|
28
29
|
case '2.5': return protocols.version25(clientOpts);
|
|
29
30
|
case '2.2': return protocols.version22(clientOpts);
|
|
@@ -225,6 +226,23 @@
|
|
|
225
226
|
var decoder = p.decodeValue();
|
|
226
227
|
return futureKey(ctx, 0x03, k, p.encodeKey(k), decoder);
|
|
227
228
|
},
|
|
229
|
+
/**
|
|
230
|
+
* Query the server with the given queryString.
|
|
231
|
+
*
|
|
232
|
+
* @param q {(Object)} query to retrieve.
|
|
233
|
+
* @returns {module:promise.Promise.<?Object[]>}
|
|
234
|
+
* A promise that will be completed with the array of values associated with
|
|
235
|
+
* the query, or empty array if the no values matches the query.
|
|
236
|
+
* @memberof Client#
|
|
237
|
+
* @since 1.3
|
|
238
|
+
*/
|
|
239
|
+
query: function(q) {
|
|
240
|
+
//TODO : extend the support of query with application/json datatypes
|
|
241
|
+
var ctx = transport.context(SMALL);
|
|
242
|
+
logger.debugf('Invoke query(msgId=%d,key=%s)', ctx.id, u.str(q));
|
|
243
|
+
var decoder = p.decodeQuery();
|
|
244
|
+
return futureKey(ctx, 0x1F, q, p.encodeQuery(q), decoder);
|
|
245
|
+
},
|
|
228
246
|
/**
|
|
229
247
|
* Check whether the given key is present.
|
|
230
248
|
*
|
|
@@ -564,7 +582,7 @@
|
|
|
564
582
|
ping: function() {
|
|
565
583
|
var ctx = transport.context(TINY);
|
|
566
584
|
logger.debugf('Invoke ping(msgId=%d)', ctx.id);
|
|
567
|
-
return futureDecodeOnly(ctx, 0x17, p.
|
|
585
|
+
return futureDecodeOnly(ctx, 0x17, p.decodePingResponse);
|
|
568
586
|
},
|
|
569
587
|
|
|
570
588
|
/**
|
|
@@ -735,6 +753,14 @@
|
|
|
735
753
|
*/
|
|
736
754
|
toString: function() {
|
|
737
755
|
return util.format('Client(%s)', transport);
|
|
756
|
+
},
|
|
757
|
+
|
|
758
|
+
registerProtostreamType: function(typeName,descriptorId){
|
|
759
|
+
return p.registerProtostreamType(typeName,descriptorId);
|
|
760
|
+
},
|
|
761
|
+
|
|
762
|
+
registerProtostreamRoot: function(root){
|
|
763
|
+
return p.registerProtostreamRoot(root);
|
|
738
764
|
}
|
|
739
765
|
}
|
|
740
766
|
};
|
package/lib/io.js
CHANGED
|
@@ -7,9 +7,6 @@
|
|
|
7
7
|
var fs = require('fs');
|
|
8
8
|
var net = require('net');
|
|
9
9
|
|
|
10
|
-
var promiseFinally = require('promise.prototype.finally');
|
|
11
|
-
promiseFinally.shim(); // will be a no-op if not needed
|
|
12
|
-
|
|
13
10
|
var tls = require('tls');
|
|
14
11
|
var util = require('util');
|
|
15
12
|
|
|
@@ -259,10 +256,19 @@
|
|
|
259
256
|
});
|
|
260
257
|
},
|
|
261
258
|
write: function(buffer) {
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
259
|
+
return new Promise(function (fulfill, reject) {
|
|
260
|
+
var flushed = sock.write(buffer, (err) => {
|
|
261
|
+
if (err) {
|
|
262
|
+
logger.error('Error writing to socket: %s', err);
|
|
263
|
+
transport.retryRpcs(addr); // retry RPCs in case of error
|
|
264
|
+
}
|
|
265
|
+
fulfill();
|
|
266
|
+
});
|
|
267
|
+
if (!flushed)
|
|
268
|
+
logger.debugf('Buffer write not fully flushed, part of of data queued for: %s',
|
|
269
|
+
buffer.toString('hex').toUpperCase());
|
|
270
|
+
});
|
|
271
|
+
|
|
266
272
|
},
|
|
267
273
|
getAddress: function() {
|
|
268
274
|
return addr;
|
|
@@ -745,7 +751,7 @@
|
|
|
745
751
|
logger.debugf('Invoke ping(msgId=%d)', ctx.id);
|
|
746
752
|
var p = transport.getProtocol();
|
|
747
753
|
f.actions(p.stepsHeader(ctx, 0x17, undefined), codec.bytesEncoded)(ctx);
|
|
748
|
-
return transport.writeCommandPinned(ctx, p.
|
|
754
|
+
return transport.writeCommandPinned(ctx, p.decodePingResponse, conn);
|
|
749
755
|
}
|
|
750
756
|
|
|
751
757
|
function auth(transport, conn, topologyId) {
|
package/lib/protocols.js
CHANGED
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
(function() {
|
|
4
4
|
|
|
5
5
|
var _ = require('underscore');
|
|
6
|
-
|
|
6
|
+
|
|
7
7
|
var f = require('./functional');
|
|
8
8
|
var u = require('./utils');
|
|
9
9
|
var codec = require('./codec');
|
|
10
10
|
|
|
11
11
|
var logger = u.logger('protocols');
|
|
12
|
-
var
|
|
13
|
-
var factory = new
|
|
12
|
+
var Factory = require('./sasl/factory');
|
|
13
|
+
var factory = new Factory();
|
|
14
14
|
factory.use(require('./sasl/plain'));
|
|
15
15
|
factory.use(require('./sasl/external'));
|
|
16
16
|
factory.use('DIGEST-MD5', require('./sasl/digest'));
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
var DECODE_TIMESTAMP = f.actions([codec.decodeLong(), codec.decodeVInt()], codec.allDecoded(2));
|
|
56
56
|
var DECODE_UBYTE = f.actions([codec.decodeUByte()], codec.lastDecoded);
|
|
57
57
|
var DECODE_VINT = f.actions([codec.decodeVInt()], codec.lastDecoded);
|
|
58
|
+
var DECODE_SHORT = f.actions([codec.decodeShort()], codec.lastDecoded);
|
|
58
59
|
|
|
59
60
|
function hasOpt(opts, name) { return _.has(opts, name) && f.truthy(opts[name]); }
|
|
60
61
|
function hasOptPrev(opts) { return hasOpt(opts, 'previous'); }
|
|
@@ -117,6 +118,11 @@
|
|
|
117
118
|
return [outer.encodeMediaKey(k)]; // key
|
|
118
119
|
}
|
|
119
120
|
},
|
|
121
|
+
encodeQuery: function (q) {
|
|
122
|
+
return function() {
|
|
123
|
+
return [codec.encodeQuery(q)]; // query
|
|
124
|
+
}
|
|
125
|
+
},
|
|
120
126
|
encodeKeyVersion: function (k, version) {
|
|
121
127
|
var outer = this;
|
|
122
128
|
return function() {
|
|
@@ -361,6 +367,12 @@
|
|
|
361
367
|
return decodeObject(header, bytebuf, decodeAction);
|
|
362
368
|
}
|
|
363
369
|
},
|
|
370
|
+
decodeQuery: function() {
|
|
371
|
+
return function(header, bytebuf) {
|
|
372
|
+
var decodeAction = f.actions([f.partial2(codec.decodeQuery,ProtostreamType.lookupProtostreamTypeById,ProtobufRoot.findRootByTypeName)()],codec.lastDecoded);
|
|
373
|
+
return decodeObject(header, bytebuf, decodeAction);
|
|
374
|
+
}
|
|
375
|
+
},
|
|
364
376
|
decodeWithMeta: function() {
|
|
365
377
|
var decoderValue = decoderMedia(this.valueMediaType);
|
|
366
378
|
return function(header, bytebuf) {
|
|
@@ -749,6 +761,7 @@
|
|
|
749
761
|
return f.dispatch(
|
|
750
762
|
f.isa('application/json', encoder(2, encoderJson, decoderJson()))
|
|
751
763
|
, f.isa('text/plain', encoder(13, encoderString, decoderString()))
|
|
764
|
+
, f.isa('application/x-protostream', encoder(12, encoderProtobuf, decoderProtobuf()))
|
|
752
765
|
)(mediaType);
|
|
753
766
|
}
|
|
754
767
|
|
|
@@ -768,6 +781,14 @@
|
|
|
768
781
|
return codec.decodeString();
|
|
769
782
|
}
|
|
770
783
|
|
|
784
|
+
function encoderProtobuf(message){
|
|
785
|
+
return codec.encodeProtobuf(message,ProtostreamType.lookupProtostreamTypeByName);
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
function decoderProtobuf(){
|
|
789
|
+
return f.partial2(codec.decodeProtobuf,ProtostreamType.lookupProtostreamTypeById,ProtobufRoot.findRootByTypeName)();
|
|
790
|
+
}
|
|
791
|
+
|
|
771
792
|
function encoder(id, mediaEncoder, mediaDecoder) {
|
|
772
793
|
return function() {
|
|
773
794
|
return [
|
|
@@ -873,9 +894,9 @@
|
|
|
873
894
|
if (keyMediaType.continue) {
|
|
874
895
|
var valueMediaType = decodeServerMediaType(bytebuf);
|
|
875
896
|
if (valueMediaType.continue)
|
|
897
|
+
|
|
876
898
|
return {result: undefined, continue: true};
|
|
877
899
|
}
|
|
878
|
-
|
|
879
900
|
return {continue: false};
|
|
880
901
|
}
|
|
881
902
|
}
|
|
@@ -943,6 +964,73 @@
|
|
|
943
964
|
}
|
|
944
965
|
}());
|
|
945
966
|
|
|
967
|
+
var Ping29Mixin = (function() {
|
|
968
|
+
return {
|
|
969
|
+
decodePingResponse: function(header,bytebuf){
|
|
970
|
+
logger.debugf("header and bytebuf %s %s",header,bytebuf);
|
|
971
|
+
return MediaTypesMixin.decodeServerMediaTypes(header,bytebuf);
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
}());
|
|
975
|
+
|
|
976
|
+
var Ping30Mixin = (function() {
|
|
977
|
+
return {
|
|
978
|
+
decodePingResponse: function(header,bytebuf){
|
|
979
|
+
var serverMediaTypes= MediaTypesMixin.decodeServerMediaTypes(header,bytebuf);
|
|
980
|
+
var version=DECODE_UBYTE(bytebuf);
|
|
981
|
+
var opCount=DECODE_VINT(bytebuf);
|
|
982
|
+
var opRequestCodes=[];
|
|
983
|
+
for(let i=0;i<opCount;i++){
|
|
984
|
+
opRequestCodes.push(DECODE_SHORT(bytebuf));
|
|
985
|
+
}
|
|
986
|
+
return serverMediaTypes;
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
}());
|
|
990
|
+
|
|
991
|
+
var ProtostreamType = (function() {
|
|
992
|
+
var protostreamTypes=[];
|
|
993
|
+
return {
|
|
994
|
+
registerProtostreamType: function(protostreamTypeName,protostreamDescriptorId){
|
|
995
|
+
var protostreamType={
|
|
996
|
+
protostreamTypeName,
|
|
997
|
+
protostreamDescriptorId
|
|
998
|
+
};
|
|
999
|
+
protostreamTypes.push(protostreamType);
|
|
1000
|
+
return protostreamType;
|
|
1001
|
+
},
|
|
1002
|
+
lookupProtostreamTypeByName: function (protostreamTypeName) {
|
|
1003
|
+
return _.find(protostreamTypes,function(protostreamType){
|
|
1004
|
+
return _.isEqual(protostreamType.protostreamTypeName,protostreamTypeName)
|
|
1005
|
+
}).protostreamDescriptorId;
|
|
1006
|
+
},
|
|
1007
|
+
lookupProtostreamTypeById: function(protostreamDescriptorId){
|
|
1008
|
+
return _.find(protostreamTypes,function(protostreamType){
|
|
1009
|
+
return _.isEqual(protostreamType.protostreamDescriptorId,protostreamDescriptorId)
|
|
1010
|
+
}).protostreamTypeName;
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
}());
|
|
1014
|
+
|
|
1015
|
+
var ProtobufRoot = (function() {
|
|
1016
|
+
var protobufRoot;
|
|
1017
|
+
return {
|
|
1018
|
+
registerProtostreamRoot: function(root){
|
|
1019
|
+
protobufRoot=root;
|
|
1020
|
+
return protobufRoot;
|
|
1021
|
+
},
|
|
1022
|
+
findRootByTypeName: function(typeName){
|
|
1023
|
+
try{
|
|
1024
|
+
var root= protobufRoot.lookupType(typeName);
|
|
1025
|
+
return root;
|
|
1026
|
+
}catch(err){
|
|
1027
|
+
throw new Error("Protobuf root not found");
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
}());
|
|
1032
|
+
|
|
1033
|
+
|
|
946
1034
|
function Protocol(v, clientOpts) {
|
|
947
1035
|
this.version = v;
|
|
948
1036
|
this.clientOpts = clientOpts;
|
|
@@ -963,6 +1051,10 @@
|
|
|
963
1051
|
Protocol.call(this, 29, clientOpts);
|
|
964
1052
|
};
|
|
965
1053
|
|
|
1054
|
+
var Protocol30 = function(clientOpts) {
|
|
1055
|
+
Protocol.call(this, 30, clientOpts);
|
|
1056
|
+
};
|
|
1057
|
+
|
|
966
1058
|
// TODO: Missing operations, just for reference
|
|
967
1059
|
var IdsMixin = {
|
|
968
1060
|
queryId: function() { return 0x1F },
|
|
@@ -978,6 +1070,8 @@
|
|
|
978
1070
|
, ListenersMixin
|
|
979
1071
|
, NoListenerInterestsMixin
|
|
980
1072
|
, NoMediaTypesMixin
|
|
1073
|
+
, ProtostreamType
|
|
1074
|
+
, ProtobufRoot
|
|
981
1075
|
);
|
|
982
1076
|
|
|
983
1077
|
_.extend(Protocol25.prototype
|
|
@@ -989,6 +1083,8 @@
|
|
|
989
1083
|
, NoListenerInterestsMixin
|
|
990
1084
|
, IteratorMixin
|
|
991
1085
|
, NoMediaTypesMixin
|
|
1086
|
+
, ProtostreamType
|
|
1087
|
+
, ProtobufRoot
|
|
992
1088
|
);
|
|
993
1089
|
|
|
994
1090
|
_.extend(Protocol29.prototype
|
|
@@ -1001,6 +1097,9 @@
|
|
|
1001
1097
|
, IteratorMixin
|
|
1002
1098
|
, MediaTypesMixin
|
|
1003
1099
|
, SASLMixin
|
|
1100
|
+
, Ping29Mixin
|
|
1101
|
+
, ProtostreamType
|
|
1102
|
+
, ProtobufRoot
|
|
1004
1103
|
// TODO 2.6 new ops: getStream and putStream
|
|
1005
1104
|
// TODO 2.6 add listener change: listener event interests
|
|
1006
1105
|
// TODO 2.7 new ops: prepare, commit and rollback
|
|
@@ -1010,6 +1109,28 @@
|
|
|
1010
1109
|
// TODO 2.8 header change: media types
|
|
1011
1110
|
);
|
|
1012
1111
|
|
|
1112
|
+
_.extend(Protocol30.prototype
|
|
1113
|
+
, EncodeMixin
|
|
1114
|
+
, ExpiryEncodeMixin
|
|
1115
|
+
, DecodeMixin
|
|
1116
|
+
, IdsMixin
|
|
1117
|
+
, ListenersMixin
|
|
1118
|
+
, ListenerInterestsMixin
|
|
1119
|
+
, IteratorMixin
|
|
1120
|
+
, MediaTypesMixin
|
|
1121
|
+
, SASLMixin
|
|
1122
|
+
, Ping30Mixin
|
|
1123
|
+
, ProtostreamType
|
|
1124
|
+
, ProtobufRoot
|
|
1125
|
+
// TODO 2.6 new ops: getStream and putStream
|
|
1126
|
+
// TODO 2.6 add listener change: listener event interests
|
|
1127
|
+
// TODO 2.7 new ops: prepare, commit and rollback
|
|
1128
|
+
// TODO 2.7 new ops: counter operations
|
|
1129
|
+
// TODO 2.7 new events: counter events
|
|
1130
|
+
// TODO 2.8 listener events: can come from any connection
|
|
1131
|
+
// TODO 2.8 header change: media types
|
|
1132
|
+
);
|
|
1133
|
+
|
|
1013
1134
|
exports.version22 = function(clientOpts) {
|
|
1014
1135
|
return new Protocol22(clientOpts);
|
|
1015
1136
|
};
|
|
@@ -1022,4 +1143,8 @@
|
|
|
1022
1143
|
return new Protocol29(clientOpts);
|
|
1023
1144
|
};
|
|
1024
1145
|
|
|
1146
|
+
exports.version30 = function(clientOpts) {
|
|
1147
|
+
return new Protocol30(clientOpts);
|
|
1148
|
+
};
|
|
1149
|
+
|
|
1025
1150
|
}.call(this));
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
syntax = "proto2";
|
|
2
|
+
|
|
3
|
+
package org.infinispan.protostream;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Protobuf messages do not indicate their message type or structure. Readers of protobuf data streams are expected to
|
|
7
|
+
* know in advance what message type to expect next in the stream. Also, the wire format is not self-delimiting so the
|
|
8
|
+
* length of the next message must be computed based on the known schema so that not too much nor too little is read.
|
|
9
|
+
* This is particularly important if a sequence of multiple messages are contained in a stream. A detailed explanation
|
|
10
|
+
* is offered here: https://developers.google.com/protocol-buffers/docs/techniques#streaming
|
|
11
|
+
* <p>
|
|
12
|
+
* WrappedMessage solves this problem of self-describing messages by allowing the stream reader to detect
|
|
13
|
+
* the type of the message. Still, only the type name (or type id) is provided but the actual schema is not provided as
|
|
14
|
+
* it would not be efficient to carry so much information over the wire with each message. The application is expected
|
|
15
|
+
* to have knowledge of the schema and use it once it learns the type name/id.
|
|
16
|
+
* <p>
|
|
17
|
+
* This is similar to 'google.protobuf.Any' but is also able to handle scalars not just messages.
|
|
18
|
+
* <p>
|
|
19
|
+
* Fields should ideally arrive in the data stream in the order defined here for efficiency reasons, but implementations
|
|
20
|
+
* should be able to deal with any field order.
|
|
21
|
+
*
|
|
22
|
+
* @TypeId(0)
|
|
23
|
+
*/
|
|
24
|
+
message WrappedMessage {
|
|
25
|
+
|
|
26
|
+
// Exactly one of the following fields is used if the wrapped value is a primitive (scalar) type.
|
|
27
|
+
oneof scalarOrMessage {
|
|
28
|
+
double wrappedDouble = 1;
|
|
29
|
+
float wrappedFloat = 2;
|
|
30
|
+
int64 wrappedInt64 = 3;
|
|
31
|
+
uint64 wrappedUInt64 = 4;
|
|
32
|
+
int32 wrappedInt32 = 5;
|
|
33
|
+
fixed64 wrappedFixed64 = 6;
|
|
34
|
+
fixed32 wrappedFixed32 = 7;
|
|
35
|
+
bool wrappedBool = 8;
|
|
36
|
+
string wrappedString = 9;
|
|
37
|
+
bytes wrappedBytes = 10;
|
|
38
|
+
uint32 wrappedUInt32 = 11;
|
|
39
|
+
sfixed32 wrappedSFixed32 = 12;
|
|
40
|
+
sfixed64 wrappedSFixed64 = 13;
|
|
41
|
+
sint32 wrappedSInt32 = 14;
|
|
42
|
+
sint64 wrappedSInt64 = 15;
|
|
43
|
+
|
|
44
|
+
/** There is no native char type in protobuf so it is mapped to int32. */
|
|
45
|
+
int32 wrappedChar = 20;
|
|
46
|
+
|
|
47
|
+
/** There is no native short type in protobuf so it is mapped to int32. */
|
|
48
|
+
int32 wrappedShort = 21;
|
|
49
|
+
|
|
50
|
+
/** There is no native byte type in protobuf so it is mapped to int32. */
|
|
51
|
+
int32 wrappedByte = 22;
|
|
52
|
+
|
|
53
|
+
/** There is no native Date type in protobuf so it is mapped to int64 (milliseconds). */
|
|
54
|
+
int64 wrappedDateMillis = 23;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* There is no native Instant type in protobuf so it is mapped to an int64 (the seconds) + an int32 (the nanoseconds).
|
|
58
|
+
* The field wrappedInstantNanos must be also present if this field is present.
|
|
59
|
+
* A close equivalent to this, with binary compatible representation, is google.protobuf.Timestamp defined in timestamp.proto.
|
|
60
|
+
*/
|
|
61
|
+
int64 wrappedInstantSeconds = 24;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* This is used if the wrapped value is an enum. The actual type is indicated by oneof typeNameOrId, which
|
|
65
|
+
* is required if this field is present.
|
|
66
|
+
*/
|
|
67
|
+
int32 wrappedEnum = 18;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Stores the message's protobuf encoded bytes when the wrapped value is a message type.
|
|
71
|
+
* This is similar to google.protobuf.Any.value field. The actual type is indicated by oneof typeNameOrId, which
|
|
72
|
+
* is required if this field is present.
|
|
73
|
+
*/
|
|
74
|
+
bytes wrappedMessage = 17;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* A flag that indicates that the contents of the wrapper is empty/null.
|
|
78
|
+
*/
|
|
79
|
+
bool wrappedEmpty = 26;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* The nanoseconds of the Instant. Always present if wrappedInstantSeconds is present.
|
|
84
|
+
* This field is declared outside of scalarOrMessage oneof because it's not legal to have two of the oneof fields
|
|
85
|
+
* present simultaneously in the data stream.
|
|
86
|
+
*/
|
|
87
|
+
optional int32 wrappedInstantNanos = 25;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Stores the fully qualified type name or the optional numeric type id of the payload. This is not used for primitive types
|
|
91
|
+
* (scalars), only for message and enum types.
|
|
92
|
+
*/
|
|
93
|
+
oneof typeNameOrId {
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Stores the fully qualified type name if the wrapped value is a message or an enum type.
|
|
97
|
+
* This is similar to google.protobuf.Any.type_url field.
|
|
98
|
+
*/
|
|
99
|
+
string wrappedTypeName = 16;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* This is used as an alternative to wrappedTypeName if a unique id was assigned to the type with the TypeId
|
|
103
|
+
* annotation. Values in the range 0..65535 are reserved for internal use by Protostream and other projects
|
|
104
|
+
* from the Infinispan organisation.
|
|
105
|
+
*/
|
|
106
|
+
uint32 wrappedTypeId = 19;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Number of repeated elements. Optional; if present it indicates a container (array or Collection). The value must
|
|
111
|
+
* be positive, or 0 if the array/collection is empty. If this is present, then containerTypeNameOrId and
|
|
112
|
+
* containerMessage must also be present.
|
|
113
|
+
*/
|
|
114
|
+
optional uint32 wrappedContainerSize = 27;
|
|
115
|
+
|
|
116
|
+
oneof wrappedContainerTypeNameOrId {
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Stores the fully qualified type name if the container.
|
|
120
|
+
*/
|
|
121
|
+
string wrappedContainerTypeName = 28;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* This is used as an alternative to wrappedContainerTypeName if a unique id was assigned to the type with the
|
|
125
|
+
*/
|
|
126
|
+
uint32 wrappedContainerTypeId = 29;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* The fields of the container itself. Must always be present when wrappedContainerSize is present. If the container
|
|
131
|
+
* type itself does not have any fields then this will be a zero length bytes field.
|
|
132
|
+
*/
|
|
133
|
+
optional bytes wrappedContainerMessage = 30;
|
|
134
|
+
}
|