Skip to content

Commit 700e996

Browse files
committed
Add login/logoff messages to the 5.1
1 parent dc88dfd commit 700e996

File tree

13 files changed

+442
-6
lines changed

13 files changed

+442
-6
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/**
2+
* Copyright (c) "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 BoltProtocolV5x0 from './bolt-protocol-v5x0'
20+
21+
import transformersFactories from './bolt-protocol-v5x1.transformer'
22+
import Transformer from './transformer'
23+
import RequestMessage from './request-message'
24+
import { LoginObserver, LogoffObserver } from './stream-observers'
25+
26+
import { internal } from 'neo4j-driver-core'
27+
28+
const {
29+
constants: { BOLT_PROTOCOL_V5_1 }
30+
} = internal
31+
32+
export default class BoltProtocol extends BoltProtocolV5x0 {
33+
get version () {
34+
return BOLT_PROTOCOL_V5_1
35+
}
36+
37+
get transformer () {
38+
if (this._transformer === undefined) {
39+
this._transformer = new Transformer(Object.values(transformersFactories).map(create => create(this._config, this._log)))
40+
}
41+
return this._transformer
42+
}
43+
44+
get supportsLogoff () {
45+
return true
46+
}
47+
48+
/**
49+
* Initialize a connection with the server
50+
*
51+
* @param {Object} param0 The params
52+
* @param {string} param0.userAgent The user agent
53+
* @param {any} param0.authToken The auth token
54+
* @param {function(error)} param0.onError On error callback
55+
* @param {function(onComplte)} param0.onComplete On complete callback
56+
* @returns {LoginObserver} The Login observer
57+
*/
58+
initialize ({ userAgent, authToken, onError, onComplete } = {}) {
59+
const state = {}
60+
const observer = new LoginObserver({
61+
onError: error => this._onLoginError(error, onError),
62+
onCompleted: metadata => {
63+
state.metadata = metadata
64+
return this._onLoginCompleted(metadata)
65+
}
66+
})
67+
68+
this.write(
69+
RequestMessage.hello5x1(userAgent, this._serversideRouting),
70+
observer,
71+
false
72+
)
73+
74+
return this.login({
75+
authToken,
76+
onComplete: metadata => onComplete({ ...metadata, ...state.metadata }),
77+
onError,
78+
flush: true
79+
})
80+
}
81+
82+
/**
83+
* Performs login of the underlying connection
84+
*
85+
* @param {Object} param
86+
* @param {Object} param.authToken the authentication token.
87+
* @param {function(err: Error)} param.onError the callback to invoke on error.
88+
* @param {function()} param.onComplete the callback to invoke on completion.
89+
* @param {boolean} param.flush whether to flush the buffered messages.
90+
*
91+
* @returns {StreamObserver} the stream observer that monitors the corresponding server response.
92+
*/
93+
login ({ authToken, onComplete, onError, flush } = {}) {
94+
const observer = new LoginObserver({
95+
onCompleted: () => this._onLoginCompleted(null, authToken, onComplete),
96+
onError: (error) => this._onLoginError(error, onError)
97+
})
98+
99+
this.write(
100+
RequestMessage.login(authToken),
101+
observer,
102+
flush
103+
)
104+
105+
return observer
106+
}
107+
108+
/**
109+
* Performs logoff of the underlying connection
110+
*
111+
* @param {Object} param
112+
* @param {function(err: Error)} param.onError the callback to invoke on error.
113+
* @param {function()} param.onComplete the callback to invoke on completion.
114+
* @param {boolean} param.flush whether to flush the buffered messages.
115+
*
116+
* @returns {StreamObserver} the stream observer that monitors the corresponding server response.
117+
*/
118+
logoff ({ onComplete, onError, flush } = {}) {
119+
const observer = new LogoffObserver({
120+
onCompleted: onComplete,
121+
onError: onError
122+
})
123+
124+
this.write(
125+
RequestMessage.logoff(),
126+
observer,
127+
flush
128+
)
129+
130+
return observer
131+
}
132+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* Copyright (c) "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+
20+
import v5x0 from './bolt-protocol-v5x0.transformer'
21+
22+
export default {
23+
...v5x0
24+
}

packages/bolt-connection/src/bolt/create.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import BoltProtocolV4x2 from './bolt-protocol-v4x2'
2727
import BoltProtocolV4x3 from './bolt-protocol-v4x3'
2828
import BoltProtocolV4x4 from './bolt-protocol-v4x4'
2929
import BoltProtocolV5x0 from './bolt-protocol-v5x0'
30+
import BoltProtocolV5x1 from './bolt-protocol-v5x1'
3031
// eslint-disable-next-line no-unused-vars
3132
import { Chunker, Dechunker } from '../channel'
3233
import ResponseHandler from './response-handler'
@@ -191,6 +192,16 @@ function createProtocol (
191192
onProtocolError,
192193
serversideRouting
193194
)
195+
case 5.1:
196+
return new BoltProtocolV5x1(
197+
server,
198+
chunker,
199+
packingConfig,
200+
createResponseHandler,
201+
log,
202+
onProtocolError,
203+
serversideRouting
204+
)
194205
default:
195206
throw newError('Unknown Bolt protocol version: ' + version)
196207
}

packages/bolt-connection/src/bolt/handshake.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ function parseNegotiatedResponse (buffer) {
7676
*/
7777
function newHandshakeBuffer () {
7878
return createHandshakeMessage([
79-
version(5, 0),
79+
[version(5, 1), version(5, 0)],
8080
[version(4, 4), version(4, 2)],
8181
version(4, 1),
8282
version(3, 0)

packages/bolt-connection/src/bolt/request-message.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ const COMMIT = 0x12 // 0001 0010 // COMMIT
4040
const ROLLBACK = 0x13 // 0001 0011 // ROLLBACK
4141
const ROUTE = 0x66 // 0110 0110 // ROUTE
4242

43+
const LOGIN = 0x6A // LOGON
44+
const LOGOFF = 0x6B // LOGOFF
45+
4346
const DISCARD = 0x2f // 0010 1111 // DISCARD
4447
const PULL = 0x3f // 0011 1111 // PULL
4548

@@ -121,6 +124,52 @@ export default class RequestMessage {
121124
)
122125
}
123126

127+
/**
128+
* Create a new HELLO message.
129+
* @param {string} userAgent the user agent.
130+
* @param {Object} optional server side routing, set to routing context to turn on server side routing (> 4.1)
131+
* @return {RequestMessage} new HELLO message.
132+
*/
133+
static hello5x1 (userAgent, routing = null) {
134+
const metadata = { user_agent: userAgent }
135+
if (routing) {
136+
metadata.routing = routing
137+
}
138+
139+
return new RequestMessage(
140+
HELLO,
141+
[metadata],
142+
() => `HELLO {user_agent: '${userAgent}', ...}`
143+
)
144+
}
145+
146+
/**
147+
* Create a new LOGIN message.
148+
*
149+
* @param {object} authToken The auth token
150+
* @returns {RequestMessage} new LOGIN message
151+
*/
152+
static login (authToken) {
153+
return new RequestMessage(
154+
LOGIN,
155+
[authToken],
156+
() => 'LOGIN { ... }'
157+
)
158+
}
159+
160+
/**
161+
* Create a new LOGOFF message.
162+
*
163+
* @returns {RequestMessage} new LOGOFF message
164+
*/
165+
static logoff () {
166+
return new RequestMessage(
167+
LOGOFF,
168+
[],
169+
() => 'LOGOFF'
170+
)
171+
}
172+
124173
/**
125174
* Create a new BEGIN message.
126175
* @param {Bookmarks} bookmarks the bookmarks.

packages/bolt-connection/test/bolt/index.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,13 @@ describe('#unit Bolt', () => {
4444
const writtenBuffer = channel.written[0]
4545

4646
const boltMagicPreamble = '60 60 b0 17'
47-
const protocolVersion5x0 = '00 00 00 05'
47+
const protocolVersion5x1to5x0 = '00 01 01 05'
4848
const protocolVersion4x4to4x2 = '00 02 04 04'
4949
const protocolVersion4x1 = '00 00 01 04'
5050
const protocolVersion3 = '00 00 00 03'
5151

5252
expect(writtenBuffer.toHex()).toEqual(
53-
`${boltMagicPreamble} ${protocolVersion5x0} ${protocolVersion4x4to4x2} ${protocolVersion4x1} ${protocolVersion3}`
53+
`${boltMagicPreamble} ${protocolVersion5x1to5x0} ${protocolVersion4x4to4x2} ${protocolVersion4x1} ${protocolVersion3}`
5454
)
5555
})
5656

packages/core/src/internal/constants.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const BOLT_PROTOCOL_V4_2: number = 4.2
3434
const BOLT_PROTOCOL_V4_3: number = 4.3
3535
const BOLT_PROTOCOL_V4_4: number = 4.4
3636
const BOLT_PROTOCOL_V5_0: number = 5.0
37+
const BOLT_PROTOCOL_V5_1: number = 5.1
3738

3839
export {
3940
FETCH_ALL,
@@ -50,5 +51,6 @@ export {
5051
BOLT_PROTOCOL_V4_2,
5152
BOLT_PROTOCOL_V4_3,
5253
BOLT_PROTOCOL_V4_4,
53-
BOLT_PROTOCOL_V5_0
54+
BOLT_PROTOCOL_V5_0,
55+
BOLT_PROTOCOL_V5_1
5456
}

0 commit comments

Comments
 (0)