Skip to content
This repository was archived by the owner on Oct 31, 2024. It is now read-only.

Commit b5f198e

Browse files
author
Nir Hadassi
authored
fix(neo4j): fixed crash when connecting with aura (#78)
1 parent f75dd4f commit b5f198e

File tree

4 files changed

+55
-14
lines changed

4 files changed

+55
-14
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
run: yarn
3333

3434
- name: Build
35-
run: yarn build
35+
run: yarn build:ci
3636

3737
- name: Test
3838
run: yarn test:ci

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"test": "lerna run test",
66
"test:ci": "lerna run test:ci --since origin/master",
77
"build": "lerna run build",
8+
"build:ci": "lerna run build --since origin/master",
89
"postinstall": "lerna bootstrap",
910
"prettier": "prettier --config .prettierrc.yml --write \"**/*.{ts,tsx,js,jsx,json}\"",
1011
"version:update": "lerna run version:update",
Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
11
import { DatabaseAttribute, GeneralAttribute } from '@opentelemetry/semantic-conventions';
22

33
export function getAttributesFromNeo4jSession(session: any) {
4-
const connectionHolder = (session._mode === 'WRITE' ? session._writeConnectionHolder : session._readConnectionHolder) ?? session._connectionHolder;
5-
const address = connectionHolder._connectionProvider._address;
6-
const auth = connectionHolder._connectionProvider._authToken;
4+
const connectionHolder =
5+
(session._mode === 'WRITE' ? session._writeConnectionHolder : session._readConnectionHolder) ??
6+
session._connectionHolder ??
7+
{};
8+
const connectionProvider = connectionHolder._connectionProvider ?? {};
9+
10+
// seedRouter is used when connecting to a url that starts with "neo4j", usually aura
11+
const address = connectionProvider._address ?? connectionProvider._seedRouter;
12+
const auth = connectionProvider._authToken;
713

814
const attributes = {
9-
[GeneralAttribute.NET_PEER_NAME]: address._host,
10-
[GeneralAttribute.NET_PEER_PORT]: address._port,
1115
[GeneralAttribute.NET_TRANSPORT]: 'IP.TCP',
1216
// "neo4j" is the default database name. When used, "session._database" is an empty string
13-
[DatabaseAttribute.DB_NAME]: session._database ? session._database : 'neo4j'
17+
[DatabaseAttribute.DB_NAME]: session._database ? session._database : 'neo4j',
18+
};
19+
if (address) {
20+
attributes[GeneralAttribute.NET_PEER_NAME] = address._host;
21+
attributes[GeneralAttribute.NET_PEER_PORT] = address._port;
1422
}
1523
if (auth?.principal) {
1624
attributes[DatabaseAttribute.DB_USER] = auth.principal;
1725
}
1826
return attributes;
19-
}
27+
}

packages/instrumentation-neo4j/test/neo4j.spec.ts

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,19 +44,21 @@ describe('neo4j instrumentation', function () {
4444
driver = neo4j.driver('bolt://localhost:11011', neo4j.auth.basic('neo4j', 'test'), {
4545
disableLosslessIntegers: true,
4646
});
47-
47+
4848
let keepChecking = true;
49-
const timeoutId = setTimeout(() => { keepChecking = false}, 8000);
49+
const timeoutId = setTimeout(() => {
50+
keepChecking = false;
51+
}, 8000);
5052
while (keepChecking) {
5153
try {
5254
await driver.verifyConnectivity();
5355
clearTimeout(timeoutId);
5456
return;
5557
} catch (err) {
5658
await new Promise((res) => setTimeout(res, 1000));
57-
}
59+
}
5860
}
59-
throw new Error('Could not connect to neo4j in allowed time frame')
61+
throw new Error('Could not connect to neo4j in allowed time frame');
6062
});
6163

6264
after(async () => {
@@ -147,7 +149,7 @@ describe('neo4j instrumentation', function () {
147149

148150
it('when passing "onKeys" and onCompleted, span is closed in onCompleted, and response hook is called', (done) => {
149151
instrumentation.disable();
150-
instrumentation.setConfig({ responseHook: (span) => span.setAttribute('test', 'cool')});
152+
instrumentation.setConfig({ responseHook: (span) => span.setAttribute('test', 'cool') });
151153
instrumentation.enable();
152154

153155
driver
@@ -163,7 +165,7 @@ describe('neo4j instrumentation', function () {
163165
assertSpan(span);
164166
expect(span.attributes['test']).toBe('cool');
165167
done();
166-
}
168+
},
167169
});
168170
});
169171

@@ -465,4 +467,34 @@ describe('neo4j instrumentation', function () {
465467
});
466468
});
467469
});
470+
471+
describe('routing mode', () => {
472+
// When the connection string starts with "neo4j" routing mode is used
473+
let routingDriver: Driver;
474+
const version = require('neo4j-driver/package.json').version;
475+
const shouldCheck = !['4.0.0', '4.0.1', '4.0.2'].includes(version)
476+
477+
before(() => {
478+
if (shouldCheck) {
479+
routingDriver = neo4j.driver('neo4j://localhost:11011', neo4j.auth.basic('neo4j', 'test'));
480+
}
481+
});
482+
483+
after(async () => {
484+
shouldCheck && await routingDriver.close();
485+
});
486+
487+
it('instruments as expected in routing mode', async () => {
488+
if (!shouldCheck) {
489+
// Versions 4.0.0, 4.0.1 and 4.0.2 of neo4j-driver don't allow connection to local neo4j in routing mode.
490+
console.log(`Skipping unsupported test for version ${version}`)
491+
return;
492+
}
493+
494+
await routingDriver.session().run('CREATE (n:MyLabel) RETURN n');
495+
496+
const span = getSingleSpan();
497+
assertSpan(span);
498+
});
499+
});
468500
});

0 commit comments

Comments
 (0)