What is the error in the following HL7 encoding? - java

I am trying to encode an HL7 message of the type ORU_R01 using the HAPI 2.0 library for an OpenMRS module. I have followed the tutorials given in the HAPI documentation and according to that, I have populated the required fields of the ORU_R01 message. Now, I want to post this message using the following link:
http://localhost:8080/openmrs/remotecommunication/postHl7.form
I am using the following message for testing:
MSH|^~\&|||||20140713154042||ORU^R01|20140713154042|P|2.5|1
PID|||1
OBR|1||1234^SensorReading|88304
OBX|0|NM|1||45
OBX|1|NM|2||34
OBX|2|NM|3||23
I have properly ensured that all the parameters are correct. Once I have posted the HL7 message, I start the HL7 task from the scheduler. Then I go to the admin page and click on "Manage HL7 errors" in order to see if the message arrives there. I get the following stack trace:
ca.uhn.hl7v2.HL7Exception: HL7 encoding not supported
...
Caused by: ca.uhn.hl7v2.parser.EncodingNotSupportedException: Can't parse message beginning MSH|^~\
at ca.uhn.hl7v2.parser.Parser.parse(Parser.java:140)
The full stack trace is here: http://pastebin.com/ZnbFqfWC.
I have written the following code to encode the HL7 message (using the HAPI library):
public String createHL7Message(int p_id, int concept_id[], String val[])
throws HL7Exception {
ORU_R01 message = new ORU_R01();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss",
Locale.ENGLISH);
MSH msh = message.getMSH();
msh.getFieldSeparator().setValue("|");
msh.getEncodingCharacters().setValue("^~\\&");
msh.getProcessingID().getProcessingID().setValue("P");
msh.getSequenceNumber().setValue("1");
msh.getMessageType().getTriggerEvent().setValue("R01");
msh.getMessageType().getMessageCode().setValue("ORU");
msh.getVersionID().getVersionID().setValue("2.5");
msh.getMessageControlID().setValue(
sdf.format(Calendar.getInstance().getTime()));
msh.getDateTimeOfMessage().getTime()
.setValue(sdf.format(Calendar.getInstance().getTime()));
ORU_R01_ORDER_OBSERVATION orderObservation = message
.getPATIENT_RESULT().getORDER_OBSERVATION();
ca.uhn.hl7v2.model.v25.segment.PID pid = message.getPATIENT_RESULT()
.getPATIENT().getPID();
Patient patient = (Patient) Context.getPatientService()
.getPatient(p_id);
System.out.println(String.valueOf(p_id) + " " + patient.getGivenName()
+ " " + patient.getFamilyName());
pid.getPatientName(0).getFamilyName().getSurname()
.setValue(patient.getFamilyName());
pid.getPatientName(0).getGivenName().setValue(patient.getGivenName());
pid.getPatientIdentifierList(0).getIDNumber()
.setValue(String.valueOf(p_id));
System.out.println();
// Parser parser = new PipeParser();
// String encodedMessage = null;
// encodedMessage = parser.encode(message);
// System.out.println(encodedMessage);
// Populate the OBR
OBR obr = orderObservation.getOBR();
obr.getSetIDOBR().setValue("1");
obr.getFillerOrderNumber().getEntityIdentifier().setValue("1234");
obr.getFillerOrderNumber().getNamespaceID().setValue("SensorReading");
obr.getUniversalServiceIdentifier().getIdentifier().setValue("88304");
Varies value = null;
// Varies value[] = new Varies[4];
for (int i = 0; i < concept_id.length; i++) {
ORU_R01_OBSERVATION observation = orderObservation
.getOBSERVATION(i);
OBX obx2 = observation.getOBX();
obx2.getSetIDOBX().setValue(String.valueOf(i));
obx2.getObservationIdentifier().getIdentifier()
.setValue(String.valueOf(concept_id[i]));
obx2.getValueType().setValue("NM");
NM nm = new NM(message);
nm.setValue(val[i]);
value = obx2.getObservationValue(0);
value.setData(nm);
}
Parser parser = new PipeParser();
String encodedMessage = null;
encodedMessage = parser.encode(message);
return encodedMessage;
}
In all likelihood, something is wrong with the MSH segment of the message, but I cannot seem to figure out what it is. What can I do to correct this error?

Why do you declare the Encoding Characters using double backslashes?
msh.getEncodingCharacters().setValue("^~\\&");
Shouldn't it be:
msh.getEncodingCharacters().setValue("^~\&");
...and because your message is using the default encoding characters maybe you don't even need to declare them at all? Extract from HAPI MSH Class reference
getENCODINGCHARACTERS
public ST getENCODINGCHARACTERS()
Returns MSH-2: "ENCODING CHARACTERS" - creates it if necessary
Update
I have no previous experience with HAPI. A quick google found an ORU example. Could you try initializing your MSH with initQuickstart("ORU", "R01", "P");
According to the comments in the example-code the initQuickstart method populates all of the mandatory fields in the MSH segment of the message, including the message type, the timestamp, and the control ID. (...and hopefully the default encoding chars as well :-)

Related

Convert String to XMPP Stanza using Smack Android

or
Q) Generate XMPP Stanza From String.
Q) Cast String into XMPP Stanza.
By using Smack library in Android,
Message message = new Message();
message.setStanzaId("123");
message.setFrom("923442621149");
message.setType(Message.Type.chat);
message.setBody("shanraisshan");
final String msgString = message.toXML().toString();
Log.e("message --->", msgString);
the above code generated following stanza
msgString:
<message from='923442621149' id='123' type='chat'><body>shanraisshan</body></message>
I have save this msgString into my database.
Now, What I wanted to do is, on retrieving this string back from database
Cast this msgString back into Java Message Class
so that I can use attributes (From, Body, Id)
using message.getFrom()
Since Message is a child class of Stanza, I tried the below code:
Stanza stanza = new Stanza() {
#Override
public CharSequence toXML() {
return msgString;
}
};
Log.e("stanza XML --->", stanza.toXML().toString());
Log.e("stanza getFrom() ->", stanza.getFrom() + ":");
Log.e("stanza getStanzaId() ->", stanza.getStanzaId() + ":");
The Console Log prints follows
stanza XML --->: <message from='923442621149' id='123' type='chat'><body>shanraisshan</body></message>
stanza getFrom() ->: null:
stanza getStanzaId() ->: OtU0i-29:
I am unable to understand, why
stanza.toXML().toString() prints the right stanza while
stanza.getFrom() is null instead of 923442621149
stanza.getStanzaId() is OtU0i-29 instead of 123
Plus, on casting Stanza to Message , produces ClassCastException
Message castedMsg = (Message)stanza;
produces
java.lang.ClassCastException:
SIMPLIFYING THINGS
How can I convert msgString
msgString = "<message from='923442621149' id='123' type='chat'><body>shanraisshan</body></message>";
into org.jivesoftware.smack.packet.Message class?
After going through Smack Library source code on Github, I found out that the library is using PacketParserUtils.java method's parseStanza() for casting String to Stanza.
String msgString = "<message from='923442621149' id='123' type='chat'><body>shanraisshan</body></message>";
Message message = (Message)PacketParserUtils.parseStanza(msgString);
Log.e("message XML->", message.toXML().toString());
Log.e("message getFrom()->", message.getFrom() + ":"); //923442621149:
Log.e("message getStanzaId()->", message.getStanzaId() + ":"); //123:

How to handle foreign addresses in Java application that calls Nominatim Webservice

The following code produces a string that has question marks as the display name when I insert an Iranian address(?????, ???????). However if I put the same url into my browser, it returns Tehran, Iran instead of question marks. I know that it has something to do with encoding but how do I get the English text as the browser returns in my java application?
String rawAddress = "Tehran";
String address = URLEncoder.encode(rawAddress, "utf-8");
String geocodeURL = "http://nominatim.openstreetmap.org/search?format=json&limit=1&polygon=0&addressdetails=0&email=myemail#gmail.com&languagecodes=en&q=";
String formattedUrl = geocodeURL + address;
URL theGeocodeUrl = new URL(formattedUrl);
System.out.println("HERE " +theGeocodeUrl.toString());
InputStream is = theGeocodeUrl.openStream();
final ObjectMapper mapper = new ObjectMapper();
final List<Object> dealData = mapper.readValue(is, List.class);
System.out.println(dealData.get(0).toString());
I tried the following code but it produced this: تهران, �ايران‎ for the display name which should be Tehran, Iran.
System.out.println(new String(dealData.get(0).toString().getBytes("UTF-8")));
Use "accept-language" in the URL parameter for Nominatim to specify the preferred language of Nominatim's results, overriding whatever default the HTTP header may set. From the documentation:
accept-language= <browser language string>
Preferred language order for showing search results, overrides the
value specified in the "Accept-Language" HTTP header. Either uses
standard rfc2616 accept-language string or a simple comma separated
list of language codes.

Lotus Notes - Mail Document - Principal/From,INetFrom, SentTime, ReceivedTime fields

I have a requirement to fetch the SenderName,SenderEmail,ToNames,ToEmails,CCNames,CcEmails from a lotus notes document instance.
Issue1
Looking into lotus.domino.Document API I found out the method getItems. When I write the elements to the system.out values for SenderEmail, ToEmails and CcEmails can be found.
However values for SenderName(a.k.a From), ToNames cannot be derived that easily.
The values seems to be using an common name format. For example check check my system.output below.
Principal = "CN=Amaw Scritz/O=fictive"
$MessageID = "<OF0FF3779B.36590F8A-ON80257D15.001DBC47-65257D15.001DC804#LocalDomain>"
INetFrom = "AmawScritz#fictive.com"
Recipients = "CN=Girl1/O=fictive#fictive"
MailOptions = "0"
SaveOptions = "1"
From = "CN=Amaw Scritz/O=fictive"
AltFrom = "CN=Amaw Scritz/O=fictive"
SendTo = "CN=Girl1/O=fictive#fictive"
CopyTo = "CN=Girl2/O=fictive#fictive"
BlindCopyTo = ""
InetSendTo = "Girl1#fictive.com"
InetCopyTo = "Girl2#fictive.com"
$Abstract = "sasdasda"
$UpdatedBy = "CN=Amaw Scritz/O=fictive"
Body = "Hello World"
The question is how can I get 'Amaw Scritz' from the common name 'CN=Amaw Scritz/O=fictive'. Is there any look up mechanism that can be used. (I would prefer to have a option other than doing a substring of the common name)
Issue2
is it possible to retrieve SentTime and ReceivedTime from mail document instance?
I know that there are two methods called getCreated and getLastModified. getCreated can be loosely associated with the SentTime and getLastModified can be loosely associated with ReceivedTime. Are there are other ways to get times for SentTime and ReceivedTime.
Issue3
How can one distinguish whether a mail document is a Sent mail or a Received Mail?
Issue1
You can use Name class.
Here example from this link:
import lotus.domino.*;
public class JavaAgent extends AgentBase {
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
// (Your code goes here)
// Create a hierarchical name
Name nam = session.createName(
"CN=John B Goode/OU=Sales/OU=East/O=Acme/C=US");
// Returns:
// John B Goode
// John B Goode/Sales/East/Acme/US
// CN=John B Goode/OU=Sales/OU=East/O=Acme/C=US
System.out.println(nam.getCommon());
System.out.println(nam.getAbbreviated());
System.out.println(nam.getCanonical());
} catch(Exception e) {
e.printStackTrace();
}
}
}
Issue2
Use values of PostedDate field and DeliveredDate field of mail document.
Issue3
Check that $Inbox folder contains your mail document. Or take a look at Dave Delay answer.
I agree with #nempoBu4 on Issues 1 and 2. I disagree with the answer to Issue 3. A received message can be removed from the inbox, so checking $Inbox doesn't help you distinguish between sent and received messages.
Assuming you have the document open, the best approach is to check two items. Sent and received messages both have a PostedDate item, but only a received message has a DeliveredDate item. Incidentally, a draft message has neither PostedDate or DeliveredDate.

Smack - How to read a MultiUserChat's configuration?

I tried to create a multiuserchat with Java. I'm using smack library.
Here is my code to create multiuserchat:
MultiUserChat muc = new MultiUserChat(connection, "roomname#somehost");
muc.create("mynickname");
Form form = muc.getConfigurationForm();
Form submitForm = form.createAnswerForm();
submitForm.setAnswer("muc#roomconfig_roomname", "A nice formatted Room Name");
submitForm.setAnswer("muc#roomconfig_roomdesc", "The description. It should be longer.");
muc.sendConfigurationForm(submitForm);
muc.addMessageListener(mucMessageListener); // mucMessageListener is a PacketListener
Then, I tried to capture the message sent by this room created above using mucMessageListener:
private PacketListener mucMessageListener = new PacketListener() {
public void processPacket(Packet packet) {
if (packet instanceof Message) {
Message message = (Message) packet;
// this is where I got the problem
}
}
}
As the message received by other part (the user who is not the owner of this multiuserchat), can he somehow get the value set in this line above:
submitForm.setAnswer("muc#roomconfig_roomname", "A nice formatted Room Name");
You see, getting just the JID of the room is not really good for the view. I expect I could have a String which value is "A nice formatted Room Name".
How can we get that?
You can easily get its configurations like name and etc from this code:
MultiUserChatManager mucManager = MultiUserChatManager.getInstanceFor(connection);
RoomInfo info = mucManager.getRoomInfo(room.getRoom());
now you can get its informations like this:
String mucName = info.getName();
Boolean isPersistence = info.isPersistent();
and etc.
Retrieving the value of muc#roomconfig_romname is described in XEP-45 6.4. Smack provides the MultiUserChat.getRoomInfo() method to perform the query.
RoomInfo roomInfo = MultiUserChat.getRoomInfo(connection, "roomname#somehost.com")
String roomDescription = roomInfo.getDescription()
If you want to read a value of var for example title name of room in config
Form form = chat.getConfigurationForm();
String value = form.getField("muc#roomconfig_roomname").getValues().next();
then do what ever you want with value..

how to run the same step again without datasource in soapui

I don't have soap ui pro. I am testing the web service. The actual implementation is i need pass one error code on the request, and the corresponding error description should be displayed on the response. I need to add this assertion. Every time the description in the response varies.
Here is the thing i want exactly...
Every time i need to run the same request but the error code (which is input) only should be changed on each time and the description varies on the response. How to validate this? Is there any way to do this without data source.
Regards,
Chandra
This is the way i have created.. is there any way to improve the code to do better way;
import java.io.File;
File file = new File('c:/customers.csv');
InputStream inputFile = new FileInputStream(file);
String[] lines = inputFile.text.split('\n');
List<String[]> rows = lines.collect {it.split(',')}
log.info('There are ' + rows.size() + ' customers to be inserted');
for(int i = 0; i < rows.size(); i++) {
String[] row = rows.get(i);
String errorcode = row[0];
// log.info(errorcode)
String errorDescription = row[1];
//log.info(errorDescription)
testRunner.testCase.testSuite.project.setPropertyValue('errorcode', errorcode);
testRunner.testCase.testSuite.project.setPropertyValue('errorDescription', errorDescription);
testRunner.runTestStepByName("createCard-1");
log.info(errorcode +"Finsihed")
}

Categories