infinispan 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.githooks/commit-msg +9 -0
- package/.githooks/configure-hooks +7 -0
- package/.githooks/configure-hooks.bat +15 -0
- package/.gitmessage +7 -0
- package/AI-CODE.md +86 -0
- package/README.md +53 -75
- package/lib/codec.js +38 -1
- package/lib/functional.js +25 -0
- package/lib/infinispan.js +89 -18
- package/lib/io.js +3 -1
- package/lib/listeners.js +116 -2
- package/lib/protocols.js +20 -7
- package/lib/uri.js +206 -0
- package/package.json +9 -3
- package/server/.keep +0 -0
- package/types/index.d.ts +44 -0
- package/Dockerfile.server +0 -8
- package/docker-compose.yml +0 -272
- package/gen-asciidoc.sh +0 -46
- package/run-docker-testsuite.sh +0 -72
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
REGEX='^\[#[0-9]+\]\s[A-Z].*\n?(\n(\*\s.*\n)+)?$'
|
|
4
|
+
if ! grep -qE "$REGEX" "$1"; then
|
|
5
|
+
echo "Commit message format is incorrect. Run the following command:" >&2
|
|
6
|
+
echo " git config commit.template .gitmessage" >&2
|
|
7
|
+
echo "and retry" >&2
|
|
8
|
+
exit 1
|
|
9
|
+
fi
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
BASEDIR=$(dirname "$0")/..
|
|
4
|
+
BASEDIR_RESOLVED=$(realpath "$BASEDIR")
|
|
5
|
+
|
|
6
|
+
git config get --local core.hooksPath || git config set --local core.hooksPath "$BASEDIR_RESOLVED"/.githooks
|
|
7
|
+
git config get --local commit.template || git config set --local commit.template "$BASEDIR_RESOLVED"/.gitmessage
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
@echo off
|
|
2
|
+
|
|
3
|
+
set "DIRNAME=%~dp0%"
|
|
4
|
+
pushd "%DIRNAME%.."
|
|
5
|
+
set "BASEDIR_RESOLVED=%CD%"
|
|
6
|
+
popd
|
|
7
|
+
|
|
8
|
+
git config get --local core.hooksPath
|
|
9
|
+
if ERRORLEVEL 1 (
|
|
10
|
+
git config set --local core.hooksPath "%BASEDIR_RESOLVED%/.githooks
|
|
11
|
+
)
|
|
12
|
+
git config get --local commit.template
|
|
13
|
+
if ERRORLEVEL 1 (
|
|
14
|
+
git config set --local commit.template "%BASEDIR_RESOLVED%/.gitmessage
|
|
15
|
+
)
|
package/.gitmessage
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# [#nnnnn] Title, summary, imperative, start upper case, don't end with a period
|
|
2
|
+
# No more than 50 chars. #### 50 chars is here: #
|
|
3
|
+
# Remember blank line between title and body.
|
|
4
|
+
|
|
5
|
+
# Body: Explain *what* and *why* (not *how*)
|
|
6
|
+
# Wrap at 72 chars. ################################## which is here: #
|
|
7
|
+
|
package/AI-CODE.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# JS Client Code Instructions
|
|
2
|
+
|
|
3
|
+
## Tech Stack
|
|
4
|
+
* **Runtime:** Node.js 24 LTS
|
|
5
|
+
* **Language:** JavaScript (ES6+) with TypeScript definition files (`types/index.d.ts`)
|
|
6
|
+
* **Protocol:** Hot Rod binary protocol — versions 2.2, 2.5, 2.9, 3.0, 4.0, 4.1
|
|
7
|
+
* **Test framework:** Jasmine 6
|
|
8
|
+
* **Linting:** ESLint (ES2022, single quotes, semicolons required, JSDoc required)
|
|
9
|
+
* **Docs:** JSDoc for API docs, AsciiDoc for user documentation
|
|
10
|
+
|
|
11
|
+
## Project Structure
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
index.js # Entry point — re-exports lib/infinispan.js
|
|
15
|
+
lib/
|
|
16
|
+
infinispan.js # Main client API (connect, CRUD, listeners, queries, scripts)
|
|
17
|
+
io.js # Transport layer (TCP sockets, topology, failover, consistent hashing)
|
|
18
|
+
protocols.js # Hot Rod protocol encode/decode for all supported versions
|
|
19
|
+
codec.js # Binary codec (VInt, VLong, strings, Protobuf, JSON)
|
|
20
|
+
listeners.js # Remote/local event listener management
|
|
21
|
+
functional.js # Functional combinators (lift, actions, pipeline, partial application)
|
|
22
|
+
utils.js # Logging, MurmurHash3, ReplayableBuffer, address normalization
|
|
23
|
+
uri.js # Hot Rod URI parsing (hotrod:// and hotrods:// schemes)
|
|
24
|
+
sasl/ # SASL authentication mechanisms
|
|
25
|
+
factory.js # Mechanism registry and negotiation
|
|
26
|
+
plain.js # PLAIN
|
|
27
|
+
digest.js # DIGEST-MD5
|
|
28
|
+
scram.js # SCRAM-SHA-1/256/384/512
|
|
29
|
+
external.js # EXTERNAL (TLS cert)
|
|
30
|
+
oauthbearer.js # OAUTHBEARER
|
|
31
|
+
spec/ # Tests
|
|
32
|
+
*_spec.js # Test suites
|
|
33
|
+
utils/testing.js # Shared test utilities and assertion helpers
|
|
34
|
+
configs/ # Infinispan server XML configurations for test scenarios
|
|
35
|
+
types/ # TypeScript type definitions
|
|
36
|
+
documentation/ # AsciiDoc user documentation
|
|
37
|
+
scripts/ # Build and test tooling
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Build and Test Commands
|
|
41
|
+
* **Install dependencies:** `npm install`
|
|
42
|
+
* **Lint:** `npm run lint`
|
|
43
|
+
* **Run tests (with containers):** `npm run test:docker`
|
|
44
|
+
* **Run tests (containers already running):** `npm test`
|
|
45
|
+
* **Start test containers:** `npm run docker:up`
|
|
46
|
+
* **Stop test containers:** `npm run docker:down`
|
|
47
|
+
* **Run a single spec:** `npx jasmine spec/infinispan_local_spec.js`
|
|
48
|
+
* **Generate SSL certificates:** `npm run ssl:generate`
|
|
49
|
+
* **Generate API docs:** `npm run docs:api`
|
|
50
|
+
* **Override server version:** `INFINISPAN_VERSION=16.1.3 npm run test:docker`
|
|
51
|
+
|
|
52
|
+
## Architecture Notes
|
|
53
|
+
|
|
54
|
+
* **Consistent hashing:** Keys are routed to owning servers using MurmurHash3. Topology updates from the server adjust the hash ring automatically.
|
|
55
|
+
* **Multiplexing:** Multiple in-flight requests share a single TCP connection per server, routed by message ID.
|
|
56
|
+
* **State threading in codec:** The codec layer uses a functional "lift" pattern where encode/decode functions return `{answer, state}` tuples for immutable state management through the pipeline.
|
|
57
|
+
* **Failover:** Automatic retry with round-robin fallback to other cluster members. Cross-site failover supported via `clusters` option and `switchToCluster()`.
|
|
58
|
+
|
|
59
|
+
## Development Standards
|
|
60
|
+
* **Style:** Use `var` for variable declarations (not `const`/`let`) to match existing codebase.
|
|
61
|
+
* **Module pattern:** All modules wrap code in an IIFE: `(function() { ... }.call(this));`
|
|
62
|
+
* **JSDoc:** Required for all public functions. Use `@param`, `@returns`, `@since` tags.
|
|
63
|
+
* **Testing:** Tests use Promise chains with `spec/utils/testing.js` helpers. Follow the pattern:
|
|
64
|
+
```javascript
|
|
65
|
+
var t = require('./utils/testing');
|
|
66
|
+
it('should do something', function(done) {
|
|
67
|
+
t.client(t.local, t.authOpts)
|
|
68
|
+
.then(t.assert(t.put('key', 'value')))
|
|
69
|
+
.then(t.assert(t.get('key'), t.toBe('value')))
|
|
70
|
+
.then(t.assert(t.disconnect()))
|
|
71
|
+
.then(function() { done(); }, t.failed(done));
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
* **Commit logs:** Commit logs must always start with `[#nnnnn] Summary`.
|
|
75
|
+
* **Git branches:** Branches should be named `issueid/issue_summary` and use `origin/main` as the upstream.
|
|
76
|
+
|
|
77
|
+
## Development Platform
|
|
78
|
+
* **Repository:** https://github.com/infinispan/js-client
|
|
79
|
+
* **Issues:** Use GitHub Issues with appropriate labels.
|
|
80
|
+
* **License:** Apache-2.0
|
|
81
|
+
|
|
82
|
+
## Related Projects
|
|
83
|
+
|
|
84
|
+
* **Infinispan server:** The Infinispan server source code is in ../infinispan
|
|
85
|
+
* **Operator:** The Infinispan Operator source code is in ../infinispan-operator
|
|
86
|
+
* **Console:** The Infinispan Console source code is in ../infinispan-console
|
package/README.md
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
# Hot Rod JS Client
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/infinispan)
|
|
4
|
+
[](https://github.com/infinispan/js-client/blob/main/LICENSE)
|
|
5
|
+
[](https://github.com/infinispan/js-client/actions/workflows/ci.yml)
|
|
6
|
+
[](https://www.npmjs.com/package/infinispan)
|
|
7
|
+
[](https://www.npmjs.com/package/infinispan)
|
|
8
|
+
|
|
3
9
|
`infinispan` is an asynchronous event-driven Infinispan client for Node.js.
|
|
4
10
|
The results of the asynchronous operations are represented using
|
|
5
11
|
[Promise](https://www.promisejs.org) instances. Amongst many advantages,
|
|
6
12
|
promises make it easy to transform/chain multiple asynchronous invocations
|
|
7
13
|
and they improve error handling by making it easy to centralise it.
|
|
8
14
|
|
|
9
|
-
|
|
10
|
-
current capabilities:
|
|
15
|
+
Here's a summary of its current capabilities:
|
|
11
16
|
|
|
12
17
|
* `infinispan` client can be constructed with a single server address or
|
|
13
18
|
multiple servers addresses. When passing multiple addresses, it will iterate
|
|
@@ -54,100 +59,91 @@ The client is normally connected to one of the sites, but if its members fail to
|
|
|
54
59
|
|
|
55
60
|
Find installation, configuration, and example usage in the Hot Rod JS Client Guide at [infinispan.org/documentation](https://infinispan.org/documentation/).
|
|
56
61
|
|
|
57
|
-
You can also build the Hot Rod JS Client Guide
|
|
58
|
-
|
|
59
|
-
1. Clone the source repository.
|
|
60
|
-
```bash
|
|
61
|
-
$ git clone git@github.com:infinispan/js-client.git
|
|
62
|
-
```
|
|
62
|
+
You can also build the Hot Rod JS Client Guide locally:
|
|
63
63
|
|
|
64
|
-
2. Build the HTML from the asciidoc source.
|
|
65
64
|
```bash
|
|
66
|
-
|
|
65
|
+
npm run docs:user
|
|
67
66
|
```
|
|
68
67
|
|
|
69
|
-
|
|
68
|
+
Open `out/docs/index.html` in any browser.
|
|
70
69
|
|
|
71
70
|
# API docs
|
|
72
71
|
|
|
73
72
|
Review [Hot Rod JS client API documentation](http://docs.jboss.org/infinispan/hotrod-clients/javascript/1.0/apidocs/module-infinispan.html).
|
|
74
73
|
|
|
75
|
-
|
|
74
|
+
To generate API docs locally:
|
|
76
75
|
|
|
77
|
-
1. Generate JSDoc formatted API docs.
|
|
78
76
|
```bash
|
|
79
|
-
|
|
80
|
-
$ ./node_modules/.bin/jsdoc lib/*.js
|
|
77
|
+
npm run docs:api
|
|
81
78
|
```
|
|
82
79
|
|
|
83
|
-
|
|
80
|
+
Open `out/index.html` in any browser.
|
|
84
81
|
|
|
85
82
|
# Testing
|
|
86
83
|
|
|
87
|
-
|
|
88
|
-
up so that testsuite can run against those. To ease this process, a script
|
|
89
|
-
has been created in the root directory to start all the expected server
|
|
90
|
-
instances.
|
|
84
|
+
Tests run against Infinispan Server instances in Docker containers.
|
|
91
85
|
|
|
92
|
-
|
|
86
|
+
## Prerequisites
|
|
93
87
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
88
|
+
- Docker and Docker Compose
|
|
89
|
+
- Java (for SSL certificate generation via `keytool`)
|
|
90
|
+
- Node.js 24+
|
|
97
91
|
|
|
98
|
-
|
|
92
|
+
## Running tests
|
|
99
93
|
|
|
100
94
|
```bash
|
|
101
|
-
|
|
95
|
+
npm install
|
|
96
|
+
npm run test:docker
|
|
102
97
|
```
|
|
103
98
|
|
|
104
|
-
|
|
99
|
+
This starts all required containers, generates SSL certificates if needed,
|
|
100
|
+
waits for the cluster to form, runs the full test suite, and tears down
|
|
101
|
+
the containers on exit.
|
|
105
102
|
|
|
106
|
-
|
|
107
|
-
$ ./run-testsuite.sh
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
To run individual tests execute:
|
|
103
|
+
To test against a specific Infinispan version:
|
|
111
104
|
|
|
112
105
|
```bash
|
|
113
|
-
|
|
106
|
+
INFINISPAN_VERSION=16.1.3 npm run test:docker
|
|
114
107
|
```
|
|
115
108
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
```bash
|
|
119
|
-
$ ./smoke-tests.sh
|
|
120
|
-
```
|
|
109
|
+
### Manual container lifecycle
|
|
121
110
|
|
|
122
|
-
|
|
111
|
+
For iterative development, start containers once and run tests repeatedly:
|
|
123
112
|
|
|
124
113
|
```bash
|
|
125
|
-
|
|
114
|
+
npm run docker:up
|
|
115
|
+
npm test
|
|
116
|
+
# ... make changes ...
|
|
117
|
+
npm test
|
|
118
|
+
npm run docker:down
|
|
126
119
|
```
|
|
127
120
|
|
|
128
|
-
|
|
129
|
-
|
|
121
|
+
### Individual tests
|
|
122
|
+
|
|
123
|
+
With containers running:
|
|
130
124
|
|
|
131
125
|
```bash
|
|
132
|
-
|
|
126
|
+
npx jasmine spec/infinispan_local_spec.js
|
|
133
127
|
```
|
|
134
128
|
|
|
135
|
-
|
|
129
|
+
### SSL certificates
|
|
130
|
+
|
|
131
|
+
Certificates are generated automatically on first test run. To regenerate:
|
|
136
132
|
|
|
137
133
|
```bash
|
|
138
|
-
|
|
139
|
-
sudo route add -net 232.0.0.0/5 192.168.1.3
|
|
134
|
+
npm run ssl:generate
|
|
140
135
|
```
|
|
141
136
|
|
|
142
|
-
|
|
137
|
+
## Manual stress tests
|
|
143
138
|
|
|
144
|
-
The testsuite
|
|
139
|
+
The testsuite contains manual stress tests that take several minutes to run.
|
|
145
140
|
To run these tests, execute:
|
|
146
141
|
|
|
147
|
-
|
|
148
|
-
|
|
142
|
+
```bash
|
|
143
|
+
npx jasmine spec-manual/*_spec.js
|
|
144
|
+
```
|
|
149
145
|
|
|
150
|
-
|
|
146
|
+
## Memory profiling
|
|
151
147
|
|
|
152
148
|
The source code comes with some programs that allow the client's memory consumption to be profiled.
|
|
153
149
|
Those programs rely on having access to the global garbage collector.
|
|
@@ -158,38 +154,20 @@ Example:
|
|
|
158
154
|
node --expose-gc memory-profiling/infinispan_memory_many_get.js
|
|
159
155
|
```
|
|
160
156
|
|
|
161
|
-
|
|
157
|
+
Some programs might only report the memory usage before/after.
|
|
162
158
|
Others might generate heap dumps which can be visualized using Google Chrome.
|
|
163
159
|
Within Chrome, the Developer Tools UI contains a `Memory` tab where heap dumps can be loaded.
|
|
164
160
|
|
|
165
|
-
|
|
166
|
-
# Debugging
|
|
161
|
+
## Debugging
|
|
167
162
|
|
|
168
163
|
To debug tests with IDE:
|
|
169
164
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
node --inspect-brk node_modules/.bin/jasmine spec/infinispan_local_spec.js
|
|
165
|
+
```bash
|
|
166
|
+
node --inspect-brk node_modules/.bin/jasmine spec/codec_spec.js
|
|
167
|
+
```
|
|
175
168
|
|
|
176
169
|
And then start a remote Node.js debugger from IDE on port 9229.
|
|
177
170
|
|
|
178
|
-
# Tests, servers and ports
|
|
179
|
-
|
|
180
|
-
Here's some more detailed information on which tests interact with which servers and on which ports.
|
|
181
|
-
On top of that, you can find information on which tests are always running as opposed to those that are started (and stopped) by the tests themselves.
|
|
182
|
-
|
|
183
|
-
| Test | Server Profile | Ports (Auto/Manual) |
|
|
184
|
-
| :------------ | :-------------: | :-------------------------------------- |
|
|
185
|
-
| local spec | local | `11222` (A) |
|
|
186
|
-
| expiry spec | local | `11222` (A) |
|
|
187
|
-
| cluster spec | clustered | `11322` (A), `11332` (A), `11342` (A) |
|
|
188
|
-
| failover spec | clustered | `11422` (M), `11432` (M), `11442` (M) |
|
|
189
|
-
| ssl spec | local | `11232` (A), `12242` (A), `12252` (A) |
|
|
190
|
-
| xsite spec | earth, moon | `11522` (earth, M), `11532` (moon, M) |
|
|
191
|
-
|
|
192
171
|
# Reporting an issue
|
|
193
172
|
|
|
194
|
-
|
|
195
|
-
Instead, please report them via JIRA (project [HRJS](https://issues.jboss.org/projects/HRJS/summary)).
|
|
173
|
+
Report issues via [GitHub Issues](https://github.com/infinispan/js-client/issues).
|
package/lib/codec.js
CHANGED
|
@@ -821,11 +821,48 @@
|
|
|
821
821
|
protobuf.loadSync(path.join(`${__dirname}/protostream/message-wrapping.proto`),root); //loaded the wrappedMessage.proto to the root
|
|
822
822
|
var QueryRequest = root.lookupType('org.infinispan.query.remote.client.QueryRequest');
|
|
823
823
|
var QueryResponse = root.lookupType('org.infinispan.query.remote.client.QueryResponse');
|
|
824
|
+
var ContinuousQueryResult = root.lookupType('org.infinispan.query.remote.client.ContinuousQueryResult');
|
|
824
825
|
|
|
825
826
|
return {
|
|
826
827
|
QueryRequest,
|
|
827
|
-
QueryResponse
|
|
828
|
+
QueryResponse,
|
|
829
|
+
ContinuousQueryResult
|
|
828
830
|
};
|
|
829
831
|
}());
|
|
830
832
|
|
|
833
|
+
var CQ_RESULT_TYPES = ['leaving', 'joining', 'updated'];
|
|
834
|
+
|
|
835
|
+
/**
|
|
836
|
+
* Wrap a scalar value as a WrappedMessage byte array.
|
|
837
|
+
* @param {string|number|boolean} value - The value to wrap.
|
|
838
|
+
* @returns {Buffer} The encoded WrappedMessage bytes.
|
|
839
|
+
*/
|
|
840
|
+
exports.wrapScalar = function(value) {
|
|
841
|
+
return WrappedMessage.encode(createWrappedMessage(value, _.identity)).finish();
|
|
842
|
+
};
|
|
843
|
+
|
|
844
|
+
/**
|
|
845
|
+
* Decode a ContinuousQueryResult from raw protobuf bytes.
|
|
846
|
+
* @param {Buffer} bytes - The raw ContinuousQueryResult bytes.
|
|
847
|
+
* @returns {Object} Decoded result with resultType, key, value, projection.
|
|
848
|
+
*/
|
|
849
|
+
exports.decodeContinuousQueryResult = function(bytes) {
|
|
850
|
+
var msg = Query.ContinuousQueryResult.decode(bytes);
|
|
851
|
+
return {
|
|
852
|
+
resultType: CQ_RESULT_TYPES[msg.resultType] || 'leaving',
|
|
853
|
+
key: msg.key,
|
|
854
|
+
value: msg.value,
|
|
855
|
+
projection: msg.projection
|
|
856
|
+
};
|
|
857
|
+
};
|
|
858
|
+
|
|
859
|
+
/**
|
|
860
|
+
* Decode a WrappedMessage from raw bytes.
|
|
861
|
+
* @param {Buffer} bytes - The raw WrappedMessage bytes.
|
|
862
|
+
* @returns {Object} The decoded WrappedMessage object.
|
|
863
|
+
*/
|
|
864
|
+
exports.decodeWrappedMessage = function(bytes) {
|
|
865
|
+
return WrappedMessage.decode(bytes);
|
|
866
|
+
};
|
|
867
|
+
|
|
831
868
|
}.call(this));
|
package/lib/functional.js
CHANGED
|
@@ -193,6 +193,31 @@
|
|
|
193
193
|
return _.extend.apply(null, construct({}, arguments));
|
|
194
194
|
};
|
|
195
195
|
|
|
196
|
+
/**
|
|
197
|
+
* Deep merges multiple objects, with later arguments taking precedence.
|
|
198
|
+
* @returns {Object} A new merged object.
|
|
199
|
+
*/
|
|
200
|
+
exports.deepMerge = function(/*args*/) {
|
|
201
|
+
var sources = _.toArray(arguments);
|
|
202
|
+
var result = {};
|
|
203
|
+
for (var i = 0; i < sources.length; i++) {
|
|
204
|
+
var src = sources[i];
|
|
205
|
+
if (!existy(src)) continue;
|
|
206
|
+
var keys = _.keys(src);
|
|
207
|
+
for (var k = 0; k < keys.length; k++) {
|
|
208
|
+
var key = keys[k];
|
|
209
|
+
var val = src[key];
|
|
210
|
+
if (!existy(val)) continue;
|
|
211
|
+
if (_.isObject(val) && !_.isArray(val) && _.isObject(result[key]) && !_.isArray(result[key])) {
|
|
212
|
+
result[key] = exports.deepMerge(result[key], val);
|
|
213
|
+
} else {
|
|
214
|
+
result[key] = val;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return result;
|
|
219
|
+
};
|
|
220
|
+
|
|
196
221
|
exports.dispatch = function(/* funs */) {
|
|
197
222
|
var funs = _.toArray(arguments);
|
|
198
223
|
var size = funs.length;
|
package/lib/infinispan.js
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
var f = require('./functional');
|
|
14
14
|
var codec = require('./codec');
|
|
15
15
|
var u = require('./utils');
|
|
16
|
+
var uri = require('./uri');
|
|
16
17
|
var protocols = require('./protocols');
|
|
17
18
|
var io = require('./io');
|
|
18
19
|
var listeners = require('./listeners');
|
|
@@ -824,6 +825,58 @@
|
|
|
824
825
|
return false;
|
|
825
826
|
});
|
|
826
827
|
},
|
|
828
|
+
/**
|
|
829
|
+
* Continuous query options.
|
|
830
|
+
*
|
|
831
|
+
* @typedef {Object} ContinuousQueryOptions
|
|
832
|
+
* @property {Object} [params] - Named parameter bindings for the Ickle query.
|
|
833
|
+
* @since 0.16
|
|
834
|
+
*/
|
|
835
|
+
/**
|
|
836
|
+
* Register a continuous query that watches for cache changes
|
|
837
|
+
* matching the given Ickle query.
|
|
838
|
+
*
|
|
839
|
+
* @param {String} queryString Ickle query string.
|
|
840
|
+
* @param {ContinuousQueryOptions=} opts Optional CQ options.
|
|
841
|
+
* @returns {Promise<Object>}
|
|
842
|
+
* A promise completed with a ContinuousQuery handle.
|
|
843
|
+
* Use cq.on('joining', fn), cq.on('leaving', fn), cq.on('updated', fn)
|
|
844
|
+
* to receive events.
|
|
845
|
+
* @memberof Client#
|
|
846
|
+
* @since 0.16
|
|
847
|
+
*/
|
|
848
|
+
addContinuousQuery: function(queryString, opts) {
|
|
849
|
+
var ctx = transport.context(SMALL);
|
|
850
|
+
logger.debugf('Invoke addContinuousQuery(msgId=%d,query=%s)', ctx.id, queryString);
|
|
851
|
+
return listen.addContinuousQueryListener(transport, ctx, queryString, opts);
|
|
852
|
+
},
|
|
853
|
+
/**
|
|
854
|
+
* Remove a continuous query.
|
|
855
|
+
*
|
|
856
|
+
* @param {Object} cq ContinuousQuery handle returned by addContinuousQuery.
|
|
857
|
+
* @returns {Promise}
|
|
858
|
+
* A promise completed when the continuous query has been removed.
|
|
859
|
+
* @memberof Client#
|
|
860
|
+
* @since 0.16
|
|
861
|
+
*/
|
|
862
|
+
removeContinuousQuery: function(cq) {
|
|
863
|
+
var listenerId = cq.getListenerId();
|
|
864
|
+
var ctx = transport.context(SMALL);
|
|
865
|
+
logger.debugf('Invoke removeContinuousQuery(msgId=%d,listenerId=%s)', ctx.id, listenerId);
|
|
866
|
+
var conn = listen.findConnectionListener(listenerId);
|
|
867
|
+
if (!f.existy(conn))
|
|
868
|
+
return Promise.reject(
|
|
869
|
+
new Error(`No server connection for CQ listener (listenerId=${ listenerId })`));
|
|
870
|
+
|
|
871
|
+
var remote = futurePinned(ctx, 0x27, p.encodeListenerId(listenerId), p.complete(p.hasSuccess), conn);
|
|
872
|
+
return remote.then(function (success) {
|
|
873
|
+
if (success) {
|
|
874
|
+
listen.removeListeners(listenerId);
|
|
875
|
+
return true;
|
|
876
|
+
}
|
|
877
|
+
return false;
|
|
878
|
+
});
|
|
879
|
+
},
|
|
827
880
|
/**
|
|
828
881
|
* Add script to server(s).
|
|
829
882
|
*
|
|
@@ -1294,8 +1347,24 @@
|
|
|
1294
1347
|
*/
|
|
1295
1348
|
/**
|
|
1296
1349
|
* Infinispan client constructor taking an optional initial address,
|
|
1297
|
-
*
|
|
1298
|
-
* as well as optional configuration settings.
|
|
1350
|
+
* multiple addresses, or a Hot Rod URI string to which the client
|
|
1351
|
+
* will try to connect, as well as optional configuration settings.
|
|
1352
|
+
*
|
|
1353
|
+
* @example
|
|
1354
|
+
* // Connect with a Hot Rod URI
|
|
1355
|
+
* client('hotrod://admin:password@localhost:11222')
|
|
1356
|
+
*
|
|
1357
|
+
* @example
|
|
1358
|
+
* // URI with TLS and query parameters
|
|
1359
|
+
* client('hotrods://admin:password@localhost:11222?trust_ca=/ca.pem')
|
|
1360
|
+
*
|
|
1361
|
+
* @example
|
|
1362
|
+
* // URI with programmatic overrides
|
|
1363
|
+
* client('hotrod://admin:password@localhost:11222', {authentication: {saslMechanism: 'SCRAM-SHA-256'}})
|
|
1364
|
+
*
|
|
1365
|
+
* @example
|
|
1366
|
+
* // URI with multiple servers
|
|
1367
|
+
* client('hotrod://admin:password@node1:11222,node2:11322')
|
|
1299
1368
|
*
|
|
1300
1369
|
* @example
|
|
1301
1370
|
* client({port: 11222, host: 'localhost'})
|
|
@@ -1310,18 +1379,29 @@
|
|
|
1310
1379
|
* client([{port: 11522, host: 'myhost'}, {port: 11622, host: 'myhost'}],
|
|
1311
1380
|
* {version: '2.2', cacheName: 'myCache'})
|
|
1312
1381
|
*
|
|
1313
|
-
* @param {(ServerAddress|ServerAddress[])} args
|
|
1314
|
-
*
|
|
1315
|
-
*
|
|
1382
|
+
* @param {(String|ServerAddress|ServerAddress[])} args
|
|
1383
|
+
* A Hot Rod URI string (hotrod:// or hotrods://), a single server address,
|
|
1384
|
+
* or an array of server addresses. If none provided, the client connects
|
|
1385
|
+
* to localhost:11222 by default.
|
|
1316
1386
|
* @param {ClientOptions=} options
|
|
1317
|
-
* Optional configuration settings.
|
|
1387
|
+
* Optional configuration settings. When a URI is provided, these settings
|
|
1388
|
+
* override URI values.
|
|
1318
1389
|
* @constructs Client
|
|
1319
1390
|
* @returns {Promise<ReturnType<Client>>} A promise that resolves to a connected client.
|
|
1320
1391
|
* @since 0.3
|
|
1321
1392
|
*/
|
|
1322
1393
|
exports.client = function client(args, options) {
|
|
1323
|
-
var
|
|
1324
|
-
|
|
1394
|
+
var addrs, uriOpts;
|
|
1395
|
+
if (uri.isHotrodURI(args)) {
|
|
1396
|
+
var parsed = uri.parseHotrodURI(args);
|
|
1397
|
+
addrs = parsed.servers;
|
|
1398
|
+
uriOpts = parsed.options;
|
|
1399
|
+
} else {
|
|
1400
|
+
addrs = u.normalizeAddresses(args);
|
|
1401
|
+
uriOpts = {};
|
|
1402
|
+
}
|
|
1403
|
+
var merged = f.deepMerge(Client.config, uriOpts, options || {});
|
|
1404
|
+
var c = new Client(addrs, merged);
|
|
1325
1405
|
|
|
1326
1406
|
return c.connect();
|
|
1327
1407
|
};
|
|
@@ -1389,16 +1469,7 @@
|
|
|
1389
1469
|
enabled: false,
|
|
1390
1470
|
secureProtocol: 'TLS_client_method',
|
|
1391
1471
|
trustCerts: [],
|
|
1392
|
-
|
|
1393
|
-
key: undefined,
|
|
1394
|
-
passphrase: undefined,
|
|
1395
|
-
cert: undefined
|
|
1396
|
-
},
|
|
1397
|
-
sniHostName: undefined,
|
|
1398
|
-
cryptoStore: {
|
|
1399
|
-
path: undefined,
|
|
1400
|
-
passphrase: undefined
|
|
1401
|
-
}
|
|
1472
|
+
sniHostName: undefined
|
|
1402
1473
|
},
|
|
1403
1474
|
dataFormat : {
|
|
1404
1475
|
keyType: 'text/plain',
|
package/lib/io.js
CHANGED
|
@@ -1116,6 +1116,9 @@
|
|
|
1116
1116
|
f.actions(p.stepsHeaderBody(ctx, 0x23, p.sasl(transport.authOpts(), holder), undefined), codec.bytesEncoded)(ctx);
|
|
1117
1117
|
var result = transport.writeCommandPinned(ctx, p.decodeSasl, conn);
|
|
1118
1118
|
return result.then(function (r) {
|
|
1119
|
+
if (r.complete) {
|
|
1120
|
+
return r;
|
|
1121
|
+
}
|
|
1119
1122
|
ctx = u.context(16);
|
|
1120
1123
|
ctx.topologyId = topologyId;
|
|
1121
1124
|
holder.challenge = r.response;
|
|
@@ -1123,7 +1126,6 @@
|
|
|
1123
1126
|
return transport.writeCommandPinned(ctx, p.decodeSasl, conn).then(function (r) {
|
|
1124
1127
|
return r;
|
|
1125
1128
|
});
|
|
1126
|
-
return r;
|
|
1127
1129
|
});
|
|
1128
1130
|
}
|
|
1129
1131
|
|