Issue with parsing json response having xml attributes - apama

I have a json response using the Http Client Adapter which has the below format
{
"?xml": {
"#version":"1.0",
"#encoding":"utf-8"
},
ArrayOfBusinessTypeAPI {
"#xmlns:xsd":"http://www.w3.org/2001/XMLSchema",
"#xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance",
...
}
}
I need some information on how the below elements can be defined in the event definition.
1.?xml
2.#version
3.#xmlns:xsd
As per the documentation "#" is used for substitution and : for coassignment.
Can someone please provide any insight as to how this can be done.

I assume you mean in the yaml mapper codec, in which case you can simply quote the keys and this should work:
mapFrom:
- payload.xml: "payload.?xml"
- payload.version: "payload.#version.myField2"
- payload.xmlns_xsd: "payload.#xmlns:xsd"
If you were asking how to declare an event in EPL to handle this response, you don't need to use the exact naming scheme in your event definition. You could have:
event Response {
string xml;
string version;
string xmlns_xsd;
}
And then using the mapper codec map between the two fields like so:
mapFrom:
- payload.xml: "payload.?xml"
- payload.version: "payload.#version.myField2"
- payload.xmlns_xsd: "payload.#xmlns:xsd"
EDIT
So the first thing stopping your event parsing is that your response isn't valid JSON. The line "ArrayOfBusinessTypeAPI {" would need to be ""ArrayOfBusinessTypeAPI": {". You can only use the mapper codec to parse JSON.
The second reason this isn't working is because the content type is set to text/html. Does the JSON codec have filterOnContentType set to true? If so, it won't transform this message.
However, if the JSON is valid and gets processed by the JSON codec, you can correctly map the event like so:
mapFrom:
- payload.id: metadata.requestId
- payload.xml: "payload.?xml"
- payload.version: "payload.xml.#version"
- payload.xsd: "payload.ArrayOfBusinessTypeAPI.#xmlns:xsd"
- payload.xsi: "payload.ArrayOfBusinessTypeAPI.#xmlns:xsi"
- payload.encoding: "payload.xml.#encoding"
Which maps to an event:
event Resp {
dictionary<string, string> xml;
string version;
string xsd;
}

Related

Vibe.d REST Interface serve image

Sending a bunch of binary back to the user like an image:
interface API
{
#path("/data/image")
#contentType("image/png")
ubyte[] getImagePreview(string foo);
}
The function is returning a Json array with the values of the ubyte[]
Here are the list of attributes I can use:
adjustMethodStyle
bodyParam
contentType
extractHTTPMethodAndName
headerParam
method
noRoute
path
queryParam
rootPathFromName
Source: Vibe.d site
The only attribute that can do the job is contentType and it's said there that it only works with ubyte[] functions, and that's what I used.
What am I missing?
You can try hunt framework so easy use:
#Action
Response image(string imageName)
{
return new FileResponse("/data/image/" ~ imageName);
}
More read wiki:
https://github.com/huntlabs/hunt-framework/wiki/FileResponse

How to download CSV using REST API?

Here's a REST API that I am trying for downloading data as CSV file.
(function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
var data = '\n'; // workaround to separate <xml> start tag on first line
data += 'Firstname,Lastname,Username' + '\n';
data += 'Nikhil,vartak,niksofteng' + '\n';
data += 'Unknown,person,anonymous' + '\n';
response.setHeader("Content-Disposition", "attachment;filename=Xyz.csv");
response.setContentType("text/csv");
response.setBody({'data':data});
})(request, response);
According to docs setBody requires a JS object and thus if I just pass data variable I get error stating that data cannot be parsed into ScriptableObject.
So with the current code I get below response:
{
"result": {
"data": "\nFirstname,Lastname,Username\nNikhil,vartak,niksofteng\nUnknown,person,anonymous\n"
}
}
And the generated CSV looks like this:
Any idea how to get rid of that XML markup on 1st and 5th line?
The setBody method expects a Javascript object which it is then going to serialize to JSON or XML based on what the client tells it do via Accept header.
In your case you want to produce your own serialized format: CSV. So instead of using the setBody method, use the stream writer interface to directly write to the response stream.
response.setContentType("text/csv");
response.setStatus(200);
var writer = response.getStreamWriter();
writer.write('Firstname,Lastname,Username\n');
writer.write('Nikhil,vartak,niksofteng\n');
etc.
Note you will have to handle all the details of CSV format yourself, including properly encoding any special characters like if you want a field to contain a comma like "Nik,hil".
Cheers,
Silas

UCWA: Unable to send/Receive formatted text

I have a simple chat application working fine with plain text implemented using UCWA api in a ASP.Net MVC web application. I have to implement a formatted text next.
Referring to UCWA: integrating advanced chat options
, I go to know that, before sending the message to using ucwa.Transport.clientRequest we have to set the contentType to text/html which currently is text/plain.
So i have the function to send a message as shown below:
function sendMessage(displayName, msg, timestamp) {
var encodedMsg = encodeURIComponent(msg);
ucwa.Transport.clientRequest({
url: messagingLinks.SendMessage + "?SessionContext=" + ucwa.GeneralHelper.generateUUID(),
type: "post",
contentType: "text/html",
data: encodedMsg,
callback: function () {
addMessageToChat(displayName, encodedMsg, timestamp);
}
});
}
The implementation of handleMessage() is as shown below:
function handleMessage(data, parts) {
alert("Inside Handle message");
if (!data._embedded.message._links.plainMessage) return false;
var message = decodeMessage(data._embedded.message._links.plainMessage.href);
var decodedMsg = decodeURIComponent(message);
addMessageToChat(data._embedded.message._links.participant.title, decodedMsg, formatTime(new Date(Date.now())));
}
The problem in the above implementation is that, on the receiving end, the handleMessage() method is not entered which means i'm not receiving the incoming message.
Can anyone point me where i'm going wrong and Are the any other changes i need to do along with the above changes, so that i can send a formatted text across. A sample will be really helpful regarding the same.
Any suggestion would also be good enough. Thanks in advance.
Edit:
As suggested i have modified my makeMeAvailable method. below is the definition of the same in Authentication.js:
function makeMeAvailable() {
if (!_authenticated) {
cache.read({
id: "main"
}).done(function (cacheData) {
if (cacheData) {
var data = {
SupportedModalities: ["Messaging"],
supportedMessageFormats: ["Plain","Html"]
};
transport.clientRequest({
url: cacheData._embedded.me._links.makeMeAvailable.href,
type: "post",
data: data,
callback: handleState
});
}
});
} else {
handleState({
status: 204
});
}
}
However, the output is still the same.
The second suggestion regarding the communication API, i'm unable to locate it.
Any suggestions with this?
Here are two reasons I did not receive messages sent through UCWA API:
Charset: Default value was ISO-8859-1, I had to use UTF-8 to receive any message.
Negotiated message formats: The receiving contact only supported plain message format, but the messages were sent with text/html content type.
When it comes to the messaging formats in UCWA it should be known that by default all endpoints that support the messaging modality by default support plain messages. It is interesting to note that this limitation does not prevent sending of HTML formatted messages as you have seen in your examples.
There are two ways to enable HTML formatted messages as follows:
When issuing a request to makeMeAvailable supply an SupportedMessageFormats (array) and include Html
Issue a PUT request to communication and include Html in SupportedMessageFormats
Until either 1 or 2 has executed successfully it will be impossible to receive HTML formatted messages.

Handling form data for application/x-www-form-urlencoded contentType

I have a textarea in a jsp page and the contents of that are processed in a Servlet.
I thought the contentType was multipart so I figured I'd use getFormField() and getString() methods to extract the values but this throws an exception saying
the request doesn't contain a multipart/form-data or multipart/mixed stream, content type header is application/x-www-form-urlencoded
When I use request.getParameter("textAreaID") it is always null. How do I handle this situation? Any help would be appreciated. Please let me know if the question is not framed in a proper manner before downvoting. Thanks in advance.
If u want to extract values of many fields,you can use getParameterNames() method
Enumeration paramNames = request.getParameterNames();
while(paramNames.hasMoreElements())
{
String parameter = (String) paramNames.nextElement();
String parameterValue = (String) request.getParameter(parameter);
System.out.println("*****" + parameter + " - " + parameterValue);
}

Set Mirth destination to send transform data back as a custom ACK

I have a Mirth channel that set up as a web service listener, it receives an ID, build an HL7 query message and send this query and eventually get back an HL7 response.
Channel Name: QueryChanel
Source Connector Type: Web Service Listener
Destination Connector Name: QueryToVista
Destination connector Type:LLP Sender.
This is the typical HL7 response I receive back from my query is as follow:
MSH|~|\&|VAFC RECV|FACILITY|VAFC TRIGGER||20121011141136-0800||ADR~A19|58269|D|2.4|||NE|NE|USA
MSA|AA|1234|
QRD|20121011051137|R|I|500000001|||1^ICN|***500000001***|ICN|NI|
EVN|A1|20121004064809-0800||A1|0^^^^^^^^USVHA\\0363^L^^^NI^TEST FACILITY ID\050\L|20121004064809-0800|050
PID|1|500000001V075322|500000001V075322^^^USVHA\\0363^NI^VA FACILITY ID\050\L~123123123^^^USSSA\\0363^SS^TEST FACILITY ID\050\L~9^^^USVHA\\0363^PI^VA FACILITY ID\050\L||JOHN^DOE^^^^^L|""|19800502|M||""|""^""^""^""^""^^P^""^""~^^""^""^^^N|""|""|""||S|""||123123123|||""|""||||||""||
PD1|||SOFTWARE SERVICE^D^050
ZPD|1||||||||||||||||""
I can get all the above to return if I set my Source's Response From parameter to QueryToVista
However, I want to return only the value 500000001 from the above message. I've tried to play around with the transformer in the QueryChanel destination without success.
Update:
I tried to add a javascriptwriter connector after the QueryToVista connector in the same channel as follow:
var destination = responseMap.get('QueryToVista');
var responseMessage = destination.getMessage();
//Fails with following error: TypeError: Cannot read property "QRD.4" from undefined
var customack = ResponseFactory.getSuccessResponse(responseMessage['QRD']['QRD.4'] ['QRD.4.1'].toString())**
//work but send the whole HL7 message
var customack = ResponseFactory.getSuccessResponse(responseMessage.toString())**
responseMap.put('Barcode', customack);
I can't seem to use the normal transformation to retrieve the element at all.
Thank you.
You're on the right track, but your update illustrates a couple of issues. However, your basic approach of using two destinations is valid, so long as "Synchronize channel" is checked on the Summary tab.
Issue 1
In your example, the HL7 response you are wanting to parse is in pipe delimited HL7 form. In order to access the elements using E4X notation (eg. responseMessage['QRD']['QRD.4']['QRD.4.1']) you must first convert it into an E4X XML object. This can be done in two steps.
Convert the pipe delimited HL7 string into an XML string.
Convert the XML string into an E4X XML object
In a Javascript transformer of the JavaScript Writer (not the Javascript Writer script itself)
var response = responseMap.get("QueryToVista");
var responseStatus = response.getStatus();
// Get's the pipe delimited HL7 string
var responseMessageString = response.getMessage();
if (responseStatus == "SUCCESS")
{
// converts the pipe delimited HL7 string into an XML string
// note: the SerializeFactory object is available for use in transformer
// scripts, but not in the Javascript destination script itself
var responseMessageXMLString = SerializerFactory.getHL7Serializer(false,false,true).toXML(responseMessageString);
// convert the XML string into an E4X XML object
var responseMessageXMLE4X = new XML(responseMessageXMLString);
// grab the value you want
var ack_msg = responseMessageXMLE4X['QRD']['QRD.4']['QRD.4.1'].toString();
channelMap.put('ack_msg', ack_msg)
}
else
{
// responseStatus probably == "FAILURE" but I'm not sure of the full range of possibilities
// take whatever failure action you feel is appropriate
}
Edit**
I don't believe there is an Issue 2. After reviewing your own approach, I played a bit further, and believe I have confirmed that your approach was indeed correct for generating the SOAP reponse. I'm editing this section to reflect simpler code that still works.
In the Javascript Writer script
var barcode = channelMap.get('ack_msg');
var mirthResponse = ResponseFactory.getSuccessResponse(barcode);
responseMap.put('Barcode', mirthResponse);
Thank you very much csj,
I played around and got mine to work and looking at your solution, you pointed out my bottle neck to the issue as well which is the XML part, I did not realize you have to cast it into XML as per the new XML when you already call toXML function :)
Here is my script, though basic I thought I post it up for anyone find it useful down the road.
var destination = responseMap.get('QueryToVista');
var responseMessage = destination.getMessage();
var Xmsg = new XML(SerializerFactory.getHL7Serializer().toXML(responseMessage));
var xml_msg = '<?xml version="1.0" encoding="utf-8" ?>'+
'<XML><Patient Name="'+Xmsg['PID']['PID.5']['PID.5.1']+
'" Barcode="'+Xmsg['QRD']['QRD.8']['QRD.8.1']+'" /></XML>';
var sResp = ResponseFactory.getSuccessResponse(xml_msg)
responseMap.put('Response', sResp);