Skip to content

Commit

Permalink
Added application errors to acknowledgements
Browse files Browse the repository at this point in the history
  • Loading branch information
PantelisGeorgiadis committed Oct 31, 2024
1 parent c19f504 commit 2b756f8
Show file tree
Hide file tree
Showing 10 changed files with 2,007 additions and 902 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:

strategy:
matrix:
node-version: [14.x, 16.x, 18.x, 20.x]
node-version: [16.x, 18.x, 20.x]

steps:
- name: Checkout
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[![NPM version][npm-version-image]][npm-url] [![build][build-image]][build-url] [![MIT License][license-image]][license-url]
[![NPM version][npm-version-image]][npm-url] [![NPM downloads][npm-downloads-image]][npm-url] [![build][build-image]][build-url] [![MIT License][license-image]][license-url]

# hl7-mllp
HL7 Minimum Lower Layer Protocol (MLLP) implementation for Node.js.
Expand Down Expand Up @@ -67,6 +67,7 @@ hl7-mllp is released under the MIT License.

[npm-url]: https://npmjs.org/package/hl7-mllp
[npm-version-image]: https://img.shields.io/npm/v/hl7-mllp.svg?style=flat
[npm-downloads-image]: http://img.shields.io/npm/dm/hl7-mllp.svg?style=flat

[build-url]: https://github.com/PantelisGeorgiadis/hl7-mllp/actions/workflows/build.yml
[build-image]: https://github.com/PantelisGeorgiadis/hl7-mllp/actions/workflows/build.yml/badge.svg?branch=master
Expand Down
9 changes: 9 additions & 0 deletions examples/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"ts-node": {
"compilerOptions": {
"esModuleInterop": true,
"module": "commonjs",
"target": "es2021"
}
}
}
1 change: 1 addition & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ declare class Hl7Message extends AsyncEventEmitter<AsyncEventEmitter.EventMap> {
opts?: {
sendingApplication?: string;
sendingFacility?: string;
error?: string;
}
): Hl7Message;

Expand Down
2,799 changes: 1,921 additions & 878 deletions package-lock.json

Large diffs are not rendered by default.

26 changes: 13 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hl7-mllp",
"version": "0.0.6",
"version": "0.0.7",
"description": "HL7 Minimum Lower Layer Protocol (MLLP) implementation for Node.js",
"main": "build/hl7-mllp.min.js",
"module": "build/hl7-mllp.min.js",
Expand Down Expand Up @@ -41,25 +41,25 @@
"dependencies": {
"async-eventemitter": "^0.2.4",
"moment": "^2.30.1",
"winston": "^3.11.0"
"winston": "^3.15.0"
},
"devDependencies": {
"@types/async-eventemitter": "^0.2.4",
"@types/node": "^20.10.6",
"c8": "^8.0.1",
"chai": "^4.3.8",
"@types/node": "^22.8.5",
"c8": "^9.1.0",
"chai": "^4.3.10",
"docdash": "^2.0.2",
"eslint": "^8.56.0",
"jsdoc": "^4.0.2",
"mocha": "^10.2.0",
"open-cli": "^8.0.0",
"prettier": "^3.1.1",
"eslint": "^8.57.0",
"jsdoc": "^4.0.4",
"mocha": "^10.7.3",
"open-cli": "^7.2.0",
"prettier": "^3.3.3",
"shx": "^0.3.3",
"terser-webpack-plugin": "^5.3.10",
"ts-node": "^10.9.2",
"tsd": "^0.30.2",
"typescript": "^5.3.3",
"webpack": "^5.89.0",
"tsd": "^0.31.2",
"typescript": "^5.6.3",
"webpack": "^5.95.0",
"webpack-cli": "^5.1.4"
}
}
7 changes: 6 additions & 1 deletion src/Hl7.js
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,7 @@ class Hl7Message extends AsyncEventEmitter {
* @param {Object} [opts] - Acknowledge options.
* @param {string} [opts.sendingApplication] - Sending application.
* @param {string} [opts.sendingFacility] - Sending facility.
* @param {string} [opts.error] - Application error.
* @returns {Hl7Message} Acknowledge HL7 message object.
* @throws Error if message is not an instance of Hl7Message.
*/
Expand All @@ -527,6 +528,7 @@ class Hl7Message extends AsyncEventEmitter {
throw new Error('Message should be an instance of Hl7Message');
}
opts = opts || {};
const noError = !opts.error || !opts.error.trim();

const receivingApplication = message.get(new Tag('MSH[0].3'), '');
const receivingFacility = message.get(new Tag('MSH[0].4'), '');
Expand All @@ -540,10 +542,13 @@ class Hl7Message extends AsyncEventEmitter {
ackMessage.set(new Tag('MSH[0].6'), receivingFacility);
ackMessage.set(new Tag('MSH[0].7'), moment(new Date()).format('YYYYMMDDHHmmss'));
ackMessage.set(new Tag('MSH[0].9'), 'ACK');
ackMessage.set(new Tag('MSH[0].10'), messageControlId);
ackMessage.set(new Tag('MSH[0].11'), 'P');
ackMessage.set(new Tag('MSH[0].12'), versionId);

ackMessage.set(new Tag('MSA[0].1'), 'AA');
ackMessage.set(new Tag('MSA[0].1'), noError ? 'AA' : 'AE');
ackMessage.set(new Tag('MSA[0].2'), messageControlId);
ackMessage.set(new Tag('MSA[0].3'), noError ? '' : opts.error);

return ackMessage;
}
Expand Down
9 changes: 7 additions & 2 deletions src/Server.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ class Hl7MessageHandler extends Network {
* @param {function(Hl7Message)} callback - Message acknowledge callback function.
*/
onMessage(message, callback) {
log.error('onMessage method must be implemented');
callback(Hl7Message.createAcknowledgeMessage(message));
const error = 'onMessage method must be implemented';
log.error(error);
callback(Hl7Message.createAcknowledgeMessage(message, { error }));
}
}
//#endregion
Expand Down Expand Up @@ -71,6 +72,10 @@ class Server extends AsyncEventEmitter {
client.on('close', () => {
this.statistics.addFromOtherStatistics(client.getStatistics());
});
client.on('networkError', (err) => {
socket.end();
this.emit('networkError', err);
});
this.clients.push(client);

this.clients = this.clients.filter((item) => item.connected);
Expand Down
2 changes: 1 addition & 1 deletion src/version.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
module.exports = '0.0.6';
module.exports = '0.0.7';
51 changes: 46 additions & 5 deletions test/Network.test.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
const { Hl7Message } = require('./../src/Hl7');
const { Hl7Message, Tag } = require('./../src/Hl7');
const { Hl7MessageHandler, Server } = require('./../src/Server');
const Client = require('./../src/Client');
const log = require('./../src/log');

const chai = require('chai');
const expect = chai.expect;

class TestHl7MessageHandler extends Hl7MessageHandler {
class PositiveAcknowledgementHl7MessageHandler extends Hl7MessageHandler {
constructor(socket, opts) {
super(socket, opts);
}
Expand All @@ -15,6 +15,15 @@ class TestHl7MessageHandler extends Hl7MessageHandler {
}
}

class ApplicationErrorAcknowledgementHl7MessageHandler extends Hl7MessageHandler {
constructor(socket, opts) {
super(socket, opts);
}
onMessage(message, callback) {
callback(Hl7Message.createAcknowledgeMessage(message, { error: 'Error :-(' }));
}
}

describe('Network', () => {
before(() => {
log.level = 'error';
Expand All @@ -37,12 +46,13 @@ describe('Network', () => {
}).to.throw();
});

it('should correctly send an HL7 message and receive an acknowledgement', () => {
const expectedMcId = '1234567890';
it('should correctly send an HL7 message and receive a positive acknowledgement', () => {
const expectedMcId = `${Math.floor(Math.random() * 1000000000)}`;
let ack = false;
let mcId = undefined;
let aa = undefined;

const server = new Server(TestHl7MessageHandler);
const server = new Server(PositiveAcknowledgementHl7MessageHandler);
server.listen(2101);

const client = new Client();
Expand All @@ -53,13 +63,44 @@ describe('Network', () => {
message.on('acknowledge', (m) => {
ack = true;
mcId = m.getMessageControlId();
aa = m.get(new Tag('MSA[0].1'));
});
client.addMessage(message);
client.on('closed', () => {
expect(ack).to.be.true;
expect(mcId).to.be.eq(expectedMcId);
expect(aa).to.be.eq('AA');
server.close();
});
client.send('127.0.0.1', 2101);
});

it('should correctly send an HL7 message and receive an acknowledgement with application error', () => {
const expectedMcId = `${Math.floor(Math.random() * 1000000000)}`;
let ack = false;
let mcId = undefined;
let ae = undefined;

const server = new Server(ApplicationErrorAcknowledgementHl7MessageHandler);
server.listen(2102);

const client = new Client();
const message = new Hl7Message(
`MSH|^~\&|SENDINGAPP|SENDINGFACILITY|RECEIVINGAPP|RECEIVINGFACILITY|200001010000||ADT|${expectedMcId}|D|2.2|
PID||123456^^^2^ID 1|654321||DOE^JOHN^^^^|DOE^JOHN^^^^|19480203|M|`
);
message.on('acknowledge', (m) => {
ack = true;
mcId = m.getMessageControlId();
ae = m.get(new Tag('MSA[0].1'));
});
client.addMessage(message);
client.on('closed', () => {
expect(ack).to.be.true;
expect(mcId).to.be.eq(expectedMcId);
expect(ae).to.be.eq('AE');
server.close();
});
client.send('127.0.0.1', 2102);
});
});

0 comments on commit 2b756f8

Please sign in to comment.