From bbf2c010e77cc4f68cdf8248cab124ff298361fd Mon Sep 17 00:00:00 2001 From: Dominik Franek Date: Thu, 24 Jan 2019 22:45:49 +1300 Subject: [PATCH 01/13] Don't require crypto package anymore as it is built-in by default. * Change the way how random bytes are generated, not using the crypto package, but built-in Class. --- .../javascript/gremlin-javascript/lib/utils.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js index f996dba879f..6943365d986 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js @@ -23,7 +23,7 @@ */ 'use strict'; -const crypto = require('crypto'); +//const crypto = require('crypto'); exports.toLong = function toLong(value) { return new Long(value); @@ -37,7 +37,7 @@ const Long = exports.Long = function Long(value) { }; exports.getUuid = function getUuid() { - const buffer = crypto.randomBytes(16); + const buffer = Crypto.randomBytes(16); //clear the version buffer[6] &= 0x0f; //set the version 4 @@ -48,11 +48,11 @@ exports.getUuid = function getUuid() { buffer[8] |= 0x80; const hex = buffer.toString('hex'); return ( - hex.substr(0, 8) + '-' + - hex.substr(8, 4) + '-' + - hex.substr(12, 4) + '-' + - hex.substr(16, 4) + '-' + - hex.substr(20, 12)); + hex.substr(0, 8) + '-' + + hex.substr(8, 4) + '-' + + hex.substr(12, 4) + '-' + + hex.substr(16, 4) + '-' + + hex.substr(20, 12)); }; exports.emptyArray = Object.freeze([]); From b016cd1bbd30cd0827812808c75abe51eb7a18ee Mon Sep 17 00:00:00 2001 From: Dominik Franek Date: Thu, 24 Jan 2019 22:47:43 +1300 Subject: [PATCH 02/13] update dependency on ws package to version 6+... * remove requiring the ws package * update how WebSockets are called. --- .../lib/driver/connection.js | 118 +++++++++--------- .../gremlin-javascript/package.json | 14 ++- 2 files changed, 64 insertions(+), 68 deletions(-) diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js index 46b94f4ebeb..d7d41c01aa2 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js @@ -23,7 +23,7 @@ 'use strict'; const EventEmitter = require('events'); -const WebSocket = require('ws'); +//const WebSocket = require('ws'); const util = require('util'); const utils = require('../utils'); const serializer = require('../structure/io/graph-serializer'); @@ -117,55 +117,49 @@ class Connection extends EventEmitter { this.emit('log', `ws open`); - this._ws = new WebSocket(this.url, { - headers: this.options.headers, - ca: this.options.ca, - cert: this.options.cert, - pfx: this.options.pfx, - rejectUnauthorized: this.options.rejectUnauthorized - }); + this._ws = new WebSocket(this.url); - this._ws.on('message', (data) => this._handleMessage(data)); - this._ws.on('error', (err) => this._handleError(err)); - this._ws.on('close', (code, message) => this._handleClose(code, message)); + this._ws.onmessage = (data => this._handleMessage(data)); + this._ws.onerror = (err => this._handleError(err)); + this._ws.onclose = (code, message) => this._handleClose(code, message); - this._ws.on('pong', () => { + this._ws.pong = (() => { this.emit('log', 'ws pong received'); - if (this._pongTimeout) { - clearTimeout(this._pongTimeout); - this._pongTimeout = null; - } - }); - this._ws.on('ping', () => { + if (this._pongTimeout) { + clearTimeout(this._pongTimeout); + this._pongTimeout = null; + } + }); + this._ws.ping = (() => { this.emit('log', 'ws ping received'); - this._ws.pong(); - }); + this._ws.pong(); + }); return this._openPromise = new Promise((resolve, reject) => { - this._ws.on('open', () => { - this.isOpen = true; - if (this._pingEnabled) { - this._pingHeartbeat(); - } - resolve(); - }); - }); + this._ws.onopen = (() => { + this.isOpen = true; + if (this._pingEnabled) { + this._pingHeartbeat(); + } + resolve(); + }); + }); } /** @override */ submit(bytecode, op, args, requestId, processor) { return this.open().then(() => new Promise((resolve, reject) => { if (requestId === null || requestId === undefined) { - requestId = utils.getUuid(); - this._responseHandlers[requestId] = { - callback: (err, result) => err ? reject(err) : resolve(result), + requestId = utils.getUuid(); + this._responseHandlers[requestId] = { + callback: (err, result) => err ? reject(err) : resolve(result), result: null - }; - } + }; + } - const message = Buffer.from(this._header + JSON.stringify(this._getRequest(requestId, bytecode, op, args, processor))); - this._ws.send(message); - })); + const message = Buffer.from(this._header + JSON.stringify(this._getRequest(requestId, bytecode, op, args, processor))); + this._ws.send(message); + })); } _getRequest(id, bytecode, op, args, processor) { @@ -194,20 +188,20 @@ class Connection extends EventEmitter { this._pingInterval = setInterval(() => { if (this.isOpen === false) { - // in case of if not open.. - if (this._pingInterval) { - clearInterval(this._pingInterval); - this._pingInterval = null; - } + // in case of if not open.. + if (this._pingInterval) { + clearInterval(this._pingInterval); + this._pingInterval = null; } + } - this._pongTimeout = setTimeout(() => { - this._ws.terminate(); - }, this._pongTimeoutDelay); + this._pongTimeout = setTimeout(() => { + this._ws.terminate(); + }, this._pongTimeoutDelay); - this._ws.ping(); + this._ws.ping(); - }, this._pingIntervalDelay); + }, this._pingIntervalDelay); } _handleError(err) { @@ -232,15 +226,15 @@ class Connection extends EventEmitter { // We invoke any of the pending handlers with an error Object.keys(this._responseHandlers).forEach(requestId => { const handler = this._responseHandlers[requestId]; - this._clearHandler(requestId); - if (response.status !== undefined && response.status.message) { - return handler.callback( + this._clearHandler(requestId); + if (response.status !== undefined && response.status.message) { + return handler.callback( new Error(util.format( - 'Server error (no request information): %s (%d)', response.status.message, response.status.code))); - } else { - return handler.callback(new Error(util.format('Server error (no request information): %j', response))); - } - }); + 'Server error (no request information): %s (%d)', response.status.message, response.status.code))); + } else { + return handler.callback(new Error(util.format('Server error (no request information): %j', response))); + } + }); return; } @@ -255,14 +249,14 @@ class Connection extends EventEmitter { if (response.status.code === responseStatusCode.authenticationChallenge && this._authenticator) { this._authenticator.evaluateChallenge(response.result.data).then(res => { return this.submit(null, 'authentication', res, response.requestId); - }).catch(handler.callback); + }).catch(handler.callback); return; } else if (response.status.code >= 400) { // callback in error return handler.callback( - new Error(util.format('Server error: %s (%d)', response.status.message, response.status.code))); + new Error(util.format('Server error: %s (%d)', response.status.message, response.status.code))); } switch (response.status.code) { case responseStatusCode.noContent: @@ -327,10 +321,10 @@ class Connection extends EventEmitter { // in another map for types like EnumValue. Could be a nicer way to do this but for now it's solving the // problem with script submission of non JSON native types if (protocolLevel && key === 'bindings') - newObj[key] = this._adaptArgs(args[key], false); - else - newObj[key] = this._writer.adaptObject(args[key]); - }); + newObj[key] = this._adaptArgs(args[key], false); + else + newObj[key] = this._writer.adaptObject(args[key]); + }); return newObj; } @@ -349,8 +343,8 @@ class Connection extends EventEmitter { if (!this._closePromise) { this._closePromise = new Promise(resolve => { this._closeCallback = resolve; - this._ws.close(); - }); + this._ws.close(); + }); } return this._closePromise; } diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json b/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json index 1cc5d6a83bb..3c66541de4d 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json @@ -14,14 +14,16 @@ ], "license": "Apache-2.0", "dependencies": { - "ws": "^3.0.0" + "ws": "^6.0.0", + "util": "^0.11.1", + "events": "^3.0.0" }, "devDependencies": { - "mocha": "~4.0.1", - "cucumber": "~3.1.0", - "chai": "~4.1.2", - "grunt": "~1.0.2", - "grunt-cli": "~1.2.0", + "mocha": "~5.2.0", + "cucumber": "~5.1.0", + "chai": "~4.2.0", + "grunt": "~1.0.3", + "grunt-cli": "~1.3.2", "grunt-jsdoc": "~2.3.0" }, "repository": { From 0ba06a31f304561a72f10fe682845188ae3ba539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Fran=C4=9Bk?= Date: Thu, 24 Jan 2019 23:01:45 +1300 Subject: [PATCH 03/13] Update README.asciidoc --- README.asciidoc | 53 ++++++++----------------------------------------- 1 file changed, 8 insertions(+), 45 deletions(-) diff --git a/README.asciidoc b/README.asciidoc index 65d885eb1cc..f04a6a85ca3 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -14,49 +14,12 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. //// -== TinkerPop3 -image:https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/images/tinkerpop3-splash.png[TinkerPop3, link="http://tinkerpop.apache.org"] - -=== Documentation - -Apache TinkerPop™ provides graph computing capabilities for both graph databases (OLTP) and graph analytic systems (OLAP). - -* link:http://tinkerpop.apache.org/[homepage (downloads)] -* link:http://tinkerpop.apache.org/docs/current/reference/[reference documentation] -* link:http://tinkerpop.apache.org/javadocs/current/core/[core javadoc] -* link:http://tinkerpop.apache.org/javadocs/current/full/[full javadoc] - -=== Building and Testing - -TinkerPop uses link:https://maven.apache.org/[Maven] and requires `Java 1.8.0_40+` for proper building and proper operations. To build, execute unit tests and package Gremlin Console/Server run: - -[source,bash] -mvn clean install - -The zip distributions can be found in the following directories: - -. `gremlin-server/target` -. `gremlin-console/target` - -Please see the link:http://tinkerpop.apache.org/docs/current/dev/developer/#_contributing[CONTRIBUTING.asciidoc] file for more detailed information and options for building, test running and developing TinkerPop. - -=== Get Started - -[source,bash] ----- -$ bin/gremlin.sh - - \,,,/ - (o o) ------oOOo-(3)-oOOo----- -plugin activated: tinkerpop.server -plugin activated: tinkerpop.utilities -plugin activated: tinkerpop.tinkergraph -gremlin> graph = TinkerFactory.createModern() -==>tinkergraph[vertices:6 edges:6] -gremlin> g = graph.traversal() -==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard] -gremlin> g.V().has('name','vadas').valueMap() -==>[name:[vadas], age:[27]] ----- +== Repository Fork +This repository aims for solving the https://issues.apache.org/jira/browse/TINKERPOP-2137 issue. +Gremlin-Javascript can't be run in Browsers, because the apache dependencies rely on server-side packages (e.g. crypto, ws). +This repository removes these dependencies, but with some consequencies: + * you can't use WS config parameters to configure KeyStore, Headers or other WebSocket configs. The new WebSocket class takes only URL, if security is required, it must work as it should work in any browser (signed certificates etc...). + + If you need to know, how to setup SSL for your Gremlin Server (e.g. on Windows), use this guide: https://gist.github.com/szydan/dc19d1c833b3125a9c8fa4f6daad7f29 + Afterwards the gremlin-javascript from browser should work. From 2963c5d189fb27610bce3670d35e7ce0116f8557 Mon Sep 17 00:00:00 2001 From: Dominik Franek Date: Thu, 24 Jan 2019 22:45:49 +1300 Subject: [PATCH 04/13] Don't require crypto package anymore as it is built-in by default. * Change the way how random bytes are generated, not using the crypto package, but built-in Class. --- .../javascript/gremlin-javascript/lib/utils.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js index f996dba879f..6943365d986 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js @@ -23,7 +23,7 @@ */ 'use strict'; -const crypto = require('crypto'); +//const crypto = require('crypto'); exports.toLong = function toLong(value) { return new Long(value); @@ -37,7 +37,7 @@ const Long = exports.Long = function Long(value) { }; exports.getUuid = function getUuid() { - const buffer = crypto.randomBytes(16); + const buffer = Crypto.randomBytes(16); //clear the version buffer[6] &= 0x0f; //set the version 4 @@ -48,11 +48,11 @@ exports.getUuid = function getUuid() { buffer[8] |= 0x80; const hex = buffer.toString('hex'); return ( - hex.substr(0, 8) + '-' + - hex.substr(8, 4) + '-' + - hex.substr(12, 4) + '-' + - hex.substr(16, 4) + '-' + - hex.substr(20, 12)); + hex.substr(0, 8) + '-' + + hex.substr(8, 4) + '-' + + hex.substr(12, 4) + '-' + + hex.substr(16, 4) + '-' + + hex.substr(20, 12)); }; exports.emptyArray = Object.freeze([]); From 35750beb944faa8937c9d876ed94e0431dea9f31 Mon Sep 17 00:00:00 2001 From: Dominik Franek Date: Thu, 24 Jan 2019 22:47:43 +1300 Subject: [PATCH 05/13] update dependency on ws package to version 6+... * remove requiring the ws package * update how WebSockets are called. --- .../lib/driver/connection.js | 118 +++++++++--------- .../gremlin-javascript/package.json | 14 ++- 2 files changed, 64 insertions(+), 68 deletions(-) diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js index 46b94f4ebeb..d7d41c01aa2 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js @@ -23,7 +23,7 @@ 'use strict'; const EventEmitter = require('events'); -const WebSocket = require('ws'); +//const WebSocket = require('ws'); const util = require('util'); const utils = require('../utils'); const serializer = require('../structure/io/graph-serializer'); @@ -117,55 +117,49 @@ class Connection extends EventEmitter { this.emit('log', `ws open`); - this._ws = new WebSocket(this.url, { - headers: this.options.headers, - ca: this.options.ca, - cert: this.options.cert, - pfx: this.options.pfx, - rejectUnauthorized: this.options.rejectUnauthorized - }); + this._ws = new WebSocket(this.url); - this._ws.on('message', (data) => this._handleMessage(data)); - this._ws.on('error', (err) => this._handleError(err)); - this._ws.on('close', (code, message) => this._handleClose(code, message)); + this._ws.onmessage = (data => this._handleMessage(data)); + this._ws.onerror = (err => this._handleError(err)); + this._ws.onclose = (code, message) => this._handleClose(code, message); - this._ws.on('pong', () => { + this._ws.pong = (() => { this.emit('log', 'ws pong received'); - if (this._pongTimeout) { - clearTimeout(this._pongTimeout); - this._pongTimeout = null; - } - }); - this._ws.on('ping', () => { + if (this._pongTimeout) { + clearTimeout(this._pongTimeout); + this._pongTimeout = null; + } + }); + this._ws.ping = (() => { this.emit('log', 'ws ping received'); - this._ws.pong(); - }); + this._ws.pong(); + }); return this._openPromise = new Promise((resolve, reject) => { - this._ws.on('open', () => { - this.isOpen = true; - if (this._pingEnabled) { - this._pingHeartbeat(); - } - resolve(); - }); - }); + this._ws.onopen = (() => { + this.isOpen = true; + if (this._pingEnabled) { + this._pingHeartbeat(); + } + resolve(); + }); + }); } /** @override */ submit(bytecode, op, args, requestId, processor) { return this.open().then(() => new Promise((resolve, reject) => { if (requestId === null || requestId === undefined) { - requestId = utils.getUuid(); - this._responseHandlers[requestId] = { - callback: (err, result) => err ? reject(err) : resolve(result), + requestId = utils.getUuid(); + this._responseHandlers[requestId] = { + callback: (err, result) => err ? reject(err) : resolve(result), result: null - }; - } + }; + } - const message = Buffer.from(this._header + JSON.stringify(this._getRequest(requestId, bytecode, op, args, processor))); - this._ws.send(message); - })); + const message = Buffer.from(this._header + JSON.stringify(this._getRequest(requestId, bytecode, op, args, processor))); + this._ws.send(message); + })); } _getRequest(id, bytecode, op, args, processor) { @@ -194,20 +188,20 @@ class Connection extends EventEmitter { this._pingInterval = setInterval(() => { if (this.isOpen === false) { - // in case of if not open.. - if (this._pingInterval) { - clearInterval(this._pingInterval); - this._pingInterval = null; - } + // in case of if not open.. + if (this._pingInterval) { + clearInterval(this._pingInterval); + this._pingInterval = null; } + } - this._pongTimeout = setTimeout(() => { - this._ws.terminate(); - }, this._pongTimeoutDelay); + this._pongTimeout = setTimeout(() => { + this._ws.terminate(); + }, this._pongTimeoutDelay); - this._ws.ping(); + this._ws.ping(); - }, this._pingIntervalDelay); + }, this._pingIntervalDelay); } _handleError(err) { @@ -232,15 +226,15 @@ class Connection extends EventEmitter { // We invoke any of the pending handlers with an error Object.keys(this._responseHandlers).forEach(requestId => { const handler = this._responseHandlers[requestId]; - this._clearHandler(requestId); - if (response.status !== undefined && response.status.message) { - return handler.callback( + this._clearHandler(requestId); + if (response.status !== undefined && response.status.message) { + return handler.callback( new Error(util.format( - 'Server error (no request information): %s (%d)', response.status.message, response.status.code))); - } else { - return handler.callback(new Error(util.format('Server error (no request information): %j', response))); - } - }); + 'Server error (no request information): %s (%d)', response.status.message, response.status.code))); + } else { + return handler.callback(new Error(util.format('Server error (no request information): %j', response))); + } + }); return; } @@ -255,14 +249,14 @@ class Connection extends EventEmitter { if (response.status.code === responseStatusCode.authenticationChallenge && this._authenticator) { this._authenticator.evaluateChallenge(response.result.data).then(res => { return this.submit(null, 'authentication', res, response.requestId); - }).catch(handler.callback); + }).catch(handler.callback); return; } else if (response.status.code >= 400) { // callback in error return handler.callback( - new Error(util.format('Server error: %s (%d)', response.status.message, response.status.code))); + new Error(util.format('Server error: %s (%d)', response.status.message, response.status.code))); } switch (response.status.code) { case responseStatusCode.noContent: @@ -327,10 +321,10 @@ class Connection extends EventEmitter { // in another map for types like EnumValue. Could be a nicer way to do this but for now it's solving the // problem with script submission of non JSON native types if (protocolLevel && key === 'bindings') - newObj[key] = this._adaptArgs(args[key], false); - else - newObj[key] = this._writer.adaptObject(args[key]); - }); + newObj[key] = this._adaptArgs(args[key], false); + else + newObj[key] = this._writer.adaptObject(args[key]); + }); return newObj; } @@ -349,8 +343,8 @@ class Connection extends EventEmitter { if (!this._closePromise) { this._closePromise = new Promise(resolve => { this._closeCallback = resolve; - this._ws.close(); - }); + this._ws.close(); + }); } return this._closePromise; } diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json b/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json index 1cc5d6a83bb..3c66541de4d 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json @@ -14,14 +14,16 @@ ], "license": "Apache-2.0", "dependencies": { - "ws": "^3.0.0" + "ws": "^6.0.0", + "util": "^0.11.1", + "events": "^3.0.0" }, "devDependencies": { - "mocha": "~4.0.1", - "cucumber": "~3.1.0", - "chai": "~4.1.2", - "grunt": "~1.0.2", - "grunt-cli": "~1.2.0", + "mocha": "~5.2.0", + "cucumber": "~5.1.0", + "chai": "~4.2.0", + "grunt": "~1.0.3", + "grunt-cli": "~1.3.2", "grunt-jsdoc": "~2.3.0" }, "repository": { From 1ee64a12859a003ea0b800d745922da4435ddd53 Mon Sep 17 00:00:00 2001 From: Dominik Franek Date: Fri, 25 Jan 2019 00:24:43 +1300 Subject: [PATCH 06/13] fix to use better library for creating UUID v4... --- .../src/main/javascript/gremlin-javascript/lib/utils.js | 6 ++++-- .../src/main/javascript/gremlin-javascript/package.json | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js index 6943365d986..405ff1b3f55 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js @@ -23,6 +23,7 @@ */ 'use strict'; +const uuidv4 = require('uuid/v4'); //const crypto = require('crypto'); exports.toLong = function toLong(value) { @@ -37,7 +38,7 @@ const Long = exports.Long = function Long(value) { }; exports.getUuid = function getUuid() { - const buffer = Crypto.randomBytes(16); + /*const buffer = Crypto.randomBytes(16); //clear the version buffer[6] &= 0x0f; //set the version 4 @@ -52,7 +53,8 @@ exports.getUuid = function getUuid() { hex.substr(8, 4) + '-' + hex.substr(12, 4) + '-' + hex.substr(16, 4) + '-' + - hex.substr(20, 12)); + hex.substr(20, 12));*/ + return uuidv4(); }; exports.emptyArray = Object.freeze([]); diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json b/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json index 3c66541de4d..d2f38b4661f 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json @@ -24,7 +24,8 @@ "chai": "~4.2.0", "grunt": "~1.0.3", "grunt-cli": "~1.3.2", - "grunt-jsdoc": "~2.3.0" + "grunt-jsdoc": "~2.3.0", + "uuid": "^3.3.2" }, "repository": { "type": "git", From 9949e87be98599bec347860ddfc42fb951e51cac Mon Sep 17 00:00:00 2001 From: Dominik Franek Date: Fri, 25 Jan 2019 00:27:07 +1300 Subject: [PATCH 07/13] better use of standard Buffer of Browser instead of Buffer class from NodeJS (not available in Browsers) --- .../javascript/gremlin-javascript/lib/driver/connection.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js index d7d41c01aa2..f0f7978a2c7 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js @@ -157,7 +157,8 @@ class Connection extends EventEmitter { }; } - const message = Buffer.from(this._header + JSON.stringify(this._getRequest(requestId, bytecode, op, args, processor))); + //const message = Buffer.from(this._header + JSON.stringify(this._getRequest(requestId, bytecode, op, args, processor))); + var message = new ArrayBuffer(this._header + JSON.stringify(this._getRequest(requestId, bytecode, op, args, processor))); this._ws.send(message); })); } From ff2496ca55cc06e0793ef2344cb2e19e78e1d54d Mon Sep 17 00:00:00 2001 From: Dominik Franek Date: Thu, 24 Jan 2019 22:47:43 +1300 Subject: [PATCH 08/13] update dependency on ws package to version 6+... * remove requiring the ws package * update how WebSockets are called. (cherry picked from commit b016cd1) --- .../javascript/gremlin-javascript/lib/driver/connection.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js index f0f7978a2c7..08f61f5cf47 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js @@ -157,10 +157,9 @@ class Connection extends EventEmitter { }; } - //const message = Buffer.from(this._header + JSON.stringify(this._getRequest(requestId, bytecode, op, args, processor))); - var message = new ArrayBuffer(this._header + JSON.stringify(this._getRequest(requestId, bytecode, op, args, processor))); - this._ws.send(message); - })); + const message = Buffer.from(this._header + JSON.stringify(this._getRequest(requestId, bytecode, op, args, processor))); + this._ws.send(message); + })); } _getRequest(id, bytecode, op, args, processor) { From 6e55f8197650d71b9096e57a1ce1ce1e88d131a3 Mon Sep 17 00:00:00 2001 From: Dominik Franek Date: Sun, 27 Jan 2019 17:19:41 +1300 Subject: [PATCH 09/13] update WS handling so that correct response is parsed. --- .../lib/driver/connection.js | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js index d7d41c01aa2..964d6aa6f5b 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js @@ -24,6 +24,7 @@ const EventEmitter = require('events'); //const WebSocket = require('ws'); +//var Buffer = require('buffer'); const util = require('util'); const utils = require('../utils'); const serializer = require('../structure/io/graph-serializer'); @@ -157,8 +158,15 @@ class Connection extends EventEmitter { }; } - const message = Buffer.from(this._header + JSON.stringify(this._getRequest(requestId, bytecode, op, args, processor))); - this._ws.send(message); + //const message = Buffer.from(this._header + JSON.stringify(this._getRequest(requestId, bytecode, op, args, processor))); + const message = this._header + JSON.stringify(this._getRequest(requestId, bytecode, op, args, processor)); + var buf = new ArrayBuffer(message.length); // 2 bytes for each char + var bufView = new Uint8Array(buf); + for (var i=0, strLen=message.length; i < strLen; i++) { + bufView[i] = message.charCodeAt(i); + } + this._ws.binaryType = 'arraybuffer'; + this._ws.send(bufView); })); } @@ -167,6 +175,7 @@ class Connection extends EventEmitter { args = this._adaptArgs(args, true); } + return ({ 'requestId': { '@type': 'g:UUID', '@value': id }, 'op': op || 'bytecode', @@ -219,8 +228,15 @@ class Connection extends EventEmitter { this.emit('close', code, message); } - _handleMessage(data) { - const response = this._reader.read(JSON.parse(data.toString())); + _handleMessage(msg) { + if(event.data instanceof ArrayBuffer ) { + //if in browser javascript, the data are sent as Uint8 + var data = String.fromCharCode.apply(null, new Uint8Array(msg.data)); + console.log("Received: " + data); + }else{ + data = msg; + } + const response = this._reader.read(JSON.parse(data)); if (response.requestId === null || response.requestId === undefined) { // There was a serialization issue on the server that prevented the parsing of the request id // We invoke any of the pending handlers with an error From 4d40d6c74603bdb79394274e922ab5b8f813eb9d Mon Sep 17 00:00:00 2001 From: Dominik Franek Date: Mon, 28 Jan 2019 12:32:48 +1300 Subject: [PATCH 10/13] fix for wrong check in handling Message --- .../main/javascript/gremlin-javascript/lib/driver/connection.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js index 964d6aa6f5b..bb192387588 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js @@ -229,7 +229,7 @@ class Connection extends EventEmitter { } _handleMessage(msg) { - if(event.data instanceof ArrayBuffer ) { + if(msg.data instanceof ArrayBuffer ) { //if in browser javascript, the data are sent as Uint8 var data = String.fromCharCode.apply(null, new Uint8Array(msg.data)); console.log("Received: " + data); From 4cfa2997daf35194150bec4d12fc60b14a47c1cb Mon Sep 17 00:00:00 2001 From: Dominik Franek Date: Sun, 24 Feb 2019 11:12:59 +1400 Subject: [PATCH 11/13] Revert "Update README.asciidoc" This reverts commit 0ba06a3 as it was unintentioanlly comitted to where PR will be created --- README.asciidoc | 53 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/README.asciidoc b/README.asciidoc index f04a6a85ca3..65d885eb1cc 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -14,12 +14,49 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. //// +== TinkerPop3 -== Repository Fork -This repository aims for solving the https://issues.apache.org/jira/browse/TINKERPOP-2137 issue. -Gremlin-Javascript can't be run in Browsers, because the apache dependencies rely on server-side packages (e.g. crypto, ws). -This repository removes these dependencies, but with some consequencies: - * you can't use WS config parameters to configure KeyStore, Headers or other WebSocket configs. The new WebSocket class takes only URL, if security is required, it must work as it should work in any browser (signed certificates etc...). - - If you need to know, how to setup SSL for your Gremlin Server (e.g. on Windows), use this guide: https://gist.github.com/szydan/dc19d1c833b3125a9c8fa4f6daad7f29 - Afterwards the gremlin-javascript from browser should work. +image:https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/images/tinkerpop3-splash.png[TinkerPop3, link="http://tinkerpop.apache.org"] + +=== Documentation + +Apache TinkerPop™ provides graph computing capabilities for both graph databases (OLTP) and graph analytic systems (OLAP). + +* link:http://tinkerpop.apache.org/[homepage (downloads)] +* link:http://tinkerpop.apache.org/docs/current/reference/[reference documentation] +* link:http://tinkerpop.apache.org/javadocs/current/core/[core javadoc] +* link:http://tinkerpop.apache.org/javadocs/current/full/[full javadoc] + +=== Building and Testing + +TinkerPop uses link:https://maven.apache.org/[Maven] and requires `Java 1.8.0_40+` for proper building and proper operations. To build, execute unit tests and package Gremlin Console/Server run: + +[source,bash] +mvn clean install + +The zip distributions can be found in the following directories: + +. `gremlin-server/target` +. `gremlin-console/target` + +Please see the link:http://tinkerpop.apache.org/docs/current/dev/developer/#_contributing[CONTRIBUTING.asciidoc] file for more detailed information and options for building, test running and developing TinkerPop. + +=== Get Started + +[source,bash] +---- +$ bin/gremlin.sh + + \,,,/ + (o o) +-----oOOo-(3)-oOOo----- +plugin activated: tinkerpop.server +plugin activated: tinkerpop.utilities +plugin activated: tinkerpop.tinkergraph +gremlin> graph = TinkerFactory.createModern() +==>tinkergraph[vertices:6 edges:6] +gremlin> g = graph.traversal() +==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard] +gremlin> g.V().has('name','vadas').valueMap() +==>[name:[vadas], age:[27]] +---- From 4ec21931fb12f25387a419ccce9bda9bdbe74014 Mon Sep 17 00:00:00 2001 From: Dominik Franek Date: Sun, 24 Feb 2019 11:15:22 +1400 Subject: [PATCH 12/13] clean the console.log used for debugging only --- .../main/javascript/gremlin-javascript/lib/driver/connection.js | 1 - 1 file changed, 1 deletion(-) diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js index bb192387588..a2c2f984d35 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js @@ -232,7 +232,6 @@ class Connection extends EventEmitter { if(msg.data instanceof ArrayBuffer ) { //if in browser javascript, the data are sent as Uint8 var data = String.fromCharCode.apply(null, new Uint8Array(msg.data)); - console.log("Received: " + data); }else{ data = msg; } From cf96d423524a894173b758ecc796a435b6cc9a67 Mon Sep 17 00:00:00 2001 From: Dominik Franek Date: Sun, 24 Feb 2019 13:32:32 +1400 Subject: [PATCH 13/13] trying to fix the failing Travis build --- .../src/main/javascript/gremlin-javascript/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json b/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json index d2f38b4661f..70f4e576ba6 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json @@ -16,7 +16,8 @@ "dependencies": { "ws": "^6.0.0", "util": "^0.11.1", - "events": "^3.0.0" + "events": "^3.0.0", + "uuid": "^3.3.2" }, "devDependencies": { "mocha": "~5.2.0",