Skip to content

Commit

Permalink
fix(db2): capture the correct destination dsn per client
Browse files Browse the repository at this point in the history
This fixes an issue where we would record the wrong dsn when
multiple DB2 clients are in use by an application.

refs 120395
  • Loading branch information
Bastian Krol committed Apr 27, 2023
1 parent eb1f823 commit 9529690
Show file tree
Hide file tree
Showing 4 changed files with 250 additions and 131 deletions.
134 changes: 83 additions & 51 deletions packages/collector/test/tracing/database/db2/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,22 @@

require('../../../..')();

/* eslint-disable no-console */
const { promisify } = require('util');
const bodyParser = require('body-parser');
const express = require('express');
const fs = require('fs');
const morgan = require('morgan');
const ibmdb = require('ibm_db');
const { isCI } = require('@instana/core/test/test_util');
const { delay } = require('@instana/core/test/test_util');

const app = express();
const port = require('../../../test_util/app-port')();
const logPrefix = `DB2 App (${process.pid}):\t`;
const DB2_NAME = process.env.DB2_NAME;
let connStr = 'HOSTNAME=localhost;UID=node;PWD=nodepw;PORT=58885;PROTOCOL=TCPIP';

const DB2_DATABASE_NAME = process.env.DB2_DATABASE_NAME;
const connStr1 = process.env.DB2_CONN_STR || 'HOSTNAME=localhost;UID=node;PWD=nodepw;PORT=58885;PROTOCOL=TCPIP';
const connStr2 =
process.env.DB2_CONN_STR_ALTERNATIVE || 'HOSTNAME=127.0.0.1;UID=node;PWD=nodepw;PORT=58885;PROTOCOL=TCPIP';

/**
* We are unable to start a DB2 container on circleci, because db2 needs privileged permissions.
Expand Down Expand Up @@ -50,16 +53,8 @@ let connStr = 'HOSTNAME=localhost;UID=node;PWD=nodepw;PORT=58885;PROTOCOL=TCPIP'
* That's why we use random names for tables.
*/

if (isCI()) {
connStr = process.env.DB2_CONNECTION_STR;
if (!connStr) {
throw new Error(
'No connection string for IBM DB2, please make sure the environment variable DB2_CONNECTION_STR is set.'
);
}
}

let connection;
let connection2;

const DB2_TABLE_NAME_1 = process.env.DB2_TABLE_NAME_1;
const DB2_TABLE_NAME_2 = process.env.DB2_TABLE_NAME_2;
Expand All @@ -76,46 +71,49 @@ const MAX_TRIES = 10;
const CONNECT_TIMEOUT_IN_MS = 500;
let stmtObjectFromStart;

const connect = () => {
console.log(`trying to connect: ${tries}`);

ibmdb.open(`${connStr};DATABASE=${DB2_NAME}`, function (err, conn) {
if (err) {
console.log(err);
const db2OpenPromisified = promisify(ibmdb.open);

if (tries > MAX_TRIES) {
throw err;
}
async function connect(connectionStr) {
/* eslint-disable no-console */
console.log(`Trying to connect to DB2, attempt ${tries} of ${MAX_TRIES}`);

tries += 1;
return setTimeout(() => {
console.log('Trying again...');
connect();
}, CONNECT_TIMEOUT_IN_MS);
let conn;
try {
conn = await db2OpenPromisified(connectionStr);
} catch (err) {
console.log(err);
if (tries > MAX_TRIES) {
throw err;
}

console.log('Successfully connected.');

conn.querySync(`drop table ${DB2_TABLE_NAME_1} if exists`);

const result = conn.querySync(
`create table ${DB2_TABLE_NAME_1} (COLINT INTEGER, COLDATETIME TIMESTAMP, COLTEXT VARCHAR(255))`
);
tries += 1;
console.log(`Trying to connect to DB2 again in ${CONNECT_TIMEOUT_IN_MS} milliseconds.`);
await delay(CONNECT_TIMEOUT_IN_MS);
return connect(connectionStr);
}
console.log('A client has successfully connected.');
return conn;
/* eslint-enable no-console */
}

if (!(result instanceof Array)) {
throw new Error(result);
}
(async function openConnections() {
/* eslint-disable no-console */
connection = await connect(`${connStr1};DATABASE=${DB2_DATABASE_NAME}`);

conn.prepare(`SELECT * FROM ${DB2_TABLE_NAME_1}`, (prepareErr, stmtObject) => {
if (prepareErr) throw prepareErr;
connection.querySync(`drop table ${DB2_TABLE_NAME_1} if exists`);
const result = connection.querySync(
`create table ${DB2_TABLE_NAME_1} (COLINT INTEGER, COLDATETIME TIMESTAMP, COLTEXT VARCHAR(255))`
);
if (!(result instanceof Array)) {
throw new Error(result);
}
stmtObjectFromStart = connection.prepareSync(`SELECT * FROM ${DB2_TABLE_NAME_1}`);

stmtObjectFromStart = stmtObject;
connection = conn;
});
});
};
connection2 = await connect(`${connStr2};DATABASE=${DB2_DATABASE_NAME}`);

connect();
console.log('Both clients have successfully connected.');
/* eslint-enable no-console */
})();

if (process.env.WITH_STDOUT) {
app.use(morgan(`${logPrefix}:method :url :status`));
Expand All @@ -124,28 +122,35 @@ if (process.env.WITH_STDOUT) {
app.use(bodyParser.json());

app.get('/', (req, res) => {
if (!connection) {
if (!connection || !connection2) {
res.sendStatus(500);
} else {
res.sendStatus(200);
}
});

app.delete('/conn', (req, res) => {
/* eslint-disable no-console */
console.log('deleting conn');

if (!connection) {
return res.sendStatus(200);
if (connection) {
connection.closeSync();
connection = null;
console.log('connection 1 has been closed');
}

connection.closeSync();
connection = null;
console.log('deleted conn');
if (connection2) {
connection2.closeSync();
connection2 = null;
console.log('connection 2 has been closed');
}

res.sendStatus(200);
/* eslint-enable no-console */
});

app.delete('/tables', (req, res) => {
/* eslint-disable no-console */
console.log('deleting tables...');

if (!connection) {
Expand All @@ -159,6 +164,7 @@ app.delete('/tables', (req, res) => {
console.log('deleted tables');

res.sendStatus(200);
/* eslint-enable no-console */
});

app.get('/query-promise', (req, res) => {
Expand Down Expand Up @@ -734,6 +740,32 @@ app.get('/query-stream', (req, res) => {
});
});

app.get('/two-different-target-hosts', async (req, res) => {
if (!connection) {
log('Client 1 is not connected.');
return res.sendStatus(500);
}
if (!connection2) {
log('Client 2 is not connected.');
return res.sendStatus(500);
}

const response = {};
try {
response.data1 = await connection.query('select 1 from sysibm.sysdummy1');
} catch (e) {
log('The first DB2 query failed.', e);
return res.sendStatus(500);
}
try {
response.data2 = await connection2.query("select 'a' from sysibm.sysdummy1");
} catch (e) {
log('The second DB2 query failed.', e);
return res.sendStatus(500);
}
res.json(response);
});

app.listen(port, () => {
log(`Listening on port: ${port}`);
});
Expand Down
Loading

0 comments on commit 9529690

Please sign in to comment.