Skip to content

Commit 93807c3

Browse files
authored
Merge pull request #141 from pontusmelke/1.1-routing
Routing driver
2 parents ce8ee5c + f207842 commit 93807c3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+2055
-360
lines changed

.babelrc

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"presets": ["es2015", "stage-3"]
3+
}

gulpfile.js renamed to gulpfile.babel.js

+17-4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
* See the License for the specific language governing permissions and
1717
* limitations under the License.
1818
*/
19+
require("babel-polyfill");
1920

2021
var browserify = require('browserify');
2122
var source = require('vinyl-source-stream');
@@ -52,7 +53,8 @@ gulp.task('browser', function(cb){
5253
});
5354

5455
/** Build all-in-one files for use in the browser */
55-
gulp.task('build-browser', function () {
56+
gulp.task('bu' +
57+
'ild-browser', function () {
5658
var browserOutput = 'lib/browser';
5759
// Our app bundler
5860
var appBundler = browserify({
@@ -61,7 +63,7 @@ gulp.task('build-browser', function () {
6163
standalone: 'neo4j',
6264
packageCache: {}
6365
}).transform(babelify.configure({
64-
ignore: /external/
66+
presets: ['es2015', 'stage-3'], ignore: /external/
6567
})).bundle();
6668

6769
// Un-minified browser package
@@ -98,7 +100,7 @@ gulp.task('build-browser-test', function(){
98100
cache: {},
99101
debug: true
100102
}).transform(babelify.configure({
101-
ignore: /external/
103+
presets: ['es2015', 'stage-3'], ignore: /external/
102104
}))
103105
.bundle(function(err, res){
104106
cb();
@@ -115,7 +117,7 @@ gulp.task('build-browser-test', function(){
115117

116118
var buildNode = function(options) {
117119
return gulp.src(options.src)
118-
.pipe(babel({ignore: ['src/external/**/*.js']}))
120+
.pipe(babel({presets: ['es2015', 'stage-3'], ignore: ['src/external/**/*.js']}))
119121
.pipe(gulp.dest(options.dest))
120122
};
121123

@@ -152,6 +154,17 @@ gulp.task('test-nodejs', ['nodejs'], function () {
152154
}));
153155
});
154156

157+
gulp.task('test-boltkit', ['nodejs'], function () {
158+
return gulp.src('test/**/*.boltkit.it.js')
159+
.pipe(jasmine({
160+
// reporter: new reporters.JUnitXmlReporter({
161+
// savePath: "build/nodejs-test-reports",
162+
// consolidateAll: false
163+
// }),
164+
includeStackTrace: true
165+
}));
166+
});
167+
155168
gulp.task('test-browser', function (cb) {
156169
runSequence('all', 'run-browser-test', cb)
157170
});

package.json

+8-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
},
1111
"scripts": {
1212
"test": "gulp test",
13+
"boltkit": "gulp test-boltkit",
1314
"build": "gulp all",
1415
"start-neo4j": "gulp start-neo4j",
1516
"stop-neo4j": "gulp stop-neo4j",
@@ -18,14 +19,17 @@
1819
},
1920
"main": "lib/index.js",
2021
"devDependencies": {
21-
"babel": "^5.8.23",
22-
"babelify": "^6.3.0",
23-
"browserify": "^11.0.0",
22+
"babel-core": "^6.17.0",
23+
"babel-polyfill": "^6.16.0",
24+
"babel-preset-es2015": "^6.16.0",
25+
"babel-preset-stage-3": "^6.17.0",
26+
"babelify": "^7.3.0",
27+
"browserify": "^13.1.0",
2428
"esdoc": "^0.4.0",
2529
"esdoc-importpath-plugin": "0.0.1",
2630
"glob": "^5.0.14",
2731
"gulp": "^3.9.1",
28-
"gulp-babel": "^5.2.1",
32+
"gulp-babel": "^6.1.2",
2933
"gulp-batch": "^1.0.5",
3034
"gulp-concat": "^2.6.0",
3135
"gulp-cucumber": "0.0.14",

runTests.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ else
1616
fi
1717

1818
sleep 2
19-
npm test
19+
npm test

src/index.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,5 @@
1919

2020
import * as v1 from './v1/index';
2121

22-
export default {
23-
v1: v1
24-
}
22+
export { v1 }
23+
export default v1

src/v1/driver.js

+51-81
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@
1818
*/
1919

2020
import Session from './session';
21-
import {Pool} from './internal/pool';
21+
import Pool from './internal/pool';
22+
import Integer from './integer';
2223
import {connect} from "./internal/connector";
2324
import StreamObserver from './internal/stream-observer';
24-
import {VERSION} from '../version';
25+
import {newError, SERVICE_UNAVAILABLE} from "./error";
26+
import "babel-polyfill";
2527

28+
let READ = 'READ', WRITE = 'WRITE';
2629
/**
2730
* A driver maintains one or more {@link Session sessions} with a remote
2831
* Neo4j instance. Through the {@link Session sessions} you can send statements
@@ -53,7 +56,7 @@ class Driver {
5356
this._pool = new Pool(
5457
this._createConnection.bind(this),
5558
this._destroyConnection.bind(this),
56-
this._validateConnection.bind(this),
59+
Driver._validateConnection.bind(this),
5760
config.connectionPoolSize
5861
);
5962
}
@@ -63,13 +66,13 @@ class Driver {
6366
* @return {Connection} new connector-api session instance, a low level session API.
6467
* @access private
6568
*/
66-
_createConnection( release ) {
69+
_createConnection(url, release) {
6770
let sessionId = this._sessionIdGenerator++;
6871
let streamObserver = new _ConnectionStreamObserver(this);
69-
let conn = connect(this._url, this._config);
72+
let conn = connect(url, this._config);
7073
conn.initialize(this._userAgent, this._token, streamObserver);
7174
conn._id = sessionId;
72-
conn._release = () => release(conn);
75+
conn._release = () => release(this._url, conn);
7376

7477
this._openSessions[sessionId] = conn;
7578
return conn;
@@ -80,7 +83,7 @@ class Driver {
8083
* @return {boolean} true if the connection is open
8184
* @access private
8285
**/
83-
_validateConnection( conn ) {
86+
static _validateConnection(conn) {
8487
return conn.isOpen();
8588
}
8689

@@ -89,7 +92,7 @@ class Driver {
8992
* @return {Session} new session.
9093
* @access private
9194
*/
92-
_destroyConnection( conn ) {
95+
_destroyConnection(conn) {
9396
delete this._openSessions[conn._id];
9497
conn.close();
9598
}
@@ -105,11 +108,19 @@ class Driver {
105108
* it is returned to the pool, the session will be reset to a clean state and
106109
* made available for others to use.
107110
*
111+
* @param {String} mode of session - optional
108112
* @return {Session} new session.
109113
*/
110-
session() {
111-
let conn = this._pool.acquire();
112-
return new Session( conn, (cb) => {
114+
session(mode) {
115+
let connectionPromise = this._acquireConnection(mode);
116+
connectionPromise.catch((err) => {
117+
if (this.onError && err.code === SERVICE_UNAVAILABLE) {
118+
this.onError(err);
119+
} else {
120+
//we don't need to tell the driver about this error
121+
}
122+
});
123+
return this._createSession(connectionPromise, (cb) => {
113124
// This gets called on Session#close(), and is where we return
114125
// the pooled 'connection' instance.
115126

@@ -119,17 +130,32 @@ class Driver {
119130

120131
// Queue up a 'reset', to ensure the next user gets a clean
121132
// session to work with.
122-
conn.reset();
123-
conn.sync();
124133

125-
// Return connection to the pool
126-
conn._release();
134+
connectionPromise.then( (conn) => {
135+
conn.reset();
136+
conn.sync();
137+
138+
// Return connection to the pool
139+
conn._release();
140+
}).catch( () => {/*ignore errors here*/});
127141

128142
// Call user callback
129-
if(cb) { cb(); }
143+
if (cb) {
144+
cb();
145+
}
130146
});
131147
}
132148

149+
//Extension point
150+
_acquireConnection(mode) {
151+
return Promise.resolve(this._pool.acquire(this._url));
152+
}
153+
154+
//Extension point
155+
_createSession(connectionPromise, cb) {
156+
return new Session(connectionPromise, cb);
157+
}
158+
133159
/**
134160
* Close all open sessions and other associated resources. You should
135161
* make sure to use this when you are done with this driver instance.
@@ -140,6 +166,7 @@ class Driver {
140166
if (this._openSessions.hasOwnProperty(sessionId)) {
141167
this._openSessions[sessionId].close();
142168
}
169+
this._pool.purgeAll();
143170
}
144171
}
145172
}
@@ -151,83 +178,26 @@ class _ConnectionStreamObserver extends StreamObserver {
151178
this._driver = driver;
152179
this._hasFailed = false;
153180
}
181+
154182
onError(error) {
155183
if (!this._hasFailed) {
156184
super.onError(error);
157-
if(this._driver.onError) {
185+
if (this._driver.onError) {
158186
this._driver.onError(error);
159187
}
160188
this._hasFailed = true;
161189
}
162190
}
191+
163192
onCompleted(message) {
164-
if(this._driver.onCompleted) {
165-
this._driver.onCompleted(message);
193+
if (this._driver.onCompleted) {
194+
this._driver.onCompleted(message);
166195
}
167196
}
168197
}
169198

170-
let USER_AGENT = "neo4j-javascript/" + VERSION;
171199

172-
/**
173-
* Construct a new Neo4j Driver. This is your main entry point for this
174-
* library.
175-
*
176-
* ## Configuration
177-
*
178-
* This function optionally takes a configuration argument. Available configuration
179-
* options are as follows:
180-
*
181-
* {
182-
* // Encryption level: one of ENCRYPTION_ON, ENCRYPTION_OFF or ENCRYPTION_NON_LOCAL.
183-
* // ENCRYPTION_NON_LOCAL is on by default in modern NodeJS installs,
184-
* // but off by default in the Web Bundle and old (<=1.0.0) NodeJS installs
185-
* // due to technical limitations on those platforms.
186-
* encrypted: ENCRYPTION_ON|ENCRYPTION_OFF|ENCRYPTION_NON_LOCAL
187-
*
188-
* // Trust strategy to use if encryption is enabled. There is no mode to disable
189-
* // trust other than disabling encryption altogether. The reason for
190-
* // this is that if you don't know who you are talking to, it is easy for an
191-
* // attacker to hijack your encrypted connection, rendering encryption pointless.
192-
* //
193-
* // TRUST_ON_FIRST_USE is the default for modern NodeJS deployments, and works
194-
* // similarly to how `ssl` works - the first time we connect to a new host,
195-
* // we remember the certificate they use. If the certificate ever changes, we
196-
* // assume it is an attempt to hijack the connection and require manual intervention.
197-
* // This means that by default, connections "just work" while still giving you
198-
* // good encrypted protection.
199-
* //
200-
* // TRUST_CUSTOM_CA_SIGNED_CERTIFICATES is the classic approach to trust verification -
201-
* // whenever we establish an encrypted connection, we ensure the host is using
202-
* // an encryption certificate that is in, or is signed by, a certificate listed
203-
* // as trusted. In the web bundle, this list of trusted certificates is maintained
204-
* // by the web browser. In NodeJS, you configure the list with the next config option.
205-
* //
206-
* // TRUST_SYSTEM_CA_SIGNED_CERTIFICATES meand that you trust whatever certificates
207-
* // are in the default certificate chain of th
208-
* trust: "TRUST_ON_FIRST_USE" | "TRUST_SIGNED_CERTIFICATES" | TRUST_CUSTOM_CA_SIGNED_CERTIFICATES | TRUST_SYSTEM_CA_SIGNED_CERTIFICATES,
209-
*
210-
* // List of one or more paths to trusted encryption certificates. This only
211-
* // works in the NodeJS bundle, and only matters if you use "TRUST_CUSTOM_CA_SIGNED_CERTIFICATES".
212-
* // The certificate files should be in regular X.509 PEM format.
213-
* // For instance, ['./trusted.pem']
214-
* trustedCertificates: [],
215-
*
216-
* // Path to a file where the driver saves hosts it has seen in the past, this is
217-
* // very similar to the ssl tool's known_hosts file. Each time we connect to a
218-
* // new host, a hash of their certificate is stored along with the domain name and
219-
* // port, and this is then used to verify the host certificate does not change.
220-
* // This setting has no effect unless TRUST_ON_FIRST_USE is enabled.
221-
* knownHosts:"~/.neo4j/known_hosts",
222-
* }
223-
*
224-
* @param {string} url The URL for the Neo4j database, for instance "bolt://localhost"
225-
* @param {Map<String,String>} authToken Authentication credentials. See {@link auth} for helpers.
226-
* @param {Object} config Configuration object. See the configuration section above for details.
227-
* @returns {Driver}
228-
*/
229-
function driver(url, authToken, config={}) {
230-
return new Driver(url, USER_AGENT, authToken, config);
231-
}
232200

233-
export {Driver, driver}
201+
export {Driver, READ, WRITE}
202+
203+
export default Driver

src/v1/error.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
// A common place for constructing error objects, to keep them
2121
// uniform across the driver surface.
2222

23+
let SERVICE_UNAVAILABLE = 'ServiceUnavailable';
24+
let SESSION_EXPIRED = 'SessionExpired';
2325
function newError(message, code="N/A") {
24-
// TODO: Idea is that we can check the cod here and throw sub-classes
26+
// TODO: Idea is that we can check the code here and throw sub-classes
2527
// of Neo4jError as appropriate
2628
return new Neo4jError(message, code);
2729
}
@@ -36,5 +38,7 @@ class Neo4jError extends Error {
3638

3739
export {
3840
newError,
39-
Neo4jError
41+
Neo4jError,
42+
SERVICE_UNAVAILABLE,
43+
SESSION_EXPIRED
4044
}

src/v1/graph-types.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ class Path {
171171
}
172172
}
173173

174-
export default {
174+
export {
175175
Node,
176176
Relationship,
177177
UnboundRelationship,

0 commit comments

Comments
 (0)