Skip to content

Commit 94b5350

Browse files
committed
Create packstream components in BoltProtocol
Moved creation of `Packer` and `Unpacker` into `BoltProtocol` because they are in lockstep with each other. This makes protocol handshaker simpler because it only needs to do a single version check. Introduced a class that represents Bolt V2 with different packing and unpacking capabilities.
1 parent 100032a commit 94b5350

File tree

4 files changed

+81
-58
lines changed

4 files changed

+81
-58
lines changed

src/v1/internal/bolt-protocol-v1.js

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,20 @@
1717
* limitations under the License.
1818
*/
1919
import RequestMessage from './request-message';
20+
import * as v1 from './packstream-v1';
2021

2122
export default class BoltProtocol {
2223

2324
/**
2425
* @constructor
2526
* @param {Connection} connection the connection.
26-
* @param {Packer} packer the packer.
27-
* @param {Unpacker} unpacker the unpacker.
27+
* @param {Chunker} chunker the chunker.
28+
* @param {boolean} disableLosslessIntegers if this connection should convert all received integers to native JS numbers.
2829
*/
29-
constructor(connection, packer, unpacker) {
30+
constructor(connection, chunker, disableLosslessIntegers) {
3031
this._connection = connection;
31-
this._packer = packer;
32-
this._unpacker = unpacker;
32+
this._packer = this._createPacker(chunker);
33+
this._unpacker = this._createUnpacker(disableLosslessIntegers);
3334
}
3435

3536
/**
@@ -110,4 +111,12 @@ export default class BoltProtocol {
110111
const message = RequestMessage.reset();
111112
this._connection.write(message, observer, true);
112113
}
114+
115+
_createPacker(chunker) {
116+
return new v1.Packer(chunker);
117+
}
118+
119+
_createUnpacker(disableLosslessIntegers) {
120+
return new v1.Unpacker(disableLosslessIntegers);
121+
}
113122
}

src/v1/internal/bolt-protocol-v2.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* Copyright (c) 2002-2018 "Neo4j,"
3+
* Neo4j Sweden AB [http://neo4j.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
import BoltProtocolV1 from './bolt-protocol-v1';
20+
import * as v2 from './packstream-v2';
21+
22+
export default class BoltProtocol extends BoltProtocolV1 {
23+
24+
constructor(connection, chunker, disableLosslessIntegers) {
25+
super(connection, chunker, disableLosslessIntegers);
26+
}
27+
28+
_createPacker(chunker) {
29+
return new v2.Packer(chunker);
30+
}
31+
32+
_createUnpacker(disableLosslessIntegers) {
33+
return new v2.Unpacker(disableLosslessIntegers);
34+
}
35+
}

src/v1/internal/protocol-handshaker.js

Lines changed: 24 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,24 @@
1919

2020
import {alloc} from './buf';
2121
import {newError} from '../error';
22-
import * as v1 from './packstream-v1';
23-
import * as v2 from './packstream-v2';
24-
import BoltProtocol from './bolt-protocol-v1';
22+
import BoltProtocolV1 from './bolt-protocol-v1';
23+
import BoltProtocolV2 from './bolt-protocol-v2';
2524

2625
const HTTP_MAGIC_PREAMBLE = 1213486160; // == 0x48545450 == "HTTP"
2726
const BOLT_MAGIC_PREAMBLE = 0x6060B017;
2827

29-
const PACKER_CONSTRUCTORS_BY_VERSION = [null, v1.Packer, v2.Packer];
30-
const UNPACKER_CONSTRUCTORS_BY_VERSION = [null, v1.Unpacker, v2.Unpacker];
28+
const LATEST_PROTOCOL_VERSION = 2;
3129

3230
export default class ProtocolHandshaker {
3331

32+
/**
33+
* @constructor
34+
* @param {Connection} connection the connection owning this protocol.
35+
* @param {NodeChannel|WebSocketChannel} channel the network channel.
36+
* @param {Chunker} chunker the message chunker.
37+
* @param {boolean} disableLosslessIntegers flag to use native JS numbers.
38+
* @param {Logger} log the logger.
39+
*/
3440
constructor(connection, channel, chunker, disableLosslessIntegers, log) {
3541
this._connection = connection;
3642
this._channel = channel;
@@ -44,7 +50,7 @@ export default class ProtocolHandshaker {
4450
* @return {BoltProtocol} the protocol.
4551
*/
4652
createLatestProtocol() {
47-
return this._createProtocolWithVersion(PACKER_CONSTRUCTORS_BY_VERSION.length - 1);
53+
return this._createProtocolWithVersion(LATEST_PROTOCOL_VERSION);
4854
}
4955

5056
/**
@@ -62,54 +68,27 @@ export default class ProtocolHandshaker {
6268
*/
6369
readHandshakeResponse(buffer) {
6470
const proposedVersion = buffer.readInt32();
65-
66-
if (proposedVersion === 1 || proposedVersion === 2) {
67-
return this._createProtocolWithVersion(proposedVersion);
68-
} else if (proposedVersion === HTTP_MAGIC_PREAMBLE) {
69-
throw newError('Server responded HTTP. Make sure you are not trying to connect to the http endpoint ' +
70-
'(HTTP defaults to port 7474 whereas BOLT defaults to port 7687)');
71-
} else {
72-
throw newError('Unknown Bolt protocol version: ' + proposedVersion);
71+
if (this._log.isDebugEnabled()) {
72+
this._log.debug(`${this} negotiated protocol version ${proposedVersion}`);
7373
}
74+
return this._createProtocolWithVersion(proposedVersion);
7475
}
7576

7677
/**
7778
* @return {BoltProtocol}
7879
* @private
7980
*/
8081
_createProtocolWithVersion(version) {
81-
if (this._log.isDebugEnabled()) {
82-
this._log.debug(`${this} negotiated protocol version ${version}`);
83-
}
84-
const packer = this._createPackerForProtocolVersion(version);
85-
const unpacker = this._createUnpackerForProtocolVersion(version);
86-
return new BoltProtocol(this._connection, packer, unpacker);
87-
}
88-
89-
/**
90-
* @param {number} version
91-
* @return {Packer}
92-
* @private
93-
*/
94-
_createPackerForProtocolVersion(version) {
95-
const packerConstructor = PACKER_CONSTRUCTORS_BY_VERSION[version];
96-
if (!packerConstructor) {
97-
throw new Error(`Packer can't be created for protocol version ${version}`);
98-
}
99-
return new packerConstructor(this._chunker);
100-
}
101-
102-
/**
103-
* @param {number} version
104-
* @return {Unpacker}
105-
* @private
106-
*/
107-
_createUnpackerForProtocolVersion(version) {
108-
const unpackerConstructor = UNPACKER_CONSTRUCTORS_BY_VERSION[version];
109-
if (!unpackerConstructor) {
110-
throw new Error(`Unpacker can't be created for protocol version ${version}`);
82+
if (version === 1) {
83+
return new BoltProtocolV1(this._connection, this._chunker, this._disableLosslessIntegers);
84+
} else if (version === 2) {
85+
return new BoltProtocolV2(this._connection, this._chunker, this._disableLosslessIntegers);
86+
} else if (version === HTTP_MAGIC_PREAMBLE) {
87+
throw newError('Server responded HTTP. Make sure you are not trying to connect to the http endpoint ' +
88+
'(HTTP defaults to port 7474 whereas BOLT defaults to port 7687)');
89+
} else {
90+
throw newError('Unknown Bolt protocol version: ' + version);
11191
}
112-
return new unpackerConstructor(this._disableLosslessIntegers);
11392
}
11493
}
11594

test/internal/bolt-protocol-v1.test.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* limitations under the License.
1818
*/
1919

20-
import BoltProtocol from '../../src/v1/internal/bolt-protocol-v1';
20+
import BoltProtocolV1 from '../../src/v1/internal/bolt-protocol-v1';
2121
import RequestMessage from '../../src/v1/internal/request-message';
2222
import Bookmark from '../../src/v1/internal/bookmark';
2323

@@ -42,11 +42,11 @@ class MessageRecorder {
4242
}
4343
}
4444

45-
describe('BoltProtocol', () => {
45+
describe('BoltProtocolV1', () => {
4646

4747
it('should initialize the connection', () => {
4848
const recorder = new MessageRecorder();
49-
const protocol = new BoltProtocol(recorder, null, null);
49+
const protocol = new BoltProtocolV1(recorder, null, false);
5050

5151
const clientName = 'js-driver/1.2.3';
5252
const authToken = {username: 'neo4j', password: 'secret'};
@@ -62,7 +62,7 @@ describe('BoltProtocol', () => {
6262

6363
it('should run a statement', () => {
6464
const recorder = new MessageRecorder();
65-
const protocol = new BoltProtocol(recorder, null, null);
65+
const protocol = new BoltProtocolV1(recorder, null, false);
6666

6767
const statement = 'RETURN $x, $y';
6868
const parameters = {x: 'x', y: 'y'};
@@ -81,7 +81,7 @@ describe('BoltProtocol', () => {
8181

8282
it('should reset the connection', () => {
8383
const recorder = new MessageRecorder();
84-
const protocol = new BoltProtocol(recorder, null, null);
84+
const protocol = new BoltProtocolV1(recorder, null, false);
8585

8686
const observer = {};
8787

@@ -95,7 +95,7 @@ describe('BoltProtocol', () => {
9595

9696
it('should begin a transaction', () => {
9797
const recorder = new MessageRecorder();
98-
const protocol = new BoltProtocol(recorder, null, null);
98+
const protocol = new BoltProtocolV1(recorder, null, false);
9999

100100
const bookmark = new Bookmark('neo4j:bookmark:v1:tx42');
101101
const observer = {};
@@ -113,7 +113,7 @@ describe('BoltProtocol', () => {
113113

114114
it('should commit a transaction', () => {
115115
const recorder = new MessageRecorder();
116-
const protocol = new BoltProtocol(recorder, null, null);
116+
const protocol = new BoltProtocolV1(recorder, null, false);
117117

118118
const observer = {};
119119

@@ -130,7 +130,7 @@ describe('BoltProtocol', () => {
130130

131131
it('should rollback a transaction', () => {
132132
const recorder = new MessageRecorder();
133-
const protocol = new BoltProtocol(recorder, null, null);
133+
const protocol = new BoltProtocolV1(recorder, null, false);
134134

135135
const observer = {};
136136

0 commit comments

Comments
 (0)