Simulator Developer Guide (use of modules shared by simulators)

Introduction

This section is aimed at developers who'd like to contribute to the Gazelle Project and develop new simulators.

What is a simulator ?

A simulator is a stand alone application that mimics one (or more) IHE actors for a given set of IHE profiles. The simulator may implement a web service interface that it used for the communication between Gazelle and the Simulator. The simulator shall also implement the functionality specific to the actors it is simulating. The simulator must to store the messages exchanged with the system under test and it's strongly recommend that it is bound to a validation service to check the conformity of the messages exchanged.

How to create a new simulator project ?

All the simulators of the Gazelle platform are built on the same model using a Maven archetype. This ensures that the layout will remain the same and it avoids wasting time in developing a new template and classes which can be common to several tools.

If the simulator you are about to create will implement HL7v2 based transaction, please read the HL7v2 based simulator section of this guide.

Below, we explain how to create a new Maven project using Eclipse new project configuration feature. Before starting this tutorial, make sure that you have the Maven plug-in installed (see Development support tools section of the developer guide for the list of plug-ins to install)

  1. Start Eclipse and create a new Maven Project: File --> New --> Project ... The New project pop-up will appear. 
  2. Select the wizard entitled Maven Project (under the Maven folder) and click on the Next > button.
  3. On the New Maven Project page, verify that "Create a simple project (skip archetype selection)" is not checked and click on the Next > buttonStep 2
  4. Then, you are asked to select an archetype. Select the Nexus Indexer catalog and then Filter with net.ihe.gazelle. You should see an archetype named simulator-archetype. Make sure you have the latest version by checking the Nexus repository of Gazelle. If the latest version does not match the one displayed by Eclipse, you will be able to change it during the next step. Click on the Next > button.Step 3
  5. On the next page, enter the following informations
    • Group Id: net.ihe.gazelle.simulators
    • Artifact Id: the name of your simulator
    • Version: might be 1.0-SNAPSHOT
    • Package: net.ihe.gazelle.yoursimulatorpackage (prefer lower case)Step 4
  6. Finally, click on the Finish button
  7. Creating the simulator might take a while, once the project is build, it will appear in your list of projects under the Java view. You can now start developing your new tool by editing and completed the pom.xml file available at the root of the project.

Add this new project in SVN

Simulators are gathered in the Maven/simulators directory of our SCM. To add your simulator, follow the instructions given below

  1. Go to the "Browse SVN" view and select the Gazelle repository (at svn+ssh://yourlogin@scm.gforge.inria.fr/svn/gazelle)
  2. Right click on Maven/simulators folder and select New --> Project structure...
  3. Enter the name of your project (Shall be the same as your parent project, in the example DemoSimulator)
  4. Check the folder and its children (trunk, tags, branches) are correctly created in the good place
  5. Go back to the Java view and right-click on the parent folder of your project (DemoSimulator in the example) and select Team --> Share Project...
  6. In the dialog window, select SVN and click Next >
  7. On the next page, select the Gazelle repository and click Next >
  8. Then, select Simple mode and browse the repository to access the right location: Maven/simulators/DemoSimulator/trunk
  9. Make sure that the final folder is trunk (Eclipse might add your project name after trunk and that is not what we want)
  10. Finish the process. You might be asked to checkout the project available on the Forge, say YES.

 

Features included within simulator-common and the archetype

Application preferences

simulator-common contains an entity named ApplicationConfiguration which is used to manage the preferences of your application. This feature is used by the other functionalities of simulator-common, make sure to create the followig preferences within your database.

Preference name (variable) Description Default/Example value
application_url The URL used by any user to access the tool  
cas_url URL of the CAS service Default: https://gazelle.ihe.net
application_works_without_cas Indicates whether or not authentication uses the CAS service Default: false
ip_login Indicates whether or not IP addresses are filted at login when CAS service is not used Default : false
ip_login_admin Regex used to filter IP addresses  
message_permanent_link URL to access the messages exchanged with the tool  
time_zone Time zone of the application Default: Europe/Paris
svs_repository_url URL of Gazelle Value Set repository Default: http://gazelle.ihe.net
documentation_url URL to get the user manual of the tool  
application_release_notes_url URL to get the release notes of the tool  

A page is dedicated to the management of preferences, see /admin/configure.seam (only accessible by admin)

Messages storage

After having developed several simulators, we noticed that we always need an entity to store the messages exchanged between the simulator and the systems under test. In most of the case, we need to store the same informations (initiator, responder, message content ...) and we bind the simulator to a validator so we also store the result of the validation process.

Authentication

A simulator offers several authentication methods, the basic method, the one we use on our server uses the CAS service available at https://gazelle.ihe.net. Other methods are:

  • no authentication required, everybody has administration rights
  • authentication based on IP addresses: only the users who are connecting with an IP address matching the regex defined in the database are granted with admin permissions

The table below represents the boolean set in the database and the behaviour of the tool depending on their values

application_works_without_cas ip_login behaviour
true true Only the users whose IP address matches the regex are granted as admin (ip_login_admin must be defined)
false true Authentication and rights are managed by the CAS service
true false Any user is granted as admin
false false Authentication and rights are managed by the CAS service

Model-based validation service

If you have developed a model-based validation service to validate the messages exchanged in the context of the integration profiles implemented by your simulator, you can use this web service to allow other applications to call your validator. Using this class instead of creating a new one is easier for the clients since it's the same stub as for the other validation services.

Home

The home page can be configured through the user interface (by admin) and the content is locale dependant.

Simulator control (from Test Management)

Simulators can be driven by Test Management application. A web service is available that you must implement to allow Test Management to control your simulator.

Value Set Repository Consumer

To build the messages, your simulator may need values from a specific set of codes. We usually store those codes within the SVS Simulator and use the SVSConsumer utility class to retrieve the codes (based on OID).

XUA

Some messages must contain an XUA assertion in their header. Some mechanisms are implemented in simulator-common to help you with creating those assertions.

Test report

A REST webservice is available to retrieve information about a transaction instance.

System Under Test Configuration

If your simulator acts as an initiator, you will need to store the configuration of the system under test. An entity named SystemConfiguration is available to store those informations, it assumes that you need an URL to contact the system under test. If the system under test is HL7 based, you need to use HL7Common as a parent and not directly simulator-common.

HL7v2 based simulator

From HL7Common-2.2, the structure of the AbstractServer class has changed, some changes need to be done in classes extending this abstract class.

If you are about to implement a new simulator based on the HL7v2 standard, please read  carefully those lines, it will help you to use the common component developed by IHE Development team and to avoid wasting time rewriting existing things. Moreover, this will help us to keep a consistency between all HL7v2 simulators.

First of all, in this page, we define a simulator as the emulation of an actor of a given IHE integration profile for a given transaction. Obviously, your application can gather several simulators. Regarding the HL7v2 standard and IHE specifications, we define two different roles:

  • Initiator: a simulator acting as a initiator sends a message to a system under test (SUT) and waits for its response. It works as a client.
  • Responder: a simulator acting as a responder is a server, listening on a given port and sending a response to all received messages, this response can be an ACK, a NACK or anything else.

We are aware that some actors can play both roles but regarding the implementation of your application, you will have to distinguish each parts since the implementations differ.

Project configuration to use HL7Common maven module

IHE Development team has developed a maven archetype which enable you to build the architecture of your simulator. This archetype is available on Gazelle Maven repository. The values you need to generate the project from the archetype are given below.

  • archetypeArtifactId: simulator-archetype
  • archetypeCatalog: http://gazelle.ihe.net:9080/nexus/content/groups/public/
  • archetypeGroupId: net.ihe.gazelle.simulators
  • archetypeVersion: 1.16

If everything works well, the generated project contains three modules: EJB, WAR and EAR.

More over a maven module called HL7Common which contains all the classes and xhtml files you may use to implement your simulator based on HL7v2 standard is available in Gazelle Maven repository. To use it, complete your pom.xml files with the follwing lines.

This documentation is currently based on HL7Common:2.2.

Configure the POM file of your parent project to make the HL7Common module the parent of your new project.

<parent> 
<groupId>net.ihe.gazelle.simulator.hl7</groupId> 
<artifactId>HL7Common</artifactId> 
<version>2.2-SNAPSHOT</version> 
</parent>

Then, in the pom.xml file of the EAR and EJB modules add

<dependency> 
<groupId>net.ihe.gazelle.simulators</groupId> 
<artifactId>simulator-common-ejb</artifactId> 
<type>ejb</type> 
</dependency> 
<dependency> 
<groupId>net.ihe.gazelle.simulator.hl7</groupId> 
<artifactId>HL7Common-ejb</artifactId> 
<type>ejb</type> 
</dependency>

Also in the pom.xml file of the EAR project add the following lines in the configuration of the maven-ear-plugin

<ejbModule> 
<groupId>net.ihe.gazelle.simulators</groupId> 
<artifactId>simulator-common-ejb</artifactId> 
<uri>simulator-common-ejb.jar</uri> 
</ejbModule> 
<ejbModule> 
<groupId>net.ihe.gazelle.simulator.hl7</groupId> 
<artifactId>HL7Common-ejb</artifactId> 
<uri>HL7Common-ejb.jar</uri> 
</ejbModule>

Then, in the pom.xml file of the WAR module add 

<dependency> 
<groupId>net.ihe.gazelle.simulators</groupId> 
<artifactId>simulator-common-war</artifactId> 
<type>war</type> 
</dependency> 
<dependency> 
<groupId>net.ihe.gazelle.simulator.hl7</groupId> 
<artifactId>HL7Common-war</artifactId> 
<type>war</type> 
</dependency>

 

Charset

If you take a look to the classes defined in this module, you will find out an entity named Charset. This class is used to defined the character set encoding used by the simulator in one hand and by the system under test in another hand. For each charset we give the HL7 code used in MSH-18 segment and the code as understood by the JVM to read and write messages. By making the simulator and the system under test using the same charset, we ensure that the messages are understandable for each part. A set of data is available as an sql script in the parent parent of HL7Common module. You can also find it here.

System Under Test configuration

If your simulator acts as an initiator, it will need to know to "who" (host, port) send messages. A seam entity has been created to enable the simulator to retrieve those information and the user to store his/her system under test configuration into the simulator's database. In this way, he/she can retrieve it easily when he/she need to test his/her system. The XHTML page to manage configurations is stored in the WAR module of HL7Common, please provide a link to this page ("/systemConfigurations.seam") into your GUI. Each configuration will be linked to an actor and a charset.

Simulator configuration

To increase the interoperability between the simulator and the systems under test, we have chosen to send messages with the appropriate charset (when acting as an initiator). In the same way, when the simulator acts as a responder, we open different ports using different character set encodings. The SimulatorResponderConfiguration class has been implemented with this goal in mind. The main attributes of this object are the port number (on which the server listen)  and the character set encoding. The README file attached give you some examples of how to fill your database.

HL7 messages and message validation

The application is expected to keep a trace of all transactions initiated by itself or by a system under test. We have chosen to store in the database, the received message along with the sent message. The HL7Message class is dedicated to this task. Consequently, each time the simulator sends or receives a message, it is required to instanciate a new HL7Message object and to store both the request and the response inside.

The HL7Message object is linked to another entity named EVSCValidationResults. Actually, each HL7v2 simulator has to be linked to the HL7InriaValidator in order to provide to the user a way to validate messages against the message profiles. The XHTML pages created in the WAR part of HL7Common provides the button which called the validator by a webservice mechanism. To work properly, you will need to add a preference to your application database, the one is given in the README file attached.Morevoer, the validation service needs to know which message profile to use and this action must be transparent for the user. Consequently, another entity named ValidationParameters is defined. For each tuple (actor, transaction, affinity domain, message type) we give the OID of the message profile to use.

A page gathering all the HL7Message contained in the application's database can be added into your GUI by making a link to "/hl7Messages.seam".

Affinity domain

An application could implement a same actor in different affinity domains. In this case, some distinctions may be required, especially for the message validation. Consequently, an entity named AffinityDomain has been defined and a link is made to it from the HL7Message, the SimulatorResponderConfiguration and the ValidationParameters.

Creating HL7 messages

HL7 defines a set of segments, some of which are common to most of the messages. It is the case for example for the MSH segment. In order to save time and to avoid to build this segment in as much ways as simulators, a class SegmentBuilder has been created in HL7Common and can be extended by each simulator if needed. By now, this class contains methods to fill MSH, EVN, PV1 and MSA segments.

An HL7MessageDecoder class exists in the same package and by now contains only one method which extracts the message type from a message using the HAPI Terser.

Acting as an initiator

If your simulator acts as an initiator, you will need to

  1. Collect information from the user to build messages
  2. Collect information about the SUT to "contact"
  3. Send messages

The first two points require a user interface. In order to keep a consistency between all simulators, a XHTML page ("/configuration/initiatorFrame.xhtml) has been created which has to be included at the top of your page for each actor your application emulates. This page contains a drop-down menu with all the available SUT for the simulated actor, the sequence diagram of the transaction and the configuration of the simulator. Some parameters are expected to be given to the page in order to display properly all the informations.

  • actorKeyword: keyword of the actor played by the SUT, so that the offered configurations are filtered
  • diagramImg: path to the sequence diagram image to include in the page
  • currentConfig: the attribute from the managed bean in which the selected SUT configuration has to be set
  • simuFacility: the string reprensenting the sending facility used by the simulator
  • simuApplication: the string reprensenting the sending application used by the simulator
  • sectionsToReRender: the list of page sections to rerender when the user change the selected configuration.
  • simulatorConfigurationName: the name you want to give to the simulator's configuration

See below an example of how to include it into your page and how it is rendered.

<ui:include src="/configuration/initiatorFrame.xhtml"> 
<ui:param name="actorKeyword" value="PDC" /> 
<ui:param name="diagramImg" value="/img/diag/ident_diag.png" /> 
<ui:param name="currentConfig" value="#{creationManager.selectedSystemConfig}" /> 
<ui:param name="simuFacility" value="#{creationManager.sendingFacility}" /> 
<ui:param name="simuApplication" value="#{creationManager.sendingApplication}" /> 
<ui:param name="sectionsToReRender" value="sendMessageButtonDiv" /> 
<ui:param name="simulatorConfigurationName" value="PAM PDS Simulator"/> 
</ui:include>

  responder

 HL7Common uses HAPI to build messages and to send and received them. A class named Initiator has been implemented into HL7Common in order to help you to send message and to instanciate the HL7Message object. The constructor of this class set all the parameters required for the sending of the message and a method sendMessage() sends the message, waits for the response, builds the HL7Message object, stores it in the database and returns an instance of HL7MessageDataModel containing the created message. So that you can displayed this message in the GUI using a rich:dataTable component and the columns defined in HL7Common WAR part ("/hl7MessagesTableColumns"). See below an example of how to use this class.

public void sendMergeMessage() { 
Initiator hl7Initiator = new Initiator(selectedSystemConfiguration, 
			sendingFacility, 
			sendingApplication, 
			Actor.findActorWithKeyword("PDS"), 
			Transaction.GetTransactionByKeyword("ITI-30"), 
			createMessage(), 
			MESSAGE_TYPE, "IHE"); 
try{ 
	msgDataModel = hl7Initiator.sendMessage(); 
}catch(HL7Exception e){ 
	FacesMessages.instance().add(e.getMessage()); 
} 
}

Acting as a responder

First of all, note that when your simulator is acting as a responder, this part of the application cannot access the EntityManager using the Component class of seam. You have to declare all the entities in a configuration file and create your entityManager using this file. The squeleton of this file, usually named hibernate.cfg.xml is attached to this page.

If your simulator acts as a responder, you will need to perform the following actions:

  1. Listen for incoming messages on different ports (one port per character set encoding)
  2. Process incoming messages and send response
  3. Display received and sent messages

Concerning the first point, HAPI library offers a mechanism to create a server linked to an handler; the latter is used to process messages (2). Starting the JVM used by Jboss with the proper option enable the developer to specifiy the character set encoding used by HAPI to read and write messages on the socket. To increase interoperability between the SUT and the simulator, we have chosen to let the user choosing the character set encoding to use for sending and receiving. Consequently, some changes have been brought to the basic classes. Using IHE classes (built from HAPI ones) you can easily declare the character set encoding to use. Instead of instanciating a MinLowerLayerProtocol object, create a new IHELowerLayerProtocol instance by using the constructor which need a charset as a parameter.

We use the SimpleServer class from HAPI library to create the server part; the one has to be started at deployment time. This can be easily done using the annotations @Startup and @Create in the managed-bean dedicated to the server.

Concerning the second point, you need to create a class implementing the Application interface from HAPI. This interface contains 3 methods, two of them are very important: processMessage and processException. They are the methods called when a message is caught by the SimpleServer.

In order to save your time, two abstract classes IHEDefaultHandler and AbstractServer have been implemented and both of them have to be extended in your simulator.  The first one has to be extended by the handler, so you will have to implement processMessage and processException; for the second one, you only need to implement the abstract method startServers() as shown below. Obviously, the AbstractServer is based on the SimulatorResponderConfiguration that is to say that when you call the startServers(Actor, Transaction, AffinityDomain, IHEDefaultHandler) method, all the configurations matching the 3 first criteria are retrieved and a instance of SimpleServer is created and linked to the IHEDefaultHandler for each item of the list.

@Startup 
@Name("myServerBean") 
@Scope(ScopeType.APPLICATION) 
public class Server extends AbstractServer<MyHandler>{ 
	private static final long serialVersionUID = 1L; 
	
	@Override public void startServers() { 
		entityManagerFactory = HibernateUtil.buildEntityManagerFactory("META-INF/hibernate.cfg.xml"); 
		entityManager = HibernateUtil.beginTransaction(entityManagerFactory); 
		Actor simulatedActor = Actor.findActorWithKeyword("PDC", entityManager); 
		AffinityDomain affinityDomain = AffinityDomain.getAffinityDomainByKeyword("IHE", entityManager); 
		HibernateUtil.commitTransaction(entityManager); 
		handler = new MyHandler(entityManagerFactory); 
		startServers(simulatedActor, null, affinityDomain); 
	} 
}

 Concerning the last point, an abstract class SimulatorResponderConfigurationDisplay is used to display the list of listening ports for a given (actor, transaction, affinity domain) tuple. This class is also used to display the list of messages which have been received by the simulator. For each responder your application implements, you have to extend this class and implement the two abstract methods. An XHTML file (/configuration/simulatorResponderConfigurationTemplate.xhtml) is related to this class and has to be included into your GUI in this way:

<rich:panel> 
	<f:facet name="header">Patient Demographic Consumer</f:facet> 
	<ui:include src="/configuration/simulatorResponderConfigurationTemplate.xhtml"> 
		<ui:param name="managedBean" value="#{pdcGUIManagerBean}"/> 
		<ui:param name="diagramPath" value="/img/diag/pdcResponder.png"/> 
	</ui:include> 
</rich:panel>

Managing Simulator Responder Configuration

Has seen above, the responder part of the HL7 simulators is managed using an entity called SimulatorResponderConfiguration. This entity defines several attributes, among them

  • the IP address (this one is not used to start the service but to inform the user of the IP address to communicate with.
  • the port (on which the simulator will listen)
  • the serverBeanName (this attribute must match the @Name value of the AbstractServer which starts it, otherwise you will not be able to start/stop the server from the GUI)

The menu item "Simulator responder configuration", shown when logged as admin, leads you to the page used to configure the responder part of the simulator. From this page, you can

  • Create a new configuration that means declare a new port to listen on
  • Start/Stop listening on a port
  • Start/Stop listenning on all the declared ports

Display of HL7 messages

The part of the HL7v2.x simulator which displays received and sent HL7 messages has been developed in HL7Common module and, in most of the case, you are not expected to bring changes to it. But, as we may have specific needs in some simulators, we tried to develop this part in such a way that it is easy to bring enhancements. 

Menu

 In order to have uniform applications, the menu items common to all HL7v2 simulators are gathered in a xhtml page /layout/hl7CommonMenuBar.xhtml you have to include in the menu of your application. The HL7 menu bar looks like this

menu

Add the following lines in your file /layout/menu.xhtml

<!-- HL7 menu --> 
<ui:include src="/layout/hl7CommonMenuBar.xhtml"> 
<ui:param name="displaySUTMenu" value="true"/> 
<ui:param name="displaySimulatorMenu" value="true"/> 
</ui:include>
  • displaySUTMenu is used to indicate whether the menu for reaching the SUT configuration part must be displayed or not.
  • displaySimulatorMenu is used to indicate whether the menu for reaching the Simulator "responder" configuration part must be displayed or not.

Footer

In order to have uniform applications, it is necessary to use the same template for the "about" modal panel in the footer item.

See the screenshot below to have an example :

about_example
 

Test reports

HL7Common integrates a feature that enables the simulator to provide test logs to other applications using a REST web service. In order to make this functionnality available in your simulator, you need to update your WEB-INF/web.xml file of the war module of your project with the following lines:

<!-- REST web service (see also line 178)--> 
<context-param> 
	<param-name>resteasy.jndi.resources</param-name> 
	<param-value>${contextRootOfYourSimulator}/HL7v2TestReport/local</param-value> 
</context-param> 
<context-param> 
	<param-name>resteasy.servlet.mapping.prefix</param-name> 
	<param-value>/rest</param-value> 
</context-param> 
<listener> 
	<listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class> 
</listener> 
<servlet> 
	<servlet-name>Resteasy</servlet-name> 
	<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class> 
</servlet> 
<servlet-mapping> 
	<servlet-name>Resteasy</servlet-name> 
	<url-pattern>/rest/*</url-pattern> 
</servlet-mapping>

 

!!! Make sure the application_name and application_url entries are present and not empty in your app_configuration table.

PatientGeneration module

A common module has been developed to help developers with the patient generation part of their simulators. Indeed, some simulators require the creation and saving of patients. In order to save developers' time and to make this part of the simulators quite uniform, a small maven project named PatientGeneration has been developed.

This project is divided into two parts: a jar module and a war module.

  • The jar module contains mainly the abstract class which represents the common properties of a patient and a bean with a method which calls DDS to obtain a new patient.
  • The war module contains the patient generation page, the pages to edit and to view the patient's common informations. They can be included using <ui:include> tags.

Sources

EJB and WAR archives at available on Gazelle's Nexus release repository but if you need to check out the files, URL to use is https://scm.gforge.inria.fr/svn/gazelle/Maven/simulators/PatientGeneration/trunk 

Import notice

The PatientGeneration module calls SVSSimulator tool to get the display names for sex, race etc. Make sure you have a class annotated @MetaInfServices(PreferenceProvider.class) to retrieve the preferences of your application ; in particular, PatientGeneration will look for svs_repository_url.

How to use this module in a simulator

Note that the given examples are extracted from PAMSimulator project that you can find on the INRIA's Forge at https://scm.gforge.inria.fr/svn/gazelle/Maven/simulators/PAMSimulator/trunk.

To use the PatientGeneration project, you first have to add the following Maven dependencies to your project.

pom parent: 

<dependency> 
<groupId>net.ihe.gazelle.maven</groupId> 
<artifactId>PatientGeneration-ejb</artifactId> 
<version>${patientGeneratorVersion}</version> 
<type>ejb</type> 
</dependency> 
<dependency> 
<groupId>net.ihe.gazelle.maven</groupId> 
<artifactId>PatientGeneration-war</artifactId> 
<version>${patientGeneratorVersion}</version> 
<type>war</type> 
</dependency>

pom.xml of the EJB module:

<dependency> 
<groupId>net.ihe.gazelle.maven</groupId> 
<artifactId>PatientGeneration-ejb</artifactId> 
<type>ejb</type> 
</dependency>

pom.xml of the WAR module:

<dependency> 
<groupId>net.ihe.gazelle.maven</groupId> 
<artifactId>PatientGeneration-war</artifactId> 
<type>war</type> 
</dependency>

 The method which generate the patient by calling DDS returns an AbstractPatient object. The AbstractPatient class is annotated with @Entity and @Inheritance(strategy = InheritanceType.SINGLE_TABLE), so that when you create an entity which extends this abstract class, data will be stored in pat_patient table. Your new entity requires a constructor which takes the AbstractPatient returned by the PatientGenerator bean as parameter, and the attributes of the abstract patients have to be copied into the attributes of your patient.

@Entity
@DiscriminatorValue("my_app_patient")
public class Patient extends AbstractPatient { 
public Patient() { 
} 
public Patient(AbstractPatient abPatient){ 
this.firstName = abPatient.getFirstName(); 
this.lastName = abPatient.getLastName(); 
this.motherMaidenName = abPatient.getMotherMaidenName(); 
this.city = abPatient.getCity(); 
this.state = abPatient.getState(); 
this.street = abPatient.getStreet(); 
this.countryCode = abPatient.getCountryCode(); 
this.zipCode = abPatient.getZipCode(); 
this.genderCode = abPatient.getGenderCode(); 
this.religionCode = abPatient.getReligionCode(); 
this.raceCode = abPatient.getRaceCode(); 
this.dateOfBirth = abPatient.getDateOfBirth(); 
this.creationDate = abPatient.getCreationDate(); 
this.nationalPatientIdentifier = abPatient.getNationalPatientIdentifier(); 
this.characterSet = abPatient.getCharacterSet(); 
this.ddsIdentifier = abPatient.getDdsIdentifier(); 
} 
}

You can notice that only the code (and not the display name) is stored for the race, the religion, and the gender. Actually, we only need the code because using the repository part of SVSSimulator we can retrieve the display name according to the language selected by the user (when the translation exists in SVS). If you take a look into the edit(show)AbstractPatientDemographic.xhtml files, you will see that a method is called for those properties instead of only displaying it. Those methods calls the SVSRepository. Concerning the country, only the code is stored too and the display name is retrieved from the JVM thanks to the Locale instance. That means that, by now, when you change one of those attributes, you need to give the code and not the display name. In the future, the repository will be used to display the list of available codes.

Then, when you write the java parts of your code, the java beans in which you need to generate a patient have to extend the PatientGenerator class from net.ihe.gazelle.patient package. If your bean is stateful and implements an interface annotated @Local, this interface is expected to extends PatientGeneratorLocal interface. When you will write the presentation part of your application, you will have to include /patient/patientGenerator.xhtml and add a button which calls a method which makes a call to generatePatient() from PatientGenerator.java to retrieve the AbstractPatient object.

See below an abstract from PAMSimulator.

 
@Name("creationManager") 
@Scope(ScopeType.PAGE) 
public class CreationManager extends PatientGenerator implements Serializable{ 

private Patient selectedPatient; 
public void generateAndSavePatient(){ 
AbstractPatient aPatient = generatePatient(); 
if (aPatient != null) { 
selectedPatient = new Patient(aPatient); 
} 
} 
 
}

Here is the presentation part.

<s:div id="ddsDiv"> 
<rich:panel id="ddsPanel" rendered="#{creationManager.displayDDSPanel}"> 
<f:facet name="header">Patient Generation with DDS</f:facet> 
<ui:include src="/patient/patientGenerator.xhtml"> 
<ui:param name="patientGeneratorBean" value="#{creationManager}" /> 
</ui:include> 
<a4j:commandButton
 id="generateButton"
 value="Generate patient"
 actionListener="#{creationManager.generateAndSavePatient()}"
 onclick="Richfaces.showModalPanel('panelLoading');"
 oncomplete="Richfaces.hideModalPanel('panelLoading');"
 styleClass="commandButton"
 reRender="selectedPatientDiv, ddsDiv, sendMessageButtonDiv"/> 
</rich:panel> 
</s:div>

When the patient is created, you can display or edit his/her informations using at least the XHTML files provided in the patient folder of PatientGeneration-war module. Those files need the patient object as a parameter, use <ui:param name="patient" value="#{yourPatient}"/>

Update security check on simulators

simulator-common, version 2.5, was updated to support security check. To enable the security check on simulators you have to :

  • login as admin
  • go to : administration/configure.seam. This page is included on simulator-common, so accessible by any simulator
  • if it is the first time you are enabling the security check,
    • you have to click on the button : Set default http headers value. This will update all missing application preferences related to http security headers.
    • update the application preference: security-policies,  set its value to true
    • you have then to click on the button : Update http header security policies
  • to verify that the security headers are enabled, you can use firebug :
    • open firebug tool
    • enable "network" menu
    • reupload the home page
    • click on the GET request catched by firebug
    • verify that the header of the GET response contains attributes : X-WebKit-CSP-Report-Only,
      x-content-security-policy...


Use of codes in simulators

Sometimes, we need codes to build messages sent by our simulators. The Sharing Value Set profile defines two actors: the repository within which are stored the codes and the consumer which can perform HTTP or SOAP queries to obtain a list of codes from a given value set.

A value set is a set of codes named "concepts" and identified by a unique OID. This page (here) gathers all the value sets contained in the gazelle SVS Repository. Each concept is defined by three values:

  • Code
  • DisplayName
  • CodeSystem

A SVS repository is under development, and by now it is able to reply to HTTP queries (ITI-48 case). This IHE transaction defines a mean to retrieve a value set by giving at least its id. The language and the version. Our implementation also enables the user to retrieve a concept at random from a given value set. You can also retrieve a concept thanks to its code attribute and the value set id.

Two classes have been implemented in simulator-common-ejb to help you with retrieving codes when you require ones. The first class represents the Concept (three attributes are declared: code, displayName, and codeSystem) and the second one, named SVSConsumer implements three static methods:

  • getRandomConceptFromValueSet: returns a Concept object randomly extracted from the given value set
  • getConceptsListFromValueSet: returns the list of Concept objects gathered in the given value set
  • getDisplayNameForGivenCode: returns the displayName of a given code for a given value set

NB. Do not forget to add the application configuration value : svs_repository_url. If not, the system will create it with the default value http://gazelle.ihe.net