Articles
Java Platform, Standard Edition
|
| |
If you're a developer who works in health care, health insurance, or HMO administration, you know what a nightmare it can be to change health care systems. Patient information databases and billing systems are frequently error-prone and full of glitches. Complex, diverse computing systems that can effectively exchange huge amounts of patient data are a central requirement of a seamless health care system; but such systems are notoriously difficult to develop and maintain.
This problem is further aggravated in developing countries, where the reach of technology into remote corners is highly restricted, and it's impossible to manage patient data locally -- even on a transient basis. Undaunted by some of these challenges, however, the Brazilian government recently implemented a national repository of health records in a phased manner. After the completion of the first phase, a successful pilot -- using Java technology and XML -- was chosen to complete the remaining phases of the system.
The Brazilian National Health Care System treats about 1.2 million inpatients and 100 million outpatients per month, providing everything from immunization to heart transplants.
In 1999, the National Health Card Project (NHCP) was started to create a national patient identification and information system for the Brazilian Unique Healthcare System (SUS-- Sistema Único de Saúde). The main goal of the NHCP was to collect information on patient treatments, to be collected in a national repository of health records. This repository will give the Ministry of Health of Brazil and the municipality Health Managers an accurate, up-to-date view of the health services provided to the population by the National Healthcare System.
The project was started as a pilot to validate the architectural hardware and software components, infrastructure, standards, and training before implementing the system on a national scale. The pilot covered 44 cities in 11 states, covering 13 million people (out of a national population of 180 million). The second phase will probably address more than 500 cities, covering around 100 million patients. In a bidding process, two consortia were selected to implement the pilot for different regions of Brazil. The solution discussed in this article (using Java technology, XML, and Sun hardware) was developed by Hypercom/Singularity Systems for the pilot project for the South and Mid-West regions, consisting of 18 states and 40 cities. This article will explore the simplicity and extensibility of the Singularity pilot system design, which has been chosen for implementation on a national scale.
In the NHCP, patient treatment data is entered locally by health care providers, and later transferred and distributed to database servers organized in a hierarchy of levels -- municipal, regional, state, and federal -- reflecting the organization of the health system in Brazil, as shown in the diagram below:
Patient ID information is contained on magnetic stripe health cards; care providers are equipped with a client application and terminals to capture the following information:
The client application guides the health care professional through the process of entering the essential data for the patient visit: reason, diagnosis, procedures performed, medication, and referral information. Brazil has national standardized codes for this data, and uses the International Classification of Diseases (ICD-10) recommended by the World Health Organization.
The client application uploads its stored information to the municipal server by dialing-up to the network at intervals (few health care providers have permanent network connections). If the municipal server is not available, the data is uploaded to a concentrator server, which acts as a backup. Once the data is transferred to the municipal server, the NHCP application handles and stores the data in a local database. Later, the NHCP application at the municipal server connects to the concentrator level and uploads a copy of the data from the municipal server. Then, the data collected by the health care providers reaches the permanent network and is later replicated to the upper levels of the municipal/concentrator/state/federal hierarchy.
The main role of the client application is entering information; however, the health care provider can also use the client application to query the system for information.
The main functional requirements of the NHCP infrastructure are:
One of the main goals of the NHCP was to avoid vendor lock-in or proprietary technology. Two technologies -- Java technology and the XML data format -- were chosen to achieve this goal. Also, the nature of the project called for multiple vendors and system integrators to implement the system, and it was necessary to ease integration without hampering the different implementations. XML, Java technology, and HTTP were used as the "glue" to bring these diverse implementations together relatively quickly.
The major components of the system architecture are:
After analyzing the goals and different architectural possibilities, NHCP determined that the pilot would need an infrastructure of common services that could be reused in future application development.
The NHCP core infrastructure is responsible for receiving, processing, and/or routing the data, according to its type and destination. The infrastructure is composed of plain Java objects that provide the infrastructure services and the business logic running in Tomcat servlet containers, Apache web servers, and Oracle databases -- all running on Sun hardware.
The main technologies used in the NHCP core are:
A major problem for the development team was the lack of proper software specifications and frequently changing requirements. To address this issue, the designers built a generic framework of Java business classes and XML documents. This framework allowed for the necessary adjustments and scalability as the specifications evolved.
The Java framework is based on the following concepts:
All XML is validated according to a rigid specification (DTD, infrastructure, and domain), which provides the flexibility necessary to add or remove business classes, and to modify the XML validation rules. In addition, servers and clients must authenticate to a server node using digital certification.
The figure below depicts a generic server node with its principal building blocks and data flows.
This process receives an XML file and instantiates it as an
XMLObject. The
XMLObject is then passed to the validation service. This is similar to XML binding (automatic mapping between XML documents and Java objects) using JAXB, but JAXB was not available at the time of the pilot, and hence a homegrown marshalling/unmarshalling scheme was developed.
Below is the Java code responsible for this marshalling and unmarshalling:
// Creates the main XML Object sent to a server node from its
// Input Stream
XMLObject xmlObject = XMLObjectFactory.createMainXMLObject(in);
To send XML to a generic node, there is a template pattern implementation due to restrictions on connectivity characteristics. In the Messenger abstract base class, we have the send method:
protected Message send(Message msg, MachineCode destination)
throws RemoteException {
Message answer = null;
try{
answer = sendTemplate(msg, destination);
} catch(MachineCodeException e){
.
.
.
}
// And an implementation of the sendTemplate method in some classes that inherit from
// Messenger:
public Message sendTemplate (Message msg, MachineCode destination)
throws MessengerException, MachineCodeException {
return sendMessage (msg, destination.getIdserver());
}
This process validates the received
XMLObject. It includes the DTD definitions and the data according to the information infrastructure stored in the database. For example, the system validates if the XML destination is valid. Once the validation succeeds, the
XMLObject is passed to the distribution/routing service; otherwise, an XML message is sent to the client, informing it that a problem has occurred. The validation takes place at the creation of the
XMLObject, as shown below:
public static XMLObject createMainXMLObject(InputStream in)
throws XMLObjectException {
XMLObject xml = null;
try {
// InputStream xml parsing stuff
// . . .
xml = createXMLObject(doc.getDocumentElement());
if ( !xml.validate() ) {
Logger.logErr("XMLObjectFactory.createMainXMLObject",
xml.getMsgs());
throw new XMLObjectException("XML validation failed", xml);
}
}
catch (NoSuchProviderException nspe) {
.
.
.
}
Every XML entity (message, object and so on) has an associated class that defines its scope, properties, elements, and formation rules. The validation method uses Java Reflection for all the properties and element class definitions; the validation method thus only has to match the instance data attributes with the respective XML definition class at runtime.
The distribution/routing service decides if the local business logic objects should handle the
XMLObject or if it should be forwarded to its parent in the hierarchy. If the message can't be sent, it is stored locally. After some time, a special task using the scheduler service tries to send it again. The distribution block also validates the content of the XML message according to the domain tables. For the execution of business objects with controlled access, the distribution block verifies the client's digital authentication status.
Whenever the distribution processes decide that an XML message is not to be processed locally, it invokes the messenger service to send it to the proper destination node. The Distributor class receives the XML and decides if it is to be processed locally or be sent to another server node.
public XMLObject distribute(XMLObject xml) {
XMLObject answer = null;
MachineCode destination = xmlObject.getDestination();
Boolean localExecution = destination.getIdserver().isLocalserver();
if (localExecution) {
// Check if the BusinessClass should be allowed to execute in
// this server. If not, an exception is thrown
checkLocalExecPermition(xml);
// Check if the BusinessClass should be allowed to execute
// according to whether the client has authenticated or not
// An exception may be thrown
checkAuthFreeExecPermition(xml);
answer = callBusinessClass(xml);
} else {
Messenger messenger = new Messenger(bd, _logger);
answer = messenger.send(xml);
}
return answer;
}
The scheduler oversees the timed invoking of scheduled tasks for the system. For instance, the scheduler is responsible for scanning of the XML documents stored in the database, and for sending the unprocessed ones to the distributor for further processing.
The scheduler is a singleton pattern instantiated by a servlet. It creates a
TaskManager, an instance of
TimerTask, that creates a
Timer for each schedulable task from the database. The
TaskManager itself is inserted into another
Timer for periodic refreshing from the database.
private Scheduler() {
try {
TaskManager taskManager = new TaskManager();
Timer timer = new Timer();
timer.schedule(TaskManager, 0, REFRESH_TIME); //every 60 minutes
}
catch (Exception e) {
Logger.logErr("Scheduler", e.getMessage(), e);
}
}
This component has several Java objects that implement the tasks directly related to the NHCP business, such as:
Privacy and confidentiality of health and identity information was a major issue for the pilot project. To protect privacy, a health professional using the system must be previously registered at the server level. The provider must have a valid health professional card (the list of actual health professionals working in a health care unit is kept at the point-of-care equipment). A health care professional authenticates with the system by swiping his or her card and entering a password.
Digital certificates are used for client authentication validation. The distributor service reads an attribute from the servlet as detailed below:
X509Certificate cert =
(X509Certificate)request.getAttribute("javax.servlet.request.X509Certificate");
X509Certificate certChain[] =
(X509Certificate[]) request.getAttribute("javax.net.ssl.peer_certificates");
return (validadeCertificate(cert, certChain));
protected boolean validateCertificate(X509Certificate cert,
X509Certificate[] certChain) {
// Code for the validation
.
.
.
return true // when everything is ok with the certificate
.
.
.
return false // when something is not ok with the certificate
}
Client authentication is not mandatory, so it is optional for the client to send a digital certificate to the server. This restrains the kind of XML the server accepts (executes) from the client.
The negotiation of certificates is part of the SSL handshake. The process initiates when the client makes a request to the server; the server then asks for the client digital credentials. The client sends the client certificate to the server and in return receives the server certificate. The authentication of the server is done on the client side.
Other Security Features
Back in early 2000, neither SOAP nor XML schemas -- nor even JAXB or JMS -- were available or mature enough. It is interesting to note that the technologies developed for the NHCP project can be directly mapped to the actual Java technology standards of today, as the figure below depicts:
XML over HTTP can be directly mapped to SOAP. The strong XML validation that enhances the DTD specifications are represented as XML schemas.
The messaging concepts adopted in the project are similar to JMS. There is, however, a difference: while JMS delivers messages reliably, the NHCP model guarantees that for every XML message sent, there is a response XML message containing the result of the execution.
The infrastructure design of the pilot turned out to be well-conceived, as proven by the success of this project, and by the technology trends of the Java APIs (JAXB, SOAP) from 2000-2003.
Since spring 2003, the pilot infrastructure has been fully operational, consisting of:
In parallel with the pilot project and in anticipation of consolidation for the rest of the country, 80 million people have been uniquely identified in the NHCP database, representing 40% of the Brazilian population. Interoperability with external systems is also operational. Systems from external vendors are communicating with the NHCP by exchanging XML documents.
NHCP server-side data:
Training -- and then retaining fully trained employees -- is one of the major challenges of the NHCP. In one city of 10,000, a programmer was trained as a fully Oracle certified DBA; the next month, he left for the big city of Sao Paulo for a better paying job.
The diagram below shows actual data queried from the NHCP system for San Jose dos Campos, a city of 500,000 people near Sao Paulo. The x axis shows the treatment procedures codes, the y axis the date, and the vertical z axis shows the corresponding quantity. So what happened to cause this peak? From the data, it was possible to identify that the peak was due to the annual influenza immunization program; it was in winter, and over a two-week period, nearly 5000 people got their influenza shots.
Java technology, XML, and XML Messaging over HTTP proved to be good choices for flexibility, extensibility, and interoperability as shown by the success of this pilot and its choice as the solution for continued implementation on a nationwide level.
This pilot has made it possible for participating health managers to have an accurate and reliable source of information to see what is happening in the field of health in their municipality. Up-to-date information (such as drugs prescribed, exams used, epidemiological control, tracking of diseases, fraud detection, and auditing) can now be obtained with the click of a button.
| |