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.
Files changed (58) hide show
  1. package/documentation/asciidoc/stories/assembly_client_usage_examples.adoc +2 -8
  2. package/documentation/asciidoc/stories/{assembly_configuration.adoc → assembly_installation_configuration.adoc} +6 -4
  3. package/documentation/asciidoc/titles/js_client.asciidoc +1 -0
  4. package/documentation/asciidoc/titles/stories.adoc +1 -2
  5. package/documentation/asciidoc/topics/attributes/community-attributes.adoc +1 -1
  6. package/documentation/asciidoc/topics/attributes/downstream-attributes.adoc +0 -2
  7. package/documentation/asciidoc/topics/code_examples/authentication-digest.js +3 -2
  8. package/documentation/asciidoc/topics/code_examples/authentication-external.js +3 -2
  9. package/documentation/asciidoc/topics/code_examples/authentication-oauthbearer.js +3 -2
  10. package/documentation/asciidoc/topics/code_examples/authentication-plain.js +3 -2
  11. package/documentation/asciidoc/topics/code_examples/authentication-scram.js +3 -2
  12. package/documentation/asciidoc/topics/code_examples/await-single-entries.js +1 -1
  13. package/documentation/asciidoc/topics/code_examples/conditional-operations.js +7 -1
  14. package/documentation/asciidoc/topics/code_examples/connection-multiple-servers.js +5 -1
  15. package/documentation/asciidoc/topics/code_examples/data-types.js +2 -2
  16. package/documentation/asciidoc/topics/code_examples/ephemeral-data.js +11 -6
  17. package/documentation/asciidoc/topics/code_examples/hello-world.js +13 -1
  18. package/documentation/asciidoc/topics/code_examples/key-value-converter.js +3 -4
  19. package/documentation/asciidoc/topics/code_examples/multiple-entries.js +13 -2
  20. package/documentation/asciidoc/topics/code_examples/register-event-listener.js +8 -4
  21. package/documentation/asciidoc/topics/code_examples/sample-script-execute.js +6 -1
  22. package/documentation/asciidoc/topics/code_examples/single-entries.js +13 -2
  23. package/documentation/asciidoc/topics/proc_configuring_connections.adoc +8 -9
  24. package/documentation/asciidoc/topics/proc_installing_clients.adoc +23 -5
  25. package/documentation/asciidoc/topics/ref_client_usage.adoc +116 -0
  26. package/lib/codec.js +153 -2
  27. package/lib/infinispan.js +27 -1
  28. package/lib/io.js +14 -8
  29. package/lib/protocols.js +129 -4
  30. package/lib/protostream/message-wrapping.proto +134 -0
  31. package/lib/protostream/query.proto +122 -0
  32. package/lib/sasl/bitops.js +5 -7
  33. package/lib/sasl/factory.js +71 -0
  34. package/lib/utils.js +1 -1
  35. package/memory-profiling/helper.js +9 -0
  36. package/memory-profiling/infinispan_memory_many_get.js +1 -3
  37. package/memory-profiling/infinispan_memory_one_get.js +6 -4
  38. package/package.json +7 -12
  39. package/run-servers.sh +1 -1
  40. package/spec/codec_spec.js +7 -7
  41. package/spec/configs/infinispan-clustered.xml +17 -14
  42. package/spec/configs/infinispan-ssl.xml +25 -22
  43. package/spec/configs/infinispan-xsite-EARTH.xml +17 -14
  44. package/spec/configs/infinispan-xsite-MOON.xml +14 -11
  45. package/spec/configs/infinispan.xml +22 -13
  46. package/spec/protostream_spec.js +237 -0
  47. package/spec/utils/testing.js +1 -3
  48. package/documentation/asciidoc/stories/assembly_getting_started.adoc +0 -11
  49. package/documentation/asciidoc/topics/community-attributes.adoc +0 -10
  50. package/documentation/asciidoc/topics/downstream-attributes.adoc +0 -10
  51. package/documentation/asciidoc/topics/proc_executing_scripts.adoc +0 -16
  52. package/documentation/asciidoc/topics/proc_registering_event_listeners.adoc +0 -31
  53. package/documentation/asciidoc/topics/proc_using_async_await.adoc +0 -23
  54. package/documentation/asciidoc/topics/proc_using_conditional_operations.adoc +0 -7
  55. package/documentation/asciidoc/topics/proc_working_ephemeral_data.adoc +0 -7
  56. package/documentation/asciidoc/topics/proc_working_multiple_entries.adoc +0 -7
  57. package/documentation/asciidoc/topics/proc_working_single_entries_statistics.adoc +0 -7
  58. 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^31', f.lessThan(Math.pow(2, 31)));
94
- var shortTooBig = f.validator('must be less than 2^15', f.lessThan(Math.pow(2, 15)));
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.decodeServerMediaTypes);
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
- var flushed = sock.write(buffer);
263
- if (!flushed)
264
- logger.debugf('Buffer write not fully flushed, part of of data queued for: %s',
265
- buffer.toString('hex').toUpperCase());
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.decodeServerMediaTypes, conn);
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 s = require('saslmechanisms');
13
- var factory = new s.Factory();
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
+ }