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 = ”ˆ˜\\&”;<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 = ”ˆ˜\\&”;<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 />