Skip to content

Commit

Permalink
feat: server sends back proper response
Browse files Browse the repository at this point in the history
* server can now can send the proper response back to the client if it's required.

Closes #13
  • Loading branch information
Bugs5382 committed Dec 17, 2023
1 parent ab30120 commit 681be32
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 41 deletions.
6 changes: 2 additions & 4 deletions __tests__/hl7.server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,8 @@ describe('node hl7 server', () => {
const server = new Server({bindAddress: '0.0.0.0'})
const IB_ADT = server.createInbound({port: LISTEN_PORT}, async (req, res) => {
const messageReq = req.getMessage()
const messageRes = res.getAckMessage()
expect(messageRes.get('MSA.1').toString()).toBe('AA')
expect(messageReq.get('MSH.12').toString()).toBe('2.7')
await res.sendResponse("AA")
})

await sleep(5)
Expand Down Expand Up @@ -257,9 +256,8 @@ describe('node hl7 server', () => {
})
const IB_ADT = server.createInbound({port: LISTEN_PORT}, async (req, res) => {
const messageReq = req.getMessage()
const messageRes = res.getAckMessage()
expect(messageRes.get('MSA.1').toString()).toBe('AA')
expect(messageReq.get('MSH.12').toString()).toBe('2.7')
await res.sendResponse("AA")
})

await sleep(5)
Expand Down
33 changes: 5 additions & 28 deletions src/server/hl7Inbound.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import EventEmitter from 'events'
import net, { Socket } from 'net'
import tls from 'tls'
import { Batch, Message, isBatch, isFile, createHL7Date } from 'node-hl7-client'
import { Batch, Message, isBatch, isFile } from 'node-hl7-client'
import { ListenerOptions, normalizeListenerOptions } from '../utils/normalize.js'
import { InboundRequest } from './modules/inboundRequest.js'
import { Parser } from './modules/parser.js'
Expand Down Expand Up @@ -82,8 +82,8 @@ export class Hl7Inbound extends EventEmitter {
const ipv6 = this._main._opt.ipv6

if (typeof this._main._opt.tls !== 'undefined') {
const {key, cert, requestCert, ca} = this._main._opt.tls
socket = tls.createServer({key, cert, requestCert, ca},socket => this._onTcpClientConnected(socket))
const { key, cert, requestCert, ca } = this._main._opt.tls
socket = tls.createServer({ key, cert, requestCert, ca }, socket => this._onTcpClientConnected(socket))
} else {
socket = net.createServer(socket => this._onTcpClientConnected(socket))
}
Expand Down Expand Up @@ -134,7 +134,7 @@ export class Hl7Inbound extends EventEmitter {
allMessage.forEach((message: Message) => {
const messageParsed = new Message({ text: message.toString() })
const req = new InboundRequest(messageParsed)
const res = new SendResponse(socket, this._createAckMessage(message))
const res = new SendResponse(socket, message)
this._handler(req, res)
})
} else if (isFile(data.toString())) {
Expand All @@ -145,7 +145,7 @@ export class Hl7Inbound extends EventEmitter {
// request
const req = new InboundRequest(parser)
// response
const res = new SendResponse(socket, this._createAckMessage(parser))
const res = new SendResponse(socket, parser)
this._handler(req, res)
}
} catch (err) {
Expand All @@ -166,29 +166,6 @@ export class Hl7Inbound extends EventEmitter {
this.emit('client.connect', socket)
}

/** @internal */
private _createAckMessage (message: Message): Message {
const ackMessage = new Message({
messageHeader: {
msh_9_1: 'ACK',
msh_9_2: message.get('MSH.9.2').toString(),
msh_10: `ACK${createHL7Date(new Date())}`
}
})

ackMessage.set('MSH.3', message.get('MSH.5').toRaw())
ackMessage.set('MSH.4', message.get('MSH.6').toRaw())
ackMessage.set('MSH.5', message.get('MSH.3').toRaw())
ackMessage.set('MSH.6', message.get('MSH.4').toRaw())
ackMessage.set('MSH.11', message.get('MSH.11').toRaw())

const segment = ackMessage.addSegment('MSA')
segment.set('1', 'AA')
segment.set('2', message.get('MSH.10').toString())

return ackMessage
}

/** @internal */
private _closeSocket (socket: Socket): void {
socket.destroy()
Expand Down
72 changes: 64 additions & 8 deletions src/server/modules/sendResponse.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,80 @@
import { Socket } from 'net'
import { Message } from 'node-hl7-client'
import { createHL7Date, Message } from 'node-hl7-client'

/**
* Send Response
* @since 1.0.0
*/
export class SendResponse {
/** @internal */
private readonly _ack: Message
private _ack: Message | undefined
/** @internal */
private readonly _socket: Socket
/** @internal */
private readonly _message: Message
/** @internal */
private _ackSent: boolean

constructor (socket: Socket, ack: Message) {
this._ack = ack
socket.write(Buffer.from(ack.toString()))
constructor (socket: Socket, message: Message) {
this._ack = undefined
this._ackSent = false
this._message = message
this._socket = socket
}

/**
* Get Ack Message Object
* Send Response back to End User
* @since 1.0.0
* @see {@link https://hl7-definition.caristix.com/v2/HL7v2.1/Tables/0008}
* @param type
* @example
* If you are to confirm to the end user (client) that the message they sent was good and processed successfully.
* you would send an "AA" style message (Application Accept).
* Otherwise, send an "AR" (Application Reject) to tell the client the data was
* no accept.ed/processed.
* ```
* const server = new Server({bindAddress: '0.0.0.0'})
* const IB_ADT = server.createInbound({port: LISTEN_PORT}, async (req, res) => {
* const messageReq = req.getMessage()
* await res.sendResponse("AA")
* })
* ```
* "AE" (Application Error) will be sent if there is a problem creating either an "AA" or "AR" message from the orginial message sent.
*/
getAckMessage (): Message {
return this._ack
async sendResponse (type: 'AA' | 'AR'): Promise<boolean> {
try {
this._ack = this._createAckMessage(type, this._message)
this._socket.write(Buffer.from(this._ack.toString()))
} catch (_e: any) {
this._ack = this._createAckMessage('AE', this._message)
this._socket.write(Buffer.from(this._ack.toString()))
}

this._ackSent = true

return this._ackSent
}

/** @internal */
private _createAckMessage (type: string, message: Message): Message {
const ackMessage = new Message({
messageHeader: {
msh_9_1: 'ACK',
msh_9_2: message.get('MSH.9.2').toString(),
msh_10: `ACK${createHL7Date(new Date())}`
}
})

ackMessage.set('MSH.3', message.get('MSH.5').toRaw())
ackMessage.set('MSH.4', message.get('MSH.6').toRaw())
ackMessage.set('MSH.5', message.get('MSH.3').toRaw())
ackMessage.set('MSH.6', message.get('MSH.4').toRaw())
ackMessage.set('MSH.11', message.get('MSH.11').toRaw())

const segment = ackMessage.addSegment('MSA')
segment.set('1', type)
segment.set('2', message.get('MSH.10').toString())

return ackMessage
}
}
2 changes: 1 addition & 1 deletion src/utils/normalize.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { TcpSocketConnectOpts } from 'node:net'
import type { ConnectionOptions as TLSOptions } from 'node:tls'
import {assertNumber, randomString, validIPv4, validIPv6} from 'node-hl7-client'
import { assertNumber, randomString, validIPv4, validIPv6 } from 'node-hl7-client'
import { HL7ListenerError, HL7ServerError } from './exception.js'

const DEFAULT_SERVER_OPTS = {
Expand Down

0 comments on commit 681be32

Please sign in to comment.