infinispan 0.8.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/Jenkinsfile-release +1 -1
- package/README.md +31 -907
- package/documentation/asciidoc/stories/assembly_client_usage_examples.adoc +10 -0
- package/documentation/asciidoc/stories/assembly_installation_configuration.adoc +20 -0
- package/documentation/asciidoc/titles/js_client.asciidoc +28 -0
- package/documentation/asciidoc/titles/stories.adoc +5 -0
- package/documentation/asciidoc/topics/attributes/community-attributes.adoc +8 -0
- package/documentation/asciidoc/topics/attributes/downstream-attributes.adoc +2 -0
- package/documentation/asciidoc/topics/code_examples/authentication-digest.js +12 -0
- package/documentation/asciidoc/topics/code_examples/authentication-external.js +15 -0
- package/documentation/asciidoc/topics/code_examples/authentication-oauthbearer.js +10 -0
- package/documentation/asciidoc/topics/code_examples/authentication-plain.js +11 -0
- package/documentation/asciidoc/topics/code_examples/authentication-scram.js +11 -0
- package/documentation/asciidoc/topics/code_examples/await-multiple-entries.js +36 -0
- package/documentation/asciidoc/topics/code_examples/await-single-entries.js +29 -0
- package/documentation/asciidoc/topics/code_examples/conditional-operations.js +57 -0
- package/documentation/asciidoc/topics/code_examples/connection-multiple-servers.js +23 -0
- package/documentation/asciidoc/topics/code_examples/connection-xsite-cluster-switch.js +39 -0
- package/documentation/asciidoc/topics/code_examples/connection-xsite.js +13 -0
- package/documentation/asciidoc/topics/code_examples/data-types.js +30 -0
- package/documentation/asciidoc/topics/code_examples/encryption-crypto-store.js +11 -0
- package/documentation/asciidoc/topics/code_examples/encryption-private-key.js +13 -0
- package/documentation/asciidoc/topics/code_examples/encryption-sni-hostname.js +9 -0
- package/documentation/asciidoc/topics/code_examples/encryption-trust-certs.js +8 -0
- package/documentation/asciidoc/topics/code_examples/ephemeral-data.js +52 -0
- package/documentation/asciidoc/topics/code_examples/hello-world.js +42 -0
- package/documentation/asciidoc/topics/code_examples/key-value-converter.js +67 -0
- package/documentation/asciidoc/topics/code_examples/logging-configuration.js +2 -0
- package/documentation/asciidoc/topics/code_examples/multiple-entries.js +64 -0
- package/documentation/asciidoc/topics/code_examples/register-event-listener.js +64 -0
- package/documentation/asciidoc/topics/code_examples/sample-script-execute.js +33 -0
- package/documentation/asciidoc/topics/code_examples/sample-script.js +3 -0
- package/documentation/asciidoc/topics/code_examples/single-entries.js +49 -0
- package/documentation/asciidoc/topics/config_examples/logging.json +14 -0
- package/documentation/asciidoc/topics/proc_configuring_authentication.adoc +16 -0
- package/documentation/asciidoc/topics/proc_configuring_connections.adoc +25 -0
- package/documentation/asciidoc/topics/proc_configuring_connections_xsite.adoc +18 -0
- package/documentation/asciidoc/topics/proc_configuring_data_formats.adoc +30 -0
- package/documentation/asciidoc/topics/proc_configuring_encryption.adoc +15 -0
- package/documentation/asciidoc/topics/proc_configuring_logging.adoc +28 -0
- package/documentation/asciidoc/topics/proc_installing_clients.adoc +58 -0
- package/documentation/asciidoc/topics/proc_switching_clusters.adoc +17 -0
- package/documentation/asciidoc/topics/ref_authentication_mechanisms.adoc +68 -0
- package/documentation/asciidoc/topics/ref_client_usage.adoc +116 -0
- package/documentation/asciidoc/topics/ref_encryption.adoc +71 -0
- package/lib/codec.js +153 -2
- package/lib/infinispan.js +33 -1
- package/lib/io.js +23 -16
- package/lib/protocols.js +165 -68
- package/lib/protostream/message-wrapping.proto +134 -0
- package/lib/protostream/query.proto +122 -0
- package/lib/sasl/bitops.js +24 -0
- package/lib/sasl/digest.js +188 -0
- package/lib/sasl/external.js +54 -0
- package/lib/sasl/factory.js +71 -0
- package/lib/sasl/oauthbearer.js +63 -0
- package/lib/sasl/plain.js +65 -0
- package/lib/sasl/scram.js +135 -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 -13
- package/run-servers.sh +17 -8
- package/run-testsuite.sh +1 -1
- package/smoke-tests.sh +8 -2
- 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/infinispan_auth_spec.js +16 -37
- package/spec/protostream_spec.js +237 -0
- package/spec/utils/testing.js +1 -3
- package/lib/bitops.js +0 -26
- package/lib/scram.js +0 -116
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Hot Rod JS Client
|
|
2
2
|
|
|
3
3
|
`infinispan` is an asynchronous event-driven Infinispan client for Node.js.
|
|
4
4
|
The results of the asynchronous operations are represented using
|
|
@@ -50,919 +50,37 @@ The client is normally connected to one of the sites, but if its members fail to
|
|
|
50
50
|
* Finally, clients can stop communication with the server(s) using the
|
|
51
51
|
`disconnect` method.
|
|
52
52
|
|
|
53
|
-
#
|
|
53
|
+
# Hot Rod JS client documentation
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
Find installation, configuration, and example usage in the Hot Rod JS Client Guide at [infinispan.org/documentation](https://infinispan.org/documentation/).
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
It can only talk to Infinispan Server 9.4.x or higher versions.
|
|
60
|
-
|
|
61
|
-
By default, Infinispan clients talk Hot Rod protocol version `2.9` which is
|
|
62
|
-
supported starting with Infinispan server 9.4.x.
|
|
63
|
-
*Version '3.0' is not yet supported.*
|
|
64
|
-
|
|
65
|
-
For versions between `8.2.x` and `9.3.x`, use js-client `0.7`.
|
|
66
|
-
|
|
67
|
-
# API docs
|
|
68
|
-
|
|
69
|
-
API documentation for the client can be found
|
|
70
|
-
[here](http://docs.jboss.org/infinispan/hotrod-clients/javascript/1.0/apidocs/module-infinispan.html),
|
|
71
|
-
where you can find detailed information of the APIs exposed.
|
|
72
|
-
|
|
73
|
-
# Usage
|
|
74
|
-
|
|
75
|
-
Before executing these code samples, Infinispan Server must be downloaded
|
|
76
|
-
from [here](http://infinispan.org/download/) and installed locally bearing
|
|
77
|
-
in the support version information provided above. Unless indicated
|
|
78
|
-
otherwise, the code samples below require an Infinispan Server instance
|
|
79
|
-
to be started. The simplest way to do so is to execute the following script:
|
|
80
|
-
|
|
81
|
-
$ [INFINISPAN_SERVER_HOME]/bin/server.sh
|
|
82
|
-
|
|
83
|
-
Please find below samples codes showing how the Infinispan Javascript client
|
|
84
|
-
can be used:
|
|
85
|
-
|
|
86
|
-
## Working with single entries and statistics
|
|
87
|
-
|
|
88
|
-
```Javascript
|
|
89
|
-
var infinispan = require('infinispan');
|
|
90
|
-
|
|
91
|
-
var connected = infinispan.client({port: 11222, host: '127.0.0.1'});
|
|
92
|
-
|
|
93
|
-
connected.then(function (client) {
|
|
94
|
-
|
|
95
|
-
var clientPut = client.put('key', 'value');
|
|
96
|
-
|
|
97
|
-
var clientGet = clientPut.then(
|
|
98
|
-
function() { return client.get('key'); });
|
|
99
|
-
|
|
100
|
-
var showGet = clientGet.then(
|
|
101
|
-
function(value) { console.log('get(key)=' + value); });
|
|
102
|
-
|
|
103
|
-
var clientRemove = showGet.then(
|
|
104
|
-
function() { return client.remove('key'); });
|
|
105
|
-
|
|
106
|
-
var showRemove = clientRemove.then(
|
|
107
|
-
function(success) { console.log('remove(key)=' + success); });
|
|
108
|
-
|
|
109
|
-
var clientStats = showRemove.then(
|
|
110
|
-
function() { return client.stats(); });
|
|
111
|
-
|
|
112
|
-
var showStats = clientStats.then(
|
|
113
|
-
function(stats) {
|
|
114
|
-
console.log('Number of stores: ' + stats.stores);
|
|
115
|
-
console.log('Number of cache hits: ' + stats.hits);
|
|
116
|
-
console.log('All stats: ' + JSON.stringify(stats, null, " "));
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
return showStats.finally(
|
|
120
|
-
function() { return client.disconnect(); });
|
|
121
|
-
|
|
122
|
-
}).catch(function(error) {
|
|
123
|
-
|
|
124
|
-
console.log("Got error: " + error.message);
|
|
125
|
-
|
|
126
|
-
});
|
|
127
|
-
```
|
|
128
|
-
## Authentication
|
|
129
|
-
The client supports PLAIN authentication. Other authentication mechanisms will be supported
|
|
130
|
-
in the next releases.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
```Javascript
|
|
134
|
-
var connected = infinispan.client({port: 11222, host: '127.0.0.1'},
|
|
135
|
-
{
|
|
136
|
-
authentication: {
|
|
137
|
-
enabled: true,
|
|
138
|
-
serverName: 'infinispan',
|
|
139
|
-
saslMechanism: 'PLAIN',
|
|
140
|
-
userName: 'admin',
|
|
141
|
-
password: 'pass'
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
);
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
## Using conditional operations
|
|
148
|
-
|
|
149
|
-
```Javascript
|
|
150
|
-
var infinispan = require('infinispan');
|
|
151
|
-
|
|
152
|
-
var connected = infinispan.client({port: 11222, host: '127.0.0.1'});
|
|
153
|
-
|
|
154
|
-
connected.then(function (client) {
|
|
155
|
-
|
|
156
|
-
var clientPut = client.putIfAbsent('cond', 'v0');
|
|
157
|
-
|
|
158
|
-
var showPut = clientPut.then(
|
|
159
|
-
function(success) { console.log(':putIfAbsent(cond)=' + success); });
|
|
160
|
-
|
|
161
|
-
var clientReplace = showPut.then(
|
|
162
|
-
function() { return client.replace('cond', 'v1'); } );
|
|
163
|
-
|
|
164
|
-
var showReplace = clientReplace.then(
|
|
165
|
-
function(success) { console.log('replace(cond)=' + success); });
|
|
166
|
-
|
|
167
|
-
var clientGetMetaForReplace = showReplace.then(
|
|
168
|
-
function() { return client.getWithMetadata('cond'); });
|
|
169
|
-
|
|
170
|
-
var clientReplaceWithVersion = clientGetMetaForReplace.then(
|
|
171
|
-
function(entry) {
|
|
172
|
-
console.log('getWithMetadata(cond)=' + JSON.stringify(entry));
|
|
173
|
-
return client.replaceWithVersion('cond', 'v2', entry.version);
|
|
174
|
-
}
|
|
175
|
-
);
|
|
176
|
-
|
|
177
|
-
var showReplaceWithVersion = clientReplaceWithVersion.then(
|
|
178
|
-
function(success) { console.log('replaceWithVersion(cond)=' + success); });
|
|
179
|
-
|
|
180
|
-
var clientGetMetaForRemove = showReplaceWithVersion.then(
|
|
181
|
-
function() { return client.getWithMetadata('cond'); });
|
|
182
|
-
|
|
183
|
-
var clientRemoveWithVersion = clientGetMetaForRemove.then(
|
|
184
|
-
function(entry) {
|
|
185
|
-
console.log('getWithMetadata(cond)=' + JSON.stringify(entry));
|
|
186
|
-
return client.removeWithVersion('cond', entry.version);
|
|
187
|
-
}
|
|
188
|
-
);
|
|
189
|
-
|
|
190
|
-
var showRemoveWithVersion = clientRemoveWithVersion.then(
|
|
191
|
-
function(success) { console.log('removeWithVersion(cond)=' + success)});
|
|
192
|
-
|
|
193
|
-
return showRemoveWithVersion.finally(
|
|
194
|
-
function() { return client.disconnect(); });
|
|
195
|
-
|
|
196
|
-
}).catch(function(error) {
|
|
197
|
-
|
|
198
|
-
console.log("Got error: " + error.message);
|
|
199
|
-
|
|
200
|
-
});
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
## Working with multiple entries
|
|
204
|
-
|
|
205
|
-
```Javascript
|
|
206
|
-
var infinispan = require('infinispan');
|
|
207
|
-
|
|
208
|
-
var connected = infinispan.client({port: 11222, host: '127.0.0.1'});
|
|
209
|
-
|
|
210
|
-
connected.then(function (client) {
|
|
211
|
-
var data = [
|
|
212
|
-
{key: 'multi1', value: 'v1'},
|
|
213
|
-
{key: 'multi2', value: 'v2'},
|
|
214
|
-
{key: 'multi3', value: 'v3'}];
|
|
215
|
-
|
|
216
|
-
var clientPutAll = client.putAll(data);
|
|
217
|
-
|
|
218
|
-
var clientGetAll = clientPutAll.then(
|
|
219
|
-
function() { return client.getAll(['multi2', 'multi3']); });
|
|
220
|
-
|
|
221
|
-
var showGetAll = clientGetAll.then(
|
|
222
|
-
function(entries) {
|
|
223
|
-
console.log('getAll(multi2, multi3)=%s', JSON.stringify(entries));
|
|
224
|
-
}
|
|
225
|
-
);
|
|
226
|
-
|
|
227
|
-
var clientIterator = showGetAll.then(
|
|
228
|
-
function() { return client.iterator(1); });
|
|
229
|
-
|
|
230
|
-
var showIterated = clientIterator.then(
|
|
231
|
-
function(it) {
|
|
232
|
-
function loop(promise, fn) {
|
|
233
|
-
// Simple recursive loop over iterator's next() call
|
|
234
|
-
return promise.then(fn).then(function (entry) {
|
|
235
|
-
return entry.done
|
|
236
|
-
? it.close().then(function () { return entry.value; })
|
|
237
|
-
: loop(it.next(), fn);
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
return loop(it.next(), function (entry) {
|
|
242
|
-
console.log('iterator.next()=' + JSON.stringify(entry));
|
|
243
|
-
return entry;
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
);
|
|
247
|
-
|
|
248
|
-
var clientClear = showIterated.then(
|
|
249
|
-
function() { return client.clear(); });
|
|
250
|
-
|
|
251
|
-
return clientClear.finally(
|
|
252
|
-
function() { return client.disconnect(); });
|
|
253
|
-
|
|
254
|
-
}).catch(function(error) {
|
|
255
|
-
|
|
256
|
-
console.log("Got error: " + error.message);
|
|
257
|
-
|
|
258
|
-
});
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
## Working with ephemeral data
|
|
262
|
-
|
|
263
|
-
```Javascript
|
|
264
|
-
var infinispan = require('infinispan');
|
|
265
|
-
|
|
266
|
-
var connected = infinispan.client({port: 11222, host: '127.0.0.1'});
|
|
267
|
-
|
|
268
|
-
connected.then(function (client) {
|
|
269
|
-
|
|
270
|
-
var clientPutExpiry = client.put('expiry', 'value', {lifespan: '1s'});
|
|
271
|
-
|
|
272
|
-
var clientGetMetaAndSize = clientPutExpiry.then(
|
|
273
|
-
function() {
|
|
274
|
-
// Compute getWithMetadata and size in parallel
|
|
275
|
-
return Promise.all([client.getWithMetadata('expiry'), client.size()]);
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
var showGetMetaAndSize = clientGetMetaAndSize.then(
|
|
279
|
-
function(values) {
|
|
280
|
-
console.log('before expiration:');
|
|
281
|
-
console.log('getWithMetadata(expiry)=' + JSON.stringify(values[0]));
|
|
282
|
-
console.log('size=' + values[1]);
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
var clientContainsAndSize = showGetMetaAndSize.then(
|
|
286
|
-
function() {
|
|
287
|
-
sleepFor(1100); // Sleep to force expiration
|
|
288
|
-
return Promise.all([client.containsKey('expiry'), client.size()]);
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
var showContainsAndSize = clientContainsAndSize.then(
|
|
292
|
-
function(values) {
|
|
293
|
-
console.log('after expiration:');
|
|
294
|
-
console.log('containsKey(expiry)=' + values[0]);
|
|
295
|
-
console.log('size=' + values[1]);
|
|
296
|
-
});
|
|
297
|
-
|
|
298
|
-
return showContainsAndSize.finally(
|
|
299
|
-
function() { return client.disconnect(); });
|
|
300
|
-
|
|
301
|
-
}).catch(function(error) {
|
|
302
|
-
|
|
303
|
-
console.log("Got error: " + error.message);
|
|
304
|
-
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
function sleepFor(sleepDuration){
|
|
308
|
-
var now = new Date().getTime();
|
|
309
|
-
while(new Date().getTime() < now + sleepDuration){ /* do nothing */ }
|
|
310
|
-
}
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
## Interact with named caches
|
|
314
|
-
|
|
315
|
-
```Javascript
|
|
316
|
-
var infinispan = require('infinispan');
|
|
317
|
-
|
|
318
|
-
var connected = infinispan.client(
|
|
319
|
-
{port: 11222, host: '127.0.0.1'}, {cacheName: 'namedCache'});
|
|
320
|
-
|
|
321
|
-
connected.then(function (client) {
|
|
322
|
-
|
|
323
|
-
console.log('Connected to `namedCache`');
|
|
324
|
-
|
|
325
|
-
return client.disconnect();
|
|
326
|
-
|
|
327
|
-
}).catch(function(error) {
|
|
328
|
-
|
|
329
|
-
console.log("Got error: " + error.message);
|
|
330
|
-
|
|
331
|
-
});
|
|
332
|
-
```
|
|
333
|
-
|
|
334
|
-
## Connect failover
|
|
335
|
-
|
|
336
|
-
The client can be configured with multiple server addresses and it will loop
|
|
337
|
-
through them until it finds a node to which it can be connected, as shown
|
|
338
|
-
in this example:
|
|
339
|
-
|
|
340
|
-
```Javascript
|
|
341
|
-
var infinispan = require('infinispan');
|
|
342
|
-
|
|
343
|
-
// Accepts multiple addresses and fails over if connection not possible
|
|
344
|
-
var connected = infinispan.client(
|
|
345
|
-
[{port: 99999, host: '127.0.0.1'}, {port: 11222, host: '127.0.0.1'}]);
|
|
346
|
-
|
|
347
|
-
connected.then(function (client) {
|
|
348
|
-
|
|
349
|
-
var members = client.getTopologyInfo().getMembers();
|
|
350
|
-
|
|
351
|
-
console.log('Connected to: ' + JSON.stringify(members));
|
|
352
|
-
|
|
353
|
-
return client.disconnect();
|
|
354
|
-
|
|
355
|
-
}).catch(function(error) {
|
|
356
|
-
|
|
357
|
-
console.log("Got error: " + error.message);
|
|
358
|
-
|
|
359
|
-
});
|
|
360
|
-
```
|
|
361
|
-
|
|
362
|
-
# Supported data types
|
|
363
|
-
|
|
364
|
-
Before version 0.6, Infinispan Javascript client only supported String keys and values.
|
|
365
|
-
Starting at version 0.6, the client also supports native JSON objects as keys and values.
|
|
366
|
-
|
|
367
|
-
**NOTE**: This feature requires Infinispan server 9.4 or higher.
|
|
368
|
-
|
|
369
|
-
The way parameters are treated, whether String or native JSON objects, is defined by client configuration.
|
|
370
|
-
For backwards compatibility reasons, by default keys and values are treated as String values.
|
|
371
|
-
|
|
372
|
-
So, if using native JSON objects, it is necessary to adjust the client configuration:
|
|
373
|
-
|
|
374
|
-
```Javascript
|
|
375
|
-
var infinispan = require('infinispan');
|
|
376
|
-
|
|
377
|
-
var connected = infinispan.client(
|
|
378
|
-
{port: 11222, host: '127.0.0.1'}
|
|
379
|
-
, {
|
|
380
|
-
dataFormat : {
|
|
381
|
-
keyType: 'application/json',
|
|
382
|
-
valueType: 'application/json'
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
);
|
|
386
|
-
|
|
387
|
-
connected.then(function (client) {
|
|
388
|
-
|
|
389
|
-
var clientPut = client.put({k: 'key'}, {v: 'value'});
|
|
390
|
-
|
|
391
|
-
var clientGet = clientPut.then(
|
|
392
|
-
function() { return client.get({k: 'key'}); });
|
|
393
|
-
|
|
394
|
-
var showGet = clientGet.then(
|
|
395
|
-
function(value) { console.log("get({k: 'key'})=" + JSON.stringify(value)); });
|
|
396
|
-
|
|
397
|
-
return showGet.finally(
|
|
398
|
-
function() { return client.disconnect(); });
|
|
399
|
-
|
|
400
|
-
}).catch(function(error) {
|
|
401
|
-
|
|
402
|
-
console.log("Got error: " + error.message);
|
|
403
|
-
|
|
404
|
-
});
|
|
405
|
-
```
|
|
406
|
-
|
|
407
|
-
Key and value data types can be configured independently.
|
|
408
|
-
Hence, it's possible to have String keys and native JSON values or viceversa.
|
|
409
|
-
|
|
410
|
-
Currently all operations support native JSON objects except scripts.
|
|
411
|
-
They still rely on String key/value pairs and String parameters.
|
|
412
|
-
Support for native JSON objects in scripts will come at a later time.
|
|
413
|
-
|
|
414
|
-
## Remote events
|
|
415
|
-
|
|
416
|
-
Clients can register event listeners that get invoked when data changes happen.
|
|
417
|
-
Create, modified, remove and expired events are supported.
|
|
418
|
-
Create and modified events emit key and version of value after event.
|
|
419
|
-
Remove and expired events only emit key information.
|
|
420
|
-
|
|
421
|
-
```Javascript
|
|
422
|
-
var infinispan = require('infinispan');
|
|
423
|
-
|
|
424
|
-
var connected = infinispan.client({port: 11222, host: '127.0.0.1'});
|
|
425
|
-
|
|
426
|
-
connected.then(function (client) {
|
|
427
|
-
|
|
428
|
-
var clientAddListenerCreate = client.addListener('create', onCreate);
|
|
429
|
-
|
|
430
|
-
var clientAddListeners = clientAddListenerCreate.then(
|
|
431
|
-
function(listenerId) {
|
|
432
|
-
// Multiple callbacks can be associated with a single client-side listener.
|
|
433
|
-
// This is achieved by registering listeners with the same listener id
|
|
434
|
-
// as shown in the example below.
|
|
435
|
-
var clientAddListenerModify =
|
|
436
|
-
client.addListener('modify', onModify, {listenerId: listenerId});
|
|
437
|
-
|
|
438
|
-
var clientAddListenerRemove =
|
|
439
|
-
client.addListener('remove', onRemove, {listenerId: listenerId});
|
|
440
|
-
|
|
441
|
-
return Promise.all([clientAddListenerModify, clientAddListenerRemove]);
|
|
442
|
-
});
|
|
443
|
-
|
|
444
|
-
var clientCreate = clientAddListeners.then(
|
|
445
|
-
function() { return client.putIfAbsent('eventful', 'v0'); });
|
|
446
|
-
|
|
447
|
-
var clientModify = clientCreate.then(
|
|
448
|
-
function() { return client.replace('eventful', 'v1'); });
|
|
449
|
-
|
|
450
|
-
var clientRemove = clientModify.then(
|
|
451
|
-
function() { return client.remove('eventful'); });
|
|
452
|
-
|
|
453
|
-
var clientRemoveListener =
|
|
454
|
-
Promise.all([clientAddListenerCreate, clientRemove]).then(
|
|
455
|
-
function(values) {
|
|
456
|
-
var listenerId = values[0];
|
|
457
|
-
return client.removeListener(listenerId);
|
|
458
|
-
});
|
|
459
|
-
|
|
460
|
-
return clientRemoveListener.finally(
|
|
461
|
-
function() { return client.disconnect(); });
|
|
462
|
-
|
|
463
|
-
}).catch(function(error) {
|
|
464
|
-
|
|
465
|
-
console.log("Got error: " + error.message);
|
|
466
|
-
|
|
467
|
-
});
|
|
468
|
-
|
|
469
|
-
function onCreate(key, version) {
|
|
470
|
-
console.log('[Event] Created key: ' + key +
|
|
471
|
-
' with version: ' + JSON.stringify(version));
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
function onModify(key, version) {
|
|
475
|
-
console.log('[Event] Modified key: ' + key +
|
|
476
|
-
', version after update: ' + JSON.stringify(version));
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
function onRemove(key) {
|
|
480
|
-
console.log('[Event] Removed key: ' + key);
|
|
481
|
-
}
|
|
482
|
-
```
|
|
483
|
-
|
|
484
|
-
Starting with client version `0.7` and Infinispan `9.4.x` server,
|
|
485
|
-
it's possible to tailor events to add or remove information from each event.
|
|
486
|
-
|
|
487
|
-
For example, a user might want to find out the value associated with the key after an event.
|
|
488
|
-
If the value was sent back along with the key within the event, unnecessary round trips to fetch the value would be avoided.
|
|
489
|
-
This can be achieved configuring the listener with a remote event converter.
|
|
490
|
-
|
|
491
|
-
Infinispan servers come with a converter called `key-value-with-previous-converter-factory` which can be used for this purpose:
|
|
492
|
-
|
|
493
|
-
```Javascript
|
|
494
|
-
var infinispan = require('infinispan');
|
|
495
|
-
|
|
496
|
-
var connected = infinispan.client(
|
|
497
|
-
{port: 11222, host: '127.0.0.1'}
|
|
498
|
-
, {
|
|
499
|
-
dataFormat : {
|
|
500
|
-
keyType: 'application/json',
|
|
501
|
-
valueType: 'application/json'
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
);
|
|
505
|
-
|
|
506
|
-
connected.then(function (client) {
|
|
507
|
-
|
|
508
|
-
var opts = {
|
|
509
|
-
converterFactory : {
|
|
510
|
-
name: "key-value-with-previous-converter-factory"
|
|
511
|
-
}
|
|
512
|
-
};
|
|
513
|
-
|
|
514
|
-
var clientAddListenerCreate = client.addListener('create', logEvent("Created"), opts);
|
|
515
|
-
|
|
516
|
-
var clientAddListeners = clientAddListenerCreate.then(
|
|
517
|
-
function(listenerId) {
|
|
518
|
-
// Multiple callbacks can be associated with a single client-side listener.
|
|
519
|
-
// This is achieved by registering listeners with the same listener id
|
|
520
|
-
// as shown in the example below.
|
|
521
|
-
var clientAddListenerModify =
|
|
522
|
-
client.addListener('modify', logEvent("Modified"), {opts, listenerId: listenerId});
|
|
523
|
-
|
|
524
|
-
var clientAddListenerRemove =
|
|
525
|
-
client.addListener('remove', logEvent("Removed"), {opts, listenerId: listenerId});
|
|
526
|
-
|
|
527
|
-
return Promise.all([clientAddListenerModify, clientAddListenerRemove]);
|
|
528
|
-
});
|
|
529
|
-
|
|
530
|
-
var clientCreate = clientAddListeners.then(
|
|
531
|
-
function() { return client.putIfAbsent('converted', 'v0'); });
|
|
532
|
-
|
|
533
|
-
var clientModify = clientCreate.then(
|
|
534
|
-
function() { return client.replace('converted', 'v1'); });
|
|
535
|
-
|
|
536
|
-
var clientRemove = clientModify.then(
|
|
537
|
-
function() { return client.remove('converted'); });
|
|
538
|
-
|
|
539
|
-
var clientRemoveListener =
|
|
540
|
-
Promise.all([clientAddListenerCreate, clientRemove]).then(
|
|
541
|
-
function(values) {
|
|
542
|
-
var listenerId = values[0];
|
|
543
|
-
return client.removeListener(listenerId);
|
|
544
|
-
});
|
|
545
|
-
|
|
546
|
-
return clientRemoveListener.finally(
|
|
547
|
-
function() { return client.disconnect(); });
|
|
548
|
-
|
|
549
|
-
}).catch(function(error) {
|
|
550
|
-
|
|
551
|
-
console.log("Got error: " + error.message);
|
|
552
|
-
|
|
553
|
-
});
|
|
554
|
-
|
|
555
|
-
function logEvent(prefix) {
|
|
556
|
-
return function(event) {
|
|
557
|
-
console.log(prefix + " key: " + event.key);
|
|
558
|
-
console.log(prefix + " value: " + event.value);
|
|
559
|
-
console.log(prefix + " previous value: " + event.prev);
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
```
|
|
563
|
-
|
|
564
|
-
You can also create and deploy your own converters into Infinispan server instances.
|
|
565
|
-
See the
|
|
566
|
-
[event filter and conversion](https://infinispan.org/docs/stable/titles/developing/developing.html#event_filtering_and_conversion)
|
|
567
|
-
section in the Developers Guide for more information.
|
|
568
|
-
|
|
569
|
-
Note that you must also configure encoding for cache definitions on Infinispan servers. Configure caches to use a MediaType that matches the data format for keys and values.
|
|
570
|
-
|
|
571
|
-
See the [configuring MediaType](https://infinispan.org/docs/dev/titles/developing/developing.html#encoding_media_type) section in the Developers Guide for more information.
|
|
572
|
-
|
|
573
|
-
## Script Execution
|
|
574
|
-
|
|
575
|
-
The client has the ability to remotely execute scripts on the server.
|
|
576
|
-
To do so, it must first load the script in the server and then invoke it.
|
|
577
|
-
So, given the following script called `sample-script.js`:
|
|
578
|
-
|
|
579
|
-
```Javascript
|
|
580
|
-
// mode=local,language=javascript,parameters=[k, v],datatype='text/plain; charset=utf-8'
|
|
581
|
-
cache.put(k, v);
|
|
582
|
-
cache.get(k);
|
|
583
|
-
```
|
|
584
|
-
|
|
585
|
-
The Infinispan Javascript client could load and execute it using the
|
|
586
|
-
following code:
|
|
587
|
-
|
|
588
|
-
```Javascript
|
|
589
|
-
var infinispan = require('infinispan');
|
|
590
|
-
var readFile = Promise.denodeify(require('fs').readFile);
|
|
591
|
-
|
|
592
|
-
var connected = infinispan.client({port: 11222, host: '127.0.0.1'});
|
|
593
|
-
|
|
594
|
-
connected.then(function (client) {
|
|
595
|
-
|
|
596
|
-
var addScriptFile = readFile('sample-script.js').then(
|
|
597
|
-
function(file) {
|
|
598
|
-
return client.addScript('sample-script', file.toString());
|
|
599
|
-
});
|
|
600
|
-
|
|
601
|
-
var clientExecute = addScriptFile.then(
|
|
602
|
-
function() {
|
|
603
|
-
return client.execute('sample-script', {k: 'exec-key', v: 'exec-value'});
|
|
604
|
-
});
|
|
605
|
-
|
|
606
|
-
var showExecute = clientExecute.then(
|
|
607
|
-
function(ret) { console.log('Script execution returned: ' + ret); });
|
|
608
|
-
|
|
609
|
-
return showExecute.finally(
|
|
610
|
-
function() { return client.disconnect(); });
|
|
611
|
-
|
|
612
|
-
}).catch(function(error) {
|
|
613
|
-
|
|
614
|
-
console.log("Got error: " + error.message);
|
|
615
|
-
|
|
616
|
-
});
|
|
617
|
-
```
|
|
618
|
-
|
|
619
|
-
## Encryption
|
|
620
|
-
|
|
621
|
-
The client supports encryption via SSL/TLS with optional TLS/SNI support ([Server Name Indication](https://en.wikipedia.org/wiki/Server_Name_Indication)).
|
|
622
|
-
To set this up, it is necessary to create a [Java KeyStore (JKS)](https://en.wikipedia.org/wiki/Keystore) using the `keytool` application which is part of the JDK.
|
|
623
|
-
The keystore needs to contains the keys and certificates necessary for the Infinispan Server to authorize connections.
|
|
624
|
-
More information on how to configure the Infinispan Server for encryption, along with TLS/SNI, can be found [here](https://infinispan.org/docs/stable/titles/server/server.html#security).
|
|
625
|
-
|
|
626
|
-
In the most basic set up, the Javascript client can be configured with the location of the trusted certificates so that the client connection is authorized by the server.
|
|
627
|
-
This assumes that the server has been configured with the correct certificates as stated above.
|
|
628
|
-
With that in mind, the client can be configured in the following way:
|
|
629
|
-
|
|
630
|
-
```Javascript
|
|
631
|
-
var connected = infinispan.client({port: 11222, host: '127.0.0.1'},
|
|
632
|
-
{
|
|
633
|
-
ssl: {
|
|
634
|
-
enabled: true,
|
|
635
|
-
trustCerts: ['my-root-ca.crt.pem']
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
);
|
|
639
|
-
```
|
|
640
|
-
|
|
641
|
-
Alternatively, the client can also read trusted certificates from `PKCS#12` or `PFX` format key stores:
|
|
642
|
-
|
|
643
|
-
```Javascript
|
|
644
|
-
var connected = infinispan.client({port: 11222, host: '127.0.0.1'},
|
|
645
|
-
{
|
|
646
|
-
ssl: {
|
|
647
|
-
enabled: true,
|
|
648
|
-
cryptoStore: {
|
|
649
|
-
path: 'my-truststore.p12',
|
|
650
|
-
passphrase: 'secret'
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
);
|
|
655
|
-
```
|
|
656
|
-
|
|
657
|
-
The client can also be configured with encrypted authentication.
|
|
658
|
-
To do that, it's necessary to provide the location of the private key, the passphrase and certificate key of the client:
|
|
659
|
-
|
|
660
|
-
```Javascript
|
|
661
|
-
var connected = infinispan.client({port: 11222, host: '127.0.0.1'},
|
|
662
|
-
{
|
|
663
|
-
{
|
|
664
|
-
enabled: true,
|
|
665
|
-
trustCerts: ['my-root-ca.crt.pem'],
|
|
666
|
-
clientAuth: {
|
|
667
|
-
key: 'privkey.pem',
|
|
668
|
-
passphrase: 'secret',
|
|
669
|
-
cert:ssl 'cert.pem'
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
);
|
|
674
|
-
```
|
|
675
|
-
|
|
676
|
-
Optionally, the client can indicate which hostname it is attempting to connect to at the start of the TLS/SNI handshaking process:
|
|
677
|
-
|
|
678
|
-
```Javascript
|
|
679
|
-
var connected = infinispan.client({port: 11222, host: '127.0.0.1'},
|
|
680
|
-
{
|
|
681
|
-
ssl: {
|
|
682
|
-
enabled: true,
|
|
683
|
-
trustCerts: ['my-root-ca.crt.pem']
|
|
684
|
-
sniHostName: 'example.com'
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
);
|
|
688
|
-
```
|
|
689
|
-
|
|
690
|
-
If no `sniHostName` is provided, the underlying Node.js TLS/SNI implementation sends `localhost` as SNI parameter.
|
|
691
|
-
This is important to note because if the server's default realm does not match `localhost`, you'll encounter errors such as `Hostname/IP doesn't match certificate's altnames`.
|
|
692
|
-
|
|
693
|
-
Another gotcha with the Node.js TLS/SSL implementation is that by default it does not allow self-signed certificates.
|
|
694
|
-
If using self-signed certificates, you'll encounter errors such as `DEPTH_ZERO_SELF_SIGNED_CERT` or `SSL certificate problem: Invalid certificate chain`.
|
|
695
|
-
To avoid problems like this in testing scenarios, one possible solution is to create your own certificate authority, which is used to sign all keys.
|
|
696
|
-
An example on how to do this can be found in the `make-root-ca-and-certificates.sh` script found in the root of this repository.
|
|
697
|
-
This script contains all the commands necessary to create your own CA, sign certificates, create private keys, and even create Java KeyStore files for the server.
|
|
698
|
-
A more detailed example of the contents of this script can be found in [this repository](https://github.com/Daplie/nodejs-self-signed-certificate-example).
|
|
699
|
-
Another possibility is to get certificates from free, open certificate authorities such as [Let's Encrypt](https://letsencrypt.org).
|
|
700
|
-
|
|
701
|
-
## Working with Clusters
|
|
702
|
-
|
|
703
|
-
All previous examples are focused on how the API behaves when working with a
|
|
704
|
-
single Infinispan Server instance. Additionally, multiple Infinispan Servers
|
|
705
|
-
can be clustered in order to provide failover for the data and scale up.
|
|
706
|
-
Working with a Infinispan Server cluster is very similar to working with a
|
|
707
|
-
single instance but there's a few things to bear in mind:
|
|
708
|
-
|
|
709
|
-
* No matter the size of the Infinispan Server cluster, the client only needs
|
|
710
|
-
to know about a server's address in order to get information about the entire
|
|
711
|
-
cluster topology.
|
|
712
|
-
* For distributed caches, key-based operations are routed in the cluster
|
|
713
|
-
using the same consistent hash algorithms used by the server, so that means
|
|
714
|
-
that the client can locate where a particular key resides without the need
|
|
715
|
-
of extra network hops.
|
|
716
|
-
* For distributed caches, multi-key or key-less operations are routed in
|
|
717
|
-
round robin fashion.
|
|
718
|
-
* For replicated/invalidated caches, all operations are routed in round robin
|
|
719
|
-
fashion, regardless of whether they are key-based or multi-key/key-less.
|
|
720
|
-
|
|
721
|
-
The routing and failover is transparent to the user code, so the operations
|
|
722
|
-
executed against in a cluster look exactly the same as in the previous code
|
|
723
|
-
examples.
|
|
724
|
-
|
|
725
|
-
When a connection with a server breaks,
|
|
726
|
-
incomplete operations are retried in other servers in the cluster.
|
|
727
|
-
|
|
728
|
-
If a server that has a client listener registered fails or leaves the cluster,
|
|
729
|
-
the client transparently migrates the listener registration to another node in the cluster.
|
|
730
|
-
By doing so, the client can continue receiving events in the presence of failures or topology changes.
|
|
731
|
-
|
|
732
|
-
You can run a test locally by starting multiple instances of Infinispan
|
|
733
|
-
Server like this:
|
|
734
|
-
|
|
735
|
-
$ ./bin/server.sh -c infinispan.xml --node-name node0 -o 100
|
|
736
|
-
$ ./bin/server.sh -c infinispan.xml --node-name node1 -o 200
|
|
737
|
-
$ ./bin/server.sh -c infinispan.xml --node-name node2 -o 300
|
|
738
|
-
|
|
739
|
-
And then using this code to verify that the topology is the expected one:
|
|
740
|
-
|
|
741
|
-
#### Note for Mac Users:
|
|
742
|
-
You might experience MPING issues running an Infinispan cluster.
|
|
57
|
+
You can also build the Hot Rod JS Client Guide as follows:
|
|
743
58
|
|
|
59
|
+
1. Clone the source repository.
|
|
744
60
|
```bash
|
|
745
|
-
|
|
61
|
+
$ git clone git@github.com:infinispan/js-client.git
|
|
746
62
|
```
|
|
747
63
|
|
|
748
|
-
|
|
749
|
-
|
|
64
|
+
2. Build the HTML from the asciidoc source.
|
|
750
65
|
```bash
|
|
751
|
-
|
|
752
|
-
sudo route add -net 232.0.0.0/5 192.168.1.3
|
|
66
|
+
$ asciidoctor documentation/asciidoc/titles/js_client.asciidoc
|
|
753
67
|
```
|
|
754
68
|
|
|
755
|
-
|
|
756
|
-
var infinispan = require('infinispan');
|
|
757
|
-
|
|
758
|
-
var connected = infinispan.client({port: 11322, host: '127.0.0.1'});
|
|
759
|
-
|
|
760
|
-
connected.then(function (client) {
|
|
761
|
-
|
|
762
|
-
var members = client.getTopologyInfo().getMembers();
|
|
763
|
-
|
|
764
|
-
// Should show all expected cluster members
|
|
765
|
-
console.log('Connected to: ' + JSON.stringify(members));
|
|
766
|
-
|
|
767
|
-
// Add your own operations here...
|
|
768
|
-
|
|
769
|
-
return client.disconnect();
|
|
770
|
-
|
|
771
|
-
}).catch(function(error) {
|
|
69
|
+
3. Open `documentation/asciidoc/titles/js_client.html` in any browser.
|
|
772
70
|
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
});
|
|
776
|
-
```
|
|
777
|
-
|
|
778
|
-
## Working with Sites
|
|
779
|
-
|
|
780
|
-
Multiple Infinispan Server clusters can be deployed in such way that each cluster belongs to a different site.
|
|
781
|
-
Such deployments are done to enable data to be backed up from one cluster to another, potentially in a different geographical location.
|
|
782
|
-
This Javascript client implementation not only can failover between failures in nodes within a cluster, but if the entire cluster fails to respond, it can failover to a different cluster.
|
|
783
|
-
If the failover succeeds, the client will remain connected to the alternative cluster until this becomes unavailable, in which case it’ll try any other clusters defined, and ultimately, it’ll try the original server settings.
|
|
784
|
-
To be able to failover between clusters, first and foremost Infinispan Servers have to be [configured with cross-site replication](https://infinispan.org/docs/stable/titles/xsite/xsite.html).
|
|
785
|
-
Next, the client has to provide alternative `clusters` configuration with at least one host/port pair details for each of the clusters configured.
|
|
786
|
-
For example:
|
|
787
|
-
|
|
788
|
-
```Javascript
|
|
789
|
-
var connected = infinispan.client({port: 11322, host: '127.0.0.1'},
|
|
790
|
-
{
|
|
791
|
-
clusters: [
|
|
792
|
-
{
|
|
793
|
-
name: 'site-a',
|
|
794
|
-
servers: [{port: 1234, host: 'hostA1'}]
|
|
795
|
-
},
|
|
796
|
-
{
|
|
797
|
-
name: 'site-b',
|
|
798
|
-
servers: [{port: 2345, host: 'hostB1'}, {port: 3456, host: 'hostB2'}]
|
|
799
|
-
}
|
|
800
|
-
]
|
|
801
|
-
});
|
|
802
|
-
```
|
|
803
|
-
|
|
804
|
-
### Manual Cluster Switch
|
|
805
|
-
|
|
806
|
-
As well as supporting automatic site cluster failover, Javascript clients can also switch between site clusters manually by calling `switchToCluster(clusterName)` and `switchToDefaultCluster()`.
|
|
807
|
-
Using `switchToCluster(clusterName)``, users can force a client to switch to one of the clusters pre-defined in the client configuration. To switch to the initial servers defined in the client configuration, call `switchToDefaultCluster()`.
|
|
808
|
-
For example:
|
|
809
|
-
|
|
810
|
-
```Javascript
|
|
811
|
-
var connected = infinispan.client({port: 11322, host: '127.0.0.1'},
|
|
812
|
-
{
|
|
813
|
-
clusters: [
|
|
814
|
-
{
|
|
815
|
-
name: 'site-a',
|
|
816
|
-
servers: [{port: 1234, host: 'hostA1'}]
|
|
817
|
-
},
|
|
818
|
-
{
|
|
819
|
-
name: 'site-b',
|
|
820
|
-
servers: [{port: 2345, host: 'hostB1'}, {port: 3456, host: 'hostB2'}]
|
|
821
|
-
}
|
|
822
|
-
]
|
|
823
|
-
});
|
|
824
|
-
|
|
825
|
-
connected.then(function (client) {
|
|
826
|
-
|
|
827
|
-
var switchToB = client.getTopologyInfo().switchToCluster('site-b');
|
|
828
|
-
|
|
829
|
-
switchToB.then(function(switchSucceed) {
|
|
830
|
-
|
|
831
|
-
if (switchSucceed) {
|
|
832
|
-
...
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
...
|
|
836
|
-
|
|
837
|
-
var switchToDefault = client.getTopologyInfo().switchToDefaultCluster();
|
|
838
|
-
|
|
839
|
-
switchToDefault.then(function(switchSucceed) {
|
|
840
|
-
|
|
841
|
-
if (switchSucceed) {
|
|
842
|
-
...
|
|
843
|
-
}
|
|
844
|
-
|
|
845
|
-
})
|
|
846
|
-
|
|
847
|
-
})
|
|
848
|
-
|
|
849
|
-
});
|
|
850
|
-
```
|
|
851
|
-
|
|
852
|
-
# Logging
|
|
853
|
-
|
|
854
|
-
The client uses [`log4js`](https://www.npmjs.com/package/log4js) for logging.
|
|
855
|
-
To configure it, simply create a JSON file with the desired configuration.
|
|
856
|
-
Here is an example configuration that is used when running the client's testsuite:
|
|
857
|
-
|
|
858
|
-
```json
|
|
859
|
-
{
|
|
860
|
-
"appenders": {
|
|
861
|
-
"test": {
|
|
862
|
-
"type": "fileSync",
|
|
863
|
-
"filename": "tmp-tests.log"
|
|
864
|
-
}
|
|
865
|
-
},
|
|
866
|
-
"categories": {
|
|
867
|
-
"default": {
|
|
868
|
-
"appenders": ["test"],
|
|
869
|
-
"level": "trace"
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
}
|
|
873
|
-
```
|
|
874
|
-
|
|
875
|
-
You can find more examples [here](https://github.com/log4js-node/log4js-node/tree/master/examples).
|
|
876
|
-
|
|
877
|
-
Once you have the file, simply invoke `log4js` to use that file and then construct the client as usual, e.g.
|
|
878
|
-
|
|
879
|
-
```js
|
|
880
|
-
var log4js = require('log4js');
|
|
881
|
-
log4js.configure('path/to/my-log4js.json');
|
|
882
|
-
|
|
883
|
-
```
|
|
884
|
-
|
|
885
|
-
# Async / Await
|
|
886
|
-
|
|
887
|
-
Examples above can be greatly simplified taking advantage of `async` / `await` constructs,
|
|
888
|
-
which are available in Node.js since version `7.10.0`.
|
|
889
|
-
|
|
890
|
-
This section shows how some of the examples above can be written using `async` / `await`:
|
|
891
|
-
|
|
892
|
-
## Working with single entries and statistics
|
|
893
|
-
|
|
894
|
-
```Javascript
|
|
895
|
-
const infinispan = require("infinispan");
|
|
896
|
-
|
|
897
|
-
const log4js = require('log4js');
|
|
898
|
-
log4js.configure('example-log4js.json');
|
|
899
|
-
|
|
900
|
-
async function test() {
|
|
901
|
-
await new Promise((resolve, reject) => setTimeout(() => resolve(), 1000));
|
|
902
|
-
console.log('Hello, World!');
|
|
903
|
-
|
|
904
|
-
let client = await infinispan.client({port: 11222, host: '127.0.0.1'});
|
|
905
|
-
console.log(`Connected to Infinispan dashboard data`);
|
|
906
|
-
|
|
907
|
-
await client.put('key', 'value');
|
|
908
|
-
|
|
909
|
-
let value = await client.get('key');
|
|
910
|
-
console.log('get(key)=' + value);
|
|
911
|
-
|
|
912
|
-
let success = await client.remove('key');
|
|
913
|
-
console.log('remove(key)=' + success);
|
|
71
|
+
# API docs
|
|
914
72
|
|
|
915
|
-
|
|
916
|
-
console.log('Number of stores: ' + stats.stores);
|
|
917
|
-
console.log('Number of cache hits: ' + stats.hits);
|
|
918
|
-
console.log('All stats: ' + JSON.stringify(stats, null, " "));
|
|
73
|
+
Review [Hot Rod JS client API documentation](http://docs.jboss.org/infinispan/hotrod-clients/javascript/1.0/apidocs/module-infinispan.html).
|
|
919
74
|
|
|
920
|
-
|
|
921
|
-
}
|
|
75
|
+
You can also build API docs from the source repository as follows:
|
|
922
76
|
|
|
923
|
-
|
|
77
|
+
1. Generate JSDoc formatted API docs.
|
|
78
|
+
```bash
|
|
79
|
+
$ npm install jsdoc
|
|
80
|
+
$ ./node_modules/.bin/jsdoc lib/*.js
|
|
924
81
|
```
|
|
925
82
|
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
```Javascript
|
|
929
|
-
const infinispan = require("infinispan");
|
|
930
|
-
|
|
931
|
-
const log4js = require('log4js');
|
|
932
|
-
log4js.configure('example-log4js.json');
|
|
933
|
-
|
|
934
|
-
async function test() {
|
|
935
|
-
let client = await infinispan.client({port: 11222, host: '127.0.0.1'});
|
|
936
|
-
console.log(`Connected to Infinispan dashboard data`);
|
|
937
|
-
|
|
938
|
-
let data = [
|
|
939
|
-
{key: 'multi1', value: 'v1'},
|
|
940
|
-
{key: 'multi2', value: 'v2'},
|
|
941
|
-
{key: 'multi3', value: 'v3'}];
|
|
942
|
-
|
|
943
|
-
await client.putAll(data);
|
|
944
|
-
|
|
945
|
-
let entries = await client.getAll(['multi2', 'multi3']);
|
|
946
|
-
console.log('getAll(multi2, multi3)=%s', JSON.stringify(entries));
|
|
947
|
-
|
|
948
|
-
let iterator = await client.iterator(1);
|
|
949
|
-
|
|
950
|
-
let entry = {done: true};
|
|
951
|
-
|
|
952
|
-
do {
|
|
953
|
-
entry = await iterator.next();
|
|
954
|
-
console.log('iterator.next()=' + JSON.stringify(entry));
|
|
955
|
-
} while (!entry.done);
|
|
956
|
-
|
|
957
|
-
await iterator.close();
|
|
958
|
-
|
|
959
|
-
await client.clear();
|
|
960
|
-
|
|
961
|
-
await client.disconnect();
|
|
962
|
-
}
|
|
963
|
-
|
|
964
|
-
test();
|
|
965
|
-
```
|
|
83
|
+
2. Open `open out/index.html` in any browser.
|
|
966
84
|
|
|
967
85
|
# Testing
|
|
968
86
|
|
|
@@ -1013,6 +131,20 @@ Both testsuite and smoke tests can be run with older protocol versions, e.g.
|
|
|
1013
131
|
$ protocol=2.5 ./smoke-tests.sh
|
|
1014
132
|
```
|
|
1015
133
|
|
|
134
|
+
## Note for Mac Users:
|
|
135
|
+
You might experience MPING issues running an Infinispan cluster.
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
13:37:15,561 ERROR (jgroups-5,server-two) [org.jgroups.protocols.MPING]
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
If you run into the errors above, add the following to the routes of your host
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
sudo route add -net 224.0.0.0/5 127.0.0.1
|
|
145
|
+
sudo route add -net 232.0.0.0/5 192.168.1.3
|
|
146
|
+
```
|
|
147
|
+
|
|
1016
148
|
# Manual stress tests
|
|
1017
149
|
|
|
1018
150
|
The testsuite now contains manual stress tests that take several minutes to run.
|
|
@@ -1063,14 +195,6 @@ On top of that, you can find information on which tests are always running as op
|
|
|
1063
195
|
| ssl spec | local | `11232` (A), `12242` (A), `12252` (A) |
|
|
1064
196
|
| xsite spec | earth, moon | `11522` (earth, M), `11532` (moon, M) |
|
|
1065
197
|
|
|
1066
|
-
# Generating API documentation
|
|
1067
|
-
|
|
1068
|
-
The client contains JSDoc formatted API docs which can be generated via:
|
|
1069
|
-
|
|
1070
|
-
npm install jsdoc
|
|
1071
|
-
./node_modules/.bin/jsdoc lib/*.js
|
|
1072
|
-
open out/index.html
|
|
1073
|
-
|
|
1074
198
|
# Reporting an issue
|
|
1075
199
|
|
|
1076
200
|
This project does not use Github issues.
|