infinispan 0.9.0 → 0.11.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 (65) hide show
  1. package/.eslintrc +25 -0
  2. package/Jenkinsfile-release +5 -3
  3. package/documentation/asciidoc/stories/assembly_client_usage_examples.adoc +2 -8
  4. package/documentation/asciidoc/stories/{assembly_configuration.adoc → assembly_installation_configuration.adoc} +6 -4
  5. package/documentation/asciidoc/titles/js_client.asciidoc +1 -0
  6. package/documentation/asciidoc/titles/stories.adoc +1 -2
  7. package/documentation/asciidoc/topics/attributes/community-attributes.adoc +2 -1
  8. package/documentation/asciidoc/topics/attributes/downstream-attributes.adoc +0 -2
  9. package/documentation/asciidoc/topics/code_examples/authentication-digest.js +3 -2
  10. package/documentation/asciidoc/topics/code_examples/authentication-external.js +3 -2
  11. package/documentation/asciidoc/topics/code_examples/authentication-oauthbearer.js +3 -2
  12. package/documentation/asciidoc/topics/code_examples/authentication-plain.js +3 -2
  13. package/documentation/asciidoc/topics/code_examples/authentication-scram.js +3 -2
  14. package/documentation/asciidoc/topics/code_examples/await-single-entries.js +1 -1
  15. package/documentation/asciidoc/topics/code_examples/conditional-operations.js +7 -1
  16. package/documentation/asciidoc/topics/code_examples/connection-multiple-servers.js +5 -1
  17. package/documentation/asciidoc/topics/code_examples/data-types.js +2 -2
  18. package/documentation/asciidoc/topics/code_examples/ephemeral-data.js +11 -6
  19. package/documentation/asciidoc/topics/code_examples/hello-world.js +13 -1
  20. package/documentation/asciidoc/topics/code_examples/key-value-converter.js +3 -4
  21. package/documentation/asciidoc/topics/code_examples/multiple-entries.js +13 -2
  22. package/documentation/asciidoc/topics/code_examples/queries.js +92 -0
  23. package/documentation/asciidoc/topics/code_examples/register-event-listener.js +8 -4
  24. package/documentation/asciidoc/topics/code_examples/sample-script-execute.js +6 -1
  25. package/documentation/asciidoc/topics/code_examples/single-entries.js +13 -2
  26. package/documentation/asciidoc/topics/proc_configuring_connections.adoc +8 -9
  27. package/documentation/asciidoc/topics/proc_installing_clients.adoc +23 -5
  28. package/documentation/asciidoc/topics/ref_client_usage.adoc +128 -0
  29. package/lib/codec.js +153 -2
  30. package/lib/infinispan.js +87 -57
  31. package/lib/io.js +14 -8
  32. package/lib/protocols.js +129 -4
  33. package/lib/protostream/message-wrapping.proto +134 -0
  34. package/lib/protostream/query.proto +122 -0
  35. package/lib/sasl/bitops.js +5 -7
  36. package/lib/sasl/factory.js +71 -0
  37. package/lib/utils.js +1 -1
  38. package/memory-profiling/helper.js +9 -0
  39. package/memory-profiling/infinispan_memory_many_get.js +1 -3
  40. package/memory-profiling/infinispan_memory_one_get.js +6 -4
  41. package/package.json +10 -12
  42. package/run-servers.sh +1 -1
  43. package/smoke-tests.sh +1 -0
  44. package/spec/codec_spec.js +7 -7
  45. package/spec/configs/infinispan-clustered.xml +17 -14
  46. package/spec/configs/infinispan-ssl.xml +25 -22
  47. package/spec/configs/infinispan-xsite-EARTH.xml +17 -14
  48. package/spec/configs/infinispan-xsite-MOON.xml +14 -11
  49. package/spec/configs/infinispan.xml +22 -13
  50. package/spec/protostream_spec.js +237 -0
  51. package/spec/utils/testing.js +1 -3
  52. package/types/README.md +91 -0
  53. package/types/index.d.ts +868 -0
  54. package/.jshintrc +0 -14
  55. package/documentation/asciidoc/stories/assembly_getting_started.adoc +0 -11
  56. package/documentation/asciidoc/topics/community-attributes.adoc +0 -10
  57. package/documentation/asciidoc/topics/downstream-attributes.adoc +0 -10
  58. package/documentation/asciidoc/topics/proc_executing_scripts.adoc +0 -16
  59. package/documentation/asciidoc/topics/proc_registering_event_listeners.adoc +0 -31
  60. package/documentation/asciidoc/topics/proc_using_async_await.adoc +0 -23
  61. package/documentation/asciidoc/topics/proc_using_conditional_operations.adoc +0 -7
  62. package/documentation/asciidoc/topics/proc_working_ephemeral_data.adoc +0 -7
  63. package/documentation/asciidoc/topics/proc_working_multiple_entries.adoc +0 -7
  64. package/documentation/asciidoc/topics/proc_working_single_entries_statistics.adoc +0 -7
  65. package/documentation/asciidoc/topics/ref_basic_usage.adoc +0 -8
@@ -0,0 +1,128 @@
1
+ [id='client-usage_{context}']
2
+ = {hr_js} client examples
3
+
4
+ After you install and configure your {hr_js} client, start using it by trying out some basic cache operations before moving on to more complex interactions with {brandname}.
5
+
6
+ == Hello world
7
+
8
+ Create a cache named "myCache" on {brandname} Server then add and retrieve an entry.
9
+
10
+ [source,javascript,options="nowrap",subs=attributes+]
11
+ ----
12
+ include::code_examples/hello-world.js[]
13
+ ----
14
+
15
+ == Working with entries and retrieving cache statistics
16
+
17
+ Add, retrieve, remove single entries and view statistics for the cache.
18
+
19
+ [source,javascript,options="nowrap",subs=attributes+]
20
+ ----
21
+ include::code_examples/single-entries.js[]
22
+ ----
23
+
24
+ == Working with multiple cache entries
25
+
26
+ Create multiple cache entries with simple recursive loops.
27
+
28
+ [source,javascript,options="nowrap",subs=attributes+]
29
+ ----
30
+ include::code_examples/multiple-entries.js[]
31
+ ----
32
+
33
+ == Using Async and Await constructs
34
+
35
+ Node.js provides `async` and `await` constructs that can simplify cache operations.
36
+
37
+ .Single cache entries
38
+ [source,javascript,options="nowrap",subs=attributes+]
39
+ ----
40
+ include::code_examples/await-single-entries.js[]
41
+ ----
42
+
43
+ .Multiple cache entries
44
+ [source,javascript,options="nowrap",subs=attributes+]
45
+ ----
46
+ include::code_examples/await-multiple-entries.js[]
47
+ ----
48
+
49
+ == Running server-side scripts
50
+
51
+ You can add custom scripts to {brandname} Server and then run them from {hr_js} clients.
52
+
53
+ .Sample script
54
+ [source,javascript,options="nowrap",subs=attributes+]
55
+ ----
56
+ include::code_examples/sample-script.js[]
57
+ ----
58
+
59
+ .Script execution
60
+ [source,javascript,options="nowrap",subs=attributes+]
61
+ ----
62
+ include::code_examples/sample-script-execute.js[]
63
+ ----
64
+
65
+ == Registering event listeners
66
+
67
+ Event listeners notify {hr_js} clients when cache updates occur, including when entries are created, modified, removed, or expired.
68
+
69
+ [NOTE]
70
+ ====
71
+ Events for entry creation and modification notify clients about keys and values.
72
+ Events for entry removal and expiration notify clients about keys only.
73
+ ====
74
+
75
+ .Event listener registration
76
+ [source,javascript,options="nowrap",subs=attributes+]
77
+ ----
78
+ include::code_examples/register-event-listener.js[]
79
+ ----
80
+
81
+ You can tune notifications from event listeners to avoid unnecessary roundtrips with the `key-value-with-previous-converter-factory` converter.
82
+ This allows you to, for example, find out values associated with keys within the event instead of retrieving them afterwards.
83
+
84
+ .Remote event converter
85
+ [source,javascript,options="nowrap",subs=attributes+]
86
+ ----
87
+ include::code_examples/key-value-converter.js[]
88
+ ----
89
+
90
+ [TIP]
91
+ ====
92
+ You can add custom converters to {brandname} Server.
93
+ See the link:{doc_home}[{brandname} documentation] for information.
94
+ ====
95
+
96
+ == Using conditional operations
97
+
98
+ The Hot Rod protocol stores metadata about values in {brandname}.
99
+ This metadata provides a deterministic factor that lets you perform cache operations for certain conditions.
100
+ For example, if you want to replace the value of a key if the versions do not match.
101
+
102
+ Use the `getWithMetadata` method to retrieve metadata associated with the value for a key.
103
+
104
+ [source,javascript,options="nowrap",subs=attributes+]
105
+ ----
106
+ include::code_examples/conditional-operations.js[]
107
+ ----
108
+
109
+ == Working with ephemeral data
110
+
111
+ Use the `getWithMetadata` and `size` methods expire cache entries.
112
+
113
+ [source,javascript,options="nowrap",subs=attributes+]
114
+ ----
115
+ include::code_examples/ephemeral-data.js[]
116
+ ----
117
+
118
+ == Working with queries
119
+
120
+ Use the `query` method to perform queries on your caches.
121
+ You must configure {hr_js} client to have `application/x-protostream` data format for values in your caches.
122
+
123
+ [source,javascript,options="nowrap",subs=attributes+]
124
+ ----
125
+ include::code_examples/queries.js[]
126
+ ----
127
+
128
+ See link:{query_docs}[Querying {brandname} caches] for more information.
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));