Skip to content

Commit b75f82c

Browse files
authored
backport gremlin-js node 22+ compatibility changes from 3.8 to 3.7 (#3333)
1 parent 6474532 commit b75f82c

9 files changed

Lines changed: 73 additions & 23 deletions

File tree

.github/workflows/build-test.yml

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -238,16 +238,65 @@ jobs:
238238
run: |
239239
mvn clean install -pl -:gremlin-javascript,-gremlin-dotnet,-:gremlin-dotnet-source,-:gremlin-dotnet-tests,-:gremlint -q -DskipTests -Dci
240240
mvn verify -pl gremlin-driver -DskipIntegrationTests=false
241-
javascript:
242-
name: javascript
241+
javascript-node20:
242+
name: javascript-all-node20
243243
timeout-minutes: 15
244244
needs: cache-gremlin-server-docker-image
245-
runs-on: ${{ matrix.os }}
246-
strategy:
247-
matrix:
248-
# Windows Disabled until Linux containers are supported on Windows runners: https://github.com/actions/virtual-environments/issues/252
249-
# os: [ubuntu-latest, windows-latest]
250-
os: [ubuntu-latest]
245+
runs-on: ubuntu-latest
246+
steps:
247+
- uses: actions/checkout@v6
248+
- name: Set up JDK 11
249+
uses: actions/setup-java@v5
250+
with:
251+
java-version: '11'
252+
distribution: 'temurin'
253+
- name: Get Cached Server Base Image
254+
uses: actions/cache@v5
255+
id: gremlin-server-test-docker-image
256+
with:
257+
path: |
258+
./gremlin-server/*
259+
~/.m2/repository/org/apache/tinkerpop/*
260+
key: ${{ github.sha }}
261+
- name: Load Docker Image
262+
working-directory: ./gremlin-server
263+
run: docker load --input gremlin-server.tar
264+
- name: Build with Maven
265+
run: |
266+
mvn clean install -pl -:gremlin-python,-gremlin-dotnet,-:gremlin-dotnet-source,-:gremlin-dotnet-tests -q -DskipTests -Dci
267+
mvn verify -pl :gremlin-javascript,:gremlint -Dnode.test.version=20
268+
javascript-node22:
269+
name: javascript-glv-node22
270+
timeout-minutes: 15
271+
needs: cache-gremlin-server-docker-image
272+
runs-on: ubuntu-latest
273+
steps:
274+
- uses: actions/checkout@v6
275+
- name: Set up JDK 11
276+
uses: actions/setup-java@v5
277+
with:
278+
java-version: '11'
279+
distribution: 'temurin'
280+
- name: Get Cached Server Base Image
281+
uses: actions/cache@v5
282+
id: gremlin-server-test-docker-image
283+
with:
284+
path: |
285+
./gremlin-server/*
286+
~/.m2/repository/org/apache/tinkerpop/*
287+
key: ${{ github.sha }}
288+
- name: Load Docker Image
289+
working-directory: ./gremlin-server
290+
run: docker load --input gremlin-server.tar
291+
- name: Build with Maven
292+
run: |
293+
mvn clean install -pl -:gremlin-python,-gremlin-dotnet,-:gremlin-dotnet-source,-:gremlin-dotnet-tests -q -DskipTests -Dci
294+
mvn verify -pl :gremlin-javascript -Dnode.test.version=22
295+
javascript-node24:
296+
name: javascript-glv-node24
297+
timeout-minutes: 15
298+
needs: cache-gremlin-server-docker-image
299+
runs-on: ubuntu-latest
251300
steps:
252301
- uses: actions/checkout@v6
253302
- name: Set up JDK 11
@@ -256,27 +305,20 @@ jobs:
256305
java-version: '11'
257306
distribution: 'temurin'
258307
- name: Get Cached Server Base Image
259-
if: matrix.os == 'ubuntu-latest'
260308
uses: actions/cache@v5
261309
id: gremlin-server-test-docker-image
262310
with:
263311
path: |
264312
./gremlin-server/*
265313
~/.m2/repository/org/apache/tinkerpop/*
266314
key: ${{ github.sha }}
267-
# - name: Download Server Base Image
268-
# if: matrix.os == 'windows-latest'
269-
# uses: actions/download-artifact@v3
270-
# with:
271-
# name: ${{ github.sha }}
272-
# path: ./gremlin-server
273315
- name: Load Docker Image
274316
working-directory: ./gremlin-server
275317
run: docker load --input gremlin-server.tar
276318
- name: Build with Maven
277319
run: |
278320
mvn clean install -pl -:gremlin-python,-gremlin-dotnet,-:gremlin-dotnet-source,-:gremlin-dotnet-tests -q -DskipTests -Dci
279-
mvn verify -pl :gremlin-javascript,:gremlint
321+
mvn verify -pl :gremlin-javascript -Dnode.test.version=24
280322
python:
281323
name: python
282324
timeout-minutes: 20

CHANGELOG.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
3333
* Added `closeSessionPostGraphOp` to the Gremlin Server settings to indicate that the `Session` should be closed on either a successful commit or rollback.
3434
* Added `SessionedChildClient` that borrows connections from a different `Client` for use with `Sessions`.
3535
* Added `reuseConnectionsForSessions` to Java GLV settings to decide whether to use `SessionedChildClient` for remote transactions.
36+
* Added support for Node 22 and 24 alongside Node 20.
3637
3738
[[release-3-7-5]]
3839
=== TinkerPop 3.7.5 (Release Date: November 12, 2025)

docs/src/reference/gremlin-variants.asciidoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1375,7 +1375,7 @@ java -cp target/run-examples-shaded.jar examples.ModernTraversals
13751375
== Gremlin-JavaScript
13761376
13771377
image:gremlin-js.png[width=130,float=right] Apache TinkerPop's Gremlin-JavaScript implements Gremlin within the
1378-
JavaScript language. It targets Node.js runtime and can be used on different operating systems on any Node.js 6 or
1378+
JavaScript language. It targets Node.js runtime and can be used on different operating systems on any Node.js 20 or
13791379
above. Since the JavaScript naming conventions are very similar to that of Java, it should be very easy to switch
13801380
between Gremlin-Java and Gremlin-JavaScript.
13811381

gremlin-javascript/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ limitations under the License.
262262
<ABS_PROJECT_HOME>${project.basedir}/../</ABS_PROJECT_HOME>
263263
<!-- setting this env variable is needed to be cross-platform compatible -->
264264
<HOME>${user.home}</HOME>
265+
<NODE_VERSION>${node.test.version}</NODE_VERSION>
265266
</environmentVariables>
266267
<executable>docker</executable>
267268
<arguments>

gremlin-javascript/src/main/javascript/gremlin-javascript/docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ services:
4343

4444
gremlin-js-integration-tests:
4545
container_name: gremlin-js-integration-tests
46-
image: node:20
46+
image: node:${NODE_VERSION:-20}
4747
volumes:
4848
- .:/js_app
4949
- ../../../../../gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features:/gremlin-test

gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,12 @@ class Connection extends EventEmitter {
135135
'perMessageDeflate',
136136
]);
137137
// Check if any `ws` specific options are provided and are non-null / non-undefined
138-
const hasWsSpecificOptions = Object.entries(this.options).some(
139-
([key, value]) => wsSpecificOptions.has(key) && ![null, undefined].includes(value),
140-
);
138+
const hasWsSpecificOptions =
139+
Object.entries(this.options).some(
140+
([key, value]) => wsSpecificOptions.has(key) && ![null, undefined].includes(value),
141+
) ||
142+
this._enableCompression || // we need to check the presence of this variable and pass this into ws
143+
this._enableUserAgentOnConnect; // global websocket will send "node" as user agent by default which doesn't comply with Gremlin
141144
// Only use the global websocket if we don't have any unsupported options
142145
const useGlobalWebSocket = !hasWsSpecificOptions && globalThis.WebSocket;
143146
const WebSocket = useGlobalWebSocket || (await import('ws')).default;

gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/client-behavior-tests.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ describe('Client', function () {
5959
let result = await noUserAgentClient.submit('1', null,
6060
{requestId: settings.USER_AGENT_REQUEST_ID});
6161

62-
assert.strictEqual(result.first(), "");
62+
assert.ok(result.first() === "" || result.first() === "node"); // The default node websocket library may use a default user-agent of "node" if none is specified
6363

6464
await noUserAgentClient.close();
6565
});

gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/socket-connection-tests.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ describe('Connection', function () {
7878
globalThis.WebSocket = function () {
7979
globalWebsocketCalls++;
8080
};
81-
const connection = helper.getDriverRemoteConnection(`ws://localhost:${testServerPort}/401`);
81+
const connection = helper.getDriverRemoteConnection(`ws://localhost:${testServerPort}/401`,
82+
{enableCompression: false, enableUserAgentOnConnect: false}); // Global WebSocket is not compatible with customized compression and user agent headers
8283
return connection
8384
.open()
8485
.catch(() => {})

pom.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,8 @@ limitations under the License.
222222
--add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED
223223
--add-opens=java.base/java.net=ALL-UNNAMED
224224
</jdk17JvmArgs>
225+
226+
<node.test.version>20</node.test.version>
225227
</properties>
226228
<build>
227229
<directory>${basedir}/target</directory>

0 commit comments

Comments
 (0)