Skip to content

Bolt agent added to hello metadata #1076

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 24 commits into from
May 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
4579f14
Enables Deno specific tests in Core
bigmontz Apr 4, 2023
4cbb913
Bolt agent added to hello metadata
ConorNeo Apr 5, 2023
93aec25
Version 1 fix for user agent being empty
ConorNeo Apr 5, 2023
e945255
Fix useragent string on metadata object in 5.3
ConorNeo Apr 6, 2023
c1f9f3b
changes made after rebase onto re-auth
ConorNeo Apr 6, 2023
75d73cc
fixed deno bolt agent
ConorNeo Apr 11, 2023
a0d059d
Browser node agent
ConorNeo Apr 11, 2023
ee556a6
browser bolt agent test
ConorNeo Apr 11, 2023
eb9897a
Add deno test
ConorNeo Apr 11, 2023
ac379be
Fix unit/integration tests related with connection.connect and bolt-a…
bigmontz May 16, 2023
1e4065f
Merge pull request #1 from bigmontz/bolt-agent
ConorNeo May 16, 2023
6c004be
Revert changes in the `userAgent`
bigmontz May 16, 2023
5b02022
Improve Deno instructions
bigmontz May 16, 2023
d00a4a1
Merge pull request #2 from bigmontz/bolt-agent
ConorNeo May 17, 2023
4a8e3e4
Implements BoltAgent as structure
bigmontz May 17, 2023
690256c
Merge pull request #3 from bigmontz/bolt-agent
ConorNeo May 17, 2023
26d2366
Handling null/undefined platform information in Browser
bigmontz May 24, 2023
5d2a3eb
Use user agent instead of appVersion
bigmontz May 24, 2023
07239dd
Merge pull request #4 from bigmontz/bolt-agent
ConorNeo May 24, 2023
07969f6
Fix browser tests in the lite driver
bigmontz May 24, 2023
1bf607b
Remove `boltAgent` from API and fix declaration tests
bigmontz May 24, 2023
2c97a5d
Merge pull request #5 from bigmontz/bolt-agent
ConorNeo May 25, 2023
0893c00
Fix browser test in Node10 environment
bigmontz May 25, 2023
9672614
Merge pull request #6 from bigmontz/bolt-agent
ConorNeo May 25, 2023
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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"build::notci": "lerna bootstrap",
"docs": "lerna run docs --stream --concurrency 1",
"test::unit": "lerna run test::unit --stream",
"test::deno": "lerna run test::deno --stream",
"test::integration": "lerna run test::integration --stream",
"test::browser": "lerna run test::browser --stream",
"test::stress": "lerna run test::stress --stream",
Expand Down
2 changes: 1 addition & 1 deletion packages/bolt-connection/src/bolt/bolt-protocol-v1.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ export default class BoltProtocol {
* @param {function()} param.onComplete the callback to invoke on completion.
* @returns {StreamObserver} the stream observer that monitors the corresponding server response.
*/
initialize ({ userAgent, authToken, notificationFilter, onError, onComplete } = {}) {
initialize ({ userAgent, boltAgent, authToken, notificationFilter, onError, onComplete } = {}) {
const observer = new LoginObserver({
onError: error => this._onLoginError(error, onError),
onCompleted: metadata => this._onLoginCompleted(metadata, onComplete)
Expand Down
2 changes: 1 addition & 1 deletion packages/bolt-connection/src/bolt/bolt-protocol-v3.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default class BoltProtocol extends BoltProtocolV2 {
return metadata
}

initialize ({ userAgent, authToken, notificationFilter, onError, onComplete } = {}) {
initialize ({ userAgent, boltAgent, authToken, notificationFilter, onError, onComplete } = {}) {
const observer = new LoginObserver({
onError: error => this._onLoginError(error, onError),
onCompleted: metadata => this._onLoginCompleted(metadata, authToken, onComplete)
Expand Down
2 changes: 1 addition & 1 deletion packages/bolt-connection/src/bolt/bolt-protocol-v4x1.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export default class BoltProtocol extends BoltProtocolV4 {
return this._transformer
}

initialize ({ userAgent, authToken, notificationFilter, onError, onComplete } = {}) {
initialize ({ userAgent, boltAgent, authToken, notificationFilter, onError, onComplete } = {}) {
const observer = new LoginObserver({
onError: error => this._onLoginError(error, onError),
onCompleted: metadata => this._onLoginCompleted(metadata, authToken, onComplete)
Expand Down
2 changes: 1 addition & 1 deletion packages/bolt-connection/src/bolt/bolt-protocol-v4x3.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export default class BoltProtocol extends BoltProtocolV42 {
* @param {function(onComplte)} args.onComplete On complete callback
* @returns {LoginObserver} The Login observer
*/
initialize ({ userAgent, authToken, notificationFilter, onError, onComplete } = {}) {
initialize ({ userAgent, boltAgent, authToken, notificationFilter, onError, onComplete } = {}) {
const observer = new LoginObserver({
onError: error => this._onLoginError(error, onError),
onCompleted: metadata => {
Expand Down
2 changes: 1 addition & 1 deletion packages/bolt-connection/src/bolt/bolt-protocol-v5x0.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default class BoltProtocol extends BoltProtocolV44 {
* @param {function(onComplte)} args.onComplete On complete callback
* @returns {LoginObserver} The Login observer
*/
initialize ({ userAgent, authToken, notificationFilter, onError, onComplete } = {}) {
initialize ({ userAgent, boltAgent, authToken, notificationFilter, onError, onComplete } = {}) {
const observer = new LoginObserver({
onError: error => this._onLoginError(error, onError),
onCompleted: metadata => this._onLoginCompleted(metadata, authToken, onComplete)
Expand Down
2 changes: 1 addition & 1 deletion packages/bolt-connection/src/bolt/bolt-protocol-v5x1.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export default class BoltProtocol extends BoltProtocolV5x0 {
* @param {function(onComplete)} args.onComplete On complete callback
* @returns {LoginObserver} The Login observer
*/
initialize ({ userAgent, authToken, notificationFilter, onError, onComplete } = {}) {
initialize ({ userAgent, boltAgent, authToken, notificationFilter, onError, onComplete } = {}) {
const state = {}
const observer = new LoginObserver({
onError: error => this._onLoginError(error, onError),
Expand Down
4 changes: 3 additions & 1 deletion packages/bolt-connection/src/bolt/bolt-protocol-v5x2.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,14 @@ export default class BoltProtocol extends BoltProtocolV5x1 {
*
* @param {Object} args The params
* @param {string} args.userAgent The user agent
* @param {string} args.boltAgent The bolt agent
* @param {any} args.authToken The auth token
* @param {NotificationFilter} args.notificationFilter The notification filters.
* @param {function(error)} args.onError On error callback
* @param {function(onComplete)} args.onComplete On complete callback
* @returns {LoginObserver} The Login observer
*/
initialize ({ userAgent, authToken, notificationFilter, onError, onComplete } = {}) {
initialize ({ userAgent, boltAgent, authToken, notificationFilter, onError, onComplete } = {}) {
const state = {}
const observer = new LoginObserver({
onError: error => this._onLoginError(error, onError),
Expand All @@ -67,6 +68,7 @@ export default class BoltProtocol extends BoltProtocolV5x1 {
})

this.write(
// if useragent is null then for all versions before 5.3 it should be bolt agent by default
RequestMessage.hello5x2(userAgent, notificationFilter, this._serversideRouting),
observer,
false
Expand Down
78 changes: 78 additions & 0 deletions packages/bolt-connection/src/bolt/bolt-protocol-v5x3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [http://neo4j.com]
*
* This file is part of Neo4j.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import BoltProtocolV5x2 from './bolt-protocol-v5x2'

import transformersFactories from './bolt-protocol-v5x3.transformer'
import Transformer from './transformer'
import RequestMessage from './request-message'
import { LoginObserver } from './stream-observers'

import { internal } from 'neo4j-driver-core'

const {
constants: { BOLT_PROTOCOL_V5_3 }
} = internal

export default class BoltProtocol extends BoltProtocolV5x2 {
get version () {
return BOLT_PROTOCOL_V5_3
}

get transformer () {
if (this._transformer === undefined) {
this._transformer = new Transformer(Object.values(transformersFactories).map(create => create(this._config, this._log)))
}
return this._transformer
}

/**
* Initialize a connection with the server
*
* @param {Object} args The params
* @param {string} args.userAgent The user agent
* @param {any} args.authToken The auth token
* @param {NotificationFilter} args.notificationFilter The notification filters.
* @param {function(error)} args.onError On error callback
* @param {function(onComplete)} args.onComplete On complete callback
* @returns {LoginObserver} The Login observer
*/
initialize ({ userAgent, boltAgent, authToken, notificationFilter, onError, onComplete } = {}) {
const state = {}
const observer = new LoginObserver({
onError: error => this._onLoginError(error, onError),
onCompleted: metadata => {
state.metadata = metadata
return this._onLoginCompleted(metadata)
}
})

this.write(
RequestMessage.hello5x3(userAgent, boltAgent, notificationFilter, this._serversideRouting),
observer,
false
)

return this.logon({
authToken,
onComplete: metadata => onComplete({ ...metadata, ...state.metadata }),
onError,
flush: true
})
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [http://neo4j.com]
*
* This file is part of Neo4j.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import v5x2 from './bolt-protocol-v5x2.transformer'

export default {
...v5x2
}
9 changes: 9 additions & 0 deletions packages/bolt-connection/src/bolt/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import BoltProtocolV4x4 from './bolt-protocol-v4x4'
import BoltProtocolV5x0 from './bolt-protocol-v5x0'
import BoltProtocolV5x1 from './bolt-protocol-v5x1'
import BoltProtocolV5x2 from './bolt-protocol-v5x2'
import BoltProtocolV5x3 from './bolt-protocol-v5x3'
// eslint-disable-next-line no-unused-vars
import { Chunker, Dechunker } from '../channel'
import ResponseHandler from './response-handler'
Expand Down Expand Up @@ -213,6 +214,14 @@ function createProtocol (
onProtocolError,
serversideRouting
)
case 5.3:
return new BoltProtocolV5x3(server,
chunker,
packingConfig,
createResponseHandler,
log,
onProtocolError,
serversideRouting)
default:
throw newError('Unknown Bolt protocol version: ' + version)
}
Expand Down
2 changes: 1 addition & 1 deletion packages/bolt-connection/src/bolt/handshake.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ function parseNegotiatedResponse (buffer) {
*/
function newHandshakeBuffer () {
return createHandshakeMessage([
[version(5, 2), version(5, 0)],
[version(5, 3), version(5, 0)],
[version(4, 4), version(4, 2)],
version(4, 1),
version(3, 0)
Expand Down
45 changes: 45 additions & 0 deletions packages/bolt-connection/src/bolt/request-message.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,51 @@ export default class RequestMessage {
)
}

/**
* Create a new HELLO message.
* @param {string} userAgent the user agent.
* @param {string} boltAgent the bolt agent.
* @param {NotificationFilter} notificationFilter the notification filter configured
* @param {Object} routing server side routing, set to routing context to turn on server side routing (> 4.1)
* @return {RequestMessage} new HELLO message.
*/
static hello5x3 (userAgent, boltAgent, notificationFilter = null, routing = null) {
const metadata = { }

if (userAgent) {
metadata.user_agent = userAgent
}

if (boltAgent) {
metadata.bolt_agent = {
product: boltAgent.product,
platform: boltAgent.platform,
language: boltAgent.language,
language_details: boltAgent.languageDetails
}
}

if (notificationFilter) {
if (notificationFilter.minimumSeverityLevel) {
metadata.notifications_minimum_severity = notificationFilter.minimumSeverityLevel
}

if (notificationFilter.disabledCategories) {
metadata.notifications_disabled_categories = notificationFilter.disabledCategories
}
}

if (routing) {
metadata.routing = routing
}

return new RequestMessage(
HELLO,
[metadata],
() => `HELLO ${json.stringify(metadata)}`
)
}

/**
* Create a new LOGON message.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,10 @@ export default class WebSocketChannel {
*/
close () {
return new Promise((resolve, reject) => {
this._clearConnectionTimeout()
if (this._ws && this._ws.readyState !== WS_CLOSED) {
this._open = false
this.stopReceiveTimeout()
this._clearConnectionTimeout()
this._ws.onclose = () => resolve()
this._ws.close()
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ import { object } from '../lang'
* Class which provides Authorization for {@link Connection}
*/
export default class AuthenticationProvider {
constructor ({ authTokenManager, userAgent }) {
constructor ({ authTokenManager, userAgent, boltAgent }) {
this._authTokenManager = authTokenManager || expirationBasedAuthTokenManager({
tokenProvider: () => {}
})
this._userAgent = userAgent
this._boltAgent = boltAgent
}

async authenticate ({ connection, auth, skipReAuth, waitReAuth, forceReAuth }) {
Expand All @@ -38,15 +39,15 @@ export default class AuthenticationProvider {
forceReAuth === true
)
if (connection.authToken == null || shouldReAuth) {
return await connection.connect(this._userAgent, auth, waitReAuth || false)
return await connection.connect(this._userAgent, this._boltAgent, auth, waitReAuth || false)
}
return connection
}

const authToken = await this._authTokenManager.getToken()

if (!object.equals(authToken, connection.authToken)) {
return await connection.connect(this._userAgent, authToken)
return await connection.connect(this._userAgent, this._boltAgent, authToken, false)
}

return connection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ const {
const { SERVICE_UNAVAILABLE } = error

export default class DirectConnectionProvider extends PooledConnectionProvider {
constructor ({ id, config, log, address, userAgent, authTokenManager, newPool }) {
super({ id, config, log, userAgent, authTokenManager, newPool })
constructor ({ id, config, log, address, userAgent, boltAgent, authTokenManager, newPool }) {
super({ id, config, log, userAgent, boltAgent, authTokenManager, newPool })

this._address = address
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const AUTHENTICATION_ERRORS = [

export default class PooledConnectionProvider extends ConnectionProvider {
constructor (
{ id, config, log, userAgent, authTokenManager, newPool = (...args) => new Pool(...args) },
{ id, config, log, userAgent, boltAgent, authTokenManager, newPool = (...args) => new Pool(...args) },
createChannelConnectionHook = null
) {
super()
Expand All @@ -42,7 +42,9 @@ export default class PooledConnectionProvider extends ConnectionProvider {
this._config = config
this._log = log
this._authTokenManager = authTokenManager
this._authenticationProvider = new AuthenticationProvider({ authTokenManager, userAgent })
this._authenticationProvider = new AuthenticationProvider({ authTokenManager, userAgent, boltAgent })
this._userAgent = userAgent
this._boltAgent = boltAgent
this._createChannelConnection =
createChannelConnectionHook ||
(address => {
Expand All @@ -67,7 +69,6 @@ export default class PooledConnectionProvider extends ConnectionProvider {
config: PoolConfig.fromDriverConfig(config),
log: this._log
})
this._userAgent = userAgent
this._openConnections = {}
}

Expand All @@ -86,6 +87,7 @@ export default class PooledConnectionProvider extends ConnectionProvider {
return release(address, connection)
}
this._openConnections[connection.id] = connection

return this._authenticationProvider.authenticate({ connection, auth })
.catch(error => {
// let's destroy this connection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,12 @@ export default class RoutingConnectionProvider extends PooledConnectionProvider
config,
log,
userAgent,
boltAgent,
authTokenManager,
routingTablePurgeDelay,
newPool
}) {
super({ id, config, log, userAgent, authTokenManager, newPool }, address => {
super({ id, config, log, userAgent, boltAgent, authTokenManager, newPool }, address => {
return createChannelConnection(
address,
this._config,
Expand Down
Loading