Make POST request from Mule ESB - post

I'm stuck with making correct HTTP request to web server (running under PHP).
I need to send POST request with property json and some value, for example { "employee_id":191, "date":"2015-08-11", "time":"14:26:00" }.
It's working if I make a request from Postman or cURL for example, the request will look something like this
POST /DeliveryDetails/ HTTP/1.1
Host: 192.168.0.100:80
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
json=%7B+%22employee_id%22%3A191%2C+%22date%22%3A%222015-08-11%22%2C+%22time%22%3A%2214%3A26%3A00%22+%7D
Also I can send with conntent type multipart/form-data
POST /DeliveryDetails/ HTTP/1.1
Host: 192.168.0.100:80
Cache-Control: no-cache
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="json"
{ "employee_id":191, "date":"2015-08-11", "time":"14:26:00" }
----WebKitFormBoundary7MA4YWxkTrZu0gW
or with cURL
curl -d "json={ \"employee_id\":191, \"date\":\"2015-08-11\", \"time\":\"14:26:00\" }" http://192.168.0.100:80/DeliveryDetails/
But when I'm trying to make request from Mule ESB it's not working since the request is incorrect.
The flow looks like this
<sub-flow name="my-flow">
<logger message="Request: #[payload]" level="INFO" doc:name="Log request"/>
<http:request config-ref="request-HTTP" path="/DeliveryDetails/" method="POST" doc:name="HTTP call" />
<object-to-string-transformer doc:name="Object to String"/>
<logger message="Response: #[payload]" level="INFO" doc:name="Log response"/>
</sub-flow>
#[payload] contains the value { "employee_id":191, "date":"2015-08-11", "time":"14:26:00" }
and if I do it like this the body would simply contain it (without additional information like Content-Type, I think thats the problem).
I have tried to add query-param
<http:request-builder >
<http:query-param paramName="json" value="#[payload]" />
</http:request-builder>
or use message-properties-transformer
<message-properties-transformer doc:name="Message Properties">
<add-message-property key="json" value="#[payload]"/>
</message-properties-transformer>
but the result is still the same.
EDIT
The HTTP configuration look like this
<http:request-config name="request-HTTP"
host="192.168.0.100"
port="80"
doc:name="HTTP Request Configuration" />
Also tried to set Content-Type with
<set-property propertyName="Content-Type" value="application/x-www-form-urlencoded" doc:name="Property"/>
and
<http:request-builder>
<http:query-param paramName="json" value="#[payload]"/>
<http:header headerName="Content-Type" value="application/x-www-form-urlencoded"/>
</http:request-builder>
However the body I'm receiving is still just payload, without other properties for example json= or Content-Disposition: form-data; name="json"

Since the payload is just the JSON data, that's what will be sent in most scenarios. Your curl example sets the "json=" part to the body. So there are a couple of options here:
Modify the payload to add the body you want as you do with curl and set the Content-Type to application/x-www-form-urlencoded.
Send multipart content by adding the data as an attachment. In your case try:
<sub-flow name="my-flow">
<logger message="Request: #[payload]" level="INFO" doc:name="Log request"/>
<set-attachment attachmentName="json" value="#[payload]" contentType="application/json"/>
<http:request config-ref="request-HTTP" path="/DeliveryDetails" method="POST" doc:name="HTTP call" />
<object-to-string-transformer doc:name="Object to String"/>
<logger message="Response: #[payload]" level="INFO" doc:name="Log response"/>
</sub-flow>
Set the payload to be a map containing a key "json" with the payload as value. This should make Mule send a form request without you setting the Content-Type explicitly to application/x-www-form-urlencoded.
HTH.

You need to put path="/DeliveryDetails"
You can follow the following config :-
<http:request-config name="HTTP_Request_Configuration" host="192.168.0.100" port="80" doc:name="HTTP Request Configuration"/>
and in the Mule flow or sub flow and set the Content-Type as follows:-
<set-property propertyName="Content-Type" value="application/json" doc:name="Property"/>
<http:request config-ref="HTTP_Request_Configuration" path="/DeliveryDetails" method="POST" doc:name="HTTP call" />
<logger message="Input JSON message ****** #['\n'+ message.payloadAs(java.lang.String)]" level="INFO" doc:name="Logger"/>
You can configure the Content-Type here as per your requirement
You can also refer here :- How do I force the HTTP Request Connector to use a certain Content-Type?

Related

How to get only value part of linked list values from mule DB connector

I have the below flow which returns a list of values from DB with in mule.
I want to be able to get only the value part of the result from DB instead of a full linked list in the format of "column=value". I want to use the value part as part of a URL in the next http block. Please see my flow below. Any feedback will be helpful please.
<http:request-config name="HTTP_Request_Configuration" protocol="HTTPS" host="jsonplaceholder.typicode.com/#[flowVars.custID]" port="443" doc:name="HTTP Request Configuration"/>
<http:listener-config name="HTTP_Listener_Configuration1" host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration"/>
<flow name="dbcconnectorFlow">
<http:listener config-ref="HTTP_Listener_Configuration2" path="/lockStatus" allowedMethods="PUT" doc:name="HTTP"/>
<db:select config-ref="Oracle_Configuration" doc:name="Database">
<db:dynamic-query><![CDATA[select CUST_NO FROM CUSTOMERS WHERE LOCKED='N']]></db:dynamic-query>
</db:select>
<logger message="#[message.payload]"" level="INFO" doc:name="Logger"/>
<set-variable variableName="custID" value="#[message.payload[0]]" doc:name="Variable"/>
<http:request config-ref="HTTP_Request_Configuration" path="/" method="PUT" doc:name="HTTP"/>
</flow>
Ekow
One way to get only the value part of the result from DB is to put a transform message (Dataweave) component after the DB component and configure it as shown in this example:
<flow name="myprojectFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP"/>
<db:select config-ref="MySQL_Configuration" doc:name="Database">
<db:parameterized-query><![CDATA[select CompanyName from Customers limit 10]]></db:parameterized-query>
</db:select>
<response>
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/json
---
payload.CompanyName[1]]]></dw:set-payload>
</dw:transform-message>
</response>
</flow>
The output is the first company name string in the array. The column name is not included.
Found a way around this. I had to convert the db results which was an object into xml using the object to xml transformer. Then use the splitter to split the results since I was expecting multiple output as below
[xpath3('//root/data/"xml_tag_of_required_data"', payload, 'NODESET')]. I then set the output as a variable and referenced the variable in the http endpoint URL.

Why my PUT request using the google spreadsheet isn’t working?

I’ve been through every step mentioned here https://developers.google.com/google-apps/spreadsheets/#changing_contents_of_a_cell using the protocol and submitting the requests, right now, with POSTMAN before doing an actual script.
On the step of editing a cell via PUT i get a 403 Forbidden with the error "If-Match or If-None-Match header or entry etag attribute required”.
Right now my request URL is:
PUT https://spreadsheets.google.com/feeds/cells/MY_SPREADSHEET_ID/od6/private/full/R1C1?v=3.0
Headers:
Authorization Bearer {my access token}
Content-Type application/atom+xml
Raw
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:gs="http://schemas.google.com/spreadsheets/2006">
<id>https://spreadsheets.google.com/feeds/cells/MY_SPREADSHEET_ID/od6/private/full/R1C1</id>
<link rel="edit" type="application/atom+xml"
href="https://spreadsheets.google.com/feeds/cells/MY_SPREADSHIT_ID/od6/private/full/R1C1"/>
<gs:cell row="1" col="1" inputValue="hello"/>
</entry>
Any ideas please?
ps.: if I remove the ?v=3.0 there will be another error demanding the version
You should add the header If-Match:*
It should work out of the box that way, however, more on subject can be found on http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

Inserting data with OData in atom format

Odata is a new thing for me and I'm trying getting in deep with it. So I'm trying insert data using OData protocol in atom format and using a rest client. So I've created the following http Post request:
POST /HelloOdata/library.xsodata/books HTTP/1.1
Host: coe-he-55:8010
Authorization: Basic xxxxxxxxxxxxxxxxxxxxx
DataServiceVersion: 1.0
MaxDataServiceVersion: 2.0
accept: application/atom+xml
Content-Type: application/atom+xml
Cache-Control: no-cache
Postman-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
<?xml version="1.0" encoding="utf-8"?>
<Entry xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
xmlns="http://www.w3.org/2005/Atom">
<title type="text">books</title>
<author>
<name />
</author>
<link href="books('Test_post')/Author" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Author" title="Author" type="application/atom+xml;type=entry"/>
<category term="HelloOdata.library.booksType"
scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<content type="application/xml">
<m:properties>
<d:title>Test_post</d:title>
<d:ISBN>ISBN_POST</d:ISBN>
<d:editions>2</d:editions>
</m:properties>
</content>
</Entry>
and as a response I've got: The serialized resource has an missing value for member 'title'.
Well my table books has only three properties which are title, ISBN and editions precisely those one I'm trying insert through this statement. So, do you have any idea what can be wrong in it?
Thank you
Pablo
I've found where the error was.
Unbelievably the right xml request is:
POST /HelloOdata/library.xsodata/books HTTP/1.1
Host: coe-he-55:8010
Authorization: Basic xxxxxxxxxxxxxxxxxxxxx
DataServiceVersion: 1.0
MaxDataServiceVersion: 2.0
accept: application/atom+xml
Content-Type: application/atom+xml
Cache-Control: no-cache
Postman-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
<?xml version="1.0" encoding="utf-8"?>
<entry xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
xmlns="http://www.w3.org/2005/Atom">
<title type="text">books</title>
<author>
<name />
</author>
<category term="HelloOdata.library.booksType"
scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<content type="application/xml">
<m:properties>
<d:title>Test_post</d:title>
<d:ISBN>ISBN_POST</d:ISBN>
<d:editions>2</d:editions>
</m:properties>
</content>
</entry>
well I also had to get off with this part:
<link href="books('Test_post')/Author" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Author" title="Author" type="application/atom+xml;type=entry"/>
but this was an attempt after the first one, because the real problem was the tag
<Entry>
write with E and not
<entry>
Once I changed it, the Http request works well.
I saw this example of insertion of data with OData on the official website guideline:
http://www.odata.org/documentation/odata-version-2-0/operations and there the tag entry was written with capital letter.
Thank you!
Pablo

WebHarvest can't find response headers

I'm working with WebHarvest to fetch data from a site that requires logging in.
It's setup like this:
Page 1 = Login page
Page 2 = Login validation page
Page 3 = Statistics page
On page 2 a cookie is set. When monitoring the opening of Page 2 with Firebug I get these headers:
Connection Keep-Alive
Content-Type text/html; charset=UTF-8
Date Tue, 23 Oct 2012 18:25:12 GMT
Keep-Alive timeout=15, max=100
Server Apache/2.0.64 (Win32) JRun/4.0 SVN/1.3.2 DAV/2
Set-Cookie SESSION=hej123;expires=Thu, 16-Oct-2042 18:25:12 GMT;path=/
Transfer-Encoding chunked
When calling the same page with WebHarvest I only get these headers:
Date=Tue, 23 Oct 2012 18:31:51 GMT
Server=Apache/2.0.64 (Win32) JRun/4.0 SVN/1.3.2 DAV/2
Transfer-Encoding=chunked
Content-Type=text/html; charset=UTF-8
It seems that three headers (Set-Cookie, Connection and Keep-Alive) are not found by WebHarvest. Page 1, 2 and 3 are dummys so no actual validation is done. The cookie is always set on the serverside for Page 2.
Here is the WebHarvest code I am currently using:
<var-def name="content2">
<html-to-xml>
<http method="post" url="http://myurl.com/page2.cfm">
<http-param name="Login">sigge</http-param>
<http-param name="Password">hej123</http-param>
<http-param name="doLogin">Logga in</http-param>
<loop item="currField">
<list>
<var name="ctxtNewInputs" />
</list>
<body>
<script><![CDATA[
item = (NvPair) currField.getWrappedObject();
SetContextVar("itemName", item.name);
SetContextVar("itemValue", item.value);
]]></script>
<http-param name="${item.name}"><var name="itemValue" /></http-param>
</body>
</loop>
<script><![CDATA[
String keys="";
for(int i=0;i<http.headers.length;i++) {
keys+=(http.headers[i].key + "=" + http.headers[i].value +"\n---\n");
}
SetContextVar("myCookie", keys);
]]></script>
<file action="write" path="c:/kaka.txt">
<var name="myCookie"/>
</file>
</http>
</html-to-xml>
</var-def>
Edit:
when checking I noticed that the cookie is set in WebHarvest, even if the http header can't be found programatically. Is it possible that some response headers are hidden from usage?
Does anyone know a work-around for this problem?
Thank you and best regards,
SiggeLund
The way to get http header value into user-defined variable scoped for the whole config is the following:
<http url="your.url.here" method="GET">
<!--Any settings you apply for the POST/GET call-->
</http>
<!--Now you've got your http object you are going to get header value from -->
<!--At it simplest the acquisition of value goes like the below-->
<var-def name="fifth_header_val">
<script return="http.headers[5].value"/>
</var-def>
The above is just to give a clue. You can iterate over http.headers index and collect keys and values you need for your particular task.

Making a SOAP / XML request from Rails

I have an xml object xml:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<GetLocations xmlns="http://clients.mindbodyonline.com/api/0_5_1">
<Request>
<SourceCredentials>
<SourceName>{SourceName}</SourceName>
<Password>{Password}</Password>
<SiteIDs>
<int>{SiteID}</int>
</SiteIDs>
</SourceCredentials>
<XMLDetail>Bare</XMLDetail>
<PageSize>10</PageSize>
<CurrentPageIndex>0</CurrentPageIndex>
<Fields>
<string>Locations.Name</string>
<string>Locations.City</string>
</Fields>
</Request>
</GetLocations>
</soapenv:Body>
</soapenv:Envelope>
and am trying to copy this request I found in an example:
POST https://clients.mindbodyonline.com/api/0_5_1/SiteService.asmx HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: "http://clients.mindbodyonline.com/api/0_5_1/GetLocations"
Host: clients.mindbodyonline.com
Content-Length: 795
But I do not know how to include things like SOAPAction in my request using something like RestClient.
How do you include such parameters, or is there a different way to make this type of request?
Check out the example code they have written in ruby here.
You can use savon gem to do the request, you can have a look at this code sample that shows how to do that.

Resources