20.04.2014 Views

internship report

internship report

internship report

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

David Vogler<br />

University of Applied Sciences Esslingen<br />

Faculty of Information Technology<br />

Software Technology<br />

Development of a<br />

Pilot Server Gateway Interface<br />

<strong>internship</strong> <strong>report</strong><br />

revision 0.11<br />

September 4, 2000 to February 28, 2001<br />

6th semester, 2nd practical semester<br />

Supervisor:<br />

Michael C. Higgins, Ph.D.<br />

Agilent Laboratories<br />

Medical Department - eDx<br />

3500 Deer Creek Road<br />

Palo Alto, CA 94301-1392


Contents<br />

Contents<br />

i<br />

1 Project Overview 1<br />

1.1 System Overview and Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1<br />

1.2 Project Plan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2<br />

2 Analyze System 4<br />

2.1 System Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4<br />

2.2 Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5<br />

2.3 Context Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6<br />

2.4 Use Cases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6<br />

2.4.1 Use Case Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6<br />

2.4.2 Use Case: Send Test Result Message . . . . . . . . . . . . . . . . . . . . 6<br />

2.4.3 Use Case: Send CA/CE/CR Message . . . . . . . . . . . . . . . . . . . 8<br />

2.4.4 Use Case: Send Application Acknowledgement/Error Message . . . . . . 8<br />

2.4.5 Use Case: Send Acknowledgement Message . . . . . . . . . . . . . . . . 9<br />

2.4.6 Use Case: Update Measurement Transfer Status Table . . . . . . . . . . 9<br />

2.4.7 Use Case: Log System Information . . . . . . . . . . . . . . . . . . . . . 10<br />

2.4.8 Use Case: Check Send Message Thread Timeout . . . . . . . . . . . . . 10<br />

2.4.9 Use Case: Check Pending Messages Thread Timeout . . . . . . . . . . . 11<br />

2.4.10 Use Case: Query Test Result . . . . . . . . . . . . . . . . . . . . . . . . 11<br />

3 Technical Description 13<br />

3.1 Technical Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13<br />

3.2 Nature of Communication Link . . . . . . . . . . . . . . . . . . . . . . . . . . . 14<br />

3.2.1 Physical Connection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14<br />

3.2.2 Network Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14<br />

i


CONTENTS<br />

ii<br />

3.2.3 Communication Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . 14<br />

3.2.4 Socket Connection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14<br />

3.2.5 Pilot Server Gateway Sockets . . . . . . . . . . . . . . . . . . . . . . . . 14<br />

3.2.6 MAS Bridge Behaviour . . . . . . . . . . . . . . . . . . . . . . . . . . . 15<br />

4 Design 16<br />

4.1 Send Message Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16<br />

4.1.1 Send Message Client Data Flow . . . . . . . . . . . . . . . . . . . . . . 16<br />

4.1.2 Send Message Client Sequence . . . . . . . . . . . . . . . . . . . . . . . 17<br />

4.2 Receive Message Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18<br />

4.2.1 Receive Message Server Data Flow . . . . . . . . . . . . . . . . . . . . . 18<br />

4.2.2 Receive Message Server Sequence . . . . . . . . . . . . . . . . . . . . . 18<br />

4.3 Check Pending Messages Thread . . . . . . . . . . . . . . . . . . . . . . . . . . 19<br />

4.3.1 Check Pending Messages Data Flow . . . . . . . . . . . . . . . . . . . . 19<br />

4.3.2 Check Pending Messages Thread Sequence . . . . . . . . . . . . . . . . 19<br />

4.4 Database Modifications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20<br />

5 Implementation 22<br />

5.1 XML Parsers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22<br />

5.2 Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22<br />

5.2.1 Microsoft Visual Source Safe . . . . . . . . . . . . . . . . . . . . . . . . 22<br />

5.2.2 Microsoft SDK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22<br />

5.2.3 Sun JDK 1.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23<br />

5.2.4 Microsoft Visual C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . 23<br />

5.2.5 Cywgin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23<br />

5.2.6 MS SQL Server 7.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23<br />

6 Test Strategy 24<br />

6.1 Gateway Interface Test Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 24<br />

6.2 Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24<br />

6.2.1 Two Strategies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24<br />

6.2.2 Code Execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25<br />

6.2.3 Message Exchange Format . . . . . . . . . . . . . . . . . . . . . . . . . 25<br />

6.2.4 Different Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25<br />

6.3 MAS Test Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25<br />

6.3.1 Response Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25


CONTENTS<br />

iii<br />

6.3.2 Response Times . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26<br />

6.4 Perform a Test Run . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26<br />

6.4.1 Test Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26<br />

6.4.2 Prepare a Test Run . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28<br />

6.4.3 Observation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29<br />

Bibliography 33<br />

List of Figures 34<br />

A Glossery 35<br />

B Package ncv.gatewayif 36<br />

B.1 Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38<br />

B.1.1 Class CheckPendingMessages . . . . . . . . . . . . . . . . . . . . . . 38<br />

B.1.2 Class Config . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40<br />

B.1.3 Class DBSession . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43<br />

B.1.4 Class ErrorMessage . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47<br />

B.1.5 Class ErrorMessageList . . . . . . . . . . . . . . . . . . . . . . . . . . 47<br />

B.1.6 Class GatewayIF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50<br />

B.1.7 Class Logger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52<br />

B.1.8 Class MASTestServer . . . . . . . . . . . . . . . . . . . . . . . . . . . 53<br />

B.1.9 Class MessageList . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55<br />

B.1.10 Class MiscDate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59<br />

B.1.11 Class NotifyByEmail . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59<br />

B.1.12 Class RecvMessage . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60<br />

B.1.13 Class RecvMessageServer . . . . . . . . . . . . . . . . . . . . . . . . . 62<br />

B.1.14 Class SendMessageClient . . . . . . . . . . . . . . . . . . . . . . . . . 64<br />

B.1.15 Class SendMessage . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66<br />

B.1.16 Class Timer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68<br />

B.1.17 Class XMLMessage . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69<br />

C Listings 72<br />

C.1 Java Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72<br />

C.1.1 GatewayIF.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72<br />

C.1.2 CheckPendingMessages.java . . . . . . . . . . . . . . . . . . . . . . . . 73<br />

C.1.3 Config.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78


CONTENTS<br />

iv<br />

C.1.4 DBSession.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83<br />

C.1.5 ErrorMessage.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93<br />

C.1.6 ErrorMessageList.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94<br />

C.1.7 Logger.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94<br />

C.1.8 MASTestServer.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96<br />

C.1.9 MessageList.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102<br />

C.1.10 MiscDate.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103<br />

C.1.11 NotifyByEmail.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105<br />

C.1.12 RecvMessage.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106<br />

C.1.13 RecvMessageServer.java . . . . . . . . . . . . . . . . . . . . . . . . . . . 108<br />

C.1.14 SendMessage.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112<br />

C.1.15 Timer.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121<br />

C.1.16 XMLMessage.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122<br />

C.2 SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125<br />

C.2.1 MeasXferStatus.sql . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125<br />

C.2.2 MeasXferInsertTrigger.sql . . . . . . . . . . . . . . . . . . . . . . . . . . 125<br />

C.3 Configuration Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126<br />

C.3.1 gatewayif.cfg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126<br />

C.3.2 MAS.cfg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127<br />

C.3.3 hl7 v231.dtd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127


Chapter 1<br />

Project Overview<br />

1.1 System Overview and Scope<br />

Figure 1.1: System Overview<br />

Figure 1.1 describes the system Kaiser Permanente Pilot (KPP), a demonstration pilot for a<br />

generalizable approach to the seamless integration of home monitoring data. [1]<br />

This document describes the analysis, design, implementation and test strategy of the gateway<br />

interface, which connects the Pilot Server to the MAS remote gateway.<br />

The main purpose of the gateway interface on the pilot server side is to demonstrate the usage<br />

of the CIC protocol as a format for data exchange in the health care industry.<br />

1


1.2. PROJECT PLAN 2<br />

1.2 Project Plan<br />

The project plan in figure 1.2 is a view of the team’s project plan with only my parts listed. There<br />

are mainly four sections of development:<br />

1. Analyze System: technical analysis of the system behaviour<br />

2. Design: design the system based on the technical analysis<br />

3. Implementation: develop a prototype based on the design<br />

4. Component Integration & Test: integrate the implementation into the project and test the<br />

component<br />

In the analysis phase, the requirements are explained and a requirement analysis is performed. The<br />

requirements are written down in table format. The system design is done based on this analysis<br />

of the system in UML notation, which is the most common notation in software engineering.<br />

The implementation of the system is coded in the Java language, using Sun Microsystem’s Java<br />

Development Toolkit (SDK) Version 1.3. There are small modifications to the Service Manager<br />

on the Pilot Server which spawns all the server services, written in C++.<br />

The component integration integrates the gateway interface into the Pilot Server software build<br />

tree. Therefor, GNU makefiles had to be written to compile the software within the given build<br />

structure.<br />

Finally, the system test is done by testing the component against a remote gateway simulator,<br />

which simulates the behaviour of the MAS remote gateway and the laboratory information system.


1.2. PROJECT PLAN 3<br />

Figure 1.2: Project Plan


Chapter 2<br />

Analyze System<br />

2.1 System Description<br />

The main purpose of the system is to establish a communication link between the Agilent pilot<br />

server and the Sunquest Laboratory Information System (LIS). As the LIS does not understand<br />

the CIC protocol, a bridge is needed. This bridge is represented by the MAS remote gateway.<br />

Agilent’s Pilot Server and the MAS remote gateway communicate simple test results messages<br />

and their acknowledgement messages using the CIC format. Both are exchanging messages as<br />

XML encoded HL7 (Health Level Seven) data.<br />

Figure 2.1: Pilot Server Message Exchange<br />

4


2.2. REQUIREMENTS 5<br />

2.2 Requirements<br />

requirement description<br />

100 The system shall implement the CIC EDI interface to the remote gateway<br />

of the Kaiser Permanente system.<br />

200 All messages that will be transmitted between the data manager and the<br />

Kaiser Permanente system shall be XML encoded.<br />

300 Health Level Seven (HL7) version 2.3.1 [3] defines further information of<br />

the message flow.<br />

400 The system shall send result set messages to the remote gateway after a<br />

configurable period of time.<br />

500 The system shall retransmit undelivered messages after a configurable period<br />

of time.<br />

600 The system shall send an email notification message in a configurable period<br />

of time if a message could not be sent, if there has been an error or reject<br />

acknowledgement by the remote gateway or if the laboratory information<br />

system <strong>report</strong>ed an application error.<br />

700 Definitions of the system such as the email address for the email notification<br />

shall be configurable in a configuration file.<br />

800 The system shall not log the complete messages that are transmitted. Instead,<br />

a separate message transfer status table in the SQL7 database is<br />

used. It shall be possible to reconstruct the original messages with the<br />

information provided by this database table.<br />

900 The reliability of the system is considered very high, which means that in<br />

particular loss of data is unacceptable.<br />

1000 The system shall implement two sockets for the CIC EDI interface, so each<br />

gateway interface is able to send and receive messages at the same time.<br />

1100 The system shall be integrated in the ViridiaServiceManager from the NCV<br />

software like the hub interface, but run as a separate process.<br />

Some of these requirements are derived from David Frey’s gateway analyses [2] for the data<br />

manager gateway interface at an earlier point of the project phase. The requirements of the<br />

gateway interface have changed dramatically since the connection to the laboratory information<br />

system is realized via the MAS remote gateway, so a new system had to be analyzed and designed.


2.3. CONTEXT DIAGRAM 6<br />

2.3 Context Diagram<br />

Figure 2.2 shows the context diagram of the system gateway interface. It describes the terminators<br />

of the system and the data and control flows between them and the system.<br />

Figure 2.2: Context Diagram<br />

2.4 Use Cases<br />

2.4.1 Use Case Diagram<br />

The use case diagram (figure 2.3) is derived from the context diagram. The actors of the use case<br />

diagram are basically the terminators of the context diagram, the data and control flows of the<br />

context diagram are the identified use cases.<br />

2.4.2 Use Case: Send Test Result Message<br />

initiator:<br />

data manager<br />

involved actors:


2.4. USE CASES 7<br />

Figure 2.3: Use Case Diagram<br />

ˆ SQL7 database<br />

ˆ remote gateway interface<br />

included use case:<br />

ˆ update measurement transfer status table<br />

ˆ log system information<br />

pre-conditions: none<br />

basic flow of events:<br />

The data manager wants to send a test result message to the remote gateway interface. The<br />

data manager has to query the SQL7 database for unsent test results, generate an HL7 message<br />

embedded in XML and establish a socket connection to the remote gateway interface.<br />

After sending the message, the data manager waits for a configurable period of time to receive an<br />

acknowledgement message from the remote gateway interface during the same socket connection.<br />

After successfully receiving the acknowledgement message, type and timestamp of this message<br />

are logged in the measurement status transfer database table and the socket connection will be<br />

closed.<br />

post-conditions: none<br />

alternatives: none


2.4. USE CASES 8<br />

2.4.3 Use Case: Send CA/CE/CR Message<br />

initiator:<br />

remote gateway interface<br />

involved actors:<br />

ˆ data manager<br />

ˆ SQL7 database<br />

included use cases:<br />

ˆ update measurement transfer status table<br />

ˆ log system information<br />

pre-conditions: none<br />

basic flow of events:<br />

The remote gateway interface parses and validates the incoming XML embedded HL7 message.<br />

It generates a Commit Accept, Commit Error or Commit Reject XML message depending on the<br />

validation information and sends it back to the data manager during the same socket connection<br />

session.<br />

The data manager receives the acknowledgement message and updates the timestamp and flag<br />

information in the measurement transfer status table depending on the received message type.<br />

post-conditions: none<br />

alternatives: none<br />

2.4.4 Use Case: Send Application Acknowledgement/Error Message<br />

initiator:<br />

laboratory information system<br />

involved actors:<br />

ˆ remote gateway interface<br />

ˆ data manager<br />

ˆ SQL7 database<br />

included use cases:<br />

ˆ update measurement transfer status table<br />

ˆ log system information


2.4. USE CASES 9<br />

pre-conditions: none<br />

basic flow of events:<br />

The laboratory information system (LIS) validates incoming test result messages by examinating<br />

the content of the message. It then generates an application acknowledgement or application<br />

error message and sends it back to the data manager through the remote gateway interface.<br />

post-conditions: none<br />

alternatives: none<br />

2.4.5 Use Case: Send Acknowledgement Message<br />

initiator:<br />

data manager<br />

involved actors:<br />

ˆ remote gateway interface<br />

ˆ laboratory information system<br />

included use cases:<br />

ˆ update measurement transfer status table<br />

ˆ log system information<br />

pre-conditions: none<br />

basic flow of events:<br />

The remote gateway interface transports the test result message to the laboratory information<br />

system (LIS). The laboratory information system has to validate the message and sends back<br />

an Application Acknowledgement (AA) or Application Error (AE) message through the remote<br />

gateway interface.<br />

The data manager listens on a socket for these incoming AA or AE messages, which are not time<br />

critical, and has to respond to them with an acknowledgement message.<br />

post-conditions: none<br />

alternatives: none<br />

2.4.6 Use Case: Update Measurement Transfer Status Table<br />

initiator:<br />

data manager<br />

involved actors:<br />

ˆ SQL7 database


2.4. USE CASES 10<br />

included use cases: none<br />

pre-conditions: none<br />

basic flow of events:<br />

The measurement transfer status table provides all necessary information to track the status of a<br />

test result message. Therefor each time a message has been sent or an acknowledgement message<br />

has been received, the measurement transfer status table will be updated with flag and timestamp<br />

information. If there has been an error acknowledgement, a comment that describes the kind of<br />

the error will be inserted.<br />

post-conditions: none<br />

alternatives: none<br />

2.4.7 Use Case: Log System Information<br />

initiator:<br />

data manager<br />

involved actors:<br />

ˆ remote gateway interface<br />

ˆ laboratory information system<br />

ˆ SQL7 database<br />

included use cases: none<br />

pre-conditions: none<br />

basic flow of events:<br />

The log system information use case will provide the possibility to track all important status and<br />

error information in a log file. Each part of the system has to write detailed information in the<br />

log file if an exception occured in order to make it possible to fix the problem.<br />

The log file will also include the information that a message has been sent or received successfully.<br />

post-conditions: none<br />

alternatives: none<br />

2.4.8 Use Case: Check Send Message Thread Timeout<br />

initiator:<br />

data manager<br />

involved actors: none<br />

included use cases: none<br />

pre-conditions: none<br />

basic flow of events:


2.4. USE CASES 11<br />

The system gateway interface checks the measurement transfer status table after a configurable<br />

period of time for new measurements to be send to the laboratory information system through<br />

the remote gateway interface.<br />

This will be realized by setting the send message thread asleep for the configured period of time<br />

and then call the send message routine.<br />

post-conditions: none<br />

alternatives: none<br />

2.4.9 Use Case: Check Pending Messages Thread Timeout<br />

initiator:<br />

data manager<br />

involved actors: none<br />

included use cases: none<br />

pre-conditions: none<br />

basic flow of events:<br />

The system gateway interface checks the measurement transfer status database table after a<br />

configurable period of time for pending and for error messages.<br />

If pending or error messages are found, an entry in the system log file will be written and an email<br />

notification message will be send to a configurable recipient.<br />

post-conditions: none<br />

alternatives: none<br />

2.4.10 Use Case: Query Test Result<br />

initiator:<br />

SQL7 database<br />

involved actors:<br />

ˆ data manager<br />

included use cases:<br />

ˆ update measurement transfer status table<br />

ˆ log system information<br />

pre-conditions: none<br />

basic flow of events:<br />

This use case provides the system gateway interface with all necessary test result set data.


2.4. USE CASES 12<br />

Lists of test result messages, pending messages and error messages gathered with a query of the<br />

SQL7 database will be provided for the system.<br />

post-conditions: none<br />

alternatives: none


Chapter 3<br />

Technical Description<br />

3.1 Technical Overview<br />

Figure 3.1 gives an overview of the physical realization of the pilot server. The pilot server will be<br />

placed in a closed server room, secure from unauthorized access.<br />

Figure 3.1: Physical Overview of the Pilot<br />

The communication between the Sunquest laboratory information system (LIS) will be realized<br />

indirectly through the MAS remote gateway. Both, the MAS bridge and the LIS server are inside<br />

the Kaiser intranet. This section will describe the nature of the communication and data flow<br />

between the pilot server gateway interface and the MAS bridge.<br />

13


3.2. NATURE OF COMMUNICATION LINK 14<br />

3.2 Nature of Communication Link<br />

3.2.1 Physical Connection<br />

The pilot server will not be placed within the Kaiser intranet, so it will be connected via a dedicated<br />

line to the MAS bridge.<br />

3.2.2 Network Protocol<br />

The communication in the lower levels of the ISO OSI layer model will be handled with a TCP/IP<br />

connection over the dedicated line.<br />

3.2.3 Communication Protocol<br />

The pilot server gateway interface and the MAS bridge will send and receive XML encoded Health<br />

Level Seven (HL7 version 2.3.1) messages.<br />

3.2.4 Socket Connection<br />

The MAS bridge and the pilot server will communicate over a TCP/IP socket connection. Two<br />

sockets will be placed on each side.<br />

Connect pilot server gateway interface<br />

MAS bridge<br />

Sunquest LIS<br />

Sessions<br />

1 port #5000: send XML port #5000: receive<br />

encoded HL7 ORM O01 ORM O01, send ACK<br />

message to MAS port CA/CE/CR back during<br />

#5000<br />

this socket connection.<br />

Close socket connection.<br />

2 1 send result set to LIS receive result set,<br />

generate AA/AE<br />

messages.<br />

3 port #5001: wait for Generate XML encoded<br />

Application Acknowledgement<br />

AA/AE message.<br />

(AA).<br />

port #5001: receive Send AA/AE XML message<br />

AA/AE XML message,<br />

to port #5001. Re-<br />

send acknowledgement. ceive acknowledgement<br />

Close socket connection. message. Close socket<br />

connection.<br />

3.2.5 Pilot Server Gateway Sockets<br />

The gateway interface is seen from the outside as two threads:<br />

1 not included in the pilot server gateway interface application


3.2. NATURE OF COMMUNICATION LINK 15<br />

ˆ Thread one listens on port #5001 for incoming messages from the MAS bridge. The MAS<br />

gateway opens a socket connection to port #5001, sends its AA/AE message and closes the<br />

socket connection. The gateway interface closes the socket and re-opens it for listening.<br />

ˆ Thread two waits for new measurements received by the pilot server to be transmitted<br />

through the MAS bridge on port #5000, sends one ORM O01 result set, then waits for a<br />

CA, CE or CR acknowledgement message from MAS and sends the next message after that<br />

until there are no more result sets in the message list to be transmitted.<br />

3.2.6 MAS Bridge Behaviour<br />

The MAS bridge receives the ORM O01 result set messages from the pilot server gateway interface,<br />

generates a CA, CE or CR XML message and sends it during the same session to the pilot server.<br />

After passing the result set to the LIS it gets an Application Acknowledgement (AA) or Application<br />

Error (AE) back from LIS.<br />

This AA or AE message will be passed to the data manager via a new socket connection. MAS<br />

opens a connection to the pilot server on port #5001 and submits the XML encoded message.


Chapter 4<br />

Design<br />

4.1 Send Message Client<br />

4.1.1 Send Message Client Data Flow<br />

Figure 4.1: Send Message Data Flow<br />

When the Send Message Client thread starts, it queries the SQL7 database for new test results<br />

and the gateway interface receives the test results as arrays from the database. It generates XML<br />

objects out of it, opens a socket connction to the remote gateway interface and sends the list of<br />

unsent messages (one by one) to the MAS gateway.<br />

In the same session the gateway interface receives acknowledgement messages from the remote<br />

16


4.1. SEND MESSAGE CLIENT 17<br />

gateway interface and updates the timestamp and flag fields in the SQL7 database.<br />

4.1.2 Send Message Client Sequence<br />

Figure 4.2 shows the sequence diagram of the send message client thread. The send message<br />

client thread will be created by the data manager. It waits for a configurable period of time until<br />

it starts querying the database for new arrived test results. The query is done by the DBSession<br />

object, which creates a list of XML messages represented by the Send Message List Object. The<br />

message objects will be represented by the DOM document model implemented in the DOM<br />

Parser Xerces (Java Version).<br />

The SendMessage class provides a method for converting the DOM object into a string and sends<br />

this string to the remote gateway interface.<br />

Figure 4.2: Send Message Sequence Diagram


4.2. RECEIVE MESSAGE SERVER 18<br />

4.2 Receive Message Server<br />

4.2.1 Receive Message Server Data Flow<br />

Figure 4.3: Receive Message Data Flow<br />

The receive message server will be started as a thread by the datamanager and listen to a socket for<br />

incoming socket connections from the remote gateway interface. It will be designed for receiving<br />

and validating information sent from the LIS through the remote gateway to the data manager.<br />

When a socket connection has been established, the receive message server parses the incoming<br />

XML message with the DOM parser Xerces, extracts the acknowledgement type and message ID<br />

and updates the timestamp and flag information in the Measurement Transfer Status table in the<br />

SQL7 database.<br />

After having successfully received the acknowledgement message it will close the socket connection<br />

and wait for the next imcoming socket connection request.<br />

4.2.2 Receive Message Server Sequence<br />

The data manager creates the receive message thread, which will wait for incoming socket connections.<br />

When the socket connection has been established, the receive message server will read the<br />

incoming byte stream and send it to the receive message class, which will create a DOM object<br />

with the DOM parser Xerces out of it. The ReceiveMessage class provides methods to access the<br />

relevant data out of the document object model. This data will be send to the DBSession class,<br />

which provides all the methods for accessing the SQL7 database.


4.3. CHECK PENDING MESSAGES THREAD 19<br />

Figure 4.4: Receive Message Sequence Diagram<br />

4.3 Check Pending Messages Thread<br />

4.3.1 Check Pending Messages Data Flow<br />

The Check Pending Messages thread will be created by the data manager. It will be set asleep<br />

for a configurable period of time. When it starts, it sends a query to the SQL7 database that<br />

queries for messages with errors and messages for which now acknowledgement messages have<br />

been received within a configurable amount of time.<br />

These messages will be stored into a error message list out of which an email notification message<br />

will be generated and send to a configurable email address.<br />

4.3.2 Check Pending Messages Thread Sequence<br />

The check pending message thread calls the DBSession class which returns error message objects<br />

that will be inserted into a error message linked list.<br />

JavaMail provides methods for sending emails through a SMTP server - this package will be used<br />

to send the email message generated out of the information the error message list provides.


4.4. DATABASE MODIFICATIONS 20<br />

Figure 4.5: Check Pending Messages Data Flow<br />

4.4 Database Modifications<br />

For keeping track of the current status of the messages, a new database table has to be inserted<br />

into the existing database model as shown in figure 4.7.<br />

The system gateway interface stores all information about the current message status in this<br />

table. New measurements are recognized by querying the database table for measurement IDs<br />

with no timestamp or flag values (NULL values). These new measurement IDs are inserted into<br />

the Measurement Transfer Status table by using a trigger in the SQL7 database that inserts a<br />

MeasID into this table each time a new insert entry is made into the Measurement table.


4.4. DATABASE MODIFICATIONS 21<br />

Figure 4.6: Check Pending Messages Sequence Diagram<br />

Figure 4.7: Database Modifications


Chapter 5<br />

Implementation<br />

5.1 XML Parsers<br />

The XML parser sits in the middle between an XML document and an application that uses it.<br />

There are two different types of parsers available, SAX and DOM parsers. In order to process a<br />

document, you need to read from an input source that delivers the message’s content. To analyze<br />

this document, the parser provides access in two ways (as described in [7]):<br />

ˆ It builds an internal representation of the document, a tree of nodes. The parser then gets<br />

out of the way and the application works with the internal representation (the DOM way).<br />

ˆ It provides access to the tokes as they are encountered in a pass through the document,<br />

without constructing an internal representation of the document (the SAX way).<br />

We decided to take the DOM parser for our pilot server. The DOM model has the advantage of<br />

allowing random access to the document parsed, which is useful when fields are optional as in the<br />

CIC protocol. DOM on the other side requires more memory, but this will not be a concern with<br />

the small size of the CIC EDI message.<br />

We are using the DOM parser Xerces from the Apache project as it is freely available and we use<br />

the getElementsByTagName() method to extract the node values.<br />

5.2 Tools<br />

5.2.1 Microsoft Visual Source Safe<br />

MS Visual Source Safe is used for configuration management of source code files.<br />

5.2.2 Microsoft SDK<br />

This is Microsoft’s propriatary version of Sun’s Java Developer’s Kit. It uses the Microsoft Java<br />

compiler (JVC) and Microsoft’s Virtual Machine at run time for the classes compiled with MS<br />

SDK.<br />

22


5.2. TOOLS 23<br />

5.2.3 Sun JDK 1.3<br />

JDK 1.3 contains the software and tools that are needed to compile, debug, run and document<br />

(javadoc) applications written in the Java programming language. It includes the Java Runtime<br />

Environment (JRE) 1.3.<br />

5.2.4 Microsoft Visual C++<br />

MS Visual C++ is needed to compile the Viridia Service Manager application which spawns all<br />

the services like the gateway interface and provides methods for the application log.<br />

5.2.5 Cywgin<br />

Cygwin allows to run GNU software like the Make utility to be run on a Windows NT platfrom as<br />

used in this project. We use GNU make to generate all our binaries.<br />

5.2.6 MS SQL Server 7.0<br />

The back end server database will be a MS SQL Server Version 7.0. The database will be used<br />

to store devices, logging and patient data.


Chapter 6<br />

Test Strategy<br />

6.1 Gateway Interface Test Overview<br />

Figure 6.1 gives an overview of the physical realization of the Pilot Server Gateway Interface test<br />

environment.<br />

Figure 6.1: Physical Test Overview<br />

Messages will be exchanged between the pilot server and the MAS bridge and between the MAS<br />

bridge and the Sunquest Laboratory Information System (LIS).<br />

6.2 Tests<br />

6.2.1 Two Strategies<br />

The Pilot Server Gateway Interface will be tested with two strategies: one will cover the requirement<br />

that all parts of the code will be executed at some time, the other one will be a MAS bridge<br />

24


6.3. MAS TEST SERVER 25<br />

simulator, called the MAS Test Server.<br />

6.2.2 Code Execution<br />

In order to make sure that any part of the code is executed at some time, there will be a simple<br />

System.out.println("..."); statement in each branch of the code, i.e. switch...case-,<br />

if...then...else-, while- and conditional-statements.<br />

These statements will be removed or commented out after the test phase.<br />

6.2.3 Message Exchange Format<br />

The MAS bridge and the Pilot Server Gateway Interface (GatewayIF) exchange HL7 messages<br />

embedded in XML format. To make sure that the XML messages are in a proper format, the<br />

DOM parser Xerces in combination with an HL7 Document Type Definition (DTD) file will be<br />

used for message generation and message parsing. The Xerces document creater throws exceptions<br />

when the received message is in a wrong format or does not apply to the DTD.<br />

6.2.4 Different Messages<br />

There are six kinds of different messages in the whole message exchange process possible.<br />

type description<br />

ORM O01 Result Set (measurement)<br />

ORR O02 Application Acknowledgement (AA), MSA.1 = AA<br />

ORR O02 Application Error (AE), MSA.1 = AE, MSA.3 = error comment<br />

ACK Commit Accept (CA), MSA.1 = CA<br />

ACK Commit Accept (CE), MSA.1 = CA, MSA.3 = error comment<br />

ACK Commit Accept (CR), MSA.1 = CA, MSA.3 = reject comment<br />

All of these messages have to be generated and validated by the test environment.<br />

6.3 MAS Test Server<br />

The MAS Test Server is the counterpart to the Gateway Interface. It will - like its name implies -<br />

simulate the MAS bridge and its behaviour.<br />

6.3.1 Response Messages<br />

There are several flows of data possible:


6.4. PERFORM A TEST RUN 26<br />

normal flow of data<br />

error flow one<br />

error flow two<br />

error flow three<br />

GatewayIF sends ORM O01, MAS responds with CA, later LIS<br />

reponds with AA<br />

GatewayIF sends ORM O01, MAS responds with CE, no response<br />

from LIS<br />

GatewayIF sends ORM O01, MAS responds with CR, no response<br />

from LIS<br />

GatewayIF sends ORM O01, MAS responds with CA, later LIS<br />

reponds with AE<br />

6.3.2 Response Times<br />

In addition to the possible response message types it’s possible that messages will not be received<br />

within a certain (configurable) period of time.<br />

LIS Messages<br />

Messages from LIS (AA and AE) are not time critical, the system is able to handle these messages<br />

at any time.<br />

MAS Messages<br />

Messages from MAS (CA, CE and CR) are time critical. The Gateway Interface is only able to<br />

handle these messages within one socket session. If the connection to MAS drops down or the ACK<br />

message is not received within the configured period of time, there will be no timeStampRcvd<br />

update in the database table MeasXferStatus and no flags will be set in the database.<br />

These errors will be identified by the CheckPendingMessages thread and an email notification<br />

will be send to the responsible case worker or the system administrator (configurable).<br />

6.4 Perform a Test Run<br />

6.4.1 Test Environment<br />

Hardware requirements to perform a test<br />

The test environment has mainly four parts:<br />

ˆ Personal computer on which the MAS Test Server runs<br />

ˆ Personal computer on which the Pilot Server Gateway Interface runs<br />

ˆ MS SQL7 database server<br />

ˆ Internet connection (here: Agilent Labs 10MBit/s Ethernet)<br />

It is also possible to run all the software including the SQL7 database server on one single machine<br />

without the need of an Ethernet connection.


6.4. PERFORM A TEST RUN 27<br />

Figure 6.2: Test Environment Overview<br />

Software used for test observation<br />

There are several possibilities to make it possible to ”see” what is transmitted over the Ethernet<br />

connection. In this test environment some open source tools and software that comes with the<br />

operating system are used to display the communication:<br />

ˆ Notebook side (Pilot Server Gateway Interface):<br />

– sniffit (network packet sniffer) for outgoing XML messages<br />

– ethereal (Ethernet network analyzer) for incoming XML messages<br />

– xterm to see the System.out.println output of the interface<br />

– tail -f gatewayif.log to watch the log file<br />

– sendmail as mailserver to deliver status <strong>report</strong> messages<br />

– pine to read the generated status <strong>report</strong> messages<br />

ˆ Desktop side (MAS Test Server):<br />

– Cygwin shell to see the System.out.println output of the test server<br />

– MS SQL Enterprise Manager to watch the database activities<br />

– MS SQL Query Analyzer to reset the database with initial values


6.4. PERFORM A TEST RUN 28<br />

6.4.2 Prepare a Test Run<br />

Configure test behaviour<br />

Set the test cases in the file MAS.cfg. Each line describes one test case:<br />

AA send CA, later AA<br />

AE send CA, later AE<br />

00 send CA with timeout, later AA<br />

CA send CA, no AA/AE<br />

CE send CE<br />

CR send CR<br />

Prepare database table<br />

To reset the values of the MeasXferStatus table set all fields to except the MeasID row:<br />

Figure 6.3: Reset database table with SQL7 query analyzer<br />

MAS Test Server<br />

Start the MAS Test Server with the command:<br />

java ncv.gatewayif.MASTestServer<br />

Pilot Server Gateway Interface<br />

Start the Pilot Server Gateway Interface with the command:<br />

java ncv.gatewayif.GatewayIF gatewayif.cfg


6.4. PERFORM A TEST RUN 29<br />

6.4.3 Observation<br />

SQL7 Enterprise Manager<br />

Update the MeasXferStatus table view (”!”) to see which fields have been changed and to which<br />

values.<br />

Figure 6.4: SQL7 Enterprise Manager<br />

Examine outgoing XML messages with sniffit<br />

Sniffit makes it possible to listen to ports on the system it is started on. Each connection will be<br />

logged into a separate file. The filename consists of two IP addresses and the ports that habe<br />

been used for the transmission.<br />

Examine incoming XML messages with ethereal<br />

Start the ethereal application as root and select option ”start capture”. Click on the ”source”<br />

and ”destination” buttons to search for the wanted packets.<br />

Watch Gateway Interface system output in xterm<br />

Watch log file on Pilot Server Gateway Interface computer<br />

Watch MAS Test Server output in cygwin shell


6.4. PERFORM A TEST RUN 30<br />

Figure 6.5: sniffit network packet sniffer<br />

Figure 6.6: Ethereal network analyzer


6.4. PERFORM A TEST RUN 31<br />

Figure 6.7: Gateway Interface output in xterm<br />

Figure 6.8: Gateway Interface log file


6.4. PERFORM A TEST RUN 32<br />

Figure 6.9: MAS Test Server output in cygwin shell


Bibliography<br />

[1] Michael Higgins. Demonstration Pilot Proposal - Connectivity for Home Monitoring of Prothrombin<br />

Time. Agilent Technologies, CA, 2000.<br />

[2] David Frey. Gateway Analysis. Agilent Technologies, CA, 2000.<br />

[3] Health Level Seven. Health Level Seven Standard Version 2.3.1. Health Level Seven, April<br />

2000.<br />

[4] Ivor Horton. Beginning Java 2. Birmingham, UK, 1999. Wrox Press Ltd.<br />

[5] David Flanagan. Java in a nutshell. Sebastopol, CA, 1999. O’Reilly & Associates, Inc.<br />

[6] Alexander Nakhimovsky and Tom Myers. Professional Java XML Programming. Birmingham,<br />

UK, 1999. Wrox Press Ltd.<br />

[7] Brett McLaughlin. Java and XML. Sebastopol, CA, 2000. O’Reilly & Associates, Inc.<br />

[8] Tom DeMarco, Structured Analysis and System Specification. Englewood Cliffs, NJ, 1979.<br />

Prentice Hall.<br />

[9] Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides. Design Patterns. Reading, MA,<br />

1995. Addison-Wesley Publishing Company, Inc.<br />

[10] Pierre-Alain Muller. Instant UML. Birmingham, UK, 1997. Wrox Press Ltd.<br />

[11] Rational Software Corporation. Using Rational Rose. Revision 7.0, March 2000.<br />

33


List of Figures<br />

1.1 System Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1<br />

1.2 Project Plan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3<br />

2.1 Pilot Server Message Exchange . . . . . . . . . . . . . . . . . . . . . . . . . . . 4<br />

2.2 Context Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6<br />

2.3 Use Case Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7<br />

3.1 Physical Overview of the Pilot . . . . . . . . . . . . . . . . . . . . . . . . . . . 13<br />

4.1 Send Message Data Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16<br />

4.2 Send Message Sequence Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . 17<br />

4.3 Receive Message Data Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18<br />

4.4 Receive Message Sequence Diagram . . . . . . . . . . . . . . . . . . . . . . . . 19<br />

4.5 Check Pending Messages Data Flow . . . . . . . . . . . . . . . . . . . . . . . . 20<br />

4.6 Check Pending Messages Sequence Diagram . . . . . . . . . . . . . . . . . . . . 21<br />

4.7 Database Modifications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21<br />

6.1 Physical Test Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24<br />

6.2 Test Environment Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27<br />

6.3 Reset database table with SQL7 query analyzer . . . . . . . . . . . . . . . . . . 28<br />

6.4 SQL7 Enterprise Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29<br />

6.5 sniffit network packet sniffer . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30<br />

6.6 Ethereal network analyzer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30<br />

6.7 Gateway Interface output in xterm . . . . . . . . . . . . . . . . . . . . . . . . . 31<br />

6.8 Gateway Interface log file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31<br />

6.9 MAS Test Server output in cygwin shell . . . . . . . . . . . . . . . . . . . . . . 32<br />

34


Appendix A<br />

Glossery<br />

CIC<br />

EDI<br />

HL7<br />

KPP<br />

LIS<br />

NCV<br />

SQL<br />

STR<br />

XML<br />

Connectivity Industry Consortium<br />

Electronic Data Interchange<br />

Health Level Seven<br />

Kaiser Permanente Pilot<br />

Laboratory Information System<br />

New Clinical Venture<br />

Structured Query Language<br />

Simple Test Result<br />

Extensible Markup Language<br />

35


Appendix B<br />

Package ncv.gatewayif<br />

Package Contents<br />

Page<br />

Classes<br />

CheckPendingMessages. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .38<br />

This class looks in the MeasXferTable in the Pilot Server database for pending<br />

messages and error messages.<br />

Config . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40<br />

This class provides methods to read configurable values out of a configuration<br />

file.<br />

DBSession . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43<br />

This class provides all the database functionality.<br />

ErrorMessage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47<br />

This class represents an error message object used by the class CheckPendingMessages<br />

ErrorMessageList . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47<br />

This class is used by the CheckPendingMessages class to generate a list of<br />

ErrorMessages<br />

GatewayIF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50<br />

This class spawns the threads SendMessageClient, RemoteMessageServer and<br />

CheckPendingMessages.<br />

Logger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52<br />

This class is intended to log errors and other useful information to an ASCII text<br />

file<br />

MASTestServer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53<br />

Simulation of the MAS Gateway Interface and Sunquest’s Laboratory Information<br />

System (LIS)<br />

MessageList . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55<br />

This class is used by the SendMessageClient class to generate a linked list of<br />

XMLMessages to be send to the MAS remote gateway<br />

MiscDate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59<br />

This class is used to get general time and date information and to compute time<br />

differences.<br />

NotifyByEmail . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59<br />

36


APPENDIX B. PACKAGE NCV.GATEWAYIF 37<br />

...no description...<br />

RecvMessage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60<br />

This class provides the methods for accessing an incoming (reveived) message<br />

RecvMessageServer. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .62<br />

This class provides the methods for receiving incoming LIS AA and AE messages<br />

send through the MAS remote gateway.<br />

SendMessageClient . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64<br />

This class provides the basic functionality of the application, it gets a list of<br />

messages to be send, opens a socket connection to the MAS remote gateway,<br />

sends all the messages and receives CA/CE/CR message acknowledgement from<br />

the remote gateway.<br />

SendMessage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66<br />

This class provides the methods for accessing an outgoing (to be send) message<br />

Timer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68<br />

...no description...<br />

XMLMessage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69<br />

...no description...


B.1. CLASSES 38<br />

B.1 Classes<br />

B.1.1<br />

Class CheckPendingMessages<br />

This class looks in the MeasXferTable in the Pilot Server database for pending messages and error<br />

messages. If error and/or pending messages are found, an email notification will be generated and sent.<br />

Declaration<br />

public class CheckPendingMessages<br />

extends java.lang.Thread<br />

Constructors<br />

ˆ CheckPendingMessages<br />

public CheckPendingMessages( java.lang.String configFileName )<br />

– Usage<br />

* Default Constructor. Reads configFileName to set values.<br />

Methods<br />

ˆ run<br />

public void run( )<br />

– Usage<br />

* This method checks the database for CE/CR/AE and pending ACK messages<br />

from MAS and LIS. It runs permanently but sleeps for sleepTimer milliseconds.<br />

ˆ SendMail<br />

public void SendMail( java.lang.String msgText )<br />

– Usage<br />

* Send email with content of parameter msgText to configured receipient.<br />

Methods inherited from class java.lang.Thread<br />

ˆ activeCount<br />

public static int activeCount( )<br />

ˆ checkAccess<br />

public final void checkAccess( )<br />

ˆ countStackFrames<br />

public native int countStackFrames( )


B.1. CLASSES 39<br />

ˆ currentThread<br />

public static native Thread currentThread( )<br />

ˆ destroy<br />

public void destroy( )<br />

ˆ dumpStack<br />

public static void dumpStack( )<br />

ˆ enumerate<br />

public static int enumerate( java.lang.Thread [] )<br />

ˆ getContextClassLoader<br />

public ClassLoader getContextClassLoader( )<br />

ˆ getName<br />

public final String getName( )<br />

ˆ getPriority<br />

public final int getPriority( )<br />

ˆ getThreadGroup<br />

public final ThreadGroup getThreadGroup( )<br />

ˆ interrupt<br />

public void interrupt( )<br />

ˆ interrupted<br />

public static boolean interrupted( )<br />

ˆ isAlive<br />

public final native boolean isAlive( )<br />

ˆ isDaemon<br />

public final boolean isDaemon( )<br />

ˆ isInterrupted<br />

public boolean isInterrupted( )<br />

ˆ join<br />

public final void join( )<br />

ˆ join<br />

public final synchronized void join( long )<br />

ˆ join<br />

public final synchronized void join( long , int )<br />

ˆ resume<br />

public final void resume( )<br />

ˆ run<br />

public void run( )<br />

ˆ setContextClassLoader<br />

public void setContextClassLoader( java.lang.ClassLoader )<br />

ˆ setDaemon<br />

public final void setDaemon( boolean )<br />

ˆ setName<br />

public final void setName( java.lang.String )<br />

ˆ setPriority<br />

public final void setPriority( int )<br />

ˆ sleep<br />

public static native void sleep( long )<br />

ˆ sleep<br />

public static void sleep( long , int )<br />

ˆ start<br />

public native synchronized void start( )<br />

ˆ stop<br />

public final void stop( )


B.1. CLASSES 40<br />

ˆ stop<br />

public final synchronized void stop( java.lang.Throwable )<br />

ˆ suspend<br />

public final void suspend( )<br />

ˆ toString<br />

public String toString( )<br />

ˆ yield<br />

public static native void yield( )<br />

B.1.2<br />

Class Config<br />

This class provides methods to read configurable values out of a configuration file.<br />

Declaration<br />

public class Config<br />

extends java.lang.Object<br />

Constructors<br />

ˆ Config<br />

public Config( java.lang.String filename )<br />

– Usage<br />

* Constructor needs the filename of the configuration file as parameter<br />

Methods<br />

ˆ getACKTimeOut<br />

public static long getACKTimeOut( )<br />

– Usage<br />

* returns the timeout for acknowledgement messages. After this time the socket<br />

connection will be shut down.<br />

ˆ getCICInPort<br />

public static int getCICInPort( )<br />

– Usage<br />

* returns port number on pilot server side for incoming XML messages<br />

ˆ getCICOutPort<br />

public static int getCICOutPort( )<br />

– Usage


B.1. CLASSES 41<br />

* returns port number on remote gateway for outgoing XML messages<br />

ˆ getConfigFileName<br />

public static String getConfigFileName( )<br />

– Usage<br />

* returns the path and filename for the configuration file<br />

ˆ getCPMTimeOut<br />

public static long getCPMTimeOut( )<br />

– Usage<br />

* returns the sleeptimer for the CheckPendingMessages thread. After one run, the<br />

thread will be set asleep for this amount of time.<br />

ˆ getdbDriver<br />

public static String getdbDriver( )<br />

– Usage<br />

* returns the name for the database driver<br />

ˆ getdbName<br />

public static String getdbName( )<br />

– Usage<br />

* returns the database name<br />

ˆ getdbPassword<br />

public static String getdbPassword( )<br />

– Usage<br />

* returns the password for the database user<br />

ˆ getdbServer<br />

public static String getdbServer( )<br />

– Usage<br />

* returns the database server name or IP address<br />

ˆ getdbUser<br />

public static String getdbUser( )<br />

– Usage<br />

* returns the name of the database user<br />

ˆ getEmailFrom<br />

public static String getEmailFrom( )<br />

– Usage<br />

* returns the email From: field for the status <strong>report</strong><br />

ˆ getEmailHost<br />

public static String getEmailHost( )


B.1. CLASSES 42<br />

– Usage<br />

* returns the name or IP address for the SMTP server the status <strong>report</strong> message is<br />

send to<br />

ˆ getEmailSubject<br />

public static String getEmailSubject( )<br />

– Usage<br />

* returns the email Subject: field for the status <strong>report</strong><br />

ˆ getEmailTo<br />

public static String getEmailTo( )<br />

– Usage<br />

* returns the email To: field for the status <strong>report</strong><br />

ˆ getLISTimeOut<br />

public static long getLISTimeOut( )<br />

– Usage<br />

* returns the timeout for the MAS test gateway until it responds to an incoming<br />

XML message with an Application Acknowledgement message.<br />

ˆ getLogFileName<br />

public static String getLogFileName( )<br />

– Usage<br />

* returns the path and filename of the log file.<br />

ˆ getMASRcvdTimeOut<br />

public static long getMASRcvdTimeOut( )<br />

– Usage<br />

* returns the timeout for the MAS test gateway until it responds to an incoming<br />

XML message with a Commit Acknowledgement message.<br />

ˆ getPilotServer<br />

public static String getPilotServer( )<br />

– Usage<br />

* returns name or IP address of the Pilot Server<br />

ˆ getReceivingApplication<br />

public static String getReceivingApplication( )<br />

– Usage<br />

* returns the name of the receiving application<br />

ˆ getReceivingFacility<br />

public static String getReceivingFacility( )<br />

– Usage<br />

* returns the name of the receiving facility


B.1. CLASSES 43<br />

ˆ getRemoteGateway<br />

public static String getRemoteGateway( )<br />

– Usage<br />

* returns name or IP address of the remote gateway<br />

ˆ getRMSTimeOut<br />

public static long getRMSTimeOut( )<br />

– Usage<br />

* returns the sleeptimer for the ReceiveMessageServer thread. After one run, the<br />

thread will be set asleep for this amount of time.<br />

ˆ getScanDBTimeOut<br />

public static long getScanDBTimeOut( )<br />

– Usage<br />

* returns the sleeptimer for the SendMessageClient thread. After one run, the<br />

thread will be set asleep for this amount of time.<br />

ˆ getSendingApplication<br />

public static String getSendingApplication( )<br />

– Usage<br />

* returns the name of the sending application<br />

ˆ getSendingFacility<br />

public static String getSendingFacility( )<br />

– Usage<br />

* returns the name of the sending facility<br />

ˆ getSocketTimeOut<br />

public static int getSocketTimeOut( )<br />

– Usage<br />

* returns the timeout for closing an open socket connection<br />

B.1.3<br />

Class DBSession<br />

This class provides all the database functionality.<br />

Declaration<br />

public class DBSession<br />

extends java.lang.Object


B.1. CLASSES 44<br />

Constructors<br />

ˆ DBSession<br />

public DBSession( java.lang.String configFileName )<br />

– Usage<br />

* Constructor initializes member variables with values out of the given<br />

configuration file<br />

Methods<br />

ˆ closeDB<br />

public void closeDB( java.sql.Connection conn )<br />

– Usage<br />

* close database connection<br />

ˆ getApplicationErrorMessages<br />

public ErrorMessageList getApplicationErrorMessages( java.sql.Connection<br />

conn )<br />

– Usage<br />

* get Messages with flagAE set to true<br />

ˆ getCommitErrorMessages<br />

public ErrorMessageList getCommitErrorMessages( java.sql.Connection<br />

conn )<br />

– Usage<br />

* get Messages with flagCE set to true<br />

ˆ getCommitRejectMessages<br />

public ErrorMessageList getCommitRejectMessages( java.sql.Connection<br />

conn )<br />

– Usage<br />

* get Messages with flagCR set to true<br />

ˆ getMsgList<br />

public MessageList getMsgList( java.sql.Connection conn )<br />

– Usage<br />

* returns Object MessageList with all new measurements<br />

ˆ getNumRows<br />

public int getNumRows( java.sql.Connection conn )<br />

– Usage<br />

* get number of rows in table MeasXferStatys


B.1. CLASSES 45<br />

ˆ getPendingACKMessages<br />

public ErrorMessageList getPendingACKMessages( java.sql.Connection<br />

conn, long timeDiff )<br />

– Usage<br />

* get Messages with Pending timeStampRcvd<br />

ˆ getPendingLISMessages<br />

public ErrorMessageList getPendingLISMessages( java.sql.Connection<br />

conn, long timeDiff )<br />

– Usage<br />

* get Messages with Pending timeStampLIS<br />

ˆ getTimesSent<br />

public int getTimesSent( java.sql.Connection<br />

MeasID )<br />

conn, java.lang.String<br />

– Usage<br />

* get timesSent field in MeasXferStatus<br />

ˆ openDB<br />

public Connection openDB( )<br />

– Usage<br />

* Open a database connection, returns database link as a Connection<br />

ˆ updateComment<br />

public boolean updateComment( java.sql.Connection conn,<br />

java.lang.String MeasID, java.lang.String Comment )<br />

– Usage<br />

* update comment in MeasXferStatus<br />

ˆ updateFlagAA<br />

public boolean updateFlagAA( java.sql.Connection<br />

java.lang.String MeasID, boolean flag )<br />

conn,<br />

– Usage<br />

* update flagAA field in MeasXferStatus<br />

ˆ updateFlagAE<br />

public boolean updateFlagAE( java.sql.Connection<br />

java.lang.String MeasID, boolean flag )<br />

conn,<br />

– Usage<br />

* update flagAE field in MeasXferStatus<br />

ˆ updateFlagCA<br />

public boolean updateFlagCA( java.sql.Connection<br />

java.lang.String MeasID, boolean flag )<br />

conn,


B.1. CLASSES 46<br />

– Usage<br />

* update flagCA field in MeasXferStatus<br />

ˆ updateFlagCE<br />

public boolean updateFlagCE( java.sql.Connection<br />

java.lang.String MeasID, boolean flag )<br />

conn,<br />

– Usage<br />

* update flagCE field in MeasXferStatus<br />

ˆ updateFlagCR<br />

public boolean updateFlagCR( java.sql.Connection<br />

java.lang.String MeasID, boolean flag )<br />

conn,<br />

– Usage<br />

* update flagCR field in MeasXferStatus<br />

ˆ updateFlagNotified<br />

public boolean updateFlagNotified( java.sql.Connection<br />

java.lang.String MeasID, boolean flag )<br />

conn,<br />

– Usage<br />

* update flagNotified field in MeasXferStatus<br />

ˆ updateTimesSent<br />

public boolean updateTimesSent( java.sql.Connection<br />

java.lang.String MeasID, int times )<br />

conn,<br />

– Usage<br />

* update timesSent field in MeasXferStatus<br />

ˆ updateTimeStampLIS<br />

public boolean updateTimeStampLIS( java.sql.Connection<br />

java.lang.String MeasID, java.lang.String timeStamp )<br />

conn,<br />

– Usage<br />

* update timeStampLIS field in MeasXferStatus<br />

ˆ updateTimeStampRcvd<br />

public boolean updateTimeStampRcvd( java.sql.Connection<br />

java.lang.String MeasID, java.lang.String timeStamp )<br />

conn,<br />

– Usage<br />

* update timeStampRcvd field in MeasXferStatus<br />

ˆ updateTimeStampSent<br />

public boolean updateTimeStampSent( java.sql.Connection<br />

java.lang.String MeasID, java.lang.String timeStamp )<br />

conn,<br />

– Usage<br />

* update timeStampSent field in MeasXferStatus


B.1. CLASSES 47<br />

B.1.4<br />

Class ErrorMessage<br />

This class represents an error message object used by the class CheckPendingMessages<br />

Declaration<br />

public class ErrorMessage<br />

extends java.lang.Object<br />

Constructors<br />

ˆ ErrorMessage<br />

public ErrorMessage( int MeasID, java.lang.String Comment )<br />

– Usage<br />

* Constructor initializes the member values<br />

Methods<br />

ˆ getComment<br />

public String getComment( )<br />

– Usage<br />

* returns the error comment of the error message<br />

ˆ getMeasID<br />

public int getMeasID( )<br />

– Usage<br />

* returns the MeasID of the error message<br />

B.1.5<br />

Class ErrorMessageList<br />

This class is used by the CheckPendingMessages class to generate a list of ErrorMessages<br />

Declaration<br />

public class ErrorMessageList<br />

extends java.util.LinkedList


B.1. CLASSES 48<br />

Constructors<br />

ˆ ErrorMessageList<br />

public ErrorMessageList( )<br />

Methods inherited from class java.util.LinkedList<br />

ˆ add<br />

public void add( int , java.lang.Object )<br />

ˆ add<br />

public boolean add( java.lang.Object )<br />

ˆ addAll<br />

public boolean addAll( java.util.Collection )<br />

ˆ addAll<br />

public boolean addAll( int , java.util.Collection )<br />

ˆ addFirst<br />

public void addFirst( java.lang.Object )<br />

ˆ addLast<br />

public void addLast( java.lang.Object )<br />

ˆ clear<br />

public void clear( )<br />

ˆ clone<br />

public Object clone( )<br />

ˆ contains<br />

public boolean contains( java.lang.Object )<br />

ˆ get<br />

public Object get( int )<br />

ˆ getFirst<br />

public Object getFirst( )<br />

ˆ getLast<br />

public Object getLast( )<br />

ˆ indexOf<br />

public int indexOf( java.lang.Object )<br />

ˆ lastIndexOf<br />

public int lastIndexOf( java.lang.Object )<br />

ˆ listIterator<br />

public ListIterator listIterator( int )<br />

ˆ remove<br />

public Object remove( int )<br />

ˆ remove<br />

public boolean remove( java.lang.Object )<br />

ˆ removeFirst<br />

public Object removeFirst( )<br />

ˆ removeLast<br />

public Object removeLast( )<br />

ˆ set<br />

public Object set( int , java.lang.Object )<br />

ˆ size<br />

public int size( )<br />

ˆ toArray<br />

public Object toArray( )<br />

ˆ toArray<br />

public Object toArray( java.lang.Object [] )


B.1. CLASSES 49<br />

Methods inherited from class java.util.AbstractSequentialList<br />

ˆ add<br />

public void add( int , java.lang.Object )<br />

ˆ addAll<br />

public boolean addAll( int , java.util.Collection )<br />

ˆ get<br />

public Object get( int )<br />

ˆ iterator<br />

public Iterator iterator( )<br />

ˆ listIterator<br />

public abstract ListIterator listIterator( int )<br />

ˆ remove<br />

public Object remove( int )<br />

ˆ set<br />

public Object set( int , java.lang.Object )<br />

Methods inherited from class java.util.AbstractList<br />

ˆ add<br />

public void add( int , java.lang.Object )<br />

ˆ add<br />

public boolean add( java.lang.Object )<br />

ˆ addAll<br />

public boolean addAll( int , java.util.Collection )<br />

ˆ clear<br />

public void clear( )<br />

ˆ equals<br />

public boolean equals( java.lang.Object )<br />

ˆ get<br />

public abstract Object get( int )<br />

ˆ hashCode<br />

public int hashCode( )<br />

ˆ indexOf<br />

public int indexOf( java.lang.Object )<br />

ˆ iterator<br />

public Iterator iterator( )<br />

ˆ lastIndexOf<br />

public int lastIndexOf( java.lang.Object )<br />

ˆ listIterator<br />

public ListIterator listIterator( )<br />

ˆ listIterator<br />

public ListIterator listIterator( int )<br />

ˆ remove<br />

public Object remove( int )<br />

ˆ removeRange<br />

protected void removeRange( int , int )<br />

ˆ set<br />

public Object set( int , java.lang.Object )<br />

ˆ subList<br />

public List subList( int , int )


B.1. CLASSES 50<br />

Methods inherited from class java.util.AbstractCollection<br />

ˆ add<br />

public boolean add( java.lang.Object )<br />

ˆ addAll<br />

public boolean addAll( java.util.Collection )<br />

ˆ clear<br />

public void clear( )<br />

ˆ contains<br />

public boolean contains( java.lang.Object )<br />

ˆ containsAll<br />

public boolean containsAll( java.util.Collection )<br />

ˆ isEmpty<br />

public boolean isEmpty( )<br />

ˆ iterator<br />

public abstract Iterator iterator( )<br />

ˆ remove<br />

public boolean remove( java.lang.Object )<br />

ˆ removeAll<br />

public boolean removeAll( java.util.Collection )<br />

ˆ retainAll<br />

public boolean retainAll( java.util.Collection )<br />

ˆ size<br />

public abstract int size( )<br />

ˆ toArray<br />

public Object toArray( )<br />

ˆ toArray<br />

public Object toArray( java.lang.Object [] )<br />

ˆ toString<br />

public String toString( )<br />

B.1.6<br />

Class GatewayIF<br />

This class spawns the threads SendMessageClient, RemoteMessageServer and CheckPendingMessages.<br />

Declaration<br />

public class GatewayIF<br />

extends java.lang.Thread<br />

Constructors<br />

ˆ GatewayIF<br />

public GatewayIF( )


B.1. CLASSES 51<br />

Methods<br />

ˆ main<br />

public static void main( java.lang.String [] args )<br />

Methods inherited from class java.lang.Thread<br />

ˆ activeCount<br />

public static int activeCount( )<br />

ˆ checkAccess<br />

public final void checkAccess( )<br />

ˆ countStackFrames<br />

public native int countStackFrames( )<br />

ˆ currentThread<br />

public static native Thread currentThread( )<br />

ˆ destroy<br />

public void destroy( )<br />

ˆ dumpStack<br />

public static void dumpStack( )<br />

ˆ enumerate<br />

public static int enumerate( java.lang.Thread [] )<br />

ˆ getContextClassLoader<br />

public ClassLoader getContextClassLoader( )<br />

ˆ getName<br />

public final String getName( )<br />

ˆ getPriority<br />

public final int getPriority( )<br />

ˆ getThreadGroup<br />

public final ThreadGroup getThreadGroup( )<br />

ˆ interrupt<br />

public void interrupt( )<br />

ˆ interrupted<br />

public static boolean interrupted( )<br />

ˆ isAlive<br />

public final native boolean isAlive( )<br />

ˆ isDaemon<br />

public final boolean isDaemon( )<br />

ˆ isInterrupted<br />

public boolean isInterrupted( )<br />

ˆ join<br />

public final void join( )<br />

ˆ join<br />

public final synchronized void join( long )<br />

ˆ join<br />

public final synchronized void join( long , int )<br />

ˆ resume<br />

public final void resume( )


B.1. CLASSES 52<br />

ˆ run<br />

public void run( )<br />

ˆ setContextClassLoader<br />

public void setContextClassLoader( java.lang.ClassLoader )<br />

ˆ setDaemon<br />

public final void setDaemon( boolean )<br />

ˆ setName<br />

public final void setName( java.lang.String )<br />

ˆ setPriority<br />

public final void setPriority( int )<br />

ˆ sleep<br />

public static native void sleep( long )<br />

ˆ sleep<br />

public static void sleep( long , int )<br />

ˆ start<br />

public native synchronized void start( )<br />

ˆ stop<br />

public final void stop( )<br />

ˆ stop<br />

public final synchronized void stop( java.lang.Throwable )<br />

ˆ suspend<br />

public final void suspend( )<br />

ˆ toString<br />

public String toString( )<br />

ˆ yield<br />

public static native void yield( )<br />

B.1.7<br />

Class Logger<br />

This class is intended to log errors and other useful information to an ASCII text file<br />

Declaration<br />

public class Logger<br />

extends java.lang.Object<br />

Constructors<br />

ˆ Logger<br />

public Logger( )<br />

– Usage<br />

* Constructor with default filename if no parameter is given<br />

ˆ Logger<br />

public Logger( java.lang.String fileName )<br />

– Usage<br />

* Constructor needs filename of logfile


B.1. CLASSES 53<br />

Methods<br />

ˆ clearLog<br />

public void clearLog( )<br />

– Usage<br />

* clear all logged entries in logfile<br />

ˆ log<br />

public boolean log( short priority, short subSystemCode,<br />

java.lang.String moduleCode, java.lang.String errorCode,<br />

java.lang.String message )<br />

– Usage<br />

* add new entry to log file with given parameters<br />

B.1.8<br />

Class MASTestServer<br />

Simulation of the MAS Gateway Interface and Sunquest’s Laboratory Information System (LIS)<br />

Declaration<br />

public class MASTestServer<br />

extends java.lang.Thread<br />

Fields<br />

ˆ public static int CICINPORT<br />

– Port for incoming XML messages<br />

ˆ public static int CICOUTPORT<br />

– Port for outgoing XML messages<br />

ˆ public static long TIMEOUT<br />

–<br />

ˆ public static long RESPONSETIME<br />

– Time MAS waits until sending response<br />

ˆ public static long RESPONSETIMEOUT<br />

– Time MAS waits until sending timeout response<br />

ˆ public static long responseTime<br />

–<br />

ˆ public static String RECVSERVER<br />


B.1. CLASSES 54<br />

Constructors<br />

ˆ MASTestServer<br />

public MASTestServer( long delay )<br />

– Usage<br />

* constructor sets default values from MAS.cfg file<br />

Methods<br />

ˆ getDOMDocument<br />

public Document getDOMDocument( java.lang.String xmlstring )<br />

– Usage<br />

* generate DOM document out of received XML string<br />

ˆ main<br />

public static void main( java.lang.String [] args )<br />

ˆ run<br />

public void run( )<br />

Methods inherited from class java.lang.Thread<br />

ˆ activeCount<br />

public static int activeCount( )<br />

ˆ checkAccess<br />

public final void checkAccess( )<br />

ˆ countStackFrames<br />

public native int countStackFrames( )<br />

ˆ currentThread<br />

public static native Thread currentThread( )<br />

ˆ destroy<br />

public void destroy( )<br />

ˆ dumpStack<br />

public static void dumpStack( )<br />

ˆ enumerate<br />

public static int enumerate( java.lang.Thread [] )<br />

ˆ getContextClassLoader<br />

public ClassLoader getContextClassLoader( )<br />

ˆ getName<br />

public final String getName( )<br />

ˆ getPriority<br />

public final int getPriority( )<br />

ˆ getThreadGroup<br />

public final ThreadGroup getThreadGroup( )


B.1. CLASSES 55<br />

ˆ interrupt<br />

public void interrupt( )<br />

ˆ interrupted<br />

public static boolean interrupted( )<br />

ˆ isAlive<br />

public final native boolean isAlive( )<br />

ˆ isDaemon<br />

public final boolean isDaemon( )<br />

ˆ isInterrupted<br />

public boolean isInterrupted( )<br />

ˆ join<br />

public final void join( )<br />

ˆ join<br />

public final synchronized void join( long )<br />

ˆ join<br />

public final synchronized void join( long , int )<br />

ˆ resume<br />

public final void resume( )<br />

ˆ run<br />

public void run( )<br />

ˆ setContextClassLoader<br />

public void setContextClassLoader( java.lang.ClassLoader )<br />

ˆ setDaemon<br />

public final void setDaemon( boolean )<br />

ˆ setName<br />

public final void setName( java.lang.String )<br />

ˆ setPriority<br />

public final void setPriority( int )<br />

ˆ sleep<br />

public static native void sleep( long )<br />

ˆ sleep<br />

public static void sleep( long , int )<br />

ˆ start<br />

public native synchronized void start( )<br />

ˆ stop<br />

public final void stop( )<br />

ˆ stop<br />

public final synchronized void stop( java.lang.Throwable )<br />

ˆ suspend<br />

public final void suspend( )<br />

ˆ toString<br />

public String toString( )<br />

ˆ yield<br />

public static native void yield( )<br />

B.1.9<br />

Class MessageList<br />

This class is used by the SendMessageClient class to generate a linked list of XMLMessages to be send to<br />

the MAS remote gateway


B.1. CLASSES 56<br />

Declaration<br />

public class MessageList<br />

extends java.util.LinkedList<br />

Constructors<br />

ˆ MessageList<br />

public MessageList( )<br />

Methods inherited from class java.util.LinkedList<br />

ˆ add<br />

public void add( int , java.lang.Object )<br />

ˆ add<br />

public boolean add( java.lang.Object )<br />

ˆ addAll<br />

public boolean addAll( java.util.Collection )<br />

ˆ addAll<br />

public boolean addAll( int , java.util.Collection )<br />

ˆ addFirst<br />

public void addFirst( java.lang.Object )<br />

ˆ addLast<br />

public void addLast( java.lang.Object )<br />

ˆ clear<br />

public void clear( )<br />

ˆ clone<br />

public Object clone( )<br />

ˆ contains<br />

public boolean contains( java.lang.Object )<br />

ˆ get<br />

public Object get( int )<br />

ˆ getFirst<br />

public Object getFirst( )<br />

ˆ getLast<br />

public Object getLast( )<br />

ˆ indexOf<br />

public int indexOf( java.lang.Object )<br />

ˆ lastIndexOf<br />

public int lastIndexOf( java.lang.Object )<br />

ˆ listIterator<br />

public ListIterator listIterator( int )<br />

ˆ remove<br />

public Object remove( int )<br />

ˆ remove<br />

public boolean remove( java.lang.Object )


B.1. CLASSES 57<br />

ˆ removeFirst<br />

public Object removeFirst( )<br />

ˆ removeLast<br />

public Object removeLast( )<br />

ˆ set<br />

public Object set( int , java.lang.Object )<br />

ˆ size<br />

public int size( )<br />

ˆ toArray<br />

public Object toArray( )<br />

ˆ toArray<br />

public Object toArray( java.lang.Object [] )<br />

Methods inherited from class java.util.AbstractSequentialList<br />

ˆ add<br />

public void add( int , java.lang.Object )<br />

ˆ addAll<br />

public boolean addAll( int , java.util.Collection )<br />

ˆ get<br />

public Object get( int )<br />

ˆ iterator<br />

public Iterator iterator( )<br />

ˆ listIterator<br />

public abstract ListIterator listIterator( int )<br />

ˆ remove<br />

public Object remove( int )<br />

ˆ set<br />

public Object set( int , java.lang.Object )<br />

Methods inherited from class java.util.AbstractList<br />

ˆ add<br />

public void add( int , java.lang.Object )<br />

ˆ add<br />

public boolean add( java.lang.Object )<br />

ˆ addAll<br />

public boolean addAll( int , java.util.Collection )<br />

ˆ clear<br />

public void clear( )<br />

ˆ equals<br />

public boolean equals( java.lang.Object )<br />

ˆ get<br />

public abstract Object get( int )<br />

ˆ hashCode<br />

public int hashCode( )<br />

ˆ indexOf<br />

public int indexOf( java.lang.Object )


B.1. CLASSES 58<br />

ˆ iterator<br />

public Iterator iterator( )<br />

ˆ lastIndexOf<br />

public int lastIndexOf( java.lang.Object )<br />

ˆ listIterator<br />

public ListIterator listIterator( )<br />

ˆ listIterator<br />

public ListIterator listIterator( int )<br />

ˆ remove<br />

public Object remove( int )<br />

ˆ removeRange<br />

protected void removeRange( int , int )<br />

ˆ set<br />

public Object set( int , java.lang.Object )<br />

ˆ subList<br />

public List subList( int , int )<br />

Methods inherited from class java.util.AbstractCollection<br />

ˆ add<br />

public boolean add( java.lang.Object )<br />

ˆ addAll<br />

public boolean addAll( java.util.Collection )<br />

ˆ clear<br />

public void clear( )<br />

ˆ contains<br />

public boolean contains( java.lang.Object )<br />

ˆ containsAll<br />

public boolean containsAll( java.util.Collection )<br />

ˆ isEmpty<br />

public boolean isEmpty( )<br />

ˆ iterator<br />

public abstract Iterator iterator( )<br />

ˆ remove<br />

public boolean remove( java.lang.Object )<br />

ˆ removeAll<br />

public boolean removeAll( java.util.Collection )<br />

ˆ retainAll<br />

public boolean retainAll( java.util.Collection )<br />

ˆ size<br />

public abstract int size( )<br />

ˆ toArray<br />

public Object toArray( )<br />

ˆ toArray<br />

public Object toArray( java.lang.Object [] )<br />

ˆ toString<br />

public String toString( )


B.1. CLASSES 59<br />

B.1.10<br />

Class MiscDate<br />

This class is used to get general time and date information and to compute time differences.<br />

Declaration<br />

public class MiscDate<br />

extends java.lang.Object<br />

Constructors<br />

ˆ MiscDate<br />

public MiscDate( )<br />

Methods<br />

ˆ getTimeDiff<br />

public static long getTimeDiff( java.sql.Timestamp timeStampSent )<br />

– Usage<br />

* returns time difference in milliseconds between now and a given timestamp<br />

ˆ MessageDate<br />

public static String MessageDate( )<br />

– Usage<br />

* returns today’s date and time as a String like the database returns it<br />

ˆ todaysDate<br />

public static String todaysDate( )<br />

– Usage<br />

* returns today’s date as a formatted string<br />

B.1.11<br />

Class NotifyByEmail<br />

Declaration<br />

public class NotifyByEmail<br />

extends java.lang.Object


B.1. CLASSES 60<br />

Constructors<br />

ˆ NotifyByEmail<br />

public NotifyByEmail( )<br />

Methods<br />

ˆ main<br />

public static void main( java.lang.String [] args )<br />

B.1.12<br />

Class RecvMessage<br />

This class provides the methods for accessing an incoming (reveived) message<br />

Declaration<br />

public class RecvMessage<br />

extends ncv.gatewayif.XMLMessage<br />

Constructors<br />

ˆ RecvMessage<br />

public RecvMessage( java.lang.String message )<br />

– Usage<br />

* Constructor used for initializing the XML message object<br />

Methods<br />

ˆ getAckCode<br />

public String getAckCode( )<br />

– Usage<br />

* returns the Acknowledgement code out of the DOM document<br />

ˆ getDOMDocument<br />

public Document getDOMDocument( java.lang.String xmlstring )<br />

– Usage<br />

* returns a DOM Document for an incoming XML message string as it is received<br />

from the MAS remote gateway


B.1. CLASSES 61<br />

ˆ getErrorComment<br />

public String getErrorComment( )<br />

– Usage<br />

* returns the Error comment out of the DOM document<br />

ˆ getMeasID<br />

public String getMeasID( )<br />

– Usage<br />

* returns the MeasID out of the DOM document to identify the measurement in<br />

the database<br />

ˆ getMsgControlID<br />

public String getMsgControlID( )<br />

– Usage<br />

* returns the unique Message Control ID out of the DOM document<br />

Methods inherited from class ncv.gatewayif.XMLMessage<br />

( in B.1.17, page 69)<br />

ˆ getCalCode<br />

public float getCalCode( )<br />

ˆ getComment<br />

public String getComment( )<br />

ˆ getDateOfMessage<br />

public String getDateOfMessage( )<br />

ˆ getErrorComment<br />

public String getErrorComment( )<br />

ˆ getMessageControlID<br />

public String getMessageControlID( )<br />

ˆ getObservationValue<br />

public float getObservationValue( )<br />

ˆ getPatientID<br />

public String getPatientID( )<br />

ˆ getReceivingApplication<br />

public String getReceivingApplication( )<br />

ˆ getReceivingFacility<br />

public String getReceivingFacility( )<br />

ˆ getSendingApplication<br />

public String getSendingApplication( )<br />

ˆ getSendingFacility<br />

public String getSendingFacility( )<br />

ˆ setErrorComment<br />

public void setErrorComment( java.lang.String errorComment )


B.1. CLASSES 62<br />

B.1.13<br />

Class RecvMessageServer<br />

This class provides the methods for receiving incoming LIS AA and AE messages send through the MAS<br />

remote gateway. It validates the message and sends an acknowledgement message back to LIS during the<br />

same socket connection.<br />

Declaration<br />

public class RecvMessageServer<br />

extends java.lang.Thread<br />

Fields<br />

ˆ public static int CICOUTPORT<br />

–<br />

ˆ public static long TIMEOUT<br />

–<br />

Constructors<br />

ˆ RecvMessageServer<br />

public RecvMessageServer( java.lang.String cfgFileName )<br />

– Usage<br />

* Constructor sets the member values as configured in given configuration file<br />

Methods<br />

ˆ getDOMDocument<br />

public Document getDOMDocument( java.lang.String xmlstring )<br />

– Usage<br />

* returns a DOM document generated out of an incoming XML message string<br />

ˆ run<br />

public void run( )


B.1. CLASSES 63<br />

Methods inherited from class java.lang.Thread<br />

ˆ activeCount<br />

public static int activeCount( )<br />

ˆ checkAccess<br />

public final void checkAccess( )<br />

ˆ countStackFrames<br />

public native int countStackFrames( )<br />

ˆ currentThread<br />

public static native Thread currentThread( )<br />

ˆ destroy<br />

public void destroy( )<br />

ˆ dumpStack<br />

public static void dumpStack( )<br />

ˆ enumerate<br />

public static int enumerate( java.lang.Thread [] )<br />

ˆ getContextClassLoader<br />

public ClassLoader getContextClassLoader( )<br />

ˆ getName<br />

public final String getName( )<br />

ˆ getPriority<br />

public final int getPriority( )<br />

ˆ getThreadGroup<br />

public final ThreadGroup getThreadGroup( )<br />

ˆ interrupt<br />

public void interrupt( )<br />

ˆ interrupted<br />

public static boolean interrupted( )<br />

ˆ isAlive<br />

public final native boolean isAlive( )<br />

ˆ isDaemon<br />

public final boolean isDaemon( )<br />

ˆ isInterrupted<br />

public boolean isInterrupted( )<br />

ˆ join<br />

public final void join( )<br />

ˆ join<br />

public final synchronized void join( long )<br />

ˆ join<br />

public final synchronized void join( long , int )<br />

ˆ resume<br />

public final void resume( )<br />

ˆ run<br />

public void run( )<br />

ˆ setContextClassLoader<br />

public void setContextClassLoader( java.lang.ClassLoader )<br />

ˆ setDaemon<br />

public final void setDaemon( boolean )<br />

ˆ setName<br />

public final void setName( java.lang.String )


B.1. CLASSES 64<br />

ˆ setPriority<br />

public final void setPriority( int )<br />

ˆ sleep<br />

public static native void sleep( long )<br />

ˆ sleep<br />

public static void sleep( long , int )<br />

ˆ start<br />

public native synchronized void start( )<br />

ˆ stop<br />

public final void stop( )<br />

ˆ stop<br />

public final synchronized void stop( java.lang.Throwable )<br />

ˆ suspend<br />

public final void suspend( )<br />

ˆ toString<br />

public String toString( )<br />

ˆ yield<br />

public static native void yield( )<br />

B.1.14<br />

Class SendMessageClient<br />

This class provides the basic functionality of the application, it gets a list of messages to be send, opens a<br />

socket connection to the MAS remote gateway, sends all the messages and receives CA/CE/CR message<br />

acknowledgement from the remote gateway.<br />

Declaration<br />

public class SendMessageClient<br />

extends java.lang.Thread<br />

Constructors<br />

ˆ SendMessageClient<br />

public SendMessageClient( java.lang.String configFileName )<br />

– Usage<br />

* Constructor initializes member values out of given configuration file<br />

Methods<br />

ˆ run<br />

public void run( )


B.1. CLASSES 65<br />

Methods inherited from class java.lang.Thread<br />

ˆ activeCount<br />

public static int activeCount( )<br />

ˆ checkAccess<br />

public final void checkAccess( )<br />

ˆ countStackFrames<br />

public native int countStackFrames( )<br />

ˆ currentThread<br />

public static native Thread currentThread( )<br />

ˆ destroy<br />

public void destroy( )<br />

ˆ dumpStack<br />

public static void dumpStack( )<br />

ˆ enumerate<br />

public static int enumerate( java.lang.Thread [] )<br />

ˆ getContextClassLoader<br />

public ClassLoader getContextClassLoader( )<br />

ˆ getName<br />

public final String getName( )<br />

ˆ getPriority<br />

public final int getPriority( )<br />

ˆ getThreadGroup<br />

public final ThreadGroup getThreadGroup( )<br />

ˆ interrupt<br />

public void interrupt( )<br />

ˆ interrupted<br />

public static boolean interrupted( )<br />

ˆ isAlive<br />

public final native boolean isAlive( )<br />

ˆ isDaemon<br />

public final boolean isDaemon( )<br />

ˆ isInterrupted<br />

public boolean isInterrupted( )<br />

ˆ join<br />

public final void join( )<br />

ˆ join<br />

public final synchronized void join( long )<br />

ˆ join<br />

public final synchronized void join( long , int )<br />

ˆ resume<br />

public final void resume( )<br />

ˆ run<br />

public void run( )<br />

ˆ setContextClassLoader<br />

public void setContextClassLoader( java.lang.ClassLoader )<br />

ˆ setDaemon<br />

public final void setDaemon( boolean )<br />

ˆ setName<br />

public final void setName( java.lang.String )


B.1. CLASSES 66<br />

ˆ setPriority<br />

public final void setPriority( int )<br />

ˆ sleep<br />

public static native void sleep( long )<br />

ˆ sleep<br />

public static void sleep( long , int )<br />

ˆ start<br />

public native synchronized void start( )<br />

ˆ stop<br />

public final void stop( )<br />

ˆ stop<br />

public final synchronized void stop( java.lang.Throwable )<br />

ˆ suspend<br />

public final void suspend( )<br />

ˆ toString<br />

public String toString( )<br />

ˆ yield<br />

public static native void yield( )<br />

B.1.15<br />

Class SendMessage<br />

This class provides the methods for accessing an outgoing (to be send) message<br />

Declaration<br />

public class SendMessage<br />

extends ncv.gatewayif.XMLMessage<br />

Constructors<br />

ˆ SendMessage<br />

public SendMessage( int PatientID, java.lang.String kppID, int<br />

MeasID, float ObservationValue, float CalCode, java.lang.String<br />

ObservationTime )<br />

– Usage<br />

* Constructor calls constructor of SuperClass XMLMessage<br />

ˆ SendMessage<br />

public SendMessage( java.lang.String<br />

java.lang.String ACKType )<br />

MessageControlID,<br />

– Usage<br />

* Constructor calls constructor of SuperClass XMLMessage


B.1. CLASSES 67<br />

Methods<br />

ˆ toString ACK<br />

public String toString ACK( )<br />

– Usage<br />

* returns an Acknowledgement XML message string from DOM document<br />

ˆ toString ORM O01<br />

public String toString ORM O01( )<br />

– Usage<br />

* returns a ORM O01 type XML message string from document<br />

ˆ toString ORR O02<br />

public String toString ORR O02( )<br />

– Usage<br />

* returns an ORR O02 message string from DOM document<br />

Methods inherited from class ncv.gatewayif.XMLMessage<br />

( in B.1.17, page 69)<br />

ˆ getCalCode<br />

public float getCalCode( )<br />

ˆ getComment<br />

public String getComment( )<br />

ˆ getDateOfMessage<br />

public String getDateOfMessage( )<br />

ˆ getErrorComment<br />

public String getErrorComment( )<br />

ˆ getMessageControlID<br />

public String getMessageControlID( )<br />

ˆ getObservationValue<br />

public float getObservationValue( )<br />

ˆ getPatientID<br />

public String getPatientID( )<br />

ˆ getReceivingApplication<br />

public String getReceivingApplication( )<br />

ˆ getReceivingFacility<br />

public String getReceivingFacility( )<br />

ˆ getSendingApplication<br />

public String getSendingApplication( )<br />

ˆ getSendingFacility<br />

public String getSendingFacility( )<br />

ˆ setErrorComment<br />

public void setErrorComment( java.lang.String errorComment )


B.1. CLASSES 68<br />

B.1.16<br />

Class Timer<br />

Declaration<br />

public class Timer<br />

extends java.lang.Thread<br />

Constructors<br />

ˆ Timer<br />

public Timer( int length )<br />

Methods<br />

ˆ reset<br />

public synchronized void reset( )<br />

ˆ run<br />

public void run( )<br />

ˆ timeout<br />

public void timeout( )<br />

Methods inherited from class java.lang.Thread<br />

ˆ activeCount<br />

public static int activeCount( )<br />

ˆ checkAccess<br />

public final void checkAccess( )<br />

ˆ countStackFrames<br />

public native int countStackFrames( )<br />

ˆ currentThread<br />

public static native Thread currentThread( )<br />

ˆ destroy<br />

public void destroy( )<br />

ˆ dumpStack<br />

public static void dumpStack( )<br />

ˆ enumerate<br />

public static int enumerate( java.lang.Thread [] )<br />

ˆ getContextClassLoader<br />

public ClassLoader getContextClassLoader( )<br />

ˆ getName<br />

public final String getName( )


B.1. CLASSES 69<br />

ˆ getPriority<br />

public final int getPriority( )<br />

ˆ getThreadGroup<br />

public final ThreadGroup getThreadGroup( )<br />

ˆ interrupt<br />

public void interrupt( )<br />

ˆ interrupted<br />

public static boolean interrupted( )<br />

ˆ isAlive<br />

public final native boolean isAlive( )<br />

ˆ isDaemon<br />

public final boolean isDaemon( )<br />

ˆ isInterrupted<br />

public boolean isInterrupted( )<br />

ˆ join<br />

public final void join( )<br />

ˆ join<br />

public final synchronized void join( long )<br />

ˆ join<br />

public final synchronized void join( long , int )<br />

ˆ resume<br />

public final void resume( )<br />

ˆ run<br />

public void run( )<br />

ˆ setContextClassLoader<br />

public void setContextClassLoader( java.lang.ClassLoader )<br />

ˆ setDaemon<br />

public final void setDaemon( boolean )<br />

ˆ setName<br />

public final void setName( java.lang.String )<br />

ˆ setPriority<br />

public final void setPriority( int )<br />

ˆ sleep<br />

public static native void sleep( long )<br />

ˆ sleep<br />

public static void sleep( long , int )<br />

ˆ start<br />

public native synchronized void start( )<br />

ˆ stop<br />

public final void stop( )<br />

ˆ stop<br />

public final synchronized void stop( java.lang.Throwable )<br />

ˆ suspend<br />

public final void suspend( )<br />

ˆ toString<br />

public String toString( )<br />

ˆ yield<br />

public static native void yield( )<br />

B.1.17<br />

Class XMLMessage


B.1. CLASSES 70<br />

Declaration<br />

public class XMLMessage<br />

extends java.lang.Object<br />

Constructors<br />

ˆ XMLMessage<br />

public XMLMessage( int PatientID, java.lang.String kppID, int<br />

MeasID, float ObservationValue, float CalCode, java.lang.String<br />

ObservationTime )<br />

ˆ XMLMessage<br />

public XMLMessage( java.lang.String message )<br />

ˆ XMLMessage<br />

public XMLMessage( java.lang.String<br />

java.lang.String ACKType )<br />

MessageControlID,<br />

Methods<br />

ˆ getCalCode<br />

public float getCalCode( )<br />

ˆ getComment<br />

public String getComment( )<br />

ˆ getDateOfMessage<br />

public String getDateOfMessage( )<br />

ˆ getErrorComment<br />

public String getErrorComment( )<br />

ˆ getMessageControlID<br />

public String getMessageControlID( )<br />

ˆ getObservationValue<br />

public float getObservationValue( )<br />

ˆ getPatientID<br />

public String getPatientID( )<br />

ˆ getReceivingApplication<br />

public String getReceivingApplication( )<br />

ˆ getReceivingFacility<br />

public String getReceivingFacility( )<br />

ˆ getSendingApplication<br />

public String getSendingApplication( )


B.1. CLASSES 71<br />

ˆ getSendingFacility<br />

public String getSendingFacility( )<br />

ˆ setErrorComment<br />

public void setErrorComment( java.lang.String errorComment )


Appendix C<br />

Listings<br />

C.1 Java Code<br />

C.1.1<br />

/**<br />

GatewayIF.java<br />

2 * $Workfile : GatewayIF.java<br />

*<br />

4 * @version $Revision : 0 $<br />

* @author $Author: David Vogler $<br />

6 * @date $Date: 02/11/00 10:00a $<br />

*<br />

8 * Created by: David Vogler<br />

* Created on: November 2, 2000<br />

10 * Contact: Mike Higgins <br />

*<br />

12 * @description<br />

*<br />

14 * Startup file for Gateway Interface . Spawns all the other services<br />

* and threads for the Pilot Server − MAS/LIS Gateway connection.<br />

16 *<br />

* (C) Copyright Agilent Technologies 2000. All rights reserved .<br />

18 * Reproduction, adaption or translation without prior written<br />

* permission is prohibited except as allowed under the copyright<br />

20 * permission .<br />

*<br />

22 */<br />

24 package ncv.gatewayif;<br />

26 import java. sql .Connection;<br />

import java.io .*;<br />

28 import java.net .*;<br />

import ncv.gatewayif.Config;<br />

30 import ncv.gatewayif.XMLMessage;<br />

import ncv.gatewayif.MessageList;<br />

32<br />

/** This class spawns the threads SendMessageClient, RemoteMessageServer and<br />

34 * CheckPendingMessages.<br />

*/<br />

36<br />

72


C.1. JAVA CODE 73<br />

public class GatewayIF extends Thread {<br />

38 private static int CICOUTPORT;<br />

// private static final String SERVER = ”130.29.247.27”;<br />

40 private static String REMOTESERVER;<br />

private static final long TIMEOUT = 15000L;<br />

42<br />

44<br />

46<br />

public static void main(String [] args) {<br />

String configFileName = new String();<br />

switch(args. length) {<br />

48 case 2:<br />

System.err . println (”Usage: GatewayIF ”);<br />

50 System.exit (1);<br />

break;<br />

52 case 1:<br />

configFileName = args [0];<br />

54 break;<br />

default:<br />

56 configFileName = ”gatewayif.cfg”;<br />

break;<br />

58 }<br />

60 System.out. println (”GWI: Config file name: ” + configFileName);<br />

Config cfg = new Config(configFileName);<br />

62<br />

REMOTESERVER = cfg.getRemoteGateway();<br />

64 CICOUTPORT = cfg.getCICOutPort();<br />

66 System.out. println (”GWI: Connecting to ”+REMOTESERVER+” on port #”+CICOUTPORT);<br />

System.out. println (”GWI: Database server is: ”+cfg.getdbServer ());<br />

68<br />

Thread SMClientThread = new SendMessageClient(configFileName);<br />

70 Thread RMServerThread = new RecvMessageServer(configFileName);<br />

Thread CPMessagesThread = new CheckPendingMessages(configFileName);<br />

72<br />

SMClientThread.start ();<br />

74 RMServerThread.start();<br />

CPMessagesThread.start();<br />

76<br />

try {<br />

78 System.in.read ();<br />

System.out. println (”GWI: Enter pressed.”);<br />

80 } catch (IOException e) {<br />

System.err . println (”GWI: ” + e);<br />

82 e. printStackTrace ();<br />

System.exit (1);<br />

84 }<br />

return;<br />

86 }<br />

}<br />

C.1.2<br />

/**<br />

CheckPendingMessages.java<br />

2 * $Workfile : CheckPendingMessages.java<br />

*


C.1. JAVA CODE 74<br />

4 * @version $Revision : 0 $<br />

* @author $Author: David Vogler $<br />

6 * @date $Date: 02/11/00 10:00a $<br />

*<br />

8 * Created by: David Vogler<br />

* Created on: November 2, 2000<br />

10 * Contact: Mike Higgins <br />

*<br />

12 * @description<br />

*<br />

14 * (C) Copyright Agilent Technologies 2000. All rights reserved .<br />

* Reproduction, adaption or translation without prior written<br />

16 * permission is prohibited except as allowed under the copyright<br />

* permission .<br />

18 *<br />

*/<br />

20<br />

22<br />

package ncv.gatewayif;<br />

import java. sql .Connection;<br />

24 import java.io .*;<br />

import java.net .*;<br />

26 import java. util . Properties ;<br />

28 import java.lang.NumberFormatException;<br />

30 import javax.mail .*;<br />

import javax.mail. internet .*;<br />

32<br />

import ncv.gatewayif.XMLMessage;<br />

34 import ncv.gatewayif.MessageList;<br />

36 /**<br />

This class looks in the MeasXferTable in the Pilot Server database for pending<br />

38 messages and error messages. If error and/or pending messages are found, an email<br />

notification will be generated and sent.<br />

40 */<br />

42 public class CheckPendingMessages extends Thread {<br />

private long sleepTimer;<br />

44 private long MASRcvdTimeOut;<br />

private long LISTimeOut;<br />

46 private String logFileName;<br />

private String EmailFrom;<br />

48 private String EmailTo;<br />

private String EmailSubject;<br />

50 private String EmailHost;<br />

private String configFileName;<br />

52<br />

54 /** Send email with content of parameter msgText to configured receipient . */<br />

public void SendMail (String msgText) {<br />

56 boolean debug = false;<br />

boolean sendmutlipart = false;<br />

58<br />

// set the host


C.1. JAVA CODE 75<br />

60 Properties props = new Properties();<br />

props.put(”mail.smtp.host”, EmailHost);<br />

62<br />

// create some properties and get the default Session<br />

64 Session session = Session. getDefaultInstance (props , null );<br />

66 try {<br />

// create a message<br />

68 Message msg = new MimeMessage(session);<br />

70 // set the from<br />

InternetAddress from = new InternetAddress(EmailFrom);<br />

72 msg.setFrom(from);<br />

74 InternetAddress [] address = {new InternetAddress(EmailTo)};<br />

msg. setRecipients (Message.RecipientType.TO, address);<br />

76 msg.setSubject(EmailSubject);<br />

78 msg.setContent(msgText, ”text/plain”);<br />

80 Transport.send(msg);<br />

System.out. println (”CPM: Message sent to ”+EmailTo+” via ”+EmailHost+”.”);<br />

82 } catch (MessagingException mex) {<br />

mex.printStackTrace ();<br />

84 }<br />

}<br />

86<br />

/** Default Constructor . Reads configFileName to set values . */<br />

88 public CheckPendingMessages (String configFileName) {<br />

this .configFileName = configFileName;<br />

90 Config cfg = new Config(configFileName);<br />

92 sleepTimer = cfg.getCPMTimeOut();<br />

setDaemon(true);<br />

94<br />

96<br />

logFileName = cfg.getLogFileName();<br />

Logger logger = new Logger(logFileName);<br />

98 logger . log((short ) 7, ( short ) 8, ”CPM”, ”START”, ”CheckPendingMessages ”<br />

+ ”thread has been started.” );<br />

100<br />

MASRcvdTimeOut = cfg.getMASRcvdTimeOut();<br />

102 LISTimeOut = cfg.getLISTimeOut();<br />

104 EmailFrom = cfg.getEmailFrom();<br />

EmailTo = cfg.getEmailTo();<br />

106 EmailSubject = cfg.getEmailSubject ();<br />

EmailHost = cfg.getEmailHost();<br />

108 }<br />

110 /** This method checks the database for CE/CR/AE and pending ACK messages from<br />

* MAS and LIS.<br />

112 * It runs permanently but sleeps for sleepTimer milliseconds .<br />

*/<br />

114<br />

public void run() {


C.1. JAVA CODE 76<br />

116 ErrorMessageList CEMsgList;<br />

ErrorMessageList CRMsgList;<br />

118 ErrorMessageList AEMsgList;<br />

ErrorMessageList PendingACKMsgList;<br />

120 ErrorMessageList PendingLISMsgList;<br />

ErrorMessage errMsg;<br />

122 DBSession db;<br />

Connection conn;<br />

124 int i ;<br />

126 while(true) {<br />

db = new DBSession(configFileName);<br />

128 conn = db.openDB();<br />

int numMessages = db.getNumRows(conn);<br />

130 String msgText = ”Gateway Interface Status Report\n”<br />

+ ”−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−\n\n”;<br />

132<br />

CEMsgList = db.getCommitErrorMessages(conn);<br />

134 CRMsgList = db.getCommitRejectMessages(conn);<br />

AEMsgList = db.getApplicationErrorMessages(conn);<br />

136<br />

if (CEMsgList.size() == 0)<br />

138 System.out. println (”CPM: no CE messages found.”);<br />

else {<br />

140 for ( i = 0; i < CEMsgList.size (); i++) {<br />

errMsg = (ErrorMessage) CEMsgList.get(i);<br />

142 db.updateFlagNotified(conn, ””+errMsg.getMeasID(), true);<br />

System.out. println (”DBS: ACK CE MeasID #”+errMsg.getMeasID()<br />

144 +” Comment: ”+errMsg.getComment()+”.”);<br />

}<br />

146 }<br />

System.out. println (”DBS: CE Percentage: ”+ (float) CEMsgList.size()<br />

148 /numMessages+” (”+CEMsgList.size()+” out of ”+numMessages+”).”);<br />

msgText += ”CE Percentage: ”+ (float) CEMsgList.size()/numMessages<br />

150 +” (”+CEMsgList.size()+” out of ”+numMessages+”).\n”;<br />

152 if (CRMsgList.size() == 0)<br />

System.out. println (”CPM: no CR messages found.”);<br />

154 else {<br />

for ( i = 0; i < CRMsgList.size (); i++) {<br />

156 errMsg = (ErrorMessage) CRMsgList.get(i);<br />

db.updateFlagNotified(conn, ””+errMsg.getMeasID(), true);<br />

158 System.out. println (”DBS: ACK CR MeasID #”+errMsg.getMeasID()<br />

+” Comment: ”+errMsg.getComment()+”.”);<br />

160 }<br />

}<br />

162 System.out. println (”DBS: CR Percentage: ”+ (float) CRMsgList.size()<br />

/numMessages+” (”+CRMsgList.size()+” out of ”+numMessages+”).”);<br />

164 msgText += ”CR Percentage: ”+ (float) CRMsgList.size()/numMessages<br />

+” (”+CRMsgList.size()+” out of ”+numMessages+”).\n”;<br />

166<br />

if (AEMsgList.size() == 0)<br />

168 System.out. println (”CPM: no AE messages found.”);<br />

else {<br />

170 for ( i = 0; i < AEMsgList.size (); i++) {<br />

errMsg = (ErrorMessage) AEMsgList.get(i);


C.1. JAVA CODE 77<br />

172 db.updateFlagNotified(conn, ””+errMsg.getMeasID(), true);<br />

System.out. println (”DBS: ACK AE MeasID #”+errMsg.getMeasID()<br />

174 +” Comment: ”+errMsg.getComment()+”.”);<br />

}<br />

176 }<br />

System.out. println (”DBS: AE Percentage: ”+ (float) AEMsgList.size()<br />

178 /numMessages+” (”+AEMsgList.size()+” out of ”+numMessages+”).”);<br />

msgText += ”AE Percentage: ”+ (float) AEMsgList.size()/numMessages<br />

180 +” (”+AEMsgList.size()+” out of ”+numMessages+”).\n”;<br />

182 try {<br />

PendingACKMsgList = db.getPendingACKMessages(conn, MASRcvdTimeOut);<br />

184 if (PendingACKMsgList.size() == 0)<br />

System.out. println (”CPM: no pending ACK messages found.”);<br />

186 else {<br />

for ( i = 0; i < PendingACKMsgList.size(); i++) {<br />

188 errMsg = (ErrorMessage) PendingACKMsgList.get(i);<br />

db.updateFlagNotified(conn, ””+errMsg.getMeasID(), true);<br />

190 db.updateComment(conn, ””+errMsg.getMeasID(), ”Pending ACK”);<br />

System.out. println (”DBS: Pending ACK MeasID #”<br />

192 +errMsg.getMeasID()+”.”);<br />

}<br />

194 }<br />

System.out. println (”DBS: Pending ACK Percentage: ”<br />

196 + (float) PendingACKMsgList.size()/numMessages<br />

+” (”+PendingACKMsgList.size()+” out of ”+numMessages+”).”);<br />

198 msgText += ”Pending ACK Percentage: ”<br />

+ (float) PendingACKMsgList.size()/numMessages+” (”<br />

200 +PendingACKMsgList.size()+” out of ”+numMessages+”).\n”;<br />

202 } catch (NumberFormatException nfe) {<br />

System.err . println (”CPM: NumberFormatException thrown.”);<br />

204 }<br />

206 PendingLISMsgList = db.getPendingLISMessages(conn, LISTimeOut);<br />

if (PendingLISMsgList.size() == 0)<br />

208 System.out. println (”CPM: no pending LIS messages found.”);<br />

else {<br />

210 for ( i = 0; i < PendingLISMsgList.size (); i++) {<br />

errMsg = (ErrorMessage) PendingLISMsgList.get(i);<br />

212 db.updateFlagNotified(conn, ””+errMsg.getMeasID(), true);<br />

db.updateComment(conn, ””+errMsg.getMeasID(), ”Pending LIS ACK”);<br />

214 System.out. println (”DBS: Pending LIS MeasID #”<br />

+errMsg.getMeasID()+”.”);<br />

216 }<br />

}<br />

218 System.out. println (”DBS: Pending LIS Percentage: ”<br />

+ (float) PendingLISMsgList.size()/numMessages<br />

220 +” (”+PendingLISMsgList.size()+” out of ”+numMessages+”).”);<br />

msgText += ”Pending LIS Percentage: ”<br />

222 + (float) PendingLISMsgList.size()/numMessages<br />

+” (”+PendingLISMsgList.size()+” out of ”+numMessages+”).\n”;<br />

224<br />

226<br />

db.closeDB(conn);<br />

SendMail(msgText);


C.1. JAVA CODE 78<br />

228<br />

try {<br />

230 sleep (sleepTimer);<br />

} catch (InterruptedException ie ) {<br />

232 System.err . println (”CPM: Interrupted Exception caught.”);<br />

Logger logger = new Logger(logFileName);<br />

234 logger . log((short ) 7, ( short ) 8, ”CPM”, ”INT EX”,<br />

” Interrupted Exception: CheckPendingMessages thread ”<br />

236 + ”has been shut killed .” );<br />

}<br />

238 } // end while<br />

} // end run<br />

240 } // end CheckPendingMessages class<br />

C.1.3<br />

/**<br />

Config.java<br />

2 * $Workfile : Config. java<br />

*<br />

4 * @version $Revision : 0 $<br />

* @author $Author: David Vogler $<br />

6 * @date $Date: 02/11/00 10:00a $<br />

*<br />

8 * Created by: David Vogler<br />

* Created on: November 2, 2000<br />

10 * Contact: Mike Higgins <br />

*<br />

12 * @description<br />

*<br />

14 * (C) Copyright Agilent Technologies 2000. All rights reserved .<br />

* Reproduction, adaption or translation without prior written<br />

16 * permission is prohibited except as allowed under the copyright<br />

* permission .<br />

18 *<br />

*/<br />

20<br />

22<br />

package ncv.gatewayif;<br />

import java.io . File ;<br />

24 import java.io . FileInputStream ;<br />

import java.io .FileNotFoundException;<br />

26 import java.io .InputStream;<br />

import java.io .IOException;<br />

28 import java.lang. Integer ;<br />

import java. util . Properties ;<br />

30<br />

/** This class provides methods to read configurable values out of a configuration file .<br />

32 */<br />

34 public class Config {<br />

/** filename of the configuration file . */<br />

36 private static String configFileName = ”gatewayif.cfg”;<br />

38 // Socket connection related values */<br />

40 /** name or IP address of the Pilot Server */<br />

private static String PilotServer ;


C.1. JAVA CODE 79<br />

42 /** name or IP address of the remote gateway (MAS) */<br />

private static String RemoteGateway;<br />

44 /** Port on Pilot Server for incoming messages */<br />

private static int CICInPort;<br />

46 /** Port on remote System for outgoing messages */<br />

private static int CICOutPort;<br />

48<br />

private static String SendingApplication ;<br />

50 private static String SendingFacility ;<br />

private static String ReceivingApplication ;<br />

52 private static String ReceivingFacility ;<br />

54 // Database related values<br />

56 /** name of database user */<br />

private static String dbUser;<br />

58 /** password of database user */<br />

private static String dbPassword;<br />

60 /** name of database server */<br />

private static String dbServer;<br />

62 /** name of database */<br />

private static String dbName;<br />

64 /** name of database driver */<br />

private static String dbDriver;<br />

66<br />

68<br />

// Timeouts in milliseconds<br />

/** Time to wait for ACK (CA) message from remote gateway */<br />

70 private static long ACKTimeOut;<br />

/** Timeout for SendMessageClient Thread (sleeptimer) */<br />

72 private static long ScanDBTimeOut;<br />

/** Timeout for CheckPendingMessages Thread (sleeptimer) */<br />

74 private static long CPMTimeOut;<br />

/** Timeout for ReceiveMessageServer Thread (sleeptimer) */<br />

76 private static long RMSTimeOut;<br />

/** Time MAS Test Server waits until sending ACK message */<br />

78 private static long MASRcvdTimeOut;<br />

/** Time MAS Test Server waits until sending LIS ACK message */<br />

80 private static long LISTimeOut;<br />

/** Timeout for closing open socket connections */<br />

82 private static int SocketTimeOut;<br />

84 /** filename of the log file */<br />

private static String logFileName;<br />

86<br />

88<br />

// email related values<br />

/** email From: field */<br />

90 private static String EmailFrom;<br />

/** email To: field */<br />

92 private static String EmailTo;<br />

/** email Subject : field */<br />

94 private static String EmailSubject;<br />

/** name or IP Address of the SMTP server */<br />

96 private static String EmailHost;


C.1. JAVA CODE 80<br />

98 /** returns name or IP address of the Pilot Server */<br />

public static String getPilotServer () {<br />

100 return PilotServer ;<br />

}<br />

102<br />

/** returns name or IP address of the remote gateway */<br />

104 public static String getRemoteGateway() {<br />

return RemoteGateway;<br />

106 }<br />

108 /** returns port number on pilot server side for incoming XML messages */<br />

public static int getCICInPort() {<br />

110 return CICInPort;<br />

}<br />

112<br />

/** returns port number on remote gateway for outgoing XML messages */<br />

114 public static int getCICOutPort() {<br />

return CICOutPort;<br />

116 }<br />

118 /** returns the name of the sending application */<br />

public static String getSendingApplication () {<br />

120 return SendingApplication ;<br />

}<br />

122<br />

/** returns the name of the sending facility */<br />

124 public static String getSendingFacility () {<br />

return SendingFacility ;<br />

126 }<br />

128 /** returns the name of the receiving application */<br />

public static String getReceivingApplication () {<br />

130 return ReceivingApplication ;<br />

}<br />

132<br />

/** returns the name of the receiving facility */<br />

134 public static String getReceivingFacility () {<br />

return ReceivingFacility ;<br />

136 }<br />

138 /** returns the name of the database user */<br />

public static String getdbUser() {<br />

140 return dbUser;<br />

}<br />

142<br />

/** returns the password for the database user */<br />

144 public static String getdbPassword() {<br />

return dbPassword;<br />

146 }<br />

148 /** returns the database server name or IP address */<br />

public static String getdbServer() {<br />

150 return dbServer;<br />

}<br />

152<br />

/** returns the database name */


C.1. JAVA CODE 81<br />

154 public static String getdbName() {<br />

return dbName;<br />

156 }<br />

158 /** returns the name for the database driver */<br />

public static String getdbDriver() {<br />

160 return dbDriver;<br />

}<br />

162<br />

/** returns the path and filename for the configuration file */<br />

164 public static String getConfigFileName() {<br />

return configFileName;<br />

166 }<br />

168 /** returns the timeout for acknowledgement messages. After this time<br />

* the socket connection will be shut down.<br />

170 */<br />

public static long getACKTimeOut() {<br />

172 return ACKTimeOut;<br />

}<br />

174<br />

/** returns the sleeptimer for the SendMessageClient thread. After one<br />

176 * run , the thread will be set asleep for this amount of time.<br />

*/<br />

178 public static long getScanDBTimeOut() {<br />

return ScanDBTimeOut;<br />

180 }<br />

182 /** returns the sleeptimer for the CheckPendingMessages thread. After one<br />

* run , the thread will be set asleep for this amount of time.<br />

184 */<br />

public static long getCPMTimeOut() {<br />

186 return CPMTimeOut;<br />

}<br />

188<br />

/** returns the sleeptimer for the ReceiveMessageServer thread. After one<br />

190 * run , the thread will be set asleep for this amount of time.<br />

*/<br />

192 public static long getRMSTimeOut() {<br />

return RMSTimeOut;<br />

194 }<br />

196 /** returns the timeout for the MAS test gateway until it responds to an incoming<br />

* XML message with a Commit Acknowledgement message.<br />

198 */<br />

public static long getMASRcvdTimeOut() {<br />

200 return MASRcvdTimeOut;<br />

}<br />

202<br />

/** returns the timeout for the MAS test gateway until it responds to an incoming<br />

204 * XML message with an Application Acknowledgement message.<br />

*/<br />

206 public static long getLISTimeOut() {<br />

return LISTimeOut;<br />

208 }


C.1. JAVA CODE 82<br />

210 /** returns the timeout for closing an open socket connection */<br />

public static int getSocketTimeOut() {<br />

212 return SocketTimeOut;<br />

}<br />

214<br />

/** returns the path and filename of the log file . */<br />

216 public static String getLogFileName() {<br />

return logFileName;<br />

218 }<br />

220 /** returns the email From: field for the status <strong>report</strong> */<br />

public static String getEmailFrom() {<br />

222 return EmailFrom;<br />

}<br />

224<br />

/** returns the email To: field for the status <strong>report</strong> */<br />

226 public static String getEmailTo() {<br />

return EmailTo;<br />

228 }<br />

230 /** returns the email Subject : field for the status <strong>report</strong> */<br />

public static String getEmailSubject() {<br />

232 return EmailSubject;<br />

}<br />

234<br />

/** returns the name or IP address for the SMTP server the status <strong>report</strong><br />

236 * message is send to<br />

*/<br />

238 public static String getEmailHost() {<br />

return EmailHost;<br />

240 }<br />

242 /** Constructor needs the filename of the configuration file as parameter */<br />

public Config(String filename ) {<br />

244 configFileName = filename;<br />

File cfgFile = new File(filename );<br />

246 try {<br />

InputStream inStream = new FileInputStream(cfgFile);<br />

248 Properties cfgProp = new Properties();<br />

cfgProp.load(inStream);<br />

250<br />

// get the values from the configuration file , second parameter<br />

252 // is a default value if no value is set in the configuration file<br />

PilotServer = cfgProp.getProperty(” PilotServer ”, ” PilotServer . Agilent”);<br />

254 RemoteGateway = cfgProp.getProperty(”RemoteGateway”, ”MASTestServer”);<br />

CICInPort = Integer . parseInt (cfgProp.getProperty(”CICInPort”, ”5000”));<br />

256 CICOutPort = Integer.parseInt (cfgProp.getProperty(”CICOutPort”, ”5001”));<br />

258 SendingApplication = cfgProp.getProperty(”SendingApplication”,<br />

”SendingApplication”);<br />

260 SendingFacility = cfgProp.getProperty(” SendingFacility ”,<br />

” SendingFacility ”);<br />

262 ReceivingApplication = cfgProp.getProperty(” ReceivingApplication ”,<br />

” ReceivingApplication ”);<br />

264 ReceivingFacility = cfgProp.getProperty(” ReceivingFacility ”,<br />

” ReceivingFacility ”);


C.1. JAVA CODE 83<br />

266<br />

dbUser = cfgProp.getProperty(”dbUser”, ”dbUser”);<br />

268 dbPassword = cfgProp.getProperty(”dbPassword”, ”dbPassword”);<br />

dbServer = cfgProp.getProperty(”dbServer”, ”dbServer”);<br />

270 dbName = cfgProp.getProperty(”dbName”, ”dbName”);<br />

dbDriver = cfgProp.getProperty(”dbDriver”, ”dbDriver”);<br />

272<br />

ACKTimeOut = Long.parseLong(cfgProp.getProperty(”ACKTimeOut”, ”15000”));<br />

274 ScanDBTimeOut = Long.parseLong(cfgProp.getProperty(”ScanDBTimeOut”,<br />

”15000”));<br />

276 CPMTimeOut = Long.parseLong(cfgProp.getProperty(”CPMTimeOut”, ”300000”));<br />

RMSTimeOut = Long.parseLong(cfgProp.getProperty(”RMSTimeOut”, ”1000”));<br />

278<br />

MASRcvdTimeOut = Long.parseLong(cfgProp.getProperty(”MASRcvdTimeOut”,<br />

280 ”60000”));<br />

LISTimeOut = Long.parseLong(cfgProp.getProperty(”LISTimeOut”, ”300000”));<br />

282 SocketTimeOut = Integer.parseInt(cfgProp.getProperty(”SocketTimeOut”,<br />

”60000”));<br />

284<br />

286<br />

logFileName = cfgProp.getProperty(”LogFile”, ”gatewayif . log”);<br />

EmailFrom = cfgProp.getProperty(”EmailFrom”,<br />

288 ”gatewayif@labs. agilent .com”);<br />

EmailTo = cfgProp.getProperty(”EmailTo”, ”david vogler@agilent .com”);<br />

290 EmailSubject = cfgProp.getProperty(”EmailSubject”,<br />

”GatewayIF status <strong>report</strong>”);<br />

292 EmailHost = cfgProp.getProperty(”EmailHost”, ”localhost”);<br />

294 inStream. close ();<br />

296 } catch (FileNotFoundException e) {<br />

System.out. println (”config file not found: ” + filename );<br />

298 System.exit (1);<br />

} catch (IOException e) {<br />

300 System.err . println (”unable to get properties .” );<br />

e. printStackTrace ();<br />

302 System.exit (1);<br />

}<br />

304 }<br />

306 } // end Config class<br />

C.1.4<br />

/**<br />

DBSession.java<br />

2 * $Workfile : DBSession.java<br />

*<br />

4 * @version $Revision : 0 $<br />

* @author $Author: David Vogler $<br />

6 * @date $Date: 02/11/00 10:00a $<br />

*<br />

8 * Created by: David Vogler<br />

* Created on: November 2, 2000<br />

10 * Contact: Mike Higgins <br />

*<br />

12 * @description<br />

*


C.1. JAVA CODE 84<br />

14 * Handles connection to the pilot server database.<br />

*<br />

16 * (C) Copyright Agilent Technologies 2000. All rights reserved .<br />

* Reproduction, adaption or translation without prior written<br />

18 * permission is prohibited except as allowed under the copyright<br />

* permission .<br />

20 *<br />

*/<br />

22<br />

24<br />

26<br />

28<br />

package ncv.gatewayif;<br />

import java. sql .*;<br />

/** This class provides all the database functionality . */<br />

public class DBSession{<br />

30 // username for database login<br />

private static String user = ”sa”;<br />

32 // password for database login<br />

private static String password = ””;<br />

34 // database server name or IP address<br />

private static String server = ”med−iris”;<br />

36 // database name<br />

private static String db = ”demodb”;<br />

38 // database driver<br />

private static String driver = ”com.inet.tds .TdsDriver”;<br />

40 // URL for database driver<br />

private static String url = ”jdbc:inetdae :”+server+”:1433?database=”<br />

42 +db;<br />

44 Connection conn = null;<br />

Statement stmt = null;<br />

46 ResultSet rs = null;<br />

ResultSetMetaData rsmd = null;<br />

48<br />

// query for fetching all new measurements with the information<br />

50 // needed to generate an ORM R01 XML message<br />

private static String query = ”select p.ID as PatientID, p.kppID, ”<br />

52 + ”m.ID as MeasID, mINR.INR Value, mINR.calCode, m.timeStamp ”<br />

+ ”from ”+db+”.dbo.patient p, ”+db+”.dbo.measINR mINR, ”<br />

54 + db+”.dbo.Measurement m ”<br />

+ ”where (m.type = 6) and (p.ID = m.patientID) and (mINR.measID = m.ID) ”<br />

56 + ”and (m.ID in (”<br />

+ ”select MeasID from MeasXferStatus ”<br />

58 + ”where (timeStampSent is null) and (timeStampRcvd is null) ”<br />

+ ”))”;<br />

60<br />

private static String logFileName = ”gateway.log”;<br />

62 private static String timeStamp = ””;<br />

64 /** Constructor initializes member variables with values out of<br />

* the given configuration file<br />

66 */<br />

public DBSession(String configFileName) {<br />

68 Config cfg = new Config(configFileName);<br />

user = cfg.getdbUser();


C.1. JAVA CODE 85<br />

70 password = cfg.getdbPassword();<br />

server = cfg.getdbServer ();<br />

72 db = cfg.getdbName();<br />

driver = cfg.getdbDriver ();<br />

74 url = ”jdbc:inetdae :”+server+”:1433?database=”+db;<br />

}<br />

76<br />

// open database connection<br />

78 // returns Connection object for other methods to access database<br />

80 /** Open a database connection, returns database link as a Connection */<br />

public Connection openDB() {<br />

82 try {<br />

System.out. println (”DBS: connecting to database.”);<br />

84 Class .forName(driver ).newInstance();<br />

conn = DriverManager.getConnection(url, user , password);<br />

86 } catch (Exception e) {<br />

System.err . println (e);<br />

88 e. printStackTrace ();<br />

System.exit (1);<br />

90 }<br />

return conn;<br />

92 }<br />

94 /** update timeStampSent field in MeasXferStatus */<br />

96 public boolean updateTimeStampSent (Connection conn, String MeasID, String timeStamp) {<br />

String updateQuery = ”update ”+db+”.dbo.MeasXferStatus ”<br />

98 + ”set timeStampSent = ’”+ timeStamp + ”’”<br />

+ ” where measID = ”+ MeasID;<br />

100 try {<br />

stmt = conn.createStatement();<br />

102 if (stmt.execute(updateQuery))<br />

return true;<br />

104 else<br />

return false ;<br />

106 } catch (SQLException e) {<br />

System.err . println (”Could not execute update timeStampSent.”);<br />

108 System.err . println (e);<br />

e. printStackTrace ();<br />

110 return false ;<br />

}<br />

112 }<br />

114 /** update timeStampRcvd field in MeasXferStatus */<br />

116 public boolean updateTimeStampRcvd (Connection conn, String MeasID, String timeStamp) {<br />

String updateQuery = ”update ”+db+”.dbo.MeasXferStatus ”<br />

118 + ”set timeStampRcvd = ’”+ timeStamp + ”’”<br />

+ ” where measID = ”+ MeasID;<br />

120 try {<br />

stmt = conn.createStatement();<br />

122 if (stmt.execute(updateQuery))<br />

return true;<br />

124 else<br />

return false ;


C.1. JAVA CODE 86<br />

126 } catch (SQLException e) {<br />

System.err . println (”Could not execute update timeStampRcvd.”);<br />

128 return false ;<br />

}<br />

130 }<br />

132 /** update timeStampLIS field in MeasXferStatus */<br />

134 public boolean updateTimeStampLIS (Connection conn, String MeasID, String timeStamp) {<br />

String updateQuery = ”update ”+db+”.dbo.MeasXferStatus ”<br />

136 + ”set timeStampLIS = ’”+ timeStamp + ”’”<br />

+ ” where measID = ”+ MeasID;<br />

138 try {<br />

stmt = conn.createStatement();<br />

140 if (stmt.execute(updateQuery))<br />

return true;<br />

142 else<br />

return false ;<br />

144 } catch (SQLException e) {<br />

System.err . println (”Could not execute update timeStampLIS.”);<br />

146 return false ;<br />

}<br />

148 }<br />

150 /** update flagCA field in MeasXferStatus */<br />

152 public boolean updateFlagCA (Connection conn, String MeasID, boolean flag) {<br />

int MSSQLFlag = (flag) ? 1 : 0;<br />

154 String updateQuery = ”update ”+db+”.dbo.MeasXferStatus ”<br />

+ ”set flagCA = ”+ MSSQLFlag<br />

156 + ” where measID = ”+ MeasID;<br />

try {<br />

158 stmt = conn.createStatement();<br />

if (stmt.execute(updateQuery))<br />

160 return true;<br />

else<br />

162 return false ;<br />

} catch (SQLException e) {<br />

164 System.err . println (”Could not execute update flagCA.”);<br />

System.err . println (e);<br />

166 e. printStackTrace ();<br />

return false ;<br />

168 }<br />

}<br />

170<br />

172<br />

/** update flagCE field in MeasXferStatus */<br />

public boolean updateFlagCE (Connection conn, String MeasID, boolean flag) {<br />

174 int MSSQLFlag = (flag) ? 1 : 0;<br />

String updateQuery = ”update ”+db+”.dbo.MeasXferStatus ”<br />

176 + ”set flagCE = ”+ MSSQLFlag<br />

+ ” where measID = ”+ MeasID;<br />

178 try {<br />

stmt = conn.createStatement();<br />

180 if (stmt.execute(updateQuery))<br />

return true;


C.1. JAVA CODE 87<br />

182 else<br />

return false ;<br />

184 } catch (SQLException e) {<br />

System.err . println (”Could not execute update flagCE.”);<br />

186 return false ;<br />

}<br />

188 }<br />

190 /** update flagCR field in MeasXferStatus */<br />

192 public boolean updateFlagCR (Connection conn, String MeasID, boolean flag) {<br />

int MSSQLFlag = (flag) ? 1 : 0;<br />

194 String updateQuery = ”update ”+db+”.dbo.MeasXferStatus ”<br />

+ ”set flagCR = ”+ MSSQLFlag<br />

196 + ” where measID = ”+ MeasID;<br />

try {<br />

198 stmt = conn.createStatement();<br />

if (stmt.execute(updateQuery))<br />

200 return true;<br />

else<br />

202 return false ;<br />

} catch (SQLException e) {<br />

204 System.err . println (”Could not execute update flagCR.”);<br />

return false ;<br />

206 }<br />

}<br />

208<br />

210<br />

/** update flagAA field in MeasXferStatus */<br />

public boolean updateFlagAA (Connection conn, String MeasID, boolean flag) {<br />

212 int MSSQLFlag = (flag) ? 1 : 0;<br />

String updateQuery = ”update ”+db+”.dbo.MeasXferStatus ”<br />

214 + ”set flagAA = ”+ MSSQLFlag<br />

+ ” where measID = ”+ MeasID;<br />

216 try {<br />

stmt = conn.createStatement();<br />

218 if (stmt.execute(updateQuery))<br />

return true;<br />

220 else<br />

return false ;<br />

222 } catch (SQLException e) {<br />

System.err . println (”Could not execute update flagAA.”);<br />

224 return false ;<br />

}<br />

226 }<br />

228 /** update flagAE field in MeasXferStatus */<br />

230 public boolean updateFlagAE (Connection conn, String MeasID, boolean flag) {<br />

int MSSQLFlag = (flag) ? 1 : 0;<br />

232 String updateQuery = ”update ”+db+”.dbo.MeasXferStatus ”<br />

+ ”set flagAE = ”+ MSSQLFlag<br />

234 + ” where measID = ”+ MeasID;<br />

try {<br />

236 stmt = conn.createStatement();<br />

if (stmt.execute(updateQuery))


C.1. JAVA CODE 88<br />

238 return true;<br />

else<br />

240 return false ;<br />

} catch (SQLException e) {<br />

242 System.err . println (”Could not execute update flagAE.”);<br />

return false ;<br />

244 }<br />

}<br />

246<br />

248<br />

/** update flagNotified field in MeasXferStatus */<br />

public boolean updateFlagNotified (Connection conn, String MeasID, boolean flag) {<br />

250 int MSSQLFlag = (flag) ? 1 : 0;<br />

String updateQuery = ”update ”+db+”.dbo.MeasXferStatus ”<br />

252 + ”set flagNotified = ”+ MSSQLFlag<br />

+ ” where measID = ”+ MeasID;<br />

254 try {<br />

stmt = conn.createStatement();<br />

256 if (stmt.execute(updateQuery))<br />

return true;<br />

258 else<br />

return false ;<br />

260 } catch (SQLException e) {<br />

System.err . println (”DBS: Could not execute update flagNotified.”);<br />

262 return false ;<br />

}<br />

264 }<br />

266 /** update timesSent field in MeasXferStatus */<br />

268 public boolean updateTimesSent (Connection conn, String MeasID, int times) {<br />

String updateQuery = ”update ”+db+”.dbo.MeasXferStatus ”<br />

270 + ”set timesSent = ”+ times<br />

+ ” where measID = ”+ MeasID;<br />

272 try {<br />

stmt = conn.createStatement();<br />

274 if (stmt.execute(updateQuery))<br />

return true;<br />

276 else<br />

return false ;<br />

278 } catch (SQLException e) {<br />

System.err . println (”Could not execute update timesSent.”);<br />

280 return false ;<br />

}<br />

282 }<br />

284 /** update comment in MeasXferStatus */<br />

286 public boolean updateComment (Connection conn, String MeasID, String Comment) {<br />

String updateQuery = ”update ”+db+”.dbo.MeasXferStatus ”<br />

288 + ”set comment = ’”+ Comment<br />

+ ”’ where measID = ”+ MeasID;<br />

290 try {<br />

System.out. println (”DBS: updating MeasID #”+MeasID+” comment to: ”<br />

292 +Comment);<br />

stmt = conn.createStatement();


C.1. JAVA CODE 89<br />

294 if (stmt.execute(updateQuery))<br />

return true;<br />

296 else<br />

return false ;<br />

298 } catch (SQLException e) {<br />

System.err . println (”Could not execute update comment.”);<br />

300 return false ;<br />

}<br />

302 }<br />

304 /** close database connection */<br />

306 public void closeDB(Connection conn) {<br />

try {<br />

308 conn.close ();<br />

} catch (Exception e) {<br />

310 System.err . println (e);<br />

e. printStackTrace ();<br />

312 System.exit (1);<br />

}<br />

314 }<br />

316 /** returns Object MessageList with all new measurements */<br />

318 public MessageList getMsgList(Connection conn) {<br />

MessageList MsgList = new MessageList();<br />

320 try {<br />

stmt = conn.createStatement();<br />

322 if (stmt.execute(query)) {<br />

rs = stmt.getResultSet ();<br />

324 rsmd = rs.getMetaData();<br />

int numColumns = rsmd.getColumnCount();<br />

326 // for ( int i = 0; i < 3; i++) {<br />

// rs .next ();<br />

328<br />

330<br />

System.out. println (”DBS: fetching messages from database.”);<br />

while(rs .next ()) {<br />

332 SendMessage msg = new SendMessage(rs.getInt(1), rs.getString(2),<br />

rs . getInt (3), rs . getFloat (4), rs . getFloat (5),<br />

334 rs . getString (6));<br />

System.out. println (”DBS: adding new message to list.”);<br />

336 MsgList.add(msg);<br />

}<br />

338 rs . close ();<br />

}<br />

340 stmt. close ();<br />

} catch (SQLException sqle) {<br />

342 System.err . println ( sqle );<br />

sqle . printStackTrace ();<br />

344 System.exit (1);<br />

}<br />

346 return MsgList;<br />

}<br />

348<br />

/** get Messages with Pending timeStampRcvd */


C.1. JAVA CODE 90<br />

350<br />

public ErrorMessageList getPendingACKMessages(Connection conn, long timeDiff) {<br />

352 ErrorMessageList ErrMsgList = new ErrorMessageList();<br />

String selectQuery = ”select MeasID, timeStampSent, Comment from ”+db<br />

354 +”.dbo.MeasXferStatus ”<br />

+ ”where (timeStampRcvd is null) and (timeStampSent is not null) ”<br />

356 + ”and (flagNotified is null )”;<br />

try {<br />

358 stmt = conn.createStatement();<br />

if (stmt.execute(selectQuery )) {<br />

360 rs = stmt.getResultSet ();<br />

while ( rs .next ()) {<br />

362 ErrorMessage errMsg = new ErrorMessage(rs.getInt(1),<br />

rs . getString (3));<br />

364 Timestamp timeStampSent = rs.getTimestamp(2);<br />

if (MiscDate.getTimeDiff(timeStampSent) > timeDiff) {<br />

366 ErrMsgList.add(errMsg);<br />

}<br />

368 }<br />

}<br />

370 } catch (SQLException sqle) {<br />

System.err . println (”DBS: error getting pending ACK message list.”);<br />

372 Logger logger = new Logger(logFileName);<br />

logger . log((short ) 7, ( short ) 8, ”DBS”, ”GET ACK LIST ERR”,<br />

374 ”SQLError getting pending ACK message list.”);<br />

}<br />

376 return ErrMsgList;<br />

}<br />

378<br />

380<br />

/** get Messages with Pending timeStampLIS */<br />

public ErrorMessageList getPendingLISMessages(Connection conn, long timeDiff) {<br />

382 ErrorMessageList ErrMsgList = new ErrorMessageList();<br />

timeStamp = MiscDate.todaysDate();<br />

384 String selectQuery = ”select MeasID, timeStampSent, Comment from ”+db<br />

+”.dbo.MeasXferStatus ”<br />

386 + ”where (timeStampLIS is null) and (timeStampSent is not null) ”<br />

+ ”and (flagNotified is null )”;<br />

388 try {<br />

stmt = conn.createStatement();<br />

390 if (stmt.execute(selectQuery )) {<br />

rs = stmt.getResultSet ();<br />

392 while ( rs .next ()) {<br />

ErrorMessage errMsg = new ErrorMessage(rs.getInt(1),<br />

394 rs . getString (3));<br />

Timestamp timeStampSent = rs.getTimestamp(2);<br />

396 if (MiscDate.getTimeDiff(timeStampSent) > timeDiff) {<br />

ErrMsgList.add(errMsg);<br />

398 }<br />

}<br />

400 }<br />

} catch (SQLException sqle) {<br />

402 System.err . println (”DBS: error getting pending LIS message list .” );<br />

Logger logger = new Logger(logFileName);<br />

404 logger . log((short ) 7, ( short ) 8, ”DBS”, ”GET LIS LIST ERR”,<br />

”SQLError getting pending LIS message list.” );


C.1. JAVA CODE 91<br />

406 }<br />

return ErrMsgList;<br />

408 }<br />

410 /** get Messages with flagCE set to true */<br />

412 public ErrorMessageList getCommitErrorMessages(Connection conn) {<br />

ErrorMessageList ErrMsgList = new ErrorMessageList();<br />

414 String selectQuery = ”select MeasID, Comment from ”+db+”.dbo.MeasXferStatus ”<br />

+ ”where (flagCE = 1) ”<br />

416 + ”and (flagNotified is null )”;<br />

try {<br />

418 stmt = conn.createStatement();<br />

if (stmt.execute(selectQuery )) {<br />

420 rs = stmt.getResultSet ();<br />

while ( rs .next ()) {<br />

422 ErrorMessage errMsg = new ErrorMessage(rs.getInt(1),<br />

rs . getString (2));<br />

424 ErrMsgList.add(errMsg);<br />

}<br />

426 }<br />

} catch (SQLException sqle) {<br />

428 System.err . println (”DBS: error getting CE message list.” );<br />

Logger logger = new Logger(logFileName);<br />

430 logger . log((short ) 7, ( short ) 8, ”DBS”, ”GET CE LIST ERR”,<br />

”SQLError getting CE message list.”);<br />

432 }<br />

return ErrMsgList;<br />

434 }<br />

436 /** get Messages with flagCR set to true */<br />

438 public ErrorMessageList getCommitRejectMessages(Connection conn) {<br />

ErrorMessageList ErrMsgList = new ErrorMessageList();<br />

440 String selectQuery = ”select MeasID, Comment from ”+db+”.dbo.MeasXferStatus ”<br />

+ ”where (flagCR = 1) ”<br />

442 + ”and (flagNotified is null )”;<br />

try {<br />

444 stmt = conn.createStatement();<br />

if (stmt.execute(selectQuery )) {<br />

446 rs = stmt.getResultSet ();<br />

while ( rs .next ()) {<br />

448 ErrorMessage errMsg = new ErrorMessage(rs.getInt(1),<br />

rs . getString (2));<br />

450 ErrMsgList.add(errMsg);<br />

}<br />

452 }<br />

} catch (SQLException sqle) {<br />

454 System.err . println (”DBS: error getting CR message list.” );<br />

Logger logger = new Logger(logFileName);<br />

456 logger . log((short ) 7, ( short ) 8, ”DBS”, ”GET CR LIST ERR”,<br />

”SQLError getting CR message list.”);<br />

458 }<br />

return ErrMsgList;<br />

460 }


C.1. JAVA CODE 92<br />

462 /** get Messages with flagAE set to true */<br />

464 public ErrorMessageList getApplicationErrorMessages(Connection conn) {<br />

ErrorMessageList ErrMsgList = new ErrorMessageList();<br />

466 String selectQuery = ”select MeasID, Comment from ”+db+”.dbo.MeasXferStatus ”<br />

+ ”where (flagAE = 1) ”<br />

468 + ”and (flagNotified is null )”;<br />

try {<br />

470 stmt = conn.createStatement();<br />

if (stmt.execute(selectQuery )) {<br />

472 rs = stmt.getResultSet ();<br />

while ( rs .next ()) {<br />

474 ErrorMessage errMsg = new ErrorMessage(rs.getInt(1),<br />

rs . getString (2));<br />

476 ErrMsgList.add(errMsg);<br />

}<br />

478 }<br />

} catch (SQLException sqle) {<br />

480 System.err . println (”DBS: error getting AE message list.” );<br />

Logger logger = new Logger(logFileName);<br />

482 logger . log((short ) 7, ( short ) 8, ”DBS”, ”GET AE LIST ERR”,<br />

”SQLError getting AE message list.”);<br />

484 }<br />

return ErrMsgList;<br />

486 }<br />

488 /** get timesSent field in MeasXferStatus */<br />

490 public int getTimesSent (Connection conn, String MeasID) {<br />

String selectQuery = ”select timesSent from ”+db+”.dbo.MeasXferStatus ”<br />

492 + ”where measID = ”+ MeasID;<br />

try {<br />

494 stmt = conn.createStatement();<br />

if (stmt.execute(selectQuery )) {<br />

496 rs = stmt.getResultSet ();<br />

rs .next ();<br />

498 return rs . getInt (1);<br />

} else<br />

500 return −1;<br />

} catch (SQLException e) {<br />

502 System.err . println (”Could not get timesSent data.”);<br />

return −1;<br />

504 }<br />

}<br />

506<br />

508<br />

/** get number of rows in table MeasXferStatys */<br />

public int getNumRows (Connection conn) {<br />

510 String selectQuery = ”select MeasID from ”+db+”.dbo.MeasXferStatus”;<br />

int numRows = 0;<br />

512 try {<br />

stmt = conn.createStatement();<br />

514 if (stmt.execute(selectQuery )) {<br />

rs = stmt.getResultSet ();<br />

516 while ( rs .next())<br />

numRows++;


C.1. JAVA CODE 93<br />

518 } else<br />

numRows = 0;<br />

520 } catch (SQLException sqle) {<br />

System.err . println (”DBS: error getting number of rows.”);<br />

522 Logger logger = new Logger(logFileName);<br />

logger . log((short ) 7, ( short ) 8, ”DBS”, ”GET NUM ROWS ERR”,<br />

524 ”SQLError getting number of rows.”);<br />

}<br />

526 return numRows;<br />

}<br />

528 }<br />

C.1.5<br />

/**<br />

ErrorMessage.java<br />

2 * $Workfile : ErrorMessage.java<br />

*<br />

4 * @version $Revision : 0 $<br />

* @author $Author: David Vogler $<br />

6 * @date $Date: 02/11/00 10:00a $<br />

*<br />

8 * Created by: David Vogler<br />

* Created on: November 2, 2000<br />

10 * Contact: Mike Higgins <br />

*<br />

12 * @description<br />

*<br />

14 * (C) Copyright Agilent Technologies 2000. All rights reserved .<br />

* Reproduction, adaption or translation without prior written<br />

16 * permission is prohibited except as allowed under the copyright<br />

* permission .<br />

18 *<br />

*/<br />

20<br />

22<br />

package ncv.gatewayif;<br />

/** This class represents an error message object used by<br />

24 * the class CheckPendingMessages<br />

*/<br />

26<br />

28<br />

public class ErrorMessage {<br />

/** MeasID out of the database to identify the dataset */<br />

30 protected int MeasID;<br />

/** Comment string for the MeasXferStatus table */<br />

32 protected String Comment;<br />

34 /** Constructor initializes the member values */<br />

public ErrorMessage (int MeasID, String Comment) {<br />

36 this .MeasID = MeasID;<br />

this .Comment = Comment;<br />

38 }<br />

40 /** returns the MeasID of the error message */<br />

public int getMeasID() {<br />

42 return MeasID;<br />

}


C.1. JAVA CODE 94<br />

44<br />

/** returns the error comment of the error message */<br />

46 public String getComment() {<br />

return Comment;<br />

48 }<br />

}<br />

C.1.6<br />

/**<br />

ErrorMessageList.java<br />

2 * $Workfile : ErrorMessageList. java<br />

*<br />

4 * @version $Revision : 0 $<br />

* @author $Author: David Vogler $<br />

6 * @date $Date: 02/11/00 10:00a $<br />

*<br />

8 * Created by: David Vogler<br />

* Created on: November 2, 2000<br />

10 * Contact: Mike Higgins <br />

*<br />

12 * @description<br />

*<br />

14 * (C) Copyright Agilent Technologies 2000. All rights reserved .<br />

* Reproduction, adaption or translation without prior written<br />

16 * permission is prohibited except as allowed under the copyright<br />

* permission .<br />

18 *<br />

*/<br />

20<br />

22<br />

24<br />

package ncv.gatewayif;<br />

import java. util . LinkedList ;<br />

/** This class is used by the CheckPendingMessages class to generate<br />

26 * a list of ErrorMessages<br />

*/<br />

28 public class ErrorMessageList extends LinkedList{<br />

}<br />

C.1.7<br />

/**<br />

Logger.java<br />

2 * $Workfile : Logger.java<br />

*<br />

4 * @version $Revision : 0 $<br />

* @author $Author: David Vogler $<br />

6 * @date $Date: 02/11/00 10:00a $<br />

*<br />

8 * Created by: David Vogler<br />

* Created on: November 2, 2000<br />

10 * Contact: Mike Higgins <br />

*<br />

12 * @description<br />

*<br />

14 * (C) Copyright Agilent Technologies 2000. All rights reserved .<br />

* Reproduction, adaption or translation without prior written<br />

16 * permission is prohibited except as allowed under the copyright<br />

* permission .


C.1. JAVA CODE 95<br />

18 *<br />

*/<br />

20<br />

22<br />

24<br />

package ncv.gatewayif;<br />

import java.io .*;<br />

/** This class is intended to log errors and other useful information to<br />

26 * an ASCII text file<br />

*/<br />

28 public class Logger {<br />

String fileName;<br />

30<br />

/** Constructor needs filename of logfile */<br />

32 public Logger (String fileName) {<br />

this .fileName = fileName;<br />

34 }<br />

36 /** Constructor with default filename if no parameter is given */<br />

public Logger () {<br />

38 this(”gatewayif . log”);<br />

}<br />

40<br />

/** clear all logged entries in logfile */<br />

42 public void clearLog () {<br />

try {<br />

44 BufferedWriter f = new BufferedWriter (new FileWriter(fileName,<br />

false ));<br />

46 String S = MiscDate.todaysDate();<br />

f . write(S , 0, S.length ());<br />

48 f .newLine();<br />

f . close ();<br />

50 } catch (IOException e) {}<br />

}<br />

52<br />

54<br />

/** add new entry to log file with given parameters */<br />

public boolean log(short priority , short subSystemCode,<br />

56 String moduleCode, String errorCode, String message) {<br />

try {<br />

58 RandomAccessFile file = new RandomAccessFile(fileName, ”rw”);<br />

long length = file . length ();<br />

60 file .seek(length );<br />

PrintWriter out = new PrintWriter(new FileWriter( file .getFD()), true);<br />

62 if (out != null ) {<br />

out. println (””+MiscDate.todaysDate()+” prio:”+priority<br />

64 +” subSystemCode:”+subSystemCode+” moduleCode:”<br />

+moduleCode+” errorCode:”+errorCode+” msg:”+message);<br />

66 out. close ();<br />

} else<br />

68 return false ;<br />

file . close ();<br />

70 return true;<br />

} catch (IOException ioe) {<br />

72 System.err . println (” error writing logfile .” );<br />

return false ;


C.1. JAVA CODE 96<br />

74 }<br />

}<br />

76 } // end of Logger class<br />

C.1.8<br />

/**<br />

MASTestServer.java<br />

2 * $Workfile : MASTestServer.java<br />

*<br />

4 * @version $Revision : 0 $<br />

* @author $Author: David Vogler $<br />

6 * @date $Date: 02/11/00 10:00a $<br />

*<br />

8 * Created by: David Vogler<br />

* Created on: November 2, 2000<br />

10 * Contact: Mike Higgins <br />

*<br />

12 * @description<br />

*<br />

14 * (C) Copyright Agilent Technologies 2000. All rights reserved .<br />

* Reproduction, adaption or translation without prior written<br />

16 * permission is prohibited except as allowed under the copyright<br />

* permission .<br />

18 *<br />

*/<br />

20<br />

22<br />

24<br />

26<br />

package ncv.gatewayif;<br />

import java. util .Date;<br />

import java. text .DateFormat;<br />

import java.io . File ;<br />

28 import java.io .IOException;<br />

import java.io .BufferedReader;<br />

30 import java.io . FileInputStream ;<br />

import java.io .InputStream;<br />

32 import java.io .InputStreamReader;<br />

import java.io . PrintWriter ;<br />

34 import java.io .Reader;<br />

import java.io .StringReader;<br />

36<br />

import java.net.ServerSocket;<br />

38 import java.net.Socket;<br />

import java.net.UnknownHostException;<br />

40 import java.net.ConnectException;<br />

42 import org.apache.xerces . parsers .DOMParser;<br />

44 import org.w3c.dom.Document;<br />

import org.w3c.dom.Node;<br />

46 import org.w3c.dom.NodeList;<br />

48 import org.xml.sax.InputSource;<br />

50 import ncv.gatewayif.Config;


C.1. JAVA CODE 97<br />

52 /** Simulation of the MAS Gateway Interface and Sunquest’s Laboratory<br />

Information System (LIS)<br />

54 */<br />

56 public class MASTestServer extends Thread {<br />

/** Port for incoming XML messages */<br />

58 public static int CICINPORT = 5000;<br />

/** Port for outgoing XML messages */<br />

60 public static int CICOUTPORT = 5001;<br />

public static long TIMEOUT = 1000L;<br />

62 /** Time MAS waits until sending response */<br />

public static long RESPONSETIME = 10000L;<br />

64 /** Time MAS waits until sending timeout response */<br />

public static long RESPONSETIMEOUT = 60000L;<br />

66 public static long responseTime = RESPONSETIME;<br />

public static String RECVSERVER = ”130.29.247.103”;<br />

68 private static final int MAXRESP = 9;<br />

/** array for different kinds of response cases */<br />

70 private static String [] responseCase = new String[MAXRESP];<br />

private String msgType=””;<br />

72<br />

74<br />

private long sleepTimer;<br />

/** constructor sets default values from MAS.cfg file */<br />

76 public MASTestServer (long delay) {<br />

sleepTimer = delay;<br />

78 setDaemon(true);<br />

File cfgFile = new File(”MAS.cfg”);<br />

80<br />

try {<br />

82 BufferedReader in = new BufferedReader(new InputStreamReader(new<br />

FileInputStream( cfgFile )));<br />

84 for ( int i = 0; i < MAXRESP; i++) {<br />

responseCase[ i ] = in .readLine ();<br />

86 System.out. println (”MAS: case[”+i+”] = ” + responseCase[i]);<br />

}<br />

88 in . close ();<br />

} catch (IOException ioe) {<br />

90 System.err . println (”MAS: error reading configuration file .” );<br />

System.err . println (ioe );<br />

92 ioe . printStackTrace ();<br />

}<br />

94 }<br />

96 /** generate DOM document out of received XML string */<br />

98 public Document getDOMDocument(String xmlstring){<br />

Reader xmlreader = new StringReader(xmlstring);<br />

100 InputSource xmlsource = new InputSource(xmlreader);<br />

102 DOMParser parser = new DOMParser();<br />

104 try {<br />

parser . parse(xmlsource);<br />

106 } catch (Exception e) {<br />

System.err . println (”Error in parsing : ” + e.getMessage());


C.1. JAVA CODE 98<br />

108 e. printStackTrace ();<br />

}<br />

110 Document doc = parser.getDocument();<br />

return doc;<br />

112 }<br />

114 public static void main(String [] args ) throws IOException {<br />

116 System.out. println (”MAS Gateway Interface Test Server”);<br />

118 Thread first = new MASTestServer(TIMEOUT);<br />

120 System.out. println (”press enter to quit .” );<br />

122 first . start ();<br />

124 try {<br />

System.in.read ();<br />

126 System.out. println (”MASTestServer shutdown.”);<br />

} catch (IOException e) {<br />

128 System.err . println (e);<br />

e. printStackTrace ();<br />

130 System.exit (1);<br />

}<br />

132<br />

134 }<br />

return;<br />

136 public void run() {<br />

138 ServerSocket serverSocket = null;<br />

Socket clientSocket = null;<br />

140 Socket sendSocket = null;<br />

DateFormat defaultDate;<br />

142 PrintWriter out = null;<br />

BufferedReader in = null;<br />

144 String inputLine , outputLine , message;<br />

Document doc;<br />

146 NodeList nodeList;<br />

Node nodeMSH10Text; // Message Control ID<br />

148 String MessageControlID = ” uninitialized ”;<br />

String endDocumentTag = ””;<br />

150 SendMessage msg;<br />

int c;<br />

152 int rsp = 0;<br />

154 Config cfg = new Config(Config.getConfigFileName());<br />

156 RECVSERVER = cfg.getPilotServer();<br />

CICINPORT = cfg.getCICInPort();<br />

158 CICOUTPORT = cfg.getCICOutPort();<br />

160 while(true) {<br />

162 System.out. println (”ready to listen on port #”+CICINPORT+”.\n”);


C.1. JAVA CODE 99<br />

164 try {<br />

serverSocket = new ServerSocket(CICINPORT);<br />

166 } catch (IOException e) {<br />

System.err . println (”Can not listen on port #” + CICINPORT);<br />

168 System.err . println (e);<br />

e. printStackTrace ();<br />

170 System.exit (1);<br />

}<br />

172<br />

try {<br />

174 clientSocket = serverSocket .accept ();<br />

} catch (IOException e) {<br />

176 System.err . println (”Accept failed .” );<br />

System.err . println (e);<br />

178 e. printStackTrace ();<br />

}<br />

180<br />

defaultDate = DateFormat.getDateInstance();<br />

182 System.out. print (defaultDate.format(new Date()));<br />

System.out. println (” incoming socket connection established .” );<br />

184<br />

// go to next test case<br />

186 System.out. println (”Processing test case #”+rsp+”.”);<br />

188<br />

try {<br />

190 out = new<br />

PrintWriter ( clientSocket .getOutputStream(),true);<br />

192 in = new BufferedReader(new<br />

InputStreamReader(clientSocket.getInputStream()));<br />

194<br />

196<br />

message = new String();<br />

while((inputLine = in.readLine ()) != null ) {<br />

198 if ( inputLine .indexOf(”ORM O01”, 0) > 0)<br />

endDocumentTag = ””;<br />

200 if ( inputLine .indexOf(endDocumentTag, 0) > 0) {<br />

message += inputLine;<br />

202 // System.out. println (”MAS: ” + inputLine);<br />

break;<br />

204 } else {<br />

message += inputLine;<br />

206 // System.out. println (”MAS: ” + inputLine);<br />

}<br />

208 }<br />

210 doc = getDOMDocument(message);<br />

nodeList = doc.getElementsByTagName(”MSH.10”);<br />

212 nodeMSH10Text = nodeList.item(0).getFirstChild();<br />

MessageControlID = nodeMSH10Text.getNodeValue();<br />

214 System.out. println (”MSH.10 = ” + nodeMSH10Text.getNodeValue());<br />

216 System.out. println (”MAS: response case for this test run is ”<br />

+ responseCase[rsp] + ”.” );<br />

218<br />

if (responseCase[rsp ]. equals(”CA”) || responseCase[rsp ]. equals(”AA”)


C.1. JAVA CODE 100<br />

220 || responseCase[rsp ]. equals(”AE”)<br />

|| responseCase[rsp ]. equals(”00”)) {<br />

222 msgType = ”CA”;<br />

msg = new SendMessage(MessageControlID, msgType);<br />

224 System.out. println (”MAS: ACK CA generated.”);<br />

} else if (responseCase[rsp ]. equals(”CE”)) {<br />

226 msgType = ”CE”;<br />

msg = new SendMessage(MessageControlID, msgType);<br />

228 msg.setErrorComment(”General Error”);<br />

System.out. println (”MAS: ACK CE generated.”);<br />

230 } else if (responseCase[rsp ]. equals(”CR”)) {<br />

msgType = ”CR”;<br />

232 msg = new SendMessage(MessageControlID, msgType);<br />

msg.setErrorComment(”General Rejection”);<br />

234 System.out. println (”MAS: ACK CR generated.”);<br />

} else {<br />

236 msgType = ”CA”;<br />

msg = new SendMessage(MessageControlID, msgType);<br />

238 }<br />

240 // sleep to simulate response time<br />

242 if (responseCase[rsp ]. equals(”00”))<br />

responseTime = RESPONSETIMEOUT;<br />

244 else<br />

responseTime = RESPONSETIME;<br />

246<br />

System.out. println (”MAS: waiting for ” + (responseTime/1000)<br />

248 + ” seconds to send message.”);<br />

try {<br />

250 sleep (responseTime);<br />

} catch (InterruptedException ie ) {<br />

252 System.err . println (”MAS: sleep() interrupted.” );<br />

}<br />

254<br />

out. println (msg.toString ACK());<br />

256 System.out. println (”MAS: ACK ”+msgType+” message sent.”);<br />

// System.out. println (”MAS: ” + msg.toString ACK());<br />

258<br />

in . close ();<br />

260 out. close ();<br />

clientSocket . close ();<br />

262 serverSocket . close ();<br />

264 } catch (IOException e) {<br />

System.err . println (e);<br />

266 e. printStackTrace ();<br />

System.exit (1);<br />

268 }<br />

270 // now sending AA to RecvMessageServer on Port #5001<br />

// depending on test case.<br />

272<br />

if (responseCase[rsp ]. equals(”AA”) || responseCase[rsp ]. equals(”AE”)) {<br />

274 try {<br />

System.out. println (”Sending ACK to ”+RECVSERVER+” on port #”


C.1. JAVA CODE 101<br />

276 +CICOUTPORT);<br />

sendSocket = new Socket(RECVSERVER, CICOUTPORT);<br />

278 out = new PrintWriter(sendSocket.getOutputStream(), true);<br />

in = new BufferedReader(new<br />

280 InputStreamReader(sendSocket.getInputStream()));<br />

} catch (UnknownHostException e) {<br />

282 System.err . println (”Don’t know about hostname: ” +<br />

RECVSERVER);<br />

284 System.err . println (e);<br />

e. printStackTrace ();<br />

286 System.exit (1);<br />

} catch (ConnectException e) {<br />

288 System.err . println (”Connection has been refused. Try it again.” );<br />

} catch (IOException e) {<br />

290 System.err . println (”Couldn’t get I/O for connection. ”<br />

+ ”Try it again.” );<br />

292 }<br />

294<br />

try {<br />

296 System.out. println (”Sending Application Ack (”+responseCase[rsp]<br />

+”) to Pilot Server Gateway.”);<br />

298 msg = new SendMessage(MessageControlID, responseCase[rsp]);<br />

if (responseCase[rsp ]. equals(”AA”))<br />

300 msg.setErrorComment(”A24680”);<br />

else<br />

302 msg.setErrorComment(”Invalid Patient”);<br />

out. println (msg.toString ORR O02());<br />

304 System.out. println (”Closing socket connection to PS Gateway ”<br />

+ ”Interface .” );<br />

306 } catch (Exception e) {<br />

System.err . println (”Error sending message.”);<br />

308 }<br />

310 try {<br />

message = new String();<br />

312<br />

while((inputLine = in.readLine ()) != null ) {<br />

314 if ( inputLine .indexOf(”ACK”, 0) > 0)<br />

endDocumentTag = ””;<br />

316 if ( inputLine .indexOf(endDocumentTag, 0) > 0) {<br />

message += inputLine;<br />

318 break;<br />

} else {<br />

320 message += inputLine;<br />

}<br />

322 }<br />

324 RecvMessage msgIN = new RecvMessage(message);<br />

System.out. println (”MAS: rcvd ACK for AA: ”<br />

326 +msgIN.getMsgControlID());<br />

328 } catch (IOException ioe) {<br />

System.err . println (”MAS: error receiving CA.”);<br />

330 }


C.1. JAVA CODE 102<br />

332 try {<br />

sendSocket. close ();<br />

334 out. close ();<br />

in . close ();<br />

336 } catch (IOException e) {<br />

System.err . println (e);<br />

338 e. printStackTrace ();<br />

System.exit (1);<br />

340 } catch (NullPointerException e) {<br />

System.err . println (”Null Pointer Exception for closing socket.” );<br />

342 }<br />

}<br />

344<br />

// setting new test case<br />

346 rsp++;<br />

if ( rsp >= MAXRESP)<br />

348 rsp = 0;<br />

350 try {<br />

System.out. println (”Connection closed. Waiting for timeout.” );<br />

352 sleep (sleepTimer);<br />

} catch (InterruptedException e) {<br />

354 System.err . println (e);<br />

e. printStackTrace ();<br />

356 System.exit (1);<br />

}<br />

358<br />

360 }<br />

}<br />

C.1.9<br />

/**<br />

}<br />

MessageList.java<br />

2 * $Workfile : MessageList.java<br />

*<br />

4 * @version $Revision : 0 $<br />

* @author $Author: David Vogler $<br />

6 * @date $Date: 02/11/00 10:00a $<br />

*<br />

8 * Created by: David Vogler<br />

* Created on: November 2, 2000<br />

10 * Contact: Mike Higgins <br />

*<br />

12 * @description<br />

*<br />

14 * (C) Copyright Agilent Technologies 2000. All rights reserved .<br />

* Reproduction, adaption or translation without prior written<br />

16 * permission is prohibited except as allowed under the copyright<br />

* permission .<br />

18 *<br />

*/<br />

20<br />

22<br />

24<br />

package ncv.gatewayif;<br />

import java. util . LinkedList ;


C.1. JAVA CODE 103<br />

/** This class is used by the SendMessageClient class to generate<br />

26 * a linked list of XMLMessages to be send to the MAS remote gateway<br />

*/<br />

28 public class MessageList extends LinkedList{<br />

}<br />

C.1.10<br />

/**<br />

MiscDate.java<br />

2 * $Workfile : MiscDate.java<br />

*<br />

4 * @version $Revision : 0 $<br />

* @author $Author: David Vogler $<br />

6 * @date $Date: 02/11/00 10:00a $<br />

*<br />

8 * Created by: David Vogler<br />

* Created on: November 2, 2000<br />

10 * Contact: Mike Higgins <br />

*<br />

12 * @description<br />

*<br />

14 * (C) Copyright Agilent Technologies 2000. All rights reserved .<br />

* Reproduction, adaption or translation without prior written<br />

16 * permission is prohibited except as allowed under the copyright<br />

* permission .<br />

18 *<br />

*/<br />

20<br />

22<br />

package ncv.gatewayif;<br />

import java.lang. Integer ;<br />

24 import java. sql .Timestamp;<br />

import java. text .DateFormat;<br />

26 import java. util .Date;<br />

import java. util .Calendar;<br />

28 import java. util .GregorianCalendar;<br />

30 /** This class is used to get general time and date information and to compute<br />

* time differences .<br />

32 */<br />

34 public class MiscDate {<br />

/** returns today’s date as a formatted string */<br />

36 public static String todaysDate() {<br />

Calendar C = new GregorianCalendar();<br />

38 String DateString = ””;<br />

40 if (C.get(Calendar.MONTH)+1 < 10)<br />

DateString = ”0”;<br />

42 DateString += C.get(Calendar.MONTH)+1 + ”/”;<br />

if (C.get(Calendar.DAY OF MONTH) < 10)<br />

44 DateString += ”0”;<br />

DateString += C.get(Calendar.DAY OF MONTH);<br />

46 DateString += ”/”+C.get(Calendar.YEAR) + ” ”;<br />

if (C.get(Calendar.HOUR OF DAY) < 10)<br />

48 DateString += ”0”;<br />

DateString += C.get(Calendar.HOUR OF DAY) + ”:”;


C.1. JAVA CODE 104<br />

50 if (C.get(Calendar.MINUTE) < 10)<br />

DateString += ”0”;<br />

52 DateString += C.get(Calendar.MINUTE) + ”:”;<br />

if (C.get(Calendar.SECOND) < 10)<br />

54 DateString += ”0”;<br />

DateString += C.get(Calendar.SECOND);<br />

56<br />

58 }<br />

return DateString;<br />

60 /** returns time difference in milliseconds between now and<br />

* a given timestamp<br />

62 */<br />

64 public static long getTimeDiff(Timestamp timeStampSent) {<br />

Calendar today = new GregorianCalendar();<br />

66 Timestamp now = new Timestamp(today.getTime().getTime());<br />

long timeDiff = now.getTime() − timeStampSent.getTime();<br />

68<br />

System.out. println (”MD: timeStampSent: ”+timeStampSent);<br />

70 System.out. println (”MD: now: ”+now);<br />

System.out. println (”MD: difference: ”+timeDiff);<br />

72<br />

74 }<br />

return timeDiff ;<br />

76 /** returns today’s date and time as a String like the database<br />

* returns it<br />

78 */<br />

public static String MessageDate() {<br />

80 Calendar C = new GregorianCalendar();<br />

String DateString = null;<br />

82<br />

84<br />

DateString = ”” + C.get(Calendar.YEAR);<br />

if (C.get(Calendar.MONTH) < 10)<br />

86 DateString += ’0’;<br />

DateString += C.get(Calendar.MONTH);<br />

88 if (C.get(Calendar.DAY OF MONTH) < 10)<br />

DateString += ’0’;<br />

90 DateString += C.get(Calendar.DAY OF MONTH);<br />

if (C.get(Calendar.HOUR OF DAY) < 10)<br />

92 DateString += ’0’;<br />

DateString += C.get(Calendar.HOUR OF DAY);<br />

94 if (C.get(Calendar.MINUTE) < 10)<br />

DateString += ’0’;<br />

96 DateString += C.get(Calendar.MINUTE);<br />

if (C.get(Calendar.SECOND) < 10)<br />

98 DateString += ’0’;<br />

DateString += C.get(Calendar.SECOND);<br />

100<br />

102 }<br />

return DateString;<br />

104 } // end MiscDate class


C.1. JAVA CODE 105<br />

C.1.11<br />

/**<br />

NotifyByEmail.java<br />

2 * $Workfile : NotifyByEmail.java<br />

*<br />

4 * @version $Revision : 0 $<br />

* @author $Author: David Vogler $<br />

6 * @date $Date: 02/11/00 10:00a $<br />

*<br />

8 * Created by: David Vogler<br />

* Created on: November 2, 2000<br />

10 * Contact: Mike Higgins <br />

*<br />

12 * @description<br />

*<br />

14 * (C) Copyright Agilent Technologies 2000. All rights reserved .<br />

* Reproduction, adaption or translation without prior written<br />

16 * permission is prohibited except as allowed under the copyright<br />

* permission .<br />

18 *<br />

*/<br />

20<br />

22<br />

package ncv.gatewayif;<br />

import java. util .*;<br />

24 import javax.mail .*;<br />

import javax.mail. internet .*;<br />

26<br />

public class NotifyByEmail {<br />

28 public static void main(String [] args) {<br />

if ( args . length != 4) {<br />

30 System.out. println (<br />

”usage: sendmessage ” +<br />

32 ””);<br />

System.exit (1);<br />

34 }<br />

36 boolean debug = false; // change to get more information<br />

String msgText = ”A body.\nthe second line.”;<br />

38 String msgText2 = ”Another body.\nmore lines”;<br />

boolean sendmultipart =<br />

40 Boolean.valueOf(args [3]). booleanValue();<br />

42 // set the host<br />

Properties props = new Properties();<br />

44 props.put(”mail.smtp.host”, args [2]);<br />

46 // create some properties and get the default Session<br />

Session session = Session. getDefaultInstance (props , null );<br />

48 session .setDebug(debug);<br />

50 try {<br />

// create a message<br />

52 Message msg = new MimeMessage(session);<br />

54 // set the from<br />

InternetAddress from = new InternetAddress(args [1]);


C.1. JAVA CODE 106<br />

56 msg.setFrom(from);<br />

58 InternetAddress [] address = { new InternetAddress(args [0]) };<br />

msg. setRecipients (Message.RecipientType.TO, address);<br />

60 msg.setSubject(”JavaMail APIs Test”);<br />

62 if (! sendmultipart ) {<br />

// send a plain text message<br />

64 msg.setContent(msgText, ”text/plain”);<br />

} else {<br />

66 // send a multipart message<br />

// create and fill the first message part<br />

68 MimeBodyPart mbp1 = new MimeBodyPart();<br />

mbp1.setContent(msgText, ”text/plain”);<br />

70<br />

// create and fill the second message part<br />

72 MimeBodyPart mbp2 = new MimeBodyPart();<br />

mbp2.setContent(msgText2, ”text/plain”);<br />

74<br />

// create the Multipart and its parts to it<br />

76 Multipart mp = new MimeMultipart();<br />

mp.addBodyPart(mbp1);<br />

78 mp.addBodyPart(mbp2);<br />

80 // add the Multipart to the message<br />

msg.setContent(mp);<br />

82 }<br />

Transport.send(msg);<br />

84 } catch (MessagingException mex) {<br />

mex.printStackTrace ();<br />

86 }<br />

}<br />

88 }<br />

C.1.12<br />

/**<br />

RecvMessage.java<br />

2 * $Workfile : RecvMessage.java<br />

*<br />

4 * @version $Revision : 0 $<br />

* @author $Author: David Vogler $<br />

6 * @date $Date: 02/11/00 10:00a $<br />

*<br />

8 * Created by: David Vogler<br />

* Created on: November 2, 2000<br />

10 * Contact: Mike Higgins <br />

*<br />

12 * @description<br />

*<br />

14 * (C) Copyright Agilent Technologies 2000. All rights reserved .<br />

* Reproduction, adaption or translation without prior written<br />

16 * permission is prohibited except as allowed under the copyright<br />

* permission .<br />

18 *<br />

*/<br />

20<br />

package ncv.gatewayif;


C.1. JAVA CODE 107<br />

22<br />

import java.io .Reader;<br />

24 import java.io .StringReader;<br />

26 import org.apache.xerces . parsers .DOMParser;<br />

28 import org.w3c.dom.Document;<br />

import org.w3c.dom.Node;<br />

30 import org.w3c.dom.NodeList;<br />

32 import org.xml.sax.InputSource;<br />

34 /** This class provides the methods for accessing an incoming ( reveived ) message */<br />

public class RecvMessage extends XMLMessage {<br />

36<br />

protected Document doc;<br />

38 protected NodeList nodeList;<br />

protected Node node;<br />

40<br />

/** Constructor used for initializing the XML message object */<br />

42 public RecvMessage(String message) {<br />

super(message);<br />

44 doc = getDOMDocument(message);<br />

}<br />

46<br />

/** returns a DOM Document for an incoming XML message string<br />

48 * as it is received from the MAS remote gateway<br />

*/<br />

50 public Document getDOMDocument(String xmlstring){<br />

Reader xmlreader = new StringReader(xmlstring);<br />

52 InputSource xmlsource = new InputSource(xmlreader);<br />

54 DOMParser parser = new DOMParser();<br />

56 try {<br />

parser . parse(xmlsource);<br />

58 } catch (Exception e) {<br />

System.err . println (”Error in parsing : ” + e.getMessage());<br />

60 e. printStackTrace ();<br />

}<br />

62 Document doc = parser.getDocument();<br />

return doc;<br />

64 }<br />

66 /** returns the Acknowledgement code out of the DOM document */<br />

public String getAckCode() {<br />

68 nodeList = doc.getElementsByTagName(”MSA.1”);<br />

node = nodeList.item(0). getFirstChild ();<br />

70 return node.getNodeValue();<br />

}<br />

72<br />

/** returns the unique Message Control ID out of the DOM document */<br />

74 public String getMsgControlID() {<br />

nodeList = doc.getElementsByTagName(”MSA.2”);<br />

76 node = nodeList.item(0). getFirstChild ();<br />

return node.getNodeValue();


C.1. JAVA CODE 108<br />

78 }<br />

80 /** returns the Error comment out of the DOM document */<br />

public String getErrorComment() {<br />

82 nodeList = doc.getElementsByTagName(”MSA.3”);<br />

node = nodeList.item(0). getFirstChild ();<br />

84 return node.getNodeValue();<br />

}<br />

86<br />

/** returns the MeasID out of the DOM document to identify the measurement<br />

88 * in the database<br />

*/<br />

90 public String getMeasID() {<br />

String MsgControlID = this.getMsgControlID();<br />

92 int ColonPos = MsgControlID.indexOf(’:’);<br />

return MsgControlID.substring(ColonPos+1);<br />

94 }<br />

}<br />

C.1.13<br />

/**<br />

RecvMessageServer.java<br />

2 * $Workfile : RecvMessageServer.java<br />

*<br />

4 * @version $Revision : 0 $<br />

* @author $Author: David Vogler $<br />

6 * @date $Date: 02/11/00 10:00a $<br />

*<br />

8 * Created by: David Vogler<br />

* Created on: November 2, 2000<br />

10 * Contact: Mike Higgins <br />

*<br />

12 * @description<br />

*<br />

14 * (C) Copyright Agilent Technologies 2000. All rights reserved .<br />

* Reproduction, adaption or translation without prior written<br />

16 * permission is prohibited except as allowed under the copyright<br />

* permission .<br />

18 *<br />

*/<br />

20<br />

22<br />

24<br />

26<br />

package ncv.gatewayif;<br />

import java. util .Date;<br />

import java. text .DateFormat;<br />

import java.io . File ;<br />

28 import java.io .IOException;<br />

import java.io .BufferedReader;<br />

30 import java.io .InputStreamReader;<br />

import java.io . PrintWriter ;<br />

32 import java.io .Reader;<br />

import java.io .StringReader;<br />

34<br />

import java.net.BindException;<br />

36 import java.net.ServerSocket;


C.1. JAVA CODE 109<br />

38<br />

40<br />

42<br />

import java.net.Socket;<br />

import java. sql .Connection;<br />

import org.apache.xerces . parsers .DOMParser;<br />

import org.w3c.dom.Document;<br />

44 import org.w3c.dom.Node;<br />

import org.w3c.dom.NodeList;<br />

46<br />

48<br />

import org.xml.sax.InputSource;<br />

/** This class provides the methods for receiving incoming LIS AA and AE messages<br />

50 * send through the MAS remote gateway. It validates the message and sends an<br />

* acknowledgement message back to LIS during the same socket connection.<br />

52 */<br />

public class RecvMessageServer extends Thread {<br />

54 public static int CICOUTPORT = 5001;<br />

public static long TIMEOUT = 10L;<br />

56 private long sleepTimer;<br />

private String configFileName;<br />

58<br />

60 /** Constructor sets the member values as configured in given configuration file */<br />

public RecvMessageServer(String cfgFileName) {<br />

62 this .configFileName = cfgFileName;<br />

Config cfg = new Config(cfgFileName);<br />

64 CICOUTPORT = cfg.getCICOutPort();<br />

66 sleepTimer = cfg.getRMSTimeOut();<br />

setDaemon(true);<br />

68 }<br />

70 /** returns a DOM document generated out of an incoming XML message string */<br />

public Document getDOMDocument(String xmlstring){<br />

72 Reader xmlreader = new StringReader(xmlstring);<br />

InputSource xmlsource = new InputSource(xmlreader);<br />

74<br />

76<br />

DOMParser parser = new DOMParser();<br />

try {<br />

78 parser . parse(xmlsource);<br />

} catch (Exception e) {<br />

80 System.err . println (”RMS: Error in parsing ” + e.getMessage());<br />

e. printStackTrace ();<br />

82 }<br />

Document doc = parser.getDocument();<br />

84 return doc;<br />

}<br />

86<br />

88<br />

90<br />

92<br />

/* public static void main(String [] args ) throws IOException {<br />

System.out. println (”RMS: Pilot Server Gateway Interface ”);<br />

Thread first = new RecvMessageServer(TIMEOUT);


C.1. JAVA CODE 110<br />

94<br />

96<br />

System.out. println (”press enter to quit . ”);<br />

first . start ();<br />

try {<br />

98 System.in.read ();<br />

System.out. println (”RMS: RecvMessageServer shutdown.”);<br />

100 } catch (IOException e) {<br />

System.err . println (”RMS: ” + e);<br />

102 e. printStackTrace ();<br />

System.exit (1);<br />

104 }<br />

106 return ;<br />

}<br />

108 */<br />

public void run() {<br />

110<br />

ServerSocket serverSocket = null;<br />

112 Socket clientSocket = null;<br />

DateFormat defaultDate;<br />

114 PrintWriter out;<br />

BufferedReader in ;<br />

116 String inputLine , outputLine , message=””;<br />

Document doc;<br />

118 NodeList nodeList;<br />

Node nodeMSH2Text;<br />

120 String endDocumentTag=””;<br />

String AckCode=””;<br />

122 String MeasID=””;<br />

String MessageControlID=””;<br />

124 String ErrorComment=””;<br />

126 while(true) {<br />

128 System.out. println (”RMS: ready to listen on port #” + CICOUTPORT + ”.\n”);<br />

130 try {<br />

serverSocket = new ServerSocket(CICOUTPORT);<br />

132 } catch (IOException e) {<br />

System.err . println (”RMS: Can not listen on port #” + CICOUTPORT);<br />

134 System.err . println (e);<br />

e. printStackTrace ();<br />

136 System.exit (1);<br />

}<br />

138<br />

try {<br />

140 clientSocket = serverSocket .accept ();<br />

} catch (IOException e) {<br />

142 System.err . println (”RMS: Accept failed.”);<br />

System.err . println (e);<br />

144 e. printStackTrace ();<br />

}<br />

146<br />

defaultDate = DateFormat.getDateInstance();<br />

148 System.out. println (”RMS: ” + defaultDate.format(new Date()));


C.1. JAVA CODE 111<br />

150<br />

System.out. println (”RMS: incoming socket connection established.”);<br />

try {<br />

152 out = new<br />

PrintWriter ( clientSocket .getOutputStream(),true);<br />

154 in = new BufferedReader(new<br />

InputStreamReader(clientSocket.getInputStream()));<br />

156<br />

158<br />

message = new String();<br />

while((inputLine = in.readLine ()) != null ) {<br />

160 if ( inputLine .indexOf(”ORR O02”, 0) > 0)<br />

endDocumentTag = ””;<br />

162 if ( inputLine .indexOf(endDocumentTag, 0) > 0) {<br />

// System.out. println (”RMS: ” + inputLine);<br />

164 message += inputLine;<br />

break;<br />

166 } else {<br />

// System.out. println (”RMS: ” + inputLine);<br />

168 message += inputLine;<br />

}<br />

170 }<br />

172 // creating DOM Document out of incoming String<br />

174 RecvMessage msgIN = new RecvMessage(message);<br />

176 AckCode = msgIN.getAckCode();<br />

MeasID = msgIN.getMeasID();<br />

178 MessageControlID = msgIN.getMsgControlID();<br />

ErrorComment = msgIN.getErrorComment();<br />

180<br />

System.out. println (”RMS: incoming MsgAckCode: ” + AckCode);<br />

182 System.out. println (”RMS: incoming MsgControlID: ” + MessageControlID);<br />

// System.out. println (”RMS: incoming MeasID: ” + MeasID);<br />

184<br />

186<br />

System.out. println (”RMS: End of message, generating CA.\n”);<br />

SendMessage msg = new SendMessage(MessageControlID, ”CA”);<br />

188 out. println (msg.toString ACK());<br />

190 in . close ();<br />

out. close ();<br />

192 clientSocket . close ();<br />

serverSocket . close ();<br />

194<br />

} catch (IOException e) {<br />

196 System.err . println (”RMS: ” + e);<br />

e. printStackTrace ();<br />

198 System.exit (1);<br />

}<br />

200<br />

DBSession db = new DBSession(configFileName);<br />

202 String timeStamp;<br />

204 Connection conn = db.openDB();


C.1. JAVA CODE 112<br />

timeStamp = MiscDate.todaysDate();<br />

206 db.updateTimeStampLIS(conn, MeasID, timeStamp);<br />

if (AckCode.equals(”AA”)) {<br />

208 db.updateFlagAA(conn, MeasID, true);<br />

db.updateFlagAE(conn, MeasID, false);<br />

210 } else if (AckCode.equals(”AE”)) {<br />

db.updateFlagAE(conn, MeasID, true);<br />

212 db.updateFlagAA(conn, MeasID, false);<br />

db.updateComment(conn, MeasID, ErrorComment);<br />

214 }<br />

db.closeDB(conn);<br />

216<br />

try {<br />

218 sleep (sleepTimer);<br />

} catch (InterruptedException e) {<br />

220 System.err . println (”RMS: ” + e);<br />

e. printStackTrace ();<br />

222 System.exit (1);<br />

}<br />

224 }<br />

}<br />

226 }<br />

C.1.14<br />

/**<br />

SendMessage.java<br />

2 * $Workfile : SendMessage.java<br />

*<br />

4 * @version $Revision : 0 $<br />

* @author $Author: David Vogler $<br />

6 * @date $Date: 02/11/00 10:00a $<br />

*<br />

8 * Created by: David Vogler<br />

* Created on: November 2, 2000<br />

10 * Contact: Mike Higgins <br />

*<br />

12 * @description<br />

*<br />

14 * (C) Copyright Agilent Technologies 2000. All rights reserved .<br />

* Reproduction, adaption or translation without prior written<br />

16 * permission is prohibited except as allowed under the copyright<br />

* permission .<br />

18 *<br />

*/<br />

20<br />

22<br />

package ncv.gatewayif;<br />

import java. util .Date;<br />

24 import java.io .*;<br />

26 import org.w3c.dom.*;<br />

import org.apache.xerces .dom.DocumentImpl;<br />

28 import org.apache.xerces .dom.DOMImplementationImpl;<br />

import org.w3c.dom.Document;<br />

30 import org.apache.xml. serialize .OutputFormat;<br />

import org.apache.xml. serialize . Serializer ;<br />

32 import org.apache.xml. serialize . SerializerFactory ;


C.1. JAVA CODE 113<br />

34<br />

36<br />

38<br />

import org.apache.xml. serialize .XMLSerializer;<br />

/** This class provides the methods for accessing an outgoing (to be send) message */<br />

public class SendMessage extends XMLMessage {<br />

/** Constructor calls constructor of SuperClass XMLMessage */<br />

40 public SendMessage (int PatientID, String kppID, int MeasID,<br />

float ObservationValue, float CalCode, String ObservationTime) {<br />

42 super(PatientID, kppID, MeasID, ObservationValue, CalCode, ObservationTime);<br />

}<br />

44<br />

/** Constructor calls constructor of SuperClass XMLMessage */<br />

46 public SendMessage (String MessageControlID, String ACKType) {<br />

super(MessageControlID, ACKType);<br />

48 }<br />

50 /** returns a ORM O01 type XML message string from document */<br />

public String toString ORM O01() {<br />

52 StringWriter stringOut = new StringWriter();<br />

try {<br />

54 DOMImplementation domImpl = new DOMImplementationImpl();<br />

DocumentType docType = domImpl.createDocumentType(”ORM O01”, null,<br />

56 ”hl7 v231.dtd”);<br />

Document doc = new DocumentImpl(docType);<br />

58 Element root = doc.createElement(”ORM O01”);<br />

Element msh = doc.createElement(”MSH”);<br />

60<br />

Element item = doc.createElement(”MSH.1”);<br />

62 item.appendChild(doc.createTextNode(”|”));<br />

msh.appendChild(item);<br />

64<br />

item = doc.createElement(”MSH.2”);<br />

66 item.appendChild(doc.createTextNode(”ˆ˜\\&”));<br />

msh.appendChild(item);<br />

68<br />

item = doc.createElement(”MSH.3”);<br />

70 Element itemChild = doc.createElement(”HD.1”);<br />

itemChild.appendChild(doc.createTextNode(”CICDMS”));<br />

72 item.appendChild(itemChild);<br />

msh.appendChild(item);<br />

74<br />

item = doc.createElement(”MSH.4”);<br />

76 itemChild = doc.createElement(”HD.1”);<br />

itemChild.appendChild(doc.createTextNode(”OBSREP”));<br />

78 item.appendChild(itemChild);<br />

msh.appendChild(item);<br />

80<br />

item = doc.createElement(”MSH.5”);<br />

82 itemChild = doc.createElement(”HD.1”);<br />

itemChild.appendChild(doc.createTextNode(”CICLIS”));<br />

84 item.appendChild(itemChild);<br />

msh.appendChild(item);<br />

86<br />

item = doc.createElement(”MSH.6”);<br />

88 itemChild = doc.createElement(”HD.1”);


C.1. JAVA CODE 114<br />

itemChild.appendChild(doc.createTextNode(”OBSREV”));<br />

90 item.appendChild(itemChild);<br />

msh.appendChild(item);<br />

92<br />

item = doc.createElement(”MSH.7”);<br />

94 item.appendChild(doc.createTextNode(MiscDate.MessageDate()));<br />

msh.appendChild(item);<br />

96<br />

item = doc.createElement(”MSH.9”);<br />

98 itemChild = doc.createElement(”CM MSG TYPE.1”);<br />

itemChild.appendChild(doc.createTextNode(”ORM”));<br />

100 item.appendChild(itemChild);<br />

itemChild = doc.createElement(”CM MSG TYPE.2”);<br />

102 itemChild.appendChild(doc.createTextNode(”O01”));<br />

item.appendChild(itemChild);<br />

104 msh.appendChild(item);<br />

106 item = doc.createElement(”MSH.10”);<br />

item.appendChild(doc.createTextNode(MiscDate.MessageDate()+”:”<br />

108 +MessageControlID));<br />

msh.appendChild(item);<br />

110<br />

item = doc.createElement(”MSH.11”);<br />

112 itemChild = doc.createElement(”PT.1”);<br />

itemChild.appendChild(doc.createTextNode(”P”));<br />

114 item.appendChild(itemChild);<br />

msh.appendChild(item);<br />

116<br />

item = doc.createElement(”MSH.12”);<br />

118 itemChild = doc.createElement(”VID.1”);<br />

itemChild.appendChild(doc.createTextNode(”2.3.1”));<br />

120 item.appendChild(itemChild);<br />

msh.appendChild(item);<br />

122<br />

item = doc.createElement(”MSH.15”);<br />

124 item.appendChild(doc.createTextNode(”AL”));<br />

msh.appendChild(item);<br />

126<br />

item = doc.createElement(”MSH.16”);<br />

128 item.appendChild(doc.createTextNode(”AL”));<br />

msh.appendChild(item);<br />

130<br />

132<br />

134<br />

root.appendChild(msh);<br />

Element pid = doc.createElement(”PID”);<br />

item = doc.createElement(”PID.3”);<br />

136 itemChild = doc.createElement(”CX.1”);<br />

itemChild.appendChild(doc.createTextNode(”12345678”));<br />

138 item.appendChild(itemChild);<br />

itemChild = doc.createElement(”CX.4”);<br />

140 itemChild.appendChild(doc.createTextNode(”1”));<br />

item.appendChild(itemChild);<br />

142 pid.appendChild(item);<br />

144 item = doc.createElement(”PID.18”);


C.1. JAVA CODE 115<br />

itemChild = doc.createElement(”CX.1”);<br />

146 itemChild.appendChild(doc.createTextNode(”12345678”));<br />

item.appendChild(itemChild);<br />

148 itemChild = doc.createElement(”CX.4”);<br />

itemChild.appendChild(doc.createTextNode(”1”));<br />

150 item.appendChild(itemChild);<br />

pid.appendChild(item);<br />

152<br />

154<br />

156<br />

root.appendChild(pid);<br />

Element orc = doc.createElement(”ORC”);<br />

item = doc.createElement(”ORC.1”);<br />

158 item.appendChild(doc.createTextNode(”NW”));<br />

orc .appendChild(item);<br />

160<br />

162<br />

164<br />

root.appendChild(orc);<br />

Element obr = doc.createElement(”OBR”);<br />

item = doc.createElement(”OBR.4”);<br />

166 itemChild = doc.createElement(”CE.1”);<br />

itemChild.appendChild(doc.createTextNode(”L12345”));<br />

168 item.appendChild(itemChild);<br />

itemChild = doc.createElement(”CE.2”);<br />

170 itemChild.appendChild(doc.createTextNode(”GLU”));<br />

item.appendChild(itemChild);<br />

172 obr.appendChild(item);<br />

174 item = doc.createElement(”OBR.11”);<br />

item.appendChild(doc.createTextNode(”O”));<br />

176 obr.appendChild(item);<br />

178 item = doc.createElement(”OBR.16”);<br />

itemChild = doc.createElement(”XCN.1”);<br />

180 itemChild.appendChild(doc.createTextNode(”555”));<br />

item.appendChild(itemChild);<br />

182 itemChild = doc.createElement(”XCN.2”);<br />

itemChild.appendChild(doc.createTextNode(”Smith”));<br />

184 item.appendChild(itemChild);<br />

itemChild = doc.createElement(”XCN.3”);<br />

186 itemChild.appendChild(doc.createTextNode(”John”));<br />

item.appendChild(itemChild);<br />

188 itemChild = doc.createElement(”XCN.4”);<br />

itemChild.appendChild(doc.createTextNode(”J”));<br />

190 item.appendChild(itemChild);<br />

itemChild = doc.createElement(”XCN.5”);<br />

192 itemChild.appendChild(doc.createTextNode(”Dr”));<br />

item.appendChild(itemChild);<br />

194 obr.appendChild(item);<br />

196 root.appendChild(obr);<br />

198 Element obx = doc.createElement(”OBX”);<br />

200 item = doc.createElement(”OBX.2”);


C.1. JAVA CODE 116<br />

item.appendChild(doc.createTextNode(”ST”));<br />

202 obx.appendChild(item);<br />

204 item = doc.createElement(”OBX.3”);<br />

itemChild = doc.createElement(”CE.1”);<br />

206 itemChild.appendChild(doc.createTextNode(”L12345”));<br />

item.appendChild(itemChild);<br />

208 itemChild = doc.createElement(”CE.2”);<br />

itemChild.appendChild(doc.createTextNode(”GLU”));<br />

210 item.appendChild(itemChild);<br />

obx.appendChild(item);<br />

212<br />

item = doc.createElement(”OBX.5”);<br />

214 item.appendChild(doc.createTextNode(””+ObservationValue));<br />

obx.appendChild(item);<br />

216<br />

item = doc.createElement(”OBX.6”);<br />

218 itemChild = doc.createElement(”CE.1”);<br />

itemChild.appendChild(doc.createTextNode(”mg/dl”));<br />

220 item.appendChild(itemChild);<br />

obx.appendChild(item);<br />

222<br />

item = doc.createElement(”OBX.11”);<br />

224 item.appendChild(doc.createTextNode(”F”));<br />

obx.appendChild(item);<br />

226<br />

item = doc.createElement(”OBX.14”);<br />

228 item.appendChild(doc.createTextNode(””+ObservationTime));<br />

obx.appendChild(item);<br />

230<br />

item = doc.createElement(”OBX.15”);<br />

232 itemChild = doc.createElement(”CE.1”);<br />

itemChild.appendChild(doc.createTextNode(”LifeScan SureStep”));<br />

234 item.appendChild(itemChild);<br />

itemChild = doc.createElement(”CE.2”);<br />

236 itemChild.appendChild(doc.createTextNode(”77777”));<br />

item.appendChild(itemChild);<br />

238 obx.appendChild(item);<br />

240 item = doc.createElement(”OBX.16”);<br />

itemChild = doc.createElement(”XCN.1”);<br />

242 itemChild.appendChild(doc.createTextNode(”9876”));<br />

item.appendChild(itemChild);<br />

244 obx.appendChild(item);<br />

246 root.appendChild(obx);<br />

248 Element nte = doc.createElement(”NTE”);<br />

250 item = doc.createElement(”NTE.3”);<br />

item.appendChild(doc.createTextNode(”Home˜Measurement˜(”+CalCode+”)”));<br />

252 obx.appendChild(item);<br />

254 root.appendChild(nte);<br />

256 doc.appendChild(root);


C.1. JAVA CODE 117<br />

258 OutputFormat format = new OutputFormat(doc); // Serialize DOM<br />

format.setOmitDocumentType(false);<br />

260 format.setDoctype(null,”hl7 v231.dtd”);<br />

262 XMLSerializer serial = new XMLSerializer(stringOut, format);<br />

264 serial .asDOMSerializer();<br />

serial . serialize (doc.getDocumentElement());<br />

266<br />

} catch (Exception ex) {<br />

268 ex. printStackTrace ();<br />

}<br />

270 return stringOut . toString ();<br />

}<br />

272<br />

/** returns an Acknowledgement XML message string from DOM document */<br />

274 public String toString ACK() {<br />

StringWriter stringOut = new StringWriter();<br />

276 try {<br />

DOMImplementation domImpl = new DOMImplementationImpl();<br />

278 DocumentType docType = domImpl.createDocumentType(”ACK”, null,<br />

”hl7 v231.dtd”);<br />

280 Document doc = new DocumentImpl(docType);<br />

Element root = doc.createElement(”ACK”);<br />

282 Element msh = doc.createElement(”MSH”);<br />

284 Element item = doc.createElement(”MSH.1”);<br />

item.appendChild(doc.createTextNode(”|”));<br />

286 msh.appendChild(item);<br />

288 item = doc.createElement(”MSH.2”);<br />

item.appendChild(doc.createTextNode(”ˆ˜\\&”));<br />

290 msh.appendChild(item);<br />

292 item = doc.createElement(”MSH.3”);<br />

Element itemChild = doc.createElement(”HD.1”);<br />

294 itemChild.appendChild(doc.createTextNode(”SendingApplication”));<br />

item.appendChild(itemChild);<br />

296 msh.appendChild(item);<br />

298 item = doc.createElement(”MSH.4”);<br />

itemChild = doc.createElement(”HD.1”);<br />

300 itemChild.appendChild(doc.createTextNode(SendingFacility ));<br />

item.appendChild(itemChild);<br />

302 msh.appendChild(item);<br />

304 item = doc.createElement(”MSH.5”);<br />

itemChild = doc.createElement(”HD.1”);<br />

306 itemChild.appendChild(doc.createTextNode(ReceivingApplication ));<br />

item.appendChild(itemChild);<br />

308 msh.appendChild(item);<br />

310 item = doc.createElement(”MSH.6”);<br />

itemChild = doc.createElement(”HD.1”);<br />

312 itemChild.appendChild(doc.createTextNode( ReceivingFacility ));


C.1. JAVA CODE 118<br />

item.appendChild(itemChild);<br />

314 msh.appendChild(item);<br />

316 item = doc.createElement(”MSH.7”);<br />

item.appendChild(doc.createTextNode(MiscDate.MessageDate()));<br />

318 msh.appendChild(item);<br />

320 item = doc.createElement(”MSH.9”);<br />

itemChild = doc.createElement(”CM MSG TYPE.1”);<br />

322 itemChild.appendChild(doc.createTextNode(”ACK”));<br />

item.appendChild(itemChild);<br />

324 msh.appendChild(item);<br />

326 item = doc.createElement(”MSH.10”);<br />

item.appendChild(doc.createTextNode(MiscDate.MessageDate()+ACKType));<br />

328 msh.appendChild(item);<br />

330 item = doc.createElement(”MSH.11”);<br />

itemChild = doc.createElement(”PT.1”);<br />

332 itemChild.appendChild(doc.createTextNode(”P”));<br />

item.appendChild(itemChild);<br />

334 msh.appendChild(item);<br />

336 item = doc.createElement(”MSH.12”);<br />

itemChild = doc.createElement(”VID.1”);<br />

338 itemChild.appendChild(doc.createTextNode(”2.3.1”));<br />

item.appendChild(itemChild);<br />

340 msh.appendChild(item);<br />

342 item = doc.createElement(”MSH.15”);<br />

item.appendChild(doc.createTextNode(”NE”));<br />

344 msh.appendChild(item);<br />

346 item = doc.createElement(”MSH.16”);<br />

item.appendChild(doc.createTextNode(”NE”));<br />

348 msh.appendChild(item);<br />

350 root.appendChild(msh);<br />

352 Element msa = doc.createElement(”MSA”);<br />

354 item = doc.createElement(”MSA.1”);<br />

item.appendChild(doc.createTextNode(ACKType));<br />

356 msa.appendChild(item);<br />

358 item = doc.createElement(”MSA.2”);<br />

item.appendChild(doc.createTextNode(MessageControlID));<br />

360 msa.appendChild(item);<br />

362 if (ACKType.equals(”CE”) || ACKType.equals(”CR”)) {<br />

item = doc.createElement(”MSA.3”);<br />

364 item.appendChild(doc.createTextNode(errorComment));<br />

msa.appendChild(item);<br />

366 }<br />

368 root.appendChild(msa);


C.1. JAVA CODE 119<br />

370 doc.appendChild(root);<br />

372 OutputFormat format = new OutputFormat(doc); // Serialize DOM<br />

format.setOmitDocumentType(false);<br />

374 format.setDoctype(null,”hl7 v231.dtd”);<br />

376 XMLSerializer serial = new XMLSerializer(stringOut, format);<br />

378 serial .asDOMSerializer();<br />

serial . serialize (doc.getDocumentElement());<br />

380<br />

} catch (Exception ex) {<br />

382 ex. printStackTrace ();<br />

}<br />

384 return stringOut . toString ();<br />

}<br />

386<br />

/** returns an ORR O02 message string from DOM document */<br />

388 public String toString ORR O02() {<br />

StringWriter stringOut = new StringWriter();<br />

390 try {<br />

DOMImplementation domImpl = new DOMImplementationImpl();<br />

392 DocumentType docType = domImpl.createDocumentType(”ORR O02”, null,<br />

”hl7 v231.dtd”);<br />

394 Document doc = new DocumentImpl(docType);<br />

Element root = doc.createElement(”ORR O02”);<br />

396 Element msh = doc.createElement(”MSH”);<br />

398 Element item = doc.createElement(”MSH.1”);<br />

item.appendChild(doc.createTextNode(”|”));<br />

400 msh.appendChild(item);<br />

402 item = doc.createElement(”MSH.2”);<br />

item.appendChild(doc.createTextNode(”ˆ˜\\&”));<br />

404 msh.appendChild(item);<br />

406 item = doc.createElement(”MSH.3”);<br />

Element itemChild = doc.createElement(”HD.1”);<br />

408 itemChild.appendChild(doc.createTextNode(”SendingApplication”));<br />

item.appendChild(itemChild);<br />

410 msh.appendChild(item);<br />

412 item = doc.createElement(”MSH.4”);<br />

itemChild = doc.createElement(”HD.1”);<br />

414 itemChild.appendChild(doc.createTextNode(SendingFacility ));<br />

item.appendChild(itemChild);<br />

416 msh.appendChild(item);<br />

418 item = doc.createElement(”MSH.5”);<br />

itemChild = doc.createElement(”HD.1”);<br />

420 itemChild.appendChild(doc.createTextNode(ReceivingApplication ));<br />

item.appendChild(itemChild);<br />

422 msh.appendChild(item);<br />

424 item = doc.createElement(”MSH.6”);


C.1. JAVA CODE 120<br />

itemChild = doc.createElement(”HD.1”);<br />

426 itemChild.appendChild(doc.createTextNode( ReceivingFacility ));<br />

item.appendChild(itemChild);<br />

428 msh.appendChild(item);<br />

430 item = doc.createElement(”MSH.7”);<br />

item.appendChild(doc.createTextNode(MiscDate.MessageDate()));<br />

432 msh.appendChild(item);<br />

434 item = doc.createElement(”MSH.9”);<br />

itemChild = doc.createElement(”CM MSG TYPE.1”);<br />

436 itemChild.appendChild(doc.createTextNode(”ORR”));<br />

item.appendChild(itemChild);<br />

438 itemChild = doc.createElement(”CM MSG TYPE.2”);<br />

itemChild.appendChild(doc.createTextNode(”O02”));<br />

440 item.appendChild(itemChild);<br />

msh.appendChild(item);<br />

442<br />

item = doc.createElement(”MSH.10”);<br />

444 item.appendChild(doc.createTextNode(MiscDate.MessageDate()+”AA”));<br />

msh.appendChild(item);<br />

446<br />

item = doc.createElement(”MSH.11”);<br />

448 itemChild = doc.createElement(”PT.1”);<br />

itemChild.appendChild(doc.createTextNode(”P”));<br />

450 item.appendChild(itemChild);<br />

msh.appendChild(item);<br />

452<br />

item = doc.createElement(”MSH.12”);<br />

454 itemChild = doc.createElement(”VID.1”);<br />

itemChild.appendChild(doc.createTextNode(”2.3.1”));<br />

456 item.appendChild(itemChild);<br />

msh.appendChild(item);<br />

458<br />

item = doc.createElement(”MSH.15”);<br />

460 item.appendChild(doc.createTextNode(”AL”));<br />

msh.appendChild(item);<br />

462<br />

item = doc.createElement(”MSH.16”);<br />

464 item.appendChild(doc.createTextNode(”NE”));<br />

msh.appendChild(item);<br />

466<br />

468<br />

470<br />

root.appendChild(msh);<br />

Element msa = doc.createElement(”MSA”);<br />

item = doc.createElement(”MSA.1”);<br />

472 item.appendChild(doc.createTextNode(ACKType));<br />

msa.appendChild(item);<br />

474<br />

item = doc.createElement(”MSA.2”);<br />

476 item.appendChild(doc.createTextNode(MessageControlID));<br />

msa.appendChild(item);<br />

478<br />

item = doc.createElement(”MSA.3”);<br />

480 item.appendChild(doc.createTextNode(errorComment));


C.1. JAVA CODE 121<br />

482<br />

484<br />

486<br />

msa.appendChild(item);<br />

root.appendChild(msa);<br />

doc.appendChild(root);<br />

OutputFormat format = new OutputFormat(doc); // Serialize<br />

488 format.setOmitDocumentType(false);<br />

format.setDoctype(null,”hl7 v231.dtd”);<br />

490<br />

492<br />

XMLSerializer serial = new XMLSerializer(stringOut, format);<br />

serial .asDOMSerializer();<br />

494 serial . serialize (doc.getDocumentElement());<br />

DOM<br />

496 } catch (Exception ex) {<br />

ex. printStackTrace ();<br />

498 }<br />

return stringOut . toString ();<br />

500 }<br />

}<br />

C.1.15<br />

/**<br />

Timer.java<br />

2 * $Workfile : Timer.java<br />

*<br />

4 * @version $Revision : 0 $<br />

* @author $Author: David Vogler $<br />

6 * @date $Date: 02/11/00 10:00a $<br />

*<br />

8 * Created by: David Vogler<br />

* Created on: November 2, 2000<br />

10 * Contact: Mike Higgins <br />

*<br />

12 * @description<br />

*<br />

14 * (C) Copyright Agilent Technologies 2000. All rights reserved .<br />

* Reproduction, adaption or translation without prior written<br />

16 * permission is prohibited except as allowed under the copyright<br />

* permission .<br />

18 *<br />

*/<br />

20<br />

22<br />

24<br />

package ncv.gatewayif;<br />

import java.io .*;<br />

public class Timer extends Thread {<br />

26 protected int m rate = 100;<br />

private int m length;<br />

28 private int m elapsed;<br />

30 public Timer(int length ) {<br />

m length = length;<br />

32 m elapsed = 0;<br />

}


C.1. JAVA CODE 122<br />

34<br />

public synchronized void reset() {<br />

36 m elapsed = 0;<br />

}<br />

38<br />

public void run() {<br />

40 for (;;) {<br />

// put the timer to sleep<br />

42 try {<br />

Thread.sleep(m rate);<br />

44 } catch (InterruptedException ioe ) {<br />

continue;<br />

46 }<br />

48 // use ’ synchronized ’ to prevent conflicts<br />

synchronized (this) {<br />

50 m elapsed =+ m rate;<br />

if (m elapsed > m length) {<br />

52 timeout();<br />

}<br />

54 }<br />

}<br />

56 }<br />

58 public void timeout() {<br />

System.err . println (”timeout occured. terminating .” );<br />

60 }<br />

}<br />

C.1.16<br />

/**<br />

XMLMessage.java<br />

2 * $Workfile : XMLMessage.java<br />

*<br />

4 * @version $Revision : 0 $<br />

* @author $Author: David Vogler $<br />

6 * @date $Date: 02/11/00 10:00a $<br />

*<br />

8 * Created by: David Vogler<br />

* Created on: November 2, 2000<br />

10 * Contact: Mike Higgins <br />

*<br />

12 * @description<br />

*<br />

14 * (C) Copyright Agilent Technologies 2000. All rights reserved .<br />

* Reproduction, adaption or translation without prior written<br />

16 * permission is prohibited except as allowed under the copyright<br />

* permission .<br />

18 *<br />

*/<br />

20<br />

22<br />

24<br />

package ncv.gatewayif;<br />

import java. util .Date;<br />

public class XMLMessage {<br />

26 protected String FieldSeparator ; // MSH.1


C.1. JAVA CODE 123<br />

protected String EncodingCharacters; // MSH.2<br />

28 protected String SendingApplication ; // MSH.3 HD.1<br />

protected String SendingFacility ;<br />

// MSH.4 HD.1<br />

30 protected String ReceivingApplication ; // MSH.5 HD.1<br />

protected String ReceivingFacility ; // MSH.6 HD.1<br />

32 protected String DateOfMessage; // MSH.7<br />

protected String MessageType1;<br />

// MSH.9 CM MSG TYPE.1<br />

34 protected String MessageType2; // MSH.9 CM MSG TYPE.2<br />

protected String MessageControlID; // MSH.10<br />

36 protected char ProcessingID; // MSH.11 PT.1<br />

protected String VersionID;<br />

// MSH.12 VID.1<br />

38 protected String AcceptAckType; // MSH.15<br />

protected String ApplAckType;<br />

// MSH.16<br />

40 protected String PatientID1; // PID.3 CX.1<br />

protected int PatientID4;<br />

// PID.3 CX.4<br />

42 protected String OrderControl; // ORC.1<br />

protected String LOINCCode;<br />

// OBR.4 CE.1<br />

44 protected String MnemonicCode; // OBR.4 CE.2<br />

protected String ValueType;<br />

// OBX.2<br />

46 protected float ObservationValue; // OBX.5<br />

protected String ObservationUnits; // OBX.6 CE.1<br />

48 protected String ObservationResultStatus ; // OBX.11<br />

protected String ObservationTime; // OBX.14<br />

50 protected float CalCode;<br />

protected String Comment;<br />

// NTE.3<br />

52<br />

protected String ACKType;<br />

// MSA.1<br />

54 protected String errorComment; // MSA.3<br />

56 protected String MessageString;<br />

58 public XMLMessage (int PatientID, String kppID, int MeasID,<br />

float ObservationValue, float CalCode, String ObservationTime) {<br />

60<br />

this . FieldSeparator = ”|”;<br />

62 this .EncodingCharacters = ”ˆ˜\\&amp;”;<br />

// this . SendingApplication = Config.getSendingApplication ();<br />

64 this . SendingFacility = Config. getSendingFacility ();<br />

this . ReceivingApplication = Config. getReceivingApplication ();<br />

66 this . ReceivingFacility = Config. getReceivingFacility ();<br />

this .MessageControlID = ””+MeasID;<br />

68 this .PatientID1 = ””+PatientID;<br />

this .ObservationValue = ObservationValue;<br />

70 this .ObservationTime = ObservationTime;<br />

this .CalCode = CalCode;<br />

72 this .Comment = ”Home Measurement (CAL=”+CalCode+”)”;<br />

}<br />

74<br />

public XMLMessage(String MessageControlID, String ACKType) {<br />

76 this . FieldSeparator = ”|”;<br />

this .EncodingCharacters = ”ˆ˜\\&amp;”;<br />

78 this . SendingFacility = Config. getSendingFacility ();<br />

this . ReceivingApplication = Config. getReceivingApplication ();<br />

80 this . ReceivingFacility = Config. getReceivingFacility ();<br />

this .MessageControlID = MessageControlID;<br />

82 this .ACKType = ACKType;


C.1. JAVA CODE 124<br />

84<br />

}<br />

public XMLMessage(String message) {<br />

86 this .MessageString = message;<br />

}<br />

88<br />

public String getMessageControlID() {<br />

90 return MessageControlID;<br />

}<br />

92<br />

public String getDateOfMessage() {<br />

94 return DateOfMessage;<br />

}<br />

96<br />

public String getPatientID () {<br />

98 return PatientID1;<br />

}<br />

100<br />

public float getObservationValue() {<br />

102 return ObservationValue;<br />

}<br />

104<br />

public float getCalCode() {<br />

106 return CalCode;<br />

}<br />

108<br />

public String getComment() {<br />

110 return Comment;<br />

}<br />

112<br />

public String getSendingApplication () {<br />

114 return SendingApplication ;<br />

}<br />

116<br />

public String getSendingFacility () {<br />

118 return SendingFacility ;<br />

}<br />

120<br />

public String getReceivingApplication () {<br />

122 return ReceivingApplication ;<br />

}<br />

124<br />

public String getReceivingFacility () {<br />

126 return ReceivingFacility ;<br />

}<br />

128<br />

public String getErrorComment() {<br />

130 return errorComment;<br />

}<br />

132 public void setErrorComment(String errorComment) {<br />

this .errorComment = errorComment;<br />

134 }<br />

}


C.2. SQL 125<br />

C.2 SQL<br />

C.2.1<br />

/**<br />

MeasXferStatus.sql<br />

2 * $Workfile : MeasXferStatus.sql<br />

*<br />

4 * @version $Revision : 1 $<br />

* @author $Author: David Vogler $<br />

6 * @date $Date: 10/23/00 12:00p $<br />

* @description<br />

8 *<br />

* (C) Copyright Agilent Technologies Company 2000. All rights reserved .<br />

10 * Reproduction, adaptation or translation withour prior written<br />

* permission is prohibited except as allowed under the copyright<br />

12 * permission .<br />

*<br />

14 */<br />

16 set quoted identifier OFF<br />

GO<br />

18<br />

20<br />

PRINT ’Creating table dbo.MeasXferStatus’<br />

CREATE TABLE [dbo].[MeasXferStatus] (<br />

22 measID int primary key NOT NULL,<br />

timeStampSent datetime,<br />

24 timeStampRcvd datetime,<br />

timeStampLIS datetime,<br />

26 flagCA bit ,<br />

flagCE bit ,<br />

28 flagCR bit ,<br />

flagAA bit ,<br />

30 flagAE bit ,<br />

flagNotified bit ,<br />

32 timesSent int ,<br />

comment varchar(80)<br />

34 ) ON [PRIMARY]<br />

GO<br />

C.2.2<br />

/**<br />

MeasXferInsertTrigger.sql<br />

2 * $Workfile : MeasXferInsertTrigger . sql<br />

*<br />

4 * @version $Revision : 1 $<br />

* @author $Author: David Vogler $<br />

6 * @date $Date: 10/23/00 12:00p $<br />

* @description<br />

8 *<br />

* (C) Copyright Agilent Technologies Company 2000. All rights reserved .<br />

10 * Reproduction, adaptation or translation withour prior written<br />

* permission is prohibited except as allowed under the copyright<br />

12 * permission .<br />

*<br />

14 */


C.3. CONFIGURATION FILES 126<br />

16 set quoted identifier OFF<br />

GO<br />

18<br />

20<br />

PRINT ’Creating Trigger dbo.MeasXferInsertTrigger’<br />

CREATE TRIGGER [MeasXferInsertTrigger] ON dbo.Measurement FOR INSERT AS<br />

22 INSERT dbo.MeasXferStatus (measID)<br />

SELECT ID FROM Inserted<br />

24 GO<br />

C.3 Configuration Files<br />

C.3.1<br />

// gatewayif . cfg<br />

gatewayif.cfg<br />

2 // configuration file for the KPP Gateway Interface<br />

4 // Socket specific settings<br />

6 PilotServer = 130.29.247.111<br />

RemoteGateway = 130.29.247.27<br />

8 CICInPort = 5000<br />

CICOutPort = 5001<br />

10<br />

12<br />

14<br />

// XML message and HL7 specific settings<br />

DOCTYPE = hl7 v231.dtd<br />

SendingApplication = CICDMS<br />

16 SendingFacility = OBSREP<br />

ReceivingApplication = CICLIS<br />

18 ReceivingFacility = OBSREV<br />

20 // Database specific settings<br />

22 dbUser = sa<br />

dbPassword =<br />

24 dbServer = med−iris<br />

dbName = demodb<br />

26 dbDriver = com.inet.tds .TdsDriver<br />

28 // timeouts<br />

30 SocketTimeOut = 45000<br />

ACKTimeOut = 15000<br />

32 ScanDBTimeOut = 15000<br />

CPMTimeOut = 180000<br />

34 RMSTimeOut = 1000<br />

MASRcvdTimeOut = 45000<br />

36 LISTimeOut = 240000<br />

38 // logfile<br />

LogFile = gatewayif. log<br />

40<br />

// send message<br />

42 EmailFrom = gatewayif@agilent.com


C.3. CONFIGURATION FILES 127<br />

EmailTo = david@localhost<br />

44 EmailSubject = Gateway Interface Status Report<br />

EmailHost = localhost<br />

C.3.2<br />

AA<br />

2 CA<br />

00<br />

4 CE<br />

CE<br />

6 CR<br />

AE<br />

8 CA<br />

AA<br />

10 AA<br />

MAS.cfg<br />

C.3.3 hl7 v231.dtd<br />

<br />

2 <br />

4 <br />

<br />

6 <br />

<br />

8 <br />

<br />

10 <br />

<br />

12 <br />

<br />

14 <br />

<br />

16 <br />

<br />

18 <br />

<br />

20 <br />

<br />

22 <br />

<br />

24 <br />

26 <br />

<br />

28 <br />

<br />

30 <br />

<br />

32 <br />

<br />

34 <br />

<br />

36 <br />

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!