I am trying to utilize the xml to object transformer in mule while transfroming an xml payload to a Java Bean (Customer). Here is my simple flow. The exception I am seeing is below
Exception stack is:
1. CUSTOMER (com.thoughtworks.xstream.mapper.CannotResolveClassException)
com.thoughtworks.xstream.mapper.DefaultMapper:56 (null)
2. CUSTOMER (com.thoughtworks.xstream.mapper.CannotResolveClassException) (org.mule.api.transformer.TransformerException)
org.mule.module.xml.transformer.XmlToObject:76 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transformer/TransformerException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
com.thoughtworks.xstream.mapper.CannotResolveClassException: CUSTOMER
at com.thoughtworks.xstream.mapper.DefaultMapper.realClass(DefaultMapper.java:56)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.DynamicProxyMapper.realClass(DynamicProxyMapper.java:55)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
FLOW
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:mulexml="http://www.mulesoft.org/schema/mule/xml" 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" 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/xml http://www.mulesoft.org/schema/mule/xml/current/mule-xml.xsd">
<flow name="alternateFlow1" doc:name="alternateFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8999" doc:name="HTTP"/>
<http:outbound-endpoint exchange-pattern="request-response" host="www.thomas-bayer.com" port="80" path="sqlrest/CUSTOMER/3/" method="GET" doc:name="HTTP"/>
<mulexml:xml-to-object-transformer returnClass="com.abc.dto.CUSTOMER" doc:name="XML to Object"/>
<logger level="INFO" doc:name="Logger"/>
</flow>
</mule>
XML:
<CUSTOMER xmlns:xlink="w3.org/1999/xlink">
;
<ID>4</ID>
<FIRSTNAME>Sylvia</FIRSTNAME>
<LASTNAME>Ringer</LASTNAME>
<STREET>365 College Av.</STREET>
<CITY>Dallas</CITY>
</CUSTOMER>
You need to add an alias in the mulexml:xml-to-object-transformer:
<mulexml:alias name="CUSTOMER" class="com.abc.dto.CUSTOMER" />
Also there's no reason to go all caps with the class name so rename your class and alias it:
<mulexml:alias name="CUSTOMER" class="com.abc.dto.Customer" />
Related
I'm using an IMAP connector to connect to an inbox and download messages. I have the checkFrequency parameter set to 30000 (default is 60000). I've tried other values as well. With the exact code below, if I launch the flow it never checks the email on its own. Not even when it first starts and not after 30 seconds. The only way I can get it to work is by simply adding a whitespace to the XML and saving it again. This causes the connector to connect and download the email message. What am I missing?
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" 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:imap="http://www.mulesoft.org/schema/mule/imap"
xmlns:vm="http://www.mulesoft.org/schema/mule/vm"
xmlns:file="http://www.mulesoft.org/schema/mule/file"
xmlns:email="http://www.mulesoft.org/schema/mule/email"
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/3.6/mule.xsd
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/3.6/mule-file.xsd
http://www.mulesoft.org/schema/mule/imap http://www.mulesoft.org/schema/mule/imap/3.6/mule-imap.xsd
http://www.mulesoft.org/schema/mule/email http://www.mulesoft.org/schema/mule/email/3.6/mule-email.xsd
http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/3.6/mule-vm.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd" version="EE-3.6.0">
<imap:connector name="imapConnector" checkFrequency="30000" doc:name="IMAP" />
<expression-transformer name="returnAttachments" doc:name="Expression">
<return-argument evaluator="attachments-list" expression="*"/>
</expression-transformer>
<file:connector name="fileName" doc:name="File">
<file:expression-filename-parser/>
</file:connector>
<flow name="incoming-orders">
<imap:inbound-endpoint host="server" port="143" user="user" password="pass" disableTransportTransformer="true" transformer-refs="returnAttachments" doc:name="IMAP" responseTimeout="10000">
</imap:inbound-endpoint>
<foreach doc:name="For Each" collection="#[message.inboundAttachments]" >
<expression-component doc:name="Expression"><![CDATA[key == "test.xml"]]></expression-component>
<file:outbound-endpoint path="c:\Mule\in" outputPattern="#[key]" doc:name="File" responseTimeout="10000">
<expression-transformer>
<return-argument expression="payload.inputStream" evaluator="groovy"/>
</expression-transformer>
</file:outbound-endpoint>
</foreach>
</flow>
</mule>
Add the following attribute to connector definition:
mailboxFolder="INBOX"
You have created a imapConnector config which is not used.
Add to your configuration the last attribute
<imap:inbound-endpoint host="server" port="143" user="user" password="pass" disableTransportTransformer="true" transformer-refs="returnAttachments" doc:name="IMAP" responseTimeout="10000" connector-ref="imapConnector">
Here is what my flow looks like.
In the "Expression" settings, I simply have the following:
key != 0
The filename/pattern for the file connector is #[key]
It is still outputting a file named 0 which contains the email body. It does also output all other attachments properly. I just don't want it to write the email body to a file. What am I doing wrong?
Full code:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" 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:imap="http://www.mulesoft.org/schema/mule/imap"
xmlns:vm="http://www.mulesoft.org/schema/mule/vm"
xmlns:file="http://www.mulesoft.org/schema/mule/file"
xmlns:email="http://www.mulesoft.org/schema/mule/email"
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/3.6/mule.xsd
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/3.6/mule-file.xsd
http://www.mulesoft.org/schema/mule/imap http://www.mulesoft.org/schema/mule/imap/3.6/mule-imap.xsd
http://www.mulesoft.org/schema/mule/email http://www.mulesoft.org/schema/mule/email/3.6/mule-email.xsd
http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/3.6/mule-vm.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd" version="EE-3.6.0">
<imap:connector name="imapConnector" checkFrequency="10000" doc:name="IMAP" />
<expression-transformer name="returnAttachments" doc:name="Expression">
<return-argument evaluator="attachments-list" expression="*"/>
</expression-transformer>
<file:connector name="fileName" doc:name="File">
<file:expression-filename-parser/>
</file:connector>
<flow name="incoming-orders">
<imap:inbound-endpoint host="server" port="143" user="user" password="pass" disableTransportTransformer="true" transformer-refs="returnAttachments" doc:name="IMAP"/>
<foreach doc:name="For Each" collection="#[message.inboundAttachments]" counterVariableName="i" rootMessageVariableName="msg">
<expression-component doc:name="Expression">key != 0</expression-component>
<file:outbound-endpoint path="c:\Mule\in" outputPattern="#[key]" doc:name="File" responseTimeout="10000">
<expression-transformer>
<return-argument expression="payload.inputStream" evaluator="groovy"/>
</expression-transformer>
</file:outbound-endpoint>
</foreach>
</flow>
</mule>
It looks like the foreach is processing the values of the inboundAttachmentsmap so you don't get keys. I suggest something like:
<foreach doc:name="For Each" collection="#[message.inboundAttachments.entrySet()]">
<expression-transformer doc:name="Expression" expression="#[payload.key != 0]"/>
...
</foreach>
Now you'll process key-value pairs so you might need to use a set-payload to send just payload.value, saving the key before in a variable to use in the file endpoint.
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:file="http://www.mulesoft.org/schema/mule/file" xmlns:mulexml="http://www.mulesoft.org/schema/mule/xml" 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.5.0"
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/file http://www.mulesoft.org/schema/mule/file/current/mule-file.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/xml http://www.mulesoft.org/schema/mule/xml/current/mule-xml.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd">
<mulexml:namespace-manager includeConfigNamespaces="true">
<mulexml:namespace prefix="ns0" uri="http://www.cpscreen.com/schemas"/>
</mulexml:namespace-manager>
<configuration doc:name="Configuration">
<expression-language autoResolveVariables="true">
<import class="org.mule.util.StringUtils" />
<import class="org.mule.util.ArrayUtils" />
</expression-language>
</configuration>
<flow name="user_provisions_-_xml_postFlow1" doc:name="user_provisions_-_xml_postFlow1">
<file:inbound-endpoint path="E:/temp/mule" responseTimeout="10000" doc:name="File">
<file:filename-regex-filter pattern="in_(.*).csv" caseSensitive="true"/>
</file:inbound-endpoint>
<file:file-to-string-transformer doc:name="File to String"/>
<expression-component doc:name="Expression"><![CDATA[java.util.List items = new java.util.ArrayList( Arrays.asList( payload.split("\n") ));
items.remove(0);;
java.lang.String listString = '';
for (String s : items) {
listString += s + "\n";
}
payload=listString.trim();]]></expression-component>
<http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="46908" path="userprovision" method="POST" doc:name="HTTP"/>
<object-to-string-transformer mimeType="text/xml" doc:name="Object to String"/>
<splitter expression="#[xpath('//UpdateUserRequest')]" doc:name="Splitter"/>
<logger message="Here is #[payload]" level="INFO" doc:name="Logger"/>
</flow>
</mule>
I am getting like,
WARN 2014-09-10 15:30:27,181 [[user_provisions_-_xml_post].user_provisions_-_xml_postFlow1.stage1.02] org.mule.routing.ExpressionSplitter: Splitter returned no results. If this is not expected, please check your split expression
Update :
I got where the issue is but I could resolve the split issue. Because of namespace in the XML splitter does not evaluate the split expression...
<?xml version="1.0" encoding="UTF-8"?>
<UpdateUserRequests xmlns="http://www.cpscreen.com/schemas">
<UpdateUserRequest userId="Test" account="Test" password="Test">
<User>
<Account id="4">34567</Account>
<UserId>Test</UserId>
<Profile>Admin</Profile>
<PersonName>
<GivenName>Sahak</GivenName>
<FamilyName>Kn</FamilyName>
</PersonName>
</User>
</UpdateUserRequest>
<UpdateUserRequest userId="Test" account="Test" password="Test">
<User>
<Account id="5">12345</Account>
<UserId>Test</UserId>
<Profile>Admin</Profile>
<PersonName>
<GivenName>Arun</GivenName>
<FamilyName>Kumar</FamilyName>
</PersonName>
</User>
</UpdateUserRequest>
</UpdateUserRequests>
If I remove xmlns="http://www.cpscreen.com/schemas" it is splitting to multiple
How do I add the spit expression if there is a namespace in the xml ?
Use the following expression to split the xml with namespace.
<splitter expression="#[xpath('//ns0:UpdateUserRequest')]" doc:name="Splitter"/>
The above expression works considering the "ns0" namespace is added in the Mule MXL namespace manager.
Hope this helps.
You should directly use the splitter after the file inbound endpoint ...
This expression works for splitting CSV file :-
<splitter expression="#[StringUtils.split(message.payload, '\n\r')]" doc:name="Splitter_For_MultipleRow"/>
And if your CSV files have a column headers like Name, Age etc .. you can use this :-
<splitter expression="#[rows=StringUtils.split(message.payload, '\n\r');ArrayUtils.subarray(rows,1,rows.size())]" doc:name="Splitter_For_MultipleRow"></splitter>
I'm using MuleStudio 3.4 and have a simple Flow with a Drupal Connector. The Configuration for this Drupal Connector comes from a Global ElemCent Configuration.
But when i want to test the connection from the Global Elements Properties Window, i get the the message:
Test Connection failed: Invalid Global Element. Cannot access the Global Element to test.
java.long.Throwable
Here is the Configuration XML:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:json="http://www.mulesoft.org/schema/mule/json" xmlns:drupal="http://www.mulesoft.org/schema/mule/drupal" 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="CE-3.4.0" 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/json http://www.mulesoft.org/schema/mule/json/current/mule-json.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/drupal http://www.mulesoft.org/schema/mule/drupal/1.0/mule-drupal.xsd">
<drupal:config name="Drupal" username="dba" password="***" apiUrl="/service/rest/" server="localhost" port="8888" commentEndpoint="comment" fileEndpoint="file" nodeEndpoint="node" userEndpoint="user" doc:name="Drupal" taxonomyTermEndpoint="taxonomy-term" taxonomyVocabularyEndpoint="taxonomy-vocabulary">
<drupal:connection-pooling-profile initialisationPolicy="INITIALISE_ONE" exhaustedAction="WHEN_EXHAUSTED_GROW"/>
</drupal:config>
<flow name="drupal-esbFlow1" doc:name="drupal-esbFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" path="drupal/node/create" doc:name="HTTP"/>
<drupal:create-node config-ref="Drupal" username="dba" password="***" doc:name="Drupal">
<drupal:node type="article" title="[message.payload['title']]">
<drupal:body>
<drupal:und ref="#[payload]"/>
</drupal:body>
</drupal:node>
</drupal:create-node>
<json:object-to-json-transformer doc:name="Object to JSON"/>
</flow>
just make sure that you are persisting this information in mule-app.properties. Otherwise you can create another property place holder and after referencing that you can go ahead and use.
click hear to see my flow Image
My test mule application.
I use curl json post data to the http-end-point and tranforms json to object and insert on my database with name (#[message.payload.name])
I use catch-exception-strategy for keep error log (case Unique name)
I want to update my table with condition in field #[message.payload.name]
- mean Update mytable set Firstname = #[message.payload.name]
but in catch-exception-strategy can't access #[message.payload.name]
My configuration
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:jdbc-ee="http://www.mulesoft.org/schema/mule/ee/jdbc" xmlns:data-mapper="http://www.mulesoft.org/schema/mule/ee/data-mapper" xmlns:http="http://www.mulesoft.org/schema/mule/http"
xmlns:json="http://www.mulesoft.org/schema/mule/json"
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.3.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.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/jdbc http://www.mulesoft.org/schema/mule/ee/jdbc/current/mule-jdbc-ee.xsd
http://www.mulesoft.org/schema/mule/ee/data-mapper http://www.mulesoft.org/schema/mule/ee/data-mapper/current/mule-data-mapper.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 ">
<data-mapper:config name="Mapper" transformationGraphPath="mapper.grf" doc:name="DataMapper"></data-mapper:config>
<jdbc-ee:mysql-data-source name="MySQL_Data_Source1" url="jdbc:mysql://localhost:3306/mule" user="root" password="1234" transactionIsolation="UNSPECIFIED" doc:name="MySQL Data Source"/>
<jdbc-ee:connector name="Database" dataSource-ref="MySQL_Data_Source1" validateConnections="true" queryTimeout="-1" pollingFrequency="0" doc:name="Database"/>
<flow name="httpPostTestFlow1" doc:name="httpPostTestFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" path="httpPost" doc:name="httpPost"></http:inbound-endpoint>
<json:json-to-object-transformer doc:name="JSON to Object" returnClass="java.util.Map"></json:json-to-object-transformer>
<jdbc-ee:outbound-endpoint exchange-pattern="one-way" queryKey="INSERT_TOKEN" connector-ref="Database" doc:name="Database">
<jdbc-ee:query key="INSERT_TOKEN" value="insert into users(FirstName) values(#[message.payload.name]);"/>
</jdbc-ee:outbound-endpoint>
<!-- <http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="80" path="post-debug.php" contentType="application/x-www-form-urlencoded" doc:name="post-debug.php"/> -->
<catch-exception-strategy doc:name="Catch Exception Strategy">
<expression-component doc:name="Create error response">#[message.payload = "{\"status\":\"error\", \"message\":\"" + exception.cause.message + "\"}"]</expression-component>
<jdbc-ee:outbound-endpoint exchange-pattern="one-way" connector-ref="Database" doc:name="Database" queryTimeout="-1" queryKey="UPDATE_TOKEN">
<jdbc-ee:query key="UPDATE_TOKEN" value="update users SET fail_message = #[message.payload]"/>
</jdbc-ee:outbound-endpoint>
</catch-exception-strategy>
</flow>
</mule>
Based on the title you want to have a some sort of global variable, one way is you can try using flowVars as a quick fix. Using Mule Studio it is the same as Variable (under Transformers).
The message you get inside the catch exception strategy is the exception.