Sending Multipart Requests in mule - mule

I have an Database connector from the selected data i use to create a file and I want to do HTTP post with file (created from the selected data in csv) along with other data (text) as attached in the screenshot. According to the mule documentation, the payload must be an outbound attachment which I am doing by using Set Attachment property. With this approach, I am setting the Content-Type for one of my attachment as application/CVS (as my file is of CVS type) and as text/plain for the other parameter. Any thoughts on achieving this? I have attached the screenshot of how the request looks like in Postman.
Below is the config XML..!!
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:file="http://www.mulesoft.org/schema/mule/file"
xmlns:db="http://www.mulesoft.org/schema/mule/db" xmlns:metadata="http://www.mulesoft.org/schema/mule/metadata" xmlns:dw="http://www.mulesoft.org/schema/mule/ee/dw" xmlns:json="http://www.mulesoft.org/schema/mule/json" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/current/mule-file.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd
http://www.mulesoft.org/schema/mule/ee/dw http://www.mulesoft.org/schema/mule/ee/dw/current/dw.xsd
http://www.mulesoft.org/schema/mule/db http://www.mulesoft.org/schema/mule/db/current/mule-db.xsd">
<spring:beans>
<spring:bean id="CSFMDataSource" name="CSFMDataSource" class="oracle.jdbc.pool.OracleDataSource">
<spring:property name="user" value="XXCCS_OSB_O"/>
<spring:property name="password" value="OrG2_BtN"/>
<spring:property name="dataSourceName" value="ds"/>
<spring:property name="URL" value="jdbc:oracle:thin:#(DESCRIPTION=(CONNECT_TIMEOUT=5)(TRANSPORT_CONNECT_TIMEOUT=3)(RETRY_COUNT=1)(ADDRESS_LIST=(LOAD_BALANCE=ON)(FAILOVER=ON)(ADDRESS=(PROTOCOL=TCP)(HOST=scan-nprd-2023)(PORT=1541)))(CONNECT_DATA=(SERVICE_NAME=DV3CSF_SRVC_OTH.cisco.com)(SERVER=DEDICATED)))"/>
</spring:bean>
</spring:beans>
<db:oracle-config name="Oracle_Configuration" dataSource-ref="CSFMDataSource" doc:name="Oracle Configuration"/>
<http:request-config name="HTTP_Request_Configuration" host="tools-stage.cisco.com" port="80" doc:name="HTTP Request Configuration"/>
<flow name="testFlow">
<poll doc:name="Poll">
<fixed-frequency-scheduler frequency="1" timeUnit="MINUTES"/>
<logger message="Log-1" level="INFO" doc:name="Logger"/>
</poll>
<db:select config-ref="Oracle_Configuration" doc:name="Database">
<db:parameterized-query><![CDATA[SELECT sol.SW_UPG_CONTRACT_NUMBER,
sol.service_level,
sol.BILL_TO_SITE_USE_ID,
sol.SERVICE_BEGIN_DATE,
sol.SERVICE_END_DATE,
0 Net_Price,
sol.PRODUCT_ORDER_NUMBER,
sol.SERIAL_NUMBER,
sol.SW_UPG_FULFILLMENT_PID,
sol.INSTALL_SITE_USE_ID,
sii.INSTANCE_ID,
DECODE (sii.INSTANCE_ID, 'Yes', 'No') softline,
'1232' cs_cse_number,
lg.error_message
FROM apps.XXCSS_SFM_ORDER_LINES sol,
apps.XXCSS_SFM_ERROR_LOG lg,
apps.XXCSS_SFM_INSTANCE_INTERFACE sii
WHERE 1 = 1
AND sol.order_type = 'INNVO_LINE'
AND sol.entitlement_status IN ('CSFM_ERROR', 'QA_FAILED')
--AND lg.so_header_id = sol.header_id
--AND lg.so_line_id = sol.line_id
AND lg.ERROR_TYPE = 'ERROR'
AND sol.header_id = sii.so_header_id(+)
AND sol.line_id = sii.so_line_id(+)
AND lg.sfdc_case_req = 'Y'
AND lg.sfdc_case_no IS NULL]]></db:parameterized-query>
</db:select>
<dw:transform-message doc:name="Transform Message" metadata:id="38e67a04-7f03-4261-a450-72b69ae0fff1">
<dw:set-payload><![CDATA[%dw 1.0
%output application/csv
---
payload map ((payload01 , indexOfPayload01) -> {
BILL_TO_SITE_USE_ID: payload01.BILL_TO_SITE_USE_ID as :number,
CS_CSE_NUMBER: payload01.CS_CSE_NUMBER,
ERROR_MESSAGE: payload01.ERROR_MESSAGE,
INSTALL_SITE_USE_ID: payload01.INSTALL_SITE_USE_ID as :number,
INSTANCE_ID: payload01.INSTANCE_ID,
NET_PRICE: payload01.NET_PRICE as :number,
PRODUCT_ORDER_NUMBER: payload01.PRODUCT_ORDER_NUMBER,
SERIAL_NUMBER: payload01.SERIAL_NUMBER,
SERVICE_BEGIN_DATE: payload01.SERVICE_BEGIN_DATE,
SERVICE_END_DATE: payload01.SERVICE_END_DATE,
SERVICE_LEVEL: payload01.SERVICE_LEVEL,
SOFTLINE: payload01.SOFTLINE,
SW_UPG_CONTRACT_NUMBER: payload01.SW_UPG_CONTRACT_NUMBER,
SW_UPG_FULFILLMENT_PID: payload01.SW_UPG_FULFILLMENT_PID
})]]></dw:set-payload>
</dw:transform-message>
<byte-array-to-object-transformer doc:name="Byte Array to Object"/>
<set-attachment attachmentName="filedata" value="#[payload]" contentType="application/csv" doc:name="Attachment"/>
<set-attachment attachmentName="casedata" value="{ "Origin":"Web", "CaseNumber":"33315931584", "SearchCCOID":"vimerugu"}" contentType="text/plain" doc:name="Attachment"/>
<set-payload value="#[null]" doc:name="Set Payload"/>
<http:request config-ref="HTTP_Request_Configuration" path="/cvcm/was70/pwc036/caseApi/updateCaseAttach/33315931584" method="POST" doc:name="HTTP" parseResponse="false">
<http:request-builder>
<http:header headerName="Authorization" value="Basic Q1BFQ2FzZUFQSS5nZW46Y2FzZTFnZW4="/>
</http:request-builder>
</http:request>
<logger message="#[flowVars.varCaseUpdate]" level="INFO" doc:name="Logger"/>
<catch-exception-strategy doc:name="Catch Exception Strategy">
<db:insert config-ref="Oracle_Configuration" doc:name="Log_DB">
<db:parameterized-query><![CDATA[insert into XXCSS_SFM_OSB_EXECUTION_LOG (PROCESS_STATUS) values ('SFDCCaseCreationService-Exception')]]></db:parameterized-query>
</db:insert>
<db:insert config-ref="Oracle_Configuration" doc:name="SFDCCaseCreation- Exception">
<db:parameterized-query><![CDATA[insert into XXCSS_SFM_CESB_LOG_ERROR ( LOG_ERROR_ID,SERVICE_NAME,SERVICE_TYPE,SERVICE_ACTIVITY,SERVICE_PAYLOAD,LOG_ERROR_STATUS,
LOG_ERROR_MESSAGE,ERROR_CODE,ERROR_MESSAGE,ERROR_DETAILS,LOG_ERROR_SEVERITY,SUGGESTED_ACTION,NOTIFY_MAIL,NOTIFY_COUNT,ATTRIBUTE_1,
ATTRIBUTE_2,ATTRIBUTE_3,ATTRIBUTE_4,ATTRIBUTE_5,ATTRIBUTE_6,ATTRIBUTE_7,ATTRIBUTE_8,ATTRIBUTE_9,ATTRIBUTE_10,CREATED_BY,CREATION_DATE,LAST_UPDATED_BY,LAST_UPDATE_DATE,BATCH_ID)
values ('1000','SFDCCaseCreationService','SFDCCaseCreationServiceType','SFDCCaseCreationServiceActivity','SFDCCaseCreationServicePayload','ERROR','','Error_Code','Error_Message',
#[exception.getSummaryMessage()],'Critical','','NA',3,'','','','','','','','','','','SFDCCaseCreationService',sysdate,'SFDCCaseCreationService',sysdate,'1000')]]></db:parameterized-query>
</db:insert>
</catch-exception-strategy>
</flow>
</mule>

Please check if below link helps you.It tells how to read multiple files and process them.You can send them to required endpoint instead of FTP
How send a file in an HTTP request and upload it to file server via FTP in Mule

Related

How to read file in middle of the flow

I am trying to read two simultaneously file in middle of the flow and combine them into one payload. To reading the files in middle of the flow I am using mule requester component. While triggering the flow (localhost:8081/requester/requester)I am getting error :
"Exception(s) were found for route(s):
0: The endpoint "src\main\resources\input1\employees.xml" is malformed and cannot be parsed. If this is the name of a global endpoint, check the name is correct, that the endpoint exists, and that you are using the correct configuration (eg the "ref" attribute). Note that names on inbound and outbound endpoints cannot be used to send or receive messages; use a named global endpoint instead. (org.mule.api.endpoint.MalformedEndpointException).
1: The endpoint "src\main\resources\input2\employees2.xml" is malformed and cannot be parsed. If this is the name of a global endpoint, check the name is correct, that the endpoint exists, and that you are using the correct configuration (eg the "ref" attribute). Note that names on inbound and outbound endpoints cannot be used to send or receive messages; use a named global endpoint instead. (org.mule.api.endpoint.MalformedEndpointException)."
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:dw="http://www.mulesoft.org/schema/mule/ee/dw" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:mulerequester="http://www.mulesoft.org/schema/mule/mulerequester" xmlns:file="http://www.mulesoft.org/schema/mule/file" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:spring="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/mulerequester http://www.mulesoft.org/schema/mule/mulerequester/current/mule-mulerequester.xsd http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/current/mule-file.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd http://www.mulesoft.org/schema/mule/ee/dw http://www.mulesoft.org/schema/mule/ee/dw/current/dw.xsd">
<file:connector name="file-connector-config" autoDelete="false" streaming="true" validateConnections="true" doc:name="File" />
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" basePath="/requester" doc:name="HTTP Listener Configuration" />
<flow name="muleRequester">
<http:listener config-ref="HTTP_Listener_Configuration" path="/requester" doc:name="HTTP" />
<logger message="Invoking Mule Requester" level="INFO" doc:name="Logger" />
<scatter-gather doc:name="Scatter-Gather">
<mulerequester:request resource="src\main\resources\input1\employees.xml" returnClass="java.lang.String" doc:name="Retrieve File1"/>
<mulerequester:request resource="src\main\resources\input2\employees2.xml" returnClass="java.lang.String" doc:name="Retrieve File2"/>
</scatter-gather><dw:transform-message doc:name="Transform Message">
<dw:set-payload>< [CDATA[%dw 1.0 %output application/json
---
{
payload1: payload[0],
payload2: payload[1]
}]]></dw:set-payload>
</dw:transform-message>
<file:outbound-endpoint path="src/main/resources/output" responseTimeout="10000" doc:name="File"/>
<logger message="Payload after file requester #[payload]" level="INFO" doc:name="Logger" />
</flow>
I am not using maven. Do I need to download any other jar or where I can do the correction?
resource needs to be an Mule endpoint url. Mule requester module can work with many transports such as jms, file, ftp. So the path to the file is not enough. Here is an example of an endpoint url for reading a file:
<mulerequester:request resource="file://src/main/resources/in/ReadME.txt?connector=file-connector-config" doc:name="Retrieve File" returnClass="java.lang.String" />
You can also point to a global endpoint like you have defined like so:
<mulerequester:request config-ref="muleRequesterConfig" resource="myFileEndpoint" doc:name="Mule Requester" />

How to get refresh_token with the Box Connector in Mule

I'm using the 3.0.0.201609092037 version (the latest one) of the Box connector as I don't find any documentation or sample code to get the refresh token, I wrote my own flow to get it.
I achieve to execute the Authorize action with the connector and then my intension is to send a request to Box API to this url: https://api.box.com/oauth2/token in order to get an access_token and also a refresh_token (I got the API info from here https://docs.box.com/reference#token).
The problem is, once my flow has been authorized and I get access_code, and I'm using it to send it to Box I always am receiving this:
{
"error": "invalid_grant",
"error_description": "The authorization code has expired"
}
I checked all the information and I it suppose to be good, the response I'm expecting is:
{
"access_token": "T9cE5asGnuyYCCqIZFoWjFHvNbvVqHjl",
"expires_in": 3600,
"restricted_to": [],
"token_type": "bearer",
"refresh_token": "J7rxTiWOHMoSC1isKZKBZWizoRXjkQzig5C6jFgCVJ9bUnsUfGMinKBDLZWP9BgR"
}
So I'll be able to store those properties and refresh the token if is needed.
Here how my flow looks like:
and Here my XML definition:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:dw="http://www.mulesoft.org/schema/mule/ee/dw" xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting" xmlns:tls="http://www.mulesoft.org/schema/mule/tls" xmlns:json="http://www.mulesoft.org/schema/mule/json" xmlns:objectstore="http://www.mulesoft.org/schema/mule/objectstore" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns:box="http://www.mulesoft.org/schema/mule/box" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/box http://www.mulesoft.org/schema/mule/box/current/mule-box.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd
http://www.mulesoft.org/schema/mule/objectstore http://www.mulesoft.org/schema/mule/objectstore/current/mule-objectstore.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd
http://www.mulesoft.org/schema/mule/ee/dw http://www.mulesoft.org/schema/mule/ee/dw/current/dw.xsd
http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd
http://www.mulesoft.org/schema/mule/tls http://www.mulesoft.org/schema/mule/tls/current/mule-tls.xsd">
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration" protocol="HTTPS">
<tls:context>
<tls:key-store type="jks" path="OBKeytore.jks" keyPassword="password" password="password"/>
</tls:context>
</http:listener-config>
<box:config-with-oauth name="Box__OAuth_2_0" clientId="my_client_id" clientSecret="My_secret" doc:name="Box: OAuth 2.0">
<box:oauth-callback-config domain="localhost" localPort="8081" remotePort="8081" path="callback" connector-ref="HTTP_Listener_Configuration"/>
<box:oauth-store-config objectStore-ref="_defaultInMemoryObjectStore"/>
</box:config-with-oauth>
<objectstore:config name="ObjectStore__Connector" partition="BoxAccessToken" persistent="true" doc:name="ObjectStore: Connector"/>
<http:request-config name="HTTP_Request_Configuration" host="api.box.com" port="443" basePath="/oauth2/" doc:name="HTTP Request Configuration" protocol="HTTPS"/>
<tls:context name="TLS_Context" doc:name="TLS Context">
<tls:trust-store path="OBKeytore.jks" password="password" type="jks"/>
<tls:key-store type="jks" path="OBKeystore.jks" keyPassword="password" password="password"/>
</tls:context>
<flow name="Authorize">
<http:listener config-ref="HTTP_Listener_Configuration" path="/authorize" doc:name="HTTP"/>
<box:authorize config-ref="Box__OAuth_2_0" doc:name="Box"/>
<flow-ref name="GenerateAcessToken" doc:name="GenerateAcessToken"/>
</flow>
<flow name="GenerateAcessToken">
<logger message="Acess Token: #[flowVars['_oauthVerifier']]" level="INFO" doc:name="Logger"/>
<set-payload value="#[[
'grant_type' :'authorization_code',
'code':flowVars['_oauthVerifier'],
'client_id':'my_client_id',
'client_secret':'my_secret'
]]" doc:name="Set Payload"/>
<http:request config-ref="HTTP_Request_Configuration" path="token" method="POST" doc:name="HTTP">
<http:success-status-code-validator values="200,400"/>
</http:request>
<object-to-string-transformer doc:name="Object to String"/>
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
<catch-exception-strategy doc:name="Catch Exception Strategy">
<object-to-string-transformer doc:name="Object to String"/>
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
</catch-exception-strategy>
</flow>
</mule>
I have to mention that I already tried to use POSTMAN with the same params, replacing the code (as far I know it is valid for 30 secs) and getting the same response.
Here some more information:
Anypoint Studio version: 6.1.1
Server Runtime: 3.8.1 EE
It sounds like the OAuth authorization configuration of the HTTP requester might be required as described for a Mule Server trying to access the resources that belong to a Box user and that are held in a Box server: https://docs.mulesoft.com/mule-user-guide/v/3.8/authentication-in-http-requests
http://mulesoft.github.io/box-connector/3.0.0/apidocs/box-apidoc.html#_oauth_2_0_server_to_server and this example of managing OAuth tokens that uses Box as an example might be worth a look if you haven't seen it.

Handling Accept encoding in esb mule

I have mule flow look like below
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:metadata="http://www.mulesoft.org/schema/mule/metadata" xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting" xmlns:json="http://www.mulesoft.org/schema/mule/json" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd
http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd">
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8111" doc:name="HTTP Listener Configuration"/>
<http:request-config name="HTTP_Request_Configuration" host="api.bonanza.com" port="443" doc:name="HTTP Request Configuration" protocol="HTTPS"/>
<flow name="bonanza_fetchtoken_ceFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/add" allowedMethods="GET,POST" doc:name="HTTP" />
<flow-ref name="bonanza_addfixedpriceitemSub_Flow" doc:name="bonanza_addfixedpriceitemSub_Flow"/>
</flow>
<sub-flow name="bonanza_addfixedpriceitemSub_Flow">
<message-properties-transformer doc:name="Message Properties">
<add-message-property key="X-BONANZLE-API-DEV-NAME" value="t******I"/>
<add-message-property key="X-BONANZLE-API-CERT-NAME" value="l*****F"/>
</message-properties-transformer>
<set-property propertyName="Content-Type" value="application/x-www-form-urlencoded" doc:name="Property"/>
<set-property propertyName="Accept" value="application/json" doc:name="Property"/>
<set-variable variableName="sim" value="{requesterCredentials:{bonanzleAuthToken:nWn1a9l3NT}}" doc:name="Variable"/>
<scripting:transformer returnClass="java.util.Map" doc:name="Groovy">
<scripting:script engine="Groovy"><![CDATA[import groovy.json.JsonBuilder
m = [addFixedPriceItemRequest:'{requesterCredentials:{bonanzleAuthToken:n*****T}}']
builder = new JsonBuilder()
builder(m)
]]></scripting:script>
</scripting:transformer>
<logger message="payload :#[payload]" level="INFO" doc:name="Logger"/>
<http:request config-ref="HTTP_Request_Configuration" path="/api_requests/secure_request" method="POST" followRedirects="true" parseResponse="false" doc:name="HTTP">
<http:success-status-code-validator values="0..599"/>
</http:request>
<logger message="resp :#[message.payloadAs(java.lang.String)]" level="INFO" doc:name="Logger"/>
</sub-flow>
</mule>
I am able to receiving successful response from API using postman tool. I try to simulate same thing using above ESB mule flow. But API throws me an error as like below. Hence i have used requestb.in to compare the requests going from esb mule and postman tool. i found differences in the HTTP headers alone.
RAW body from postman to requestb.in -
addFixedPriceItemRequest={requesterCredentials:{bonanzleAuthToken:nW*****NT}}
RAW Body from ESB mule to requestb.in
addFixedPriceItemRequest=%7BrequesterCredentials%3A%7BbonanzleAuthToken%3AnW****NT%7D%7D
It seems that i have to serialize the json content before sending as content type - application/x-www-form-urlencoded. I found this info in this mule doc
How can i serialize json payload in groovy and sending as map payload?
API Error Response
{
"ack": "Failure",
"version": "1.0beta",
"timestamp": "2016-03-15T07:18:11.000Z",
"errorMessage": {
"message": "Cannot determine what type of request you are making. Often this can be the result of data that has not been escaped before being passed to the API. If you are passing data with quotation marks or other special characters, you should translate it to JSON, then escape it, before sending it over the API."
}
}
Please let me know for any additional info. Thanks in advance!
The flow got worked by adding key value pair in query parms in the http component. The flowVariable requestpayload has json string. So my Mule http component looks like below.
<http:request config-ref="HTTP_Request_Configuration" path="/api_requests/secure_request" method="POST" followRedirects="true" parseResponse="false" doc:name="HTTP">
<http:request-builder>
<http:query-param paramName="addFixedPriceItemRequest" value="#[flowVars.requestpayload]"/>
</http:request-builder>
<http:success-status-code-validator values="0..599"/>
</http:request>

how to generate multiple copies of the same file using mule

Is there a way to get a file from an inbound File connector, and generate multiple copies (say, 5) of the same file within that same folder or a different location? I have tried it with Scatter-Gather component, but it did not turn out the way I expected. Help, please?
If using Scatter-Gather is supposed to work, how do I write a MEL expression to alter the filename, keeping the original extension? My current mule flow is as follows.
<file:connector name="File_Send" readFromDirectory="C:\Users\AnypointStudio\workspace\MessageOut" autoDelete="true" streaming="true" validateConnections="true" doc:name="File"/>
<file:connector name="File_Receive" autoDelete="true" streaming="true" validateConnections="true" doc:name="File"/>
<spring:beans>
<spring:bean id="readFile" class="java.lang.String">
<spring:constructor-arg>
<spring:bean class="org.springframework.util.FileCopyUtils" factory-method="copyToByteArray">
<spring:constructor-arg type="java.io.InputStream" value="${C:\Users\AnypointStudio\workspace\MessageOut\24730717-99a3-4353-bfcc-d19d3ba7f50a.xml}"/>
</spring:bean>
</spring:constructor-arg>
</spring:bean>
</spring:beans>
<flow name="loop_testFlow">
<file:inbound-endpoint path="C:\Users\AnypointStudio\workspace" connector-ref="File_Send" responseTimeout="10000" doc:name="File"/>
<object-to-byte-array-transformer doc:name="Object to Byte Array"/>
<set-variable variableName="file" value="#[app.registry.readFile]" doc:name="Variable"/>
<scatter-gather doc:name="Scatter-Gather">
<file:outbound-endpoint path="C:\Users\AnypointStudio\workspace\MessageIn" connector-ref="File_Receive" responseTimeout="10000" doc:name="File"/>
<file:outbound-endpoint path="C:\Users\AnypointStudio\workspace\MessageIn" connector-ref="File_Receive" responseTimeout="10000" doc:name="File"/>
</scatter-gather>
</flow>
I think with a list and foreach could be a solution:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting" xmlns:file="http://www.mulesoft.org/schema/mule/file" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:spring="http://www.springframework.org/schema/beans" xmlns:stdio="http://www.mulesoft.org/schema/mule/stdio"
xsi:schemaLocation="http://www.mulesoft.org/schema/mule/stdio http://www.mulesoft.org/schema/mule/stdio/current/mule-stdio.xsd
http://www.mulesoft.org/schema/mule/stdio http://www.mulesoft.org/schema/mule/stdio/3.6/mule-stdio.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/3.6/mule.xsd
http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/current/mule-file.xsd" version="EE-3.6.1">
<stdio:connector name="stdioConnector"
messageDelayTime="1234" outputMessage="abc" promptMessage="Enter number of files:"
doc:name="STDIO" />
<flow name="flow">
<stdio:inbound-endpoint system="IN" connector-ref="stdioConnector" doc:name="STDIO"/>
<logger message="generating #[payload] files" level="INFO" doc:name="Logger"/>
<scripting:component doc:name="Groovy">
<scripting:script engine="Groovy"><![CDATA[
list = new ArrayList();
int fin = payload.toInteger()
(1..fin).each {
list.add("file_00${it}.txt")
}
return list
]]></scripting:script>
</scripting:component>
<foreach collection="#[payload]" doc:name="For Each">
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
<object-to-string-transformer doc:name="Object to String"/>
<file:outbound-endpoint path="D:\opt" outputPattern="#[payload]" responseTimeout="10000" doc:name="File outbound"/>
</foreach>
</flow>
</mule>
This example ask you the number of files:
Output:
Here the project:
https://github.com/jrichardsz/mule-esb-usefull-templates/tree/master/several-output-file
Luck!
Use below MEL to get the file name then you can append the extra string (in case you know the extension with the files your working then you can add it in the end)
#[message.inboundProperties['originalFilename']]+'Testing'.txt
in case you don't know then you need get extension first
<set-variable value="#[org.apache.commons.io.FilenameUtils.getExtension(originalFilename)]" variableName="extension" doc:name="Set extension" />
then write like below in file outbound for fileName/pattern field
#[message.inboundProperties['originalFilename'].substring(0,message.inboundProperties['originalFilename'].lastIndexOf('.'))]_Testing.#[flowVars.extension]

Mule JPA persist is not inserting or updating

I am using Mule JPA module for retrieving and insert/updating data. I can able retrieve data but not able to update the DB. Its giving no errors and as per the log it seems that the record got updated. But :( If I check DB no recorded is getting inserted.
I believe that the transaction is not getting committed.
Please help me how to achieve this issue.
Here is my mflow
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns:json="http://www.mulesoft.org/schema/mule/json" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans" version="EE-3.4.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://www.mulesoft.org/schema/mule/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/jpa http://www.mulesoft.org/schema/mule/jpa/current/mule-jpa.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd">
<spring:beans>
<spring:import resource="classpath:applicationContext.xml" />
</spring:beans>
<jpa:config name="Java_Persistence_API" entityManagerFactory-ref="entityManagerFactory" doc:name="Java Persistence API"/>
<flow name="jpa-exampleFlow1" doc:name="jpa-exampleFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" doc:name="HTTP"/>
<logger message="payload ---->>>> #[payload]" level="INFO" doc:name="Logger"/>
<logger message="#[message.inboundProperties.get("http.relative.path")]" level="INFO" doc:name="Logger"/>
<choice doc:name="Choice">
<when expression="#[message.inboundProperties.get("http.relative.path")=="getContact"]">
<logger message="in GetContact" level="INFO" doc:name="Logger"/>
<component class="com.test.test.GetContact" doc:name="Java"/>
<jpa:query statement="from ContactEO contact where contact.firstName = :firstName" queryParameters-ref="#[payload:]"></jpa:query>
<!-- <jpa:query statement="from ContactEO contact where contact.id = :id" queryParameters-ref="#[payload:]"/> -->
</when>
<when expression="#[message.inboundProperties.get("http.relative.path")=="addContact"]">
<logger message="In AddContact" level="INFO" doc:name="Logger"/>
<component class="com.test.test.AddContact" doc:name="Java"/>
<transactional action="ALWAYS_BEGIN" doc:name="Transactional">
<jpa:persist entity-ref="#[payload:]" config-ref="Java_Persistence_API" />
</transactional>
</when>
</choice>
<json:object-to-json-transformer doc:name="Object to JSON"/>
<logger message="payload ---->>>> #[payload]" level="INFO" doc:name="Logger"/>
</flow>
</mule>
Here is my persistence.xml
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="default" transaction-type="RESOURCE_LOCAL">
</persistence-unit>
</persistence>
Here is my console log
2014-05-25 23:41:38,533 INFO [org.mule.api.processor.LoggerMessageProcessor] - <payload ---->>>> /addContact>
2014-05-25 23:41:38,568 INFO [org.mule.api.processor.LoggerMessageProcessor] - <addContact>
2014-05-25 23:41:38,586 INFO [org.mule.api.processor.LoggerMessageProcessor] - <In AddContact>
Hibernate: insert into contact (EMAIL, FIRSTNAME, LASTNAME) values (?, ?, ?)
2014-05-25 23:41:38,811 INFO [org.mule.api.processor.LoggerMessageProcessor] - <payload ---->>>> {"firstName":"king","lastName":"verma","email":"vermaS#xxx.com","id":9}>
Here your console shows :- Hibernate: insert into contact (EMAIL, FIRSTNAME, LASTNAME) values (?, ?, ?) and your payload is :- {"firstName":"king","lastName":"verma","email":"vermaS#xxx.com","id":9} ... where this id:"9" will be accommodated ? your query has 3 fields firstname,lastname and email ..where as your payload contains firstname,lastname,email and id
Finally could able to commit transaction using MULE JPA transport, by creating CustomTransactionFactory which starts the transaction.
public class CustomTransactionFactory implements TransactionFactory{
#Override
public Transaction beginTransaction(MuleContext muleContext)
throws TransactionException {
EntityManagerFactory emf = muleContext.getRegistry().lookupObject("entityManagerFactory");
TransactionFactory tf = new JPATransactionFactory();
Transaction tx = tf.beginTransaction(muleContext);
tx.bindResource(emf, emf.createEntityManager());
tx.begin();
return tx;
}
#Override
public boolean isTransacted() {
return true;
}
}
By referring custom transaction manager in In-bound endpoint as below, we can achieve flow level transactions.
<flow name="jpa_exampleFlow1" doc:name="jpa_exampleFlow1">
<http:inbound-endpoint exchange-pattern="request-response" doc:name="HTTP" address="http://localhost:9090/jpa_example">
<custom-transaction action="ALWAYS_BEGIN" factory-ref="transctionManager"/>
Note: Transactional blocks are no more required.