Skip to content

Commit 2a2cc09

Browse files
Peter Wilhelmsson2hdddg
authored andcommitted
Pass routing enabled/disabled through the stack
1 parent ad645a5 commit 2a2cc09

11 files changed

+211
-19
lines changed

src/internal/connection-channel.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ export default class ChannelConnection extends Connection {
5656
errorHandler,
5757
address,
5858
log,
59-
disableLosslessIntegers = false
59+
disableLosslessIntegers = false,
60+
serversideRouting = null
6061
) {
6162
super(errorHandler)
6263

@@ -71,6 +72,7 @@ export default class ChannelConnection extends Connection {
7172
this._dechunker = new Dechunker()
7273
this._chunker = new Chunker(channel)
7374
this._log = log
75+
this._serversideRouting = serversideRouting
7476

7577
// connection from the database, returned in response for HELLO message and might not be available
7678
this._dbConnectionId = null
@@ -101,7 +103,7 @@ export default class ChannelConnection extends Connection {
101103
* @param {Logger} log - configured logger.
102104
* @return {Connection} - new connection.
103105
*/
104-
static create (address, config, errorHandler, log) {
106+
static create (address, config, errorHandler, log, serversideRouting = null) {
105107
const channelConfig = new ChannelConfig(
106108
address,
107109
config,
@@ -112,7 +114,8 @@ export default class ChannelConnection extends Connection {
112114
errorHandler,
113115
address,
114116
log,
115-
config.disableLosslessIntegers
117+
config.disableLosslessIntegers,
118+
serversideRouting
116119
)
117120
}
118121

@@ -150,7 +153,8 @@ export default class ChannelConnection extends Connection {
150153
this._ch,
151154
this._chunker,
152155
this._disableLosslessIntegers,
153-
this._log
156+
this._log,
157+
this._serversideRouting
154158
)
155159

156160
return new Promise((resolve, reject) => {

src/internal/connection-provider-pooled.js

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,27 @@ import { SERVICE_UNAVAILABLE } from '../error'
2525
import ConnectionProvider from './connection-provider'
2626

2727
export default class PooledConnectionProvider extends ConnectionProvider {
28-
constructor ({ id, config, log, userAgent, authToken }) {
28+
constructor (
29+
{ id, config, log, userAgent, authToken },
30+
createChannelConnectionHook = null
31+
) {
2932
super()
3033

3134
this._id = id
3235
this._config = config
3336
this._log = log
3437
this._userAgent = userAgent
3538
this._authToken = authToken
39+
this._createChannelConnection =
40+
createChannelConnectionHook ||
41+
(address => {
42+
return ChannelConnection.create(
43+
address,
44+
this._config,
45+
this._createConnectionErrorHandler(),
46+
this._log
47+
)
48+
})
3649
this._connectionPool = new Pool({
3750
create: this._createConnection.bind(this),
3851
destroy: this._destroyConnection.bind(this),
@@ -59,12 +72,7 @@ export default class PooledConnectionProvider extends ConnectionProvider {
5972
* @access private
6073
*/
6174
_createConnection (address, release) {
62-
const connection = ChannelConnection.create(
63-
address,
64-
this._config,
65-
this._createConnectionErrorHandler(),
66-
this._log
67-
)
75+
const connection = this._createChannelConnection(address)
6876
connection._release = () => release(address, connection)
6977
this._openConnections[connection.id] = connection
7078

src/internal/connection-provider-routing.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,20 @@ export default class RoutingConnectionProvider extends PooledConnectionProvider
5353
authToken,
5454
routingTablePurgeDelay
5555
}) {
56-
super({ id, config, log, userAgent, authToken })
56+
super({ id, config, log, userAgent, authToken }, address => {
57+
return ChannelConnection.create(
58+
address,
59+
this._config,
60+
this._createConnectionErrorHandler(),
61+
this._log,
62+
routingContext || {}
63+
)
64+
})
5765

5866
this._seedRouter = address
5967
this._routingTables = {}
6068
this._rediscovery = new Rediscovery(
61-
new RoutingUtil(routingContext, address)
69+
new RoutingUtil(routingContext, address.toString())
6270
)
6371
this._loadBalancingStrategy = new LeastConnectedLoadBalancingStrategy(
6472
this._connectionPool

src/internal/protocol-handshaker.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,20 @@ export default class ProtocolHandshaker {
3636
* @param {boolean} disableLosslessIntegers flag to use native JS numbers.
3737
* @param {Logger} log the logger.
3838
*/
39-
constructor (connection, channel, chunker, disableLosslessIntegers, log) {
39+
constructor (
40+
connection,
41+
channel,
42+
chunker,
43+
disableLosslessIntegers,
44+
log,
45+
serversideRouting = null
46+
) {
4047
this._connection = connection
4148
this._channel = channel
4249
this._chunker = chunker
4350
this._disableLosslessIntegers = disableLosslessIntegers
4451
this._log = log
52+
this._serversideRouting = serversideRouting
4553
}
4654

4755
/**
@@ -113,7 +121,8 @@ export default class ProtocolHandshaker {
113121
return new BoltProtocolV4x1(
114122
this._connection,
115123
this._chunker,
116-
this._disableLosslessIntegers
124+
this._disableLosslessIntegers,
125+
this._serversideRouting
117126
)
118127
default:
119128
throw newError('Unknown Bolt protocol version: ' + version)

test/internal/bolt-stub.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ class UnsupportedBoltStub {
3232
}
3333
}
3434

35-
const verbose =
36-
(process.env.NEOLOGLEVEL || 'error').toLowerCase() === 'debug' // for debugging purposes
35+
const verbose = (process.env.NEOLOGLEVEL || 'error').toLowerCase() === 'debug' // for debugging purposes
3736

3837
class SupportedBoltStub extends UnsupportedBoltStub {
3938
constructor () {
@@ -54,7 +53,13 @@ class SupportedBoltStub extends UnsupportedBoltStub {
5453
}
5554

5655
start (script, port) {
57-
const boltStub = this._childProcess.spawn('boltstub', ['-v', port, script])
56+
const boltStub = this._childProcess.spawn('bolt', [
57+
'stub',
58+
'-v',
59+
'-l',
60+
'localhost:' + port,
61+
script
62+
])
5863

5964
if (verbose) {
6065
boltStub.stdout.on('data', data => {
@@ -140,7 +145,7 @@ class StubServer {
140145
if (exitStatus.code === 0) {
141146
resolve()
142147
} else {
143-
reject(`stub server exited with code: ${exitCode}`)
148+
reject(`stub server exited with code: ${exitStatus.code}`)
144149
}
145150
} else {
146151
if (!timedOut) {

test/internal/node/direct.driver.boltkit.test.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,29 @@ describe('#stub-direct direct driver with stub server', () => {
6565
it('v4', () => verifyShouldRunQuery('v4'))
6666
})
6767

68+
describe('should not send any routing with hello to disable server routing', () => {
69+
async function verify (version) {
70+
if (!boltStub.supported) {
71+
return
72+
}
73+
74+
const router = await boltStub.start(
75+
`./test/resources/boltstub/${version}/hello_routing_disabled.script`,
76+
9001
77+
)
78+
79+
const driver = boltStub.newDriver('bolt://127.0.0.1:9001')
80+
const session = driver.session()
81+
const result = await session.run('MATCH (n) RETURN n.name')
82+
83+
await session.close()
84+
await driver.close()
85+
await router.exit()
86+
}
87+
88+
it('v4.1', () => verify('v4.1'))
89+
})
90+
6891
describe('should send and receive bookmark for read transaction', () => {
6992
async function verifyBookmarkForReadTxc (version) {
7093
if (!boltStub.supported) {

test/internal/node/routing.driver.boltkit.test.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2394,6 +2394,79 @@ describe('#stub-routing routing driver with stub server', () => {
23942394
})
23952395
})
23962396

2397+
describe('should send address in routing context', () => {
2398+
async function verify (version) {
2399+
if (!boltStub.supported) {
2400+
return
2401+
}
2402+
2403+
const router = await boltStub.start(
2404+
`./test/resources/boltstub/${version}/acquire_endpoints_with_context.script`,
2405+
9001
2406+
)
2407+
2408+
const driver = boltStub.newDriver(
2409+
'neo4j://127.0.0.1:9001/?policy=my_policy&region=china'
2410+
)
2411+
const session = driver.session()
2412+
const result = await session.run('MATCH (n) RETURN n.name AS name')
2413+
2414+
await session.close()
2415+
await driver.close()
2416+
await router.exit()
2417+
}
2418+
2419+
it('v4.1', () => verify('v4.1'))
2420+
})
2421+
2422+
describe('should send routing context with hello to enable server routing', () => {
2423+
async function verify (version) {
2424+
if (!boltStub.supported) {
2425+
return
2426+
}
2427+
2428+
const router = await boltStub.start(
2429+
`./test/resources/boltstub/${version}/hello_routing_context.script`,
2430+
9001
2431+
)
2432+
2433+
const driver = boltStub.newDriver(
2434+
'neo4j://127.0.0.1:9001/?policy=my_policy&region=china'
2435+
)
2436+
const session = driver.session()
2437+
const result = await session.run('MATCH (n) RETURN n.name')
2438+
2439+
await session.close()
2440+
await driver.close()
2441+
await router.exit()
2442+
}
2443+
2444+
it('v4.1', () => verify('v4.1'))
2445+
})
2446+
2447+
describe('should send empty routing context with hello to enable server routing', () => {
2448+
async function verify (version) {
2449+
if (!boltStub.supported) {
2450+
return
2451+
}
2452+
2453+
const router = await boltStub.start(
2454+
`./test/resources/boltstub/${version}/hello_routing_enabled.script`,
2455+
9001
2456+
)
2457+
2458+
const driver = boltStub.newDriver('neo4j://127.0.0.1:9001')
2459+
const session = driver.session()
2460+
const result = await session.run('MATCH (n) RETURN n.name')
2461+
2462+
await session.close()
2463+
await driver.close()
2464+
await router.exit()
2465+
}
2466+
2467+
it('v4.1', () => verify('v4.1'))
2468+
})
2469+
23972470
describe('should report whether transaction config is supported', () => {
23982471
async function verifySupportsTransactionConfig (version, expected) {
23992472
if (!boltStub.supported) {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
!: BOLT 4.1
2+
!: AUTO HELLO
3+
!: AUTO RESET
4+
!: AUTO GOODBYE
5+
6+
C: RUN "CALL dbms.routing.getRoutingTable($context, $database)" {"context": {"policy": "my_policy", "region": "china", "address": "127.0.0.1:9001"}, "database":null} {"db": "system", "mode": "r"}
7+
C: PULL {"n": -1 }
8+
S: SUCCESS {"fields": ["ttl", "servers"]}
9+
RECORD [9223372036854775807, [{"addresses": ["127.0.0.1:9001", "127.0.0.1:9002"],"role": "WRITE"}, {"addresses": ["127.0.0.1:9001", "127.0.0.1:9002"], "role": "READ"},{"addresses": ["127.0.0.1:9001", "127.0.0.1:9002"], "role": "ROUTE"}]]
10+
SUCCESS {}
11+
C: RUN "MATCH (n) RETURN n.name AS name" {} {}
12+
PULL {"n": 1000}
13+
S: SUCCESS {"fields": ["name"]}
14+
RECORD ["Alice"]
15+
RECORD ["Bob"]
16+
SUCCESS {}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
!: BOLT 4.1
2+
!: AUTO RESET
3+
4+
C: HELLO {"credentials": "password", "routing": {"policy": "my_policy", "region": "china"}, "scheme": "basic", "user_agent": "neo4j-javascript/0.0.0-dev", "principal": "neo4j"}
5+
S: SUCCESS {"server": "Neo4j/9.9.9", "connection_id": "bolt-123456789"}
6+
C: RUN "CALL dbms.routing.getRoutingTable($context, $database)" {"context": {"policy": "my_policy", "region": "china", "address": "127.0.0.1:9001"}, "database":null} {"db": "system", "mode": "r"}
7+
C: PULL {"n": -1 }
8+
S: SUCCESS {"fields": ["ttl", "servers"]}
9+
RECORD [9223372036854775807, [{"addresses": ["127.0.0.1:9001", "127.0.0.1:9002"],"role": "WRITE"}, {"addresses": ["127.0.0.1:9001", "127.0.0.1:9002"], "role": "READ"},{"addresses": ["127.0.0.1:9001", "127.0.0.1:9002"], "role": "ROUTE"}]]
10+
SUCCESS {}
11+
C: RUN "MATCH (n) RETURN n.name" {} {}
12+
PULL {"n": 1000}
13+
S: SUCCESS {"fields": ["n.name"]}
14+
RECORD ["Foo"]
15+
RECORD ["Bar"]
16+
SUCCESS {}
17+
S: <EXIT>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
!: BOLT 4.1
2+
!: AUTO RESET
3+
4+
C: HELLO {"credentials": "password", "scheme": "basic", "user_agent": "neo4j-javascript/0.0.0-dev", "principal": "neo4j"}
5+
S: SUCCESS {"server": "Neo4j/9.9.9", "connection_id": "bolt-123456789"}
6+
C: RUN "MATCH (n) RETURN n.name" {} {}
7+
PULL {"n": 1000}
8+
S: SUCCESS {"fields": ["n.name"]}
9+
RECORD ["Foo"]
10+
RECORD ["Bar"]
11+
SUCCESS {}
12+
S: <EXIT>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
!: BOLT 4.1
2+
!: AUTO RESET
3+
4+
C: HELLO {"credentials": "password", "routing": {}, "scheme": "basic", "user_agent": "neo4j-javascript/0.0.0-dev", "principal": "neo4j"}
5+
S: SUCCESS {"server": "Neo4j/9.9.9", "connection_id": "bolt-123456789"}
6+
C: RUN "CALL dbms.routing.getRoutingTable($context, $database)" {"context": {"address": "127.0.0.1:9001"}, "database":null} {"db": "system", "mode": "r"}
7+
C: PULL {"n": -1 }
8+
S: SUCCESS {"fields": ["ttl", "servers"]}
9+
RECORD [9223372036854775807, [{"addresses": ["127.0.0.1:9001", "127.0.0.1:9002"],"role": "WRITE"}, {"addresses": ["127.0.0.1:9001", "127.0.0.1:9002"], "role": "READ"},{"addresses": ["127.0.0.1:9001", "127.0.0.1:9002"], "role": "ROUTE"}]]
10+
SUCCESS {}
11+
C: RUN "MATCH (n) RETURN n.name" {} {}
12+
PULL {"n": 1000}
13+
S: SUCCESS {"fields": ["n.name"]}
14+
RECORD ["Foo"]
15+
RECORD ["Bar"]
16+
SUCCESS {}
17+
S: <EXIT>

0 commit comments

Comments
 (0)