how to generate multiple copies of the same file using mule - 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]

Related

Sending Multipart Requests in 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

Zip file not deleted in mule

I am reading a zip file using file inbound connector in mule. The file should be auto deleted, since auto delete is true. But it's not.
The flow I have is
<file:connector name="File" writeToDirectory="D:\FileProcessed\ringmoved\" readFromDirectory="D:\FileProcessed\" autoDelete="true" streaming="true" validateConnections="true" doc:name="File"/>
<flow name="filFlow">
<file:inbound-endpoint path="D:\FileProcessed\" moveToDirectory="D:\FileProcessed\moved\" connector-ref="File" responseTimeout="10000" doc:name="File"/>
<logger message="hi" level="INFO" doc:name="Logger"/>
</flow>
It's because you are not consuming the file. Try adding a transformer such as
<object-to-string-transformer />
after the file endpoint.

Mule flow design to process read large files from remote location

I have a flow with the following steps:
1) Pick a file from source SFTP sever
2) Copy it into local storage
3) Process file using the copy in the local storage
4) Place the processed file (which will be transformed) into a destination SFTP server
5) Move file present in the source SFTP into a different folder on the source SFTP server (I could not find a way to do this and hence I'm copying from the temp location back into the SFTP processed folder)
This seems to a standard workflow, however I could not find any advice on how to specifically implement this in Mule.
My current implementation is described below:
<file:connector name="tempFile" workDirectory="${temp.file.location}/work"
workFileNamePattern="#[message.inboundProperties.originalFilename]"
autoDelete="true" streaming="false" validateConnections="true"
doc:name="File" />
<sftp:connector name="InputSFTP" validateConnections="true" keepFileOnError="true" doc:name="SFTP" >
<reconnect frequency="${reconnectfrequency}" count="5"/>
</sftp:connector>
<sftp:connector name="DestinationSFTP" validateConnections="true" pollingFrequency="30000" doc:name="SFTP">
<reconnect frequency="${reconnectfrequency}" count="5"/>
</sftp:connector>
<smtp:gmail-connector name="Gmail" contentType="text/plain" validateConnections="true" doc:name="Gmail"/>
<flow name="DownloadFTPFileIntoLocalFlow" processingStrategy="synchronous" tracking:enable-default-events="true">
<sftp:inbound-endpoint connector-ref="InputSFTP" host="${source.host}" port="22" path="${source.path}" user="${source.username}"
password="${source.password}" responseTimeout="90000" pollingFrequency="120000" sizeCheckWaitTime="1000" doc:name="InputSFTP" autoDelete="true">
<file:filename-regex-filter pattern="[Z].*\.csv" caseSensitive="false" />
</sftp:inbound-endpoint>
<file:outbound-endpoint path="${temp.file.location}" responseTimeout="10000" doc:name="Templocation" outputPattern="#[message.inboundProperties.originalFilename]" connector-ref="tempFile" />
<exception-strategy ref="Default_Exception_Strategy" doc:name="Reference Exception Strategy"/>
</flow>
<flow name="ProcessCSVFlow" processingStrategy="synchronous" tracking:enable-default-events="true">
<file:inbound-endpoint path="${temp.file.location}" connector-ref="tempFile" pollingFrequency="180000" fileAge="10000" responseTimeout="10000" doc:name="TempFileLocation"/>
<transformer ref="enrichWithHeaderAndEndOfFileTransformer" doc:name="headerAndEOFEnricher" />
<set-variable variableName="outputfilename" value="#['Mercury'+server.dateTime.year+server.dateTime.month+server.dateTime.dayOfMonth+server.dateTime.hours +server.dateTime.minutes+server.dateTime.seconds+'.csv']" doc:name="outputfilename"/>
<sftp:outbound-endpoint exchange-pattern="one-way" connector-ref="DestinationSFTP" host="${destination.host}" port="22" responseTimeout="10000" doc:name="DestinationSFTP"
outputPattern="#[outputfilename]" path="${destination.path}" user="${destination.username}" password="${destination.password}"/>
<gzip-compress-transformer/>
<sftp:outbound-endpoint exchange-pattern="one-way" connector-ref="InputSFTP" host="${source.host}" port="22" responseTimeout="10000" doc:name="SourceArchiveSFTP"
outputPattern="#[outputfilename].gzip" path="Archive" user="${source.username}" password="${source.password}"/>
<set-payload value="Hello world" doc:name="Set Payload"/>
<smtp:outbound-endpoint host="${smtp.host}" port="${smtp.port}" user="${smtp.from.address}" password="${smtp.from.password}"
to="${smtp.to.address}" from="${smtp.from.address}" subject="${mail.success.subject}" responseTimeout="10000"
doc:name="SuccessEmail" connector-ref="Gmail"/>
<logger message="Process completed successfully" level="INFO" doc:name="Logger"/>
<tracking:transaction id="#[server.dateTime]"/>
<exception-strategy ref="Default_Exception_Strategy" doc:name="Reference Exception Strategy"/>
</flow>
<catch-exception-strategy name="Default_Exception_Strategy">
<logger message="Exception has occured Payload is #[payload] and Message is #[message]" level="ERROR" doc:name="Logger"/>
<!-- <smtp:outbound-endpoint host="localhost" responseTimeout="10000" doc:name="Failure Email"/> -->
</catch-exception-strategy>
Have you tried enabling autoDelete="true" on the SFTP connector to force deleting?
Also, is it not possible to do flow1: SFTP-in -> transform -> file out, flow2: file-in -> SFTP-out?
HTH

mule move multiple files from one folder to other inside for each loop

Below is my mule flow. I want to move my corresponding from the jdbc query rseult set
----------------------------------------------------
<foreach doc:name="Foreach" counterVariableName="#[message.payload.size()]">
<logger message="#[payload.filepath] - #[payload.name] - #[payload.filename]" level="INFO" doc:name="Logger" />
</foreach>
---------------------------------------------------------------------
<jdbc-ee:postgresql-data-source name="PostgreSQL_Data_Source"
user="postgres" password="postgres" url="jdbc:postgresql://localhost:5432/postgres"
transactionIsolation="UNSPECIFIED" doc:name="PostgreSQL Data Source">
</jdbc-ee:postgresql-data-source>
<jdbc-ee:connector name="JDBCConnector"
dataSource-ref="PostgreSQL_Data_Source" validateConnections="true"
doc:name="JDBCConnector">
<jdbc-ee:query key="emprec" value="select * from emp where salary>50000";">
</jdbc-ee:query>
</jdbc-ee:connector>
<flow name="empflow" >
<quartz:inbound-endpoint responseTimeout="10000"
doc:name="Quartz" jobName="CronJobSchedule" repeatInterval="0"
cronExpression="0 0/1 * ? * MON-FRI" repeatCount="1">
<quartz:event-generator-job>
<quartz:payload>quartzSchedular started</quartz:payload>
</quartz:event-generator-job>
</quartz:inbound-endpoint>
<jdbc-ee:outbound-endpoint queryKey="emprec"
queryTimeout="-1" connector-ref="JDBCConnector" exchange-pattern="request-response"
doc:name="Database" />
<logger message="Size of payload is ::: #[message.payload.size()]" level="INFO" doc:name="Logger"/>
<foreach doc:name="Foreach" counterVariableName="#[message.payload.size()]">
<logger message="#[payload.filepath] - #[payload.name] - #[payload.filename]" level="INFO" doc:name="Logger" />
</foreach>
</flow>
please suggest way to move whatever filename got using query result ,that file need to move other location
Inside for each loop i tried file inbound and outpoint .but it is not worked out
1 - You need to load the file, for that I suggest using the Mule Requester Module. You can find more on it in this blogpost.
2 - Right after that you can move it using a file outbound endpoint.
Here's an example:
<mulerequester:request config-ref="Mule_Requester" resource="file:///Users/anafelisatti/test.txt" returnClass="java.lang.String" doc:name="Mule Requester"/>
<file:outbound-endpoint responseTimeout="10000" doc:name="File" outputPattern="test.txt" path="/Users/anafelisatti/Documents"/>
Hope that helps.

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.