Skip to content

Add driver.supportsTransactionConfig #528

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/driver.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,19 @@ class Driver {
return connectionProvider.supportsMultiDb()
}

/**
* Returns whether the server supports transaction config capabilities based on the protocol
* version negotiated via handshake.
*
* Note that this function call _always_ causes a round-trip to the server.
*
* @returns {Promise<boolean>} promise resolved with a boolean or rejected with error.
*/
supportsTransactionConfig () {
const connectionProvider = this._getOrCreateConnectionProvider()
return connectionProvider.supportsTransactionConfig()
}

/**
* Acquire a session to communicate with the database. The session will
* borrow connections from the underlying connection pool as required and
Expand Down
18 changes: 15 additions & 3 deletions src/internal/connection-provider-direct.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import PooledConnectionProvider from './connection-provider-pooled'
import DelegateConnection from './connection-delegate'
import ChannelConnection from './connection-channel'
import { BOLT_PROTOCOL_V4 } from './constants'
import { BOLT_PROTOCOL_V4, BOLT_PROTOCOL_V3 } from './constants'

export default class DirectConnectionProvider extends PooledConnectionProvider {
constructor ({ id, config, log, address, userAgent, authToken }) {
Expand All @@ -39,7 +39,7 @@ export default class DirectConnectionProvider extends PooledConnectionProvider {
.then(connection => new DelegateConnection(connection, null))
}

async supportsMultiDb () {
async _hasProtocolVersion (versionPredicate) {
const connection = ChannelConnection.create(
this._address,
this._config,
Expand All @@ -52,12 +52,24 @@ export default class DirectConnectionProvider extends PooledConnectionProvider {

const protocol = connection.protocol()
if (protocol) {
return protocol.version >= BOLT_PROTOCOL_V4
return versionPredicate(protocol.version)
}

return false
} finally {
await connection.close()
}
}

async supportsMultiDb () {
return await this._hasProtocolVersion(
version => version >= BOLT_PROTOCOL_V4
)
}

async supportsTransactionConfig () {
return await this._hasProtocolVersion(
version => version >= BOLT_PROTOCOL_V3
)
}
}
18 changes: 15 additions & 3 deletions src/internal/connection-provider-routing.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import LeastConnectedLoadBalancingStrategy from './least-connected-load-balancin
import Bookmark from './bookmark'
import ChannelConnection from './connection-channel'
import { int } from '../integer'
import { BOLT_PROTOCOL_V4 } from './constants'
import { BOLT_PROTOCOL_V4, BOLT_PROTOCOL_V3 } from './constants'

const UNAUTHORIZED_ERROR_CODE = 'Neo.ClientError.Security.Unauthorized'
const DATABASE_NOT_FOUND_ERROR_CODE =
Expand Down Expand Up @@ -152,7 +152,7 @@ export default class RoutingConnectionProvider extends PooledConnectionProvider
}
}

async supportsMultiDb () {
async _hasProtocolVersion (versionPredicate) {
const addresses = await this._resolveSeedRouter(this._seedRouter)

let lastError
Expand All @@ -169,7 +169,7 @@ export default class RoutingConnectionProvider extends PooledConnectionProvider

const protocol = connection.protocol()
if (protocol) {
return protocol.version >= BOLT_PROTOCOL_V4
return versionPredicate(protocol.version)
}

return false
Expand All @@ -187,6 +187,18 @@ export default class RoutingConnectionProvider extends PooledConnectionProvider
return false
}

async supportsMultiDb () {
return await this._hasProtocolVersion(
version => version >= BOLT_PROTOCOL_V4
)
}

async supportsTransactionConfig () {
return await this._hasProtocolVersion(
version => version >= BOLT_PROTOCOL_V3
)
}

forget (address, database) {
if (database || database === '') {
this._routingTables[database].forget(address)
Expand Down
10 changes: 10 additions & 0 deletions src/internal/connection-provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ export default class ConnectionProvider {
throw new Error('not implemented')
}

/**
* This method checks whether the backend database supports transaction config functionality
* by checking protocol handshake result.
*
* @returns {Promise<boolean>}
*/
supportsTransactionConfig () {
throw new Error('not implemented')
}

/**
* Closes this connection provider along with its internals (connections, pools, etc.)
*
Expand Down
40 changes: 39 additions & 1 deletion test/internal/node/direct.driver.boltkit.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ describe('#stub-direct direct driver with stub server', () => {
}

const server = await boltStub.start(
`./test/resources/boltstub/${version}/supports_multi_db.script`,
`./test/resources/boltstub/${version}/supports_protocol_version.script`,
9001
)

Expand Down Expand Up @@ -447,6 +447,44 @@ describe('#stub-direct direct driver with stub server', () => {
})
})

describe('should report whether transaction config is supported', () => {
async function verifySupportsTransactionConfig (version, expected) {
if (!boltStub.supported) {
return
}

const server = await boltStub.start(
`./test/resources/boltstub/${version}/supports_protocol_version.script`,
9001
)

const driver = boltStub.newDriver('bolt://127.0.0.1:9001')

await expectAsync(driver.supportsTransactionConfig()).toBeResolvedTo(
expected
)

await driver.close()
await server.exit()
}

it('v1', () => verifySupportsTransactionConfig('v1', false))
it('v2', () => verifySupportsTransactionConfig('v2', false))
it('v3', () => verifySupportsTransactionConfig('v3', true))
it('v4', () => verifySupportsTransactionConfig('v4', true))
it('on error', async () => {
const driver = boltStub.newDriver('bolt://127.0.0.1:9001')

await expectAsync(driver.supportsTransactionConfig()).toBeRejectedWith(
jasmine.objectContaining({
code: SERVICE_UNAVAILABLE
})
)

await driver.close()
})
})

describe('should allow to change fetch size', () => {
async function verifyFailureOnCommit (version) {
if (!boltStub.supported) {
Expand Down
79 changes: 77 additions & 2 deletions test/internal/node/routing.driver.boltkit.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2339,7 +2339,7 @@ describe('#stub-routing routing driver with stub server', () => {
}

const server = await boltStub.start(
`./test/resources/boltstub/${version}/supports_multi_db.script`,
`./test/resources/boltstub/${version}/supports_protocol_version.script`,
9001
)

Expand All @@ -2357,7 +2357,7 @@ describe('#stub-routing routing driver with stub server', () => {
}

const server = await boltStub.start(
`./test/resources/boltstub/${version}/supports_multi_db.script`,
`./test/resources/boltstub/${version}/supports_protocol_version.script`,
9001
)

Expand Down Expand Up @@ -2396,6 +2396,81 @@ describe('#stub-routing routing driver with stub server', () => {
})
})

describe('should report whether transaction config is supported', () => {
async function verifySupportsTransactionConfig (version, expected) {
if (!boltStub.supported) {
return
}

const server = await boltStub.start(
`./test/resources/boltstub/${version}/supports_protocol_version.script`,
9001
)

const driver = boltStub.newDriver('neo4j://127.0.0.1:9001')

await expectAsync(driver.supportsTransactionConfig()).toBeResolvedTo(
expected
)

await driver.close()
await server.exit()
}

async function verifySupportsTransactionConfigWithResolver (
version,
expected
) {
if (!boltStub.supported) {
return
}

const server = await boltStub.start(
`./test/resources/boltstub/${version}/supports_protocol_version.script`,
9001
)

const driver = boltStub.newDriver('neo4j://127.0.0.1:8000', {
resolver: address => [
'neo4j://127.0.0.1:9010',
'neo4j://127.0.0.1:9005',
'neo4j://127.0.0.1:9001'
]
})

await expectAsync(driver.supportsTransactionConfig()).toBeResolvedTo(
expected
)

await driver.close()
await server.exit()
}

it('v1', () => verifySupportsTransactionConfig('v1', false))
it('v2', () => verifySupportsTransactionConfig('v2', false))
it('v3', () => verifySupportsTransactionConfig('v3', true))
it('v4', () => verifySupportsTransactionConfig('v4', true))
it('v1 with resolver', () =>
verifySupportsTransactionConfigWithResolver('v1', false))
it('v2 with resolver', () =>
verifySupportsTransactionConfigWithResolver('v2', false))
it('v3 with resolver', () =>
verifySupportsTransactionConfigWithResolver('v3', true))
it('v4 with resolver', () =>
verifySupportsTransactionConfigWithResolver('v4', true))
it('on error', async () => {
const driver = boltStub.newDriver('neo4j://127.0.0.1:9001')

await expectAsync(driver.supportsTransactionConfig()).toBeRejectedWith(
jasmine.objectContaining({
code: SESSION_EXPIRED
})
)

await driver.close()
})
})

async function testAddressPurgeOnDatabaseError (script, query, accessMode) {
if (!boltStub.supported) {
return
Expand Down
4 changes: 4 additions & 0 deletions test/types/driver.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ driver.supportsMultiDb().then((supported: boolean) => {
console.log(`multi database is supported? => ${supported}`)
})

driver.supportsTransactionConfig().then((supported: boolean) => {
console.log(`transaction config is supported? => ${supported}`)
})

const rxSession1: RxSession = driver.rxSession()
const rxSession2: RxSession = driver.rxSession({ defaultAccessMode: READ })
const rxSession3: RxSession = driver.rxSession({ defaultAccessMode: 'READ' })
Expand Down
2 changes: 2 additions & 0 deletions types/driver.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ declare interface Driver {
verifyConnectivity(): Promise<ServerInfo>

supportsMultiDb(): Promise<boolean>

supportsTransactionConfig(): Promise<boolean>
}

export {
Expand Down