How to send a very long xml file as payload in rest API Automation - rest

I want to sent a very long xml as a payload in rest API Automation.
I am using the HTTP client framework.
restClient = new RestClient();
HashMap < String, String > headerMap = new HashMap < String, String > ();
headerMap.put("Content-Type", "application/xml");
headerMap.put("Ocp-Apim-Subscription-Key", "7531bf090b6b49199ec37f9c818dc417");
//jackson API:
ObjectMapper mapper = new ObjectMapper();
Users users = new Users("morpheus", "leader"); //expected users obejct
//object to json file:

You can create object of your XML and set the data using the getter functions() or create a xml file and put it into your project with some pupolated data which will always remain common. Read the external xml file and change it depending on your requirements before making request.

Everything in body can be send as String, save long complex xml to in a file & then convert your XML file to string and pass to that json variable.
JsonRequest{
"name" : "${name}"
}
name= FileUtil.readFileToString(new File(file), StandardCharsets.UTF_8);

Related

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

SpringWS - Logging SoapRequest and SoapResponse in a table

I have a SpringWS inplementation with below enpoint implementation
#PayloadRoot(namespace="http://college.com/schema/get_XML_Request/v2",localPart="get_XML_Request")
#ResponsePayload
public JAXBElement<GetStudentResponseType> handleStudentXML(#RequestPayload JAXBElement<GetStudentXMLRequestType> SoapRequest)throws Exception
{
String xmlResponse = "";
com.college.get_student_xml_response.v2.ObjectFactory objectFactory = new com.company.schema.get_student_xml_response.v2.ObjectFactory();
com.college.schema.get_student_xml_response.v2.GetResponseType resType = objectFactory.createGetResponseType();
return objectFactory.createGetStudentResponse(resType);
}
Here my objective is to log the request which coming to my webservice and response which the web service sent back in a table. Is it possible to get the SoapRequest/Soapresponse (In Soapformat) from the above method as a String.Here am able to get the payload, but i need to log with entire SoapRequest(with soapenvelope,body) Please anyone advice on this.
Have a look at the SoapEnvelopeLoggingInterceptor which logs the whole SOAP
Envelope including headers. So basically you can extend it to add the saving to the database functionality.

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);

Parsing facebook signed response json

I have a app of google app engine for for java and it have a facebook form which on submitting send a signed_request to a servlet in our app. We are using following code to unencrypt and convert to a json string
String signedRequest = (String) req.getParameter("signed_request");
String payload = signedRequest.split("[.]", 2)[1];
payload = payload.replace("-", "+").replace("_", "/").trim();
String jsonString = new String(Base64.decodeBase64(payload.getBytes()));
System.out.println("Json is::" + jsonString);
The response looks like
[sakshumweb/3.361739372881481188].: Json is::{"algorithm":"HMAC-SHA256","expires":1347588000,"issued_at":1347584290,"oauth_token":"XXXXX","registration":{"name":"Vik Kumar","first_name":"Vik","last_name":"Kumar","bloodGroup":"B-","gender":"male","birthday":"10/31/1983","email":"vik.ceo\u0040gmail.com","cellPhone":"1234123456","homePhone":"1234123457","officePhone":"1234123458","primaryAddress":"jdfjfgj","area":"jfdjdfj","location":{"name":"Redwood Shores, California","id":103107903062719},"subscribe":true,"eyePledge":false,"reference":"fgfgfgfg"},
"registration_metadata":{"fields":"[{\"name\":\"name\"},{\"name\":\"first_name\"},{\"name\":\"last_name\"}, {\"name\":\"bloodGroup\", \"description\":\"Blood Group\", \"type\":\"select\", \"options\":{\"A+\":\"A+\",\"A-\":\"A-\",\"B+\":\"B+\",\"B-\":\"B-\",\"O+\":\"O+\",\"O-\":\"O-\",\"AB+\":\"AB+\",\"AB-\":\"AB-\",\"A1+\":\"A1+\",\"A1-\":\"A1-\",\"A2+\":\"A2+\",\"A2-\":\"A2-\",\"A1B+\":\"A1B+\",\"A1B-\":\"A1B-\",\"A2B+\":\"A2B+\",\"A2B-\":\"A2B-\",\"HH\":\"Bombay Blood Group\"}}, {\"name\":\"gender\"}, {\"name\":\"birthday\"},{\"name\":\"email\"}, {\"name\":\"cellPhone\", \"description\":\"Cell Number\", \"type\":\"text\"}, {\"name\":\"homePhone\", \"description\":\"Home Number\", \"type\":\"text\"}, {\"name\":\"officePhone\", \"description\":\"Office Number\", \"type\":\"text\"}, {\"name\":\"primaryAddress\", \"description\":\"Primary Address\", \"type\":\"text\"}, {\"name\":\"area\", \"description\":\"Locality/Village/Area\", \"type\":\"text\"},{\"name\":\"location\"}, {\"name\":\"subscribe\", \"description\":\"Subscribe me for the Sakshum activites updates.\", \"type\":\"checkbox\", \"default\":\"checked\"}, {\"name\":\"eyePledge\", \"description\":\"I want to pledge my eyes as well.\", \"type\":\"checkbox\"}, {\"name\":\"reference\", \"description\":\"How you reached to us (Friend, Facebook, google etc.)?\", \"type\":\"text\"}]"},"user":{"country":"us","locale":"en_GB"},"user_id":"875390603"}
So, how do i parse this data to extract the data in registration part of this response?
Since this is a valid JSON, you can use JSON library like Jackson or GSON to parse it.
You can use this example code to print out all registration fields:
JsonNode json = new ObjectMapper().readTree(response);
JsonNode registration_fields = json.get("registration");
Iterator<String> fieldNames = registration_fields.getFieldNames();
while(fieldNames.hasNext()){
String fieldName = fieldNames.next();
String fieldValue = registration_fields.get(fieldName).asText();
System.out.println(fieldName+" : "+fieldValue);
}

ADO.NET Data Services - Uploading files

I am trying to write REST web service through which our clients can upload a file on our file server. IS there an example or any useful links which I can refer for any guidance?
I haven't seen many examples of POST operation using ADO.NET data services available.
I've uploaded a file to ADO.NET dataservices using POST although I'm not sure whether it's the recommended approach. The way I went about it is:
On the dataservice I've implemented a service operation called UploadFile (using the WebInvoke attribute so that it caters for POST calls):
[WebInvoke]
public void UploadFile()
{
var request = HttpContext.Current.Request;
for (int i = 0; i < request.Files.Count; i++)
{
var file = request.Files[i];
var inputValues = new byte[file.ContentLength];
using (var requestStream = file.InputStream)
{
requestStream.Read(inputValues, 0, file.ContentLength);
}
File.WriteAllBytes(#"c:\temp\" + file.FileName, inputValues);
}
}
Then on the client side I call the data service using:
var urlString = "http://localhost/TestDataServicePost/CustomDataService.svc/UploadFile";
var webClient = new WebClient();
webClient.UploadFile(urlString, "POST", #"C:\temp\test.txt");
This uses a WebClient to upload the file which places the file data in the HttpRequest.Files collection and sets the content type. If you would prefer to send the contents of the file yourself (eg from an Asp FileUpload control) rather than the webClient reading a file using a path to the file, you can use a WebRequest similar to the way that it's done in this post. Although instead of using
FileStream fileStream = new FileStream(uploadfile,
FileMode.Open, FileAccess.Read);
you could use a byte array that you pass in.
I hope this helps.
I'm not 100% sure how to do this directly to a file server per se, but ADO.Net Data Services definitely support something similar to a database. The code below is how a similar goal of putting a file into a database has been accomplished. Not sure how much that will help, but
var myDocumentRepositoryUri = new Uri("uri here");
var dataContext = new FileRepositoryEntities(myDocumentRepositoryUri);
var myFile = new FileItem();
myfile.Filename = "upload.dat";
myFile.Data = new byte[1000]; // or put whatever file data you want to here
dataContext.AddToFileItem(myFile);
dataContext.SaveChanges();
Note: this code is also using Entity Framework to create a FileItem (representation of a database table as an object) and to save that data.