Skip to content

Commit 4009962

Browse files
authored
merge 5.0 into feature branch (#1233)
1 parent e585fe4 commit 4009962

37 files changed

+2548
-154
lines changed

packages/bolt-connection/src/bolt/bolt-protocol-v1.js

+13
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ const {
4545
txConfig: { TxConfig }
4646
} = internal
4747

48+
const DEFAULT_DIAGNOSTIC_RECORD = Object.freeze({
49+
OPERATION: '',
50+
OPERATION_CODE: '0',
51+
CURRENT_SCHEMA: '/'
52+
})
53+
4854
export default class BoltProtocol {
4955
/**
5056
* @callback CreateResponseHandler Creates the response handler
@@ -164,6 +170,13 @@ export default class BoltProtocol {
164170
return metadata
165171
}
166172

173+
enrichErrorMetadata (metadata) {
174+
return {
175+
...metadata,
176+
diagnostic_record: metadata.diagnostic_record !== null ? { ...DEFAULT_DIAGNOSTIC_RECORD, ...metadata.diagnostic_record } : null
177+
}
178+
}
179+
167180
/**
168181
* Perform initialization and authentication of the underlying connection.
169182
* @param {Object} param
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/**
2+
* Copyright (c) "Neo4j"
3+
* Neo4j Sweden AB [https://neo4j.com]
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
import BoltProtocolV5x6 from './bolt-protocol-v5x6'
18+
19+
import transformersFactories from './bolt-protocol-v5x5.transformer'
20+
import Transformer from './transformer'
21+
22+
import { internal } from 'neo4j-driver-core'
23+
24+
const {
25+
constants: { BOLT_PROTOCOL_V5_7 }
26+
} = internal
27+
28+
const DEFAULT_DIAGNOSTIC_RECORD = Object.freeze({
29+
OPERATION: '',
30+
OPERATION_CODE: '0',
31+
CURRENT_SCHEMA: '/'
32+
})
33+
34+
export default class BoltProtocol extends BoltProtocolV5x6 {
35+
get version () {
36+
return BOLT_PROTOCOL_V5_7
37+
}
38+
39+
get transformer () {
40+
if (this._transformer === undefined) {
41+
this._transformer = new Transformer(Object.values(transformersFactories).map(create => create(this._config, this._log)))
42+
}
43+
return this._transformer
44+
}
45+
46+
/**
47+
*
48+
* @param {object} metadata
49+
* @returns {object}
50+
*/
51+
enrichErrorMetadata (metadata) {
52+
return {
53+
...metadata,
54+
cause: (metadata.cause !== null && metadata.cause !== undefined) ? this.enrichErrorMetadata(metadata.cause) : null,
55+
code: metadata.neo4j_code,
56+
diagnostic_record: metadata.diagnostic_record !== null ? { ...DEFAULT_DIAGNOSTIC_RECORD, ...metadata.diagnostic_record } : null
57+
}
58+
}
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Copyright (c) "Neo4j"
3+
* Neo4j Sweden AB [https://neo4j.com]
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import v5x6 from './bolt-protocol-v5x6.transformer'
19+
20+
export default {
21+
...v5x6
22+
}

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

+10
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import BoltProtocolV5x3 from './bolt-protocol-v5x3'
3131
import BoltProtocolV5x4 from './bolt-protocol-v5x4'
3232
import BoltProtocolV5x5 from './bolt-protocol-v5x5'
3333
import BoltProtocolV5x6 from './bolt-protocol-v5x6'
34+
import BoltProtocolV5x7 from './bolt-protocol-v5x7'
3435
// eslint-disable-next-line no-unused-vars
3536
import { Chunker, Dechunker } from '../channel'
3637
import ResponseHandler from './response-handler'
@@ -64,6 +65,7 @@ export default function create ({
6465
const createResponseHandler = protocol => {
6566
const responseHandler = new ResponseHandler({
6667
transformMetadata: protocol.transformMetadata.bind(protocol),
68+
enrichErrorMetadata: protocol.enrichErrorMetadata.bind(protocol),
6769
log,
6870
observer
6971
})
@@ -247,6 +249,14 @@ function createProtocol (
247249
log,
248250
onProtocolError,
249251
serversideRouting)
252+
case 5.7:
253+
return new BoltProtocolV5x7(server,
254+
chunker,
255+
packingConfig,
256+
createResponseHandler,
257+
log,
258+
onProtocolError,
259+
serversideRouting)
250260
default:
251261
throw newError('Unknown Bolt protocol version: ' + version)
252262
}

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

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

packages/bolt-connection/src/bolt/response-handler.js

+21-7
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* See the License for the specific language governing permissions and
1515
* limitations under the License.
1616
*/
17-
import { newError, json } from 'neo4j-driver-core'
17+
import { newError, newGQLError, json } from 'neo4j-driver-core'
1818

1919
// Signature bytes for each response message type
2020
const SUCCESS = 0x70 // 0111 0000 // SUCCESS <metadata>
@@ -70,10 +70,11 @@ export default class ResponseHandler {
7070
* @param {Logger} log The logger
7171
* @param {ResponseHandler~Observer} observer Object which will be notified about errors
7272
*/
73-
constructor ({ transformMetadata, log, observer } = {}) {
73+
constructor ({ transformMetadata, enrichErrorMetadata, log, observer } = {}) {
7474
this._pendingObservers = []
7575
this._log = log
7676
this._transformMetadata = transformMetadata || NO_OP_IDENTITY
77+
this._enrichErrorMetadata = enrichErrorMetadata || NO_OP_IDENTITY
7778
this._observer = Object.assign(
7879
{
7980
onObserversCountChange: NO_OP,
@@ -115,11 +116,7 @@ export default class ResponseHandler {
115116
this._log.debug(`S: FAILURE ${json.stringify(msg)}`)
116117
}
117118
try {
118-
const standardizedCode = _standardizeCode(payload.code)
119-
const error = newError(payload.message, standardizedCode)
120-
this._currentFailure = this._observer.onErrorApplyTransformation(
121-
error
122-
)
119+
this._currentFailure = this._handleErrorPayload(this._enrichErrorMetadata(payload))
123120
this._currentObserver.onError(this._currentFailure)
124121
} finally {
125122
this._updateCurrentObserver()
@@ -196,6 +193,23 @@ export default class ResponseHandler {
196193
_resetFailure () {
197194
this._currentFailure = null
198195
}
196+
197+
_handleErrorPayload (payload) {
198+
const standardizedCode = _standardizeCode(payload.code)
199+
const cause = payload.cause != null ? this._handleErrorCause(payload.cause) : undefined
200+
const error = newError(payload.message, standardizedCode, cause, payload.gql_status, payload.description, payload.diagnostic_record)
201+
return this._observer.onErrorApplyTransformation(
202+
error
203+
)
204+
}
205+
206+
_handleErrorCause (payload) {
207+
const cause = payload.cause != null ? this._handleErrorCause(payload.cause) : undefined
208+
const error = newGQLError(payload.message, cause, payload.gql_status, payload.description, payload.diagnostic_record)
209+
return this._observer.onErrorApplyTransformation(
210+
error
211+
)
212+
}
199213
}
200214

201215
/**

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ export default class ChannelConnection extends Connection {
441441
reject(error)
442442
} else {
443443
const neo4jError = this._handleProtocolError(
444-
'Received FAILURE as a response for RESET: ' + error
444+
`Received FAILURE as a response for RESET: ${error}`
445445
)
446446
reject(neo4jError)
447447
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`#unit BoltProtocolV5x7 .packable() should resultant function not pack graph types (Node) 1`] = `"It is not allowed to pass nodes in query parameters, given: (c:a {a:"b"})"`;
4+
5+
exports[`#unit BoltProtocolV5x7 .packable() should resultant function not pack graph types (Path) 1`] = `"It is not allowed to pass paths in query parameters, given: [object Object]"`;
6+
7+
exports[`#unit BoltProtocolV5x7 .packable() should resultant function not pack graph types (Relationship) 1`] = `"It is not allowed to pass relationships in query parameters, given: (e)-[:a {b:"c"}]->(f)"`;
8+
9+
exports[`#unit BoltProtocolV5x7 .packable() should resultant function not pack graph types (UnboundRelationship) 1`] = `"It is not allowed to pass unbound relationships in query parameters, given: -[:a {b:"c"}]->"`;
10+
11+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (Date with less fields) 1`] = `"Wrong struct size for Date, expected 1 but was 0"`;
12+
13+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (Date with more fields) 1`] = `"Wrong struct size for Date, expected 1 but was 2"`;
14+
15+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (DateTimeWithZoneId with less fields) 1`] = `"Wrong struct size for DateTimeWithZoneId, expected 3 but was 2"`;
16+
17+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (DateTimeWithZoneId with more fields) 1`] = `"Wrong struct size for DateTimeWithZoneId, expected 3 but was 4"`;
18+
19+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (DateTimeWithZoneOffset with less fields) 1`] = `"Wrong struct size for DateTimeWithZoneOffset, expected 3 but was 2"`;
20+
21+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (DateTimeWithZoneOffset with more fields) 1`] = `"Wrong struct size for DateTimeWithZoneOffset, expected 3 but was 4"`;
22+
23+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (Duration with less fields) 1`] = `"Wrong struct size for Duration, expected 4 but was 3"`;
24+
25+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (Duration with more fields) 1`] = `"Wrong struct size for Duration, expected 4 but was 5"`;
26+
27+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (LocalDateTime with less fields) 1`] = `"Wrong struct size for LocalDateTime, expected 2 but was 1"`;
28+
29+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (LocalDateTime with more fields) 1`] = `"Wrong struct size for LocalDateTime, expected 2 but was 3"`;
30+
31+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (LocalTime with less fields) 1`] = `"Wrong struct size for LocalTime, expected 1 but was 0"`;
32+
33+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (LocalTime with more fields) 1`] = `"Wrong struct size for LocalTime, expected 1 but was 2"`;
34+
35+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (Node with less fields) 1`] = `"Wrong struct size for Node, expected 4 but was 3"`;
36+
37+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (Node with more fields) 1`] = `"Wrong struct size for Node, expected 4 but was 5"`;
38+
39+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (Path with less fields) 1`] = `"Wrong struct size for Path, expected 3 but was 2"`;
40+
41+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (Path with more fields) 1`] = `"Wrong struct size for Path, expected 3 but was 4"`;
42+
43+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (Point with less fields) 1`] = `"Wrong struct size for Point2D, expected 3 but was 2"`;
44+
45+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (Point with more fields) 1`] = `"Wrong struct size for Point2D, expected 3 but was 4"`;
46+
47+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (Point3D with less fields) 1`] = `"Wrong struct size for Point3D, expected 4 but was 3"`;
48+
49+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (Point3D with more fields) 1`] = `"Wrong struct size for Point3D, expected 4 but was 5"`;
50+
51+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (Relationship with less fields) 1`] = `"Wrong struct size for Relationship, expected 8 but was 5"`;
52+
53+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (Relationship with more fields) 1`] = `"Wrong struct size for Relationship, expected 8 but was 9"`;
54+
55+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (Time with less fields) 1`] = `"Wrong struct size for Time, expected 2 but was 1"`;
56+
57+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (Time with more fileds) 1`] = `"Wrong struct size for Time, expected 2 but was 3"`;
58+
59+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (UnboundRelationship with less fields) 1`] = `"Wrong struct size for UnboundRelationship, expected 4 but was 3"`;
60+
61+
exports[`#unit BoltProtocolV5x7 .unpack() should not unpack with wrong size (UnboundRelationship with more fields) 1`] = `"Wrong struct size for UnboundRelationship, expected 4 but was 5"`;

0 commit comments

Comments
 (0)