mule http post json data thru httpendpoint - mule

Using mule - how to post json data to invoke my application url and got response back. I have my json data like below:
{
"Reservation" : {
"reservation" : {
"#id" : "123456789"
},
"arrivingDate" : "03-09-2012",
"departureDate" : "03-15-2012",
"guestName" : "Fred",
"guestLastName" : "Davis",
"hotelID" : "03",
"room" : "1001",
"oceanView" : "true",
}
}
I want post my json data to my application http://localhost:8080/myapplication/createreservation through MULE HTTP ENDPOINT and get some application response back. Any suggestions are welcome.

First thing I like to say is your JSON data is not valid .. there should not be any comma at the end .. may be missing some attributes
If you want to post the Data to an external application you can follow the following example :-
<flow name="BestelItems" doc:name="BestelItems">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" doc:name="HTTP"/>
<set-payload doc:name="Set Payload" value="{ "Reservation" : { "reservation" : { "#id" : "123456789" }, "arrivingDate" : "03-09-2012", "departureDate" : "03-15-2012", "guestName" : "Fred", "guestLastName" : "Davis", "hotelID" : "03", "room" : "1001", "oceanView" : "true"}}"/>
<http:outbound-endpoint exchange-pattern="request-response" method="POST" address="ttp://localhost:8080/myapplication/createreservation" contentType="application/json" doc:name="HTTP"/>
</flow>
But if you want to post the JSON data to your own Mule application then you only need your flow to have Http inbound endpoint .. and you can post the data from any Rest Client or Postman ..
The data will automatically get into your Mule flow through the rest client or Postman application as below :-

It can be done in the following way:
You can create a POJO with the field names same as the JSON elements
Create an instance of the object and enter your JSON input.
Then use Mule's Object to JSON transformer specifying the source Class with the POJO class.
Invoke the respective 2- way HTTP application using HTTP Outbound endpoint.
Once the response is received, add the JSON to Object transformer and use it to process further.

Related

Mule Soft HTTP Request Path from payload

I have created simple flow in which I send id in url like this:
Path:
/api/courses/find/{id}
Result:
http://localhost:88/api/courses/find/60ee9678070e104b2c57be46
then I set this id part as payload. What I am trying to do next is Call REST API with this payload inserted into URL but no matter what I try it does not return correct JSON.
Here is how I need it to look like:
Path:
http://localhost:1234/api/courses/find/60ee9678070e104b2c57be46
Result from Transform Message:
%dw 2.0
output application/json
---
{
isPublished: payload.isPublished,
tags: payload.tags map ( tag , indexOfTag ) -> tag,
"_id": payload."_id",
dishName: payload.dishName,
category: payload.category,
author: payload.author,
ingredients: payload.ingredients map ( ingredient , indexOfIngredient ) -> {
"_id": ingredient."_id",
quantity: ingredient.quantity,
unit: ingredient.unit,
description: ingredient.description
},
cookingTime: payload.cookingTime,
sourceUrl: payload.sourceUrl,
imageUrl: payload.imageUrl,
price: payload.price,
date: payload.date,
"__v": payload."__v",
id: payload."_id"
}
I tried to do it by putting id into URI Parameters, but it is part of URL not URI parameter so that does not work, same goes with something like this:
Request Path on HTTP Request:
/api/courses/find/#[payload]
Does anyone know if I could insert payload inside URL like this? I can't find anything about it in documentation.
Thank you for help!
EDIT: Could you also please tell me if I wanted to create path for each method GET, POST, PUT, DELETE could it have the same Listener path /api/courses and only after that different HTTP Request elements (for example http://localhost:1234/api/courses/ with method POST) or I would have to change it for each one? I am wondering because I can't find if it will know that it is supposed to choose flow based on what HTTP Request elements are in this flow or it just chooses first one with that path /api/courses.
My understanding is that you need to set an URI parameter for an HTTP Request. Please find below an example of a flow that sets a payload with field id and then sets the URI parameter using this field's value. The URI parameter is set in the path attribute of the HTTP Request enclosed in curly braces ({}).
<flow name="testUriParamsFlow" >
<http:listener doc:name="Listener" config-ref="HTTP_Listener_config" path="/"/>
<ee:transform doc:name="Transform Message">
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/java
---
{
id: "123456"
}]]>
</ee:set-payload>
</ee:message>
</ee:transform>
<http:request method="GET" path="/api/courses/find/{id}" config-ref="HTTP_Request_configuration" doc:name="Request">
<http:uri-params ><![CDATA[#[output application/java
---
{
id : payload.id
}]]]>
</http:uri-params>
</http:request>
</flow>
Using HTTP Wire logging we can confirm that the request replaces the URI Parameter as part of the URI:
GET /api/courses/find/123456 HTTP/1.1

Trying to Upload .dat.gz file as as a base64 string using Jmeter http

I have to send a https rest API request through jmeter
body of the request :
{"auth":{"token":"${SessionID}"},"clientGUID":"B0DC2BE4-D744-45c6-AEF6-EBEF319A336B","taskID":"${TaskID}","chunkID":"1","chunkSize":3375134,"fileName":"${curFileTime}downloadLogsBig.dat.gz","bytes":"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"}
where XXXX is the byte array of file. Need help achieve this with the best method do this
byte[] fileContent = Files.readAllBytes(uploadFile.toPath());
uploadReq.setBytes(fileContent); --> Java to set XXXX
You can try amending your request payload as:
{
"auth": {
"token": "${SessionID}"
},
"clientGUID": "B0DC2BE4-D744-45c6-AEF6-EBEF319A336B",
"taskID": "${TaskID}",
"chunkID": "1",
"chunkSize": 3375134,
"fileName": "${curFileTime}downloadLogsBig.dat.gz",
"bytes": "${bytes}"
}
and populate the "bytes" using JSR223 PreProcessor and the following Groovy code:
vars.put('bytes', new File('jmeter.sh').bytes as String)

Setting Http response data as a varible in Mule4

I am trying to set http response values in variable. Below is response from http request
{
"kind": "drive#file",
"id": "1MxumGPQD9dH161BQJCoJ_",
"name": "2020_August",
"mimeType": "application/vnd.google-apps.folder"
}
How can i set only the id field in a variable after getting above reponse.
Am trying this logic in trans form message
%dw 2.0
output application/json
---
{
"id":payload.id
}
But giving me error
The content that's returned from your HttpRequest call is binary.
Try this:
%dw 2.0
output application/json
---
id: read(payload, "application/json").'id'
which should return what you're looking for:
{
"id": "1MxumGPQD9dH161BQJCoJ_"
}
If you are capturing that into a local variable, define the same using a set-variable, like this:
<set-variable value="#[read(payload, "application/json").'id']" doc:name="id" variableName="id"/>

How to use 'Choice Router' in Anypoint studio for this scenario?

I have used RAML file to generate flows through APIKit router. I have example.json for example response.
My RAML code is:
#%RAML 0.8
---
title: TestEmployee API
version: v1
/employee:
get:
queryParameters:
id:
enum: [1,2,3,4]
required: true
type: string
description: Employee id
name:
enum: [Charles,John,Neha,Shruti]
required: true
type: string
description: Employee_name
responses:
200:
body:
application/json:
example: !include example.json
JSON example response is :
[
{
"id": 1,
"name":"Charles",
"code": "C1ENU00",
"dateofjoining":"2019/06/24",
"domain":"ENU",
"address":"Hyderabad",
"phone": 9865458936,
"program": "WASE"
},
{
"id": 2,
"name":"John",
"code": "C2DIG00",
"dateofjoining":"2019/06/24",
"domain":"DIGITAL",
"address":"Chennai",
"phone": 9756359864,
"program": "ELITE"
}
I want to use a choice router to appropriately call flow when 'id' and 'name' matches. Like in query params if the user enters 'id=1&name=Charles' then only choice router would call main flow, else it should call default one. Initially, the payload is set to 'example JSON response' body. Please guide me achieving this.
Here are flows for reference.
Set the when expression attribute in your choice router to a Dataweave expression matching your use case. You can access queryParams by name using attributes.queryParams.YOUR-QUERY-PARAM-NAME syntax:
#[attributes.queryParams.id=='1' and attributes.queryParams.name=='Charles']
Then add a when scope for every route you need and an optional otherwise for a default route:
<choice>
<when
expression="#[attributes.queryParams.id=='1' and attributes.queryParams.name=='Charles']">
<flow-ref name="some-flow" />
</when>
<otherwise>
<flow-ref name="some-other-flow" />
</otherwise>
</choice>
For Mule 3 use:
#[message.inboundProperties.'http.query.params'.id == '1' && message.inboundProperties.'http.query.params'.name =='Charles']

How can to create a JavaScript Hello World in a Mule component

I am trying to build a simple script inside a Mule component but I can't seem to find any documentation on how to get me started.
The JavaScript Component Reference shares no ideas on how to get something simple to run.
Here is a simple example:
You send a JSON encoded array and the script will return you the sum. Simple!
There is the flow:
<flow name="calculateFlow1" doc:name="calculateFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8089" doc:name="HTTP"/>
<byte-array-to-string-transformer doc:name="Byte Array to String"/>
<scripting:component doc:name="JavaScript">
<scripting:script engine="JavaScript">
<scripting:text><![CDATA[
var a = eval('(' + payload + ')');
for (var i = 0, sum = 0; i < a.length; sum += a[i++]);
message.setPayload(sum + "");
result = message;
]]></scripting:text>
</scripting:script>
</scripting:component>
</flow>
Variables already given by Mule: message, payload.
In Anypoint Studio there is now a Script component:
https://docs.mulesoft.com/mule-user-guide/v/3.6/script-component-reference
...within which you can run scripts written in javascript.
Create your HTTP listener and allow GET
Drop in your Script component include your document.write "hello world" and deploy/run.
Call it in your browser and you're done.