Transform Http Response to object mule esb - java

Im doing a sample bookstore. When the user has booked a order, the system send him an email with the dates from the order. The system send the email but it shows the next error:
Root Exception stack trace:
java.lang.IllegalArgumentException: Cannot apply transformer HttpClientMethodResponseToObject{this=6911a11b, name='HttpClientMethodResponseToPedido', ignoreBadInput=false, returnClass=SimpleDataType{type=org.mule.entities.Pedido, mimeType='text/html'}, sourceTypes=[SimpleDataType{type=org.apache.commons.httpclient.HttpMethod, mimeType='*/*'}]} on source payload: class org.mule.transport.http.HttpResponse
at org.mule.DefaultMuleMessage.applyAllTransformers(DefaultMuleMessage.java:1427)
at org.mule.DefaultMuleMessage.applyTransformers(DefaultMuleMessage.java:1379)
at org.mule.DefaultMuleMessage.applyTransformers(DefaultMuleMessage.java:1371)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
My XML is the next:
<smtp:gmail-connector name="Gmail" validateConnections="true" doc:name="Gmail" contentType="text/html" />
<flow name="Email" doc:name="Email">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8088" doc:name="HTTP" path="Email"/>
<http:static-resource-handler resourceBase="docroot" defaultFile="index.html" doc:name="HTTP Static Resource Handler"/>
</flow>
<flow name="Correo" doc:name="Correo">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8088" path="Facturacion" doc:name="HTTP" transformer-refs="Java"/>
<component doc:name="Generar Pedido" class="org.mule.components.GenerarPedido"/>
<smtp:outbound-endpoint host="smtp.gmail.com" port="587" user="email%40gmail.com" password="pass" connector-ref="Gmail" to="#[payload.email]" from="BookStore S.A." responseTimeout="10000" doc:name="SMTP" transformer-refs="Java1" mimeType="text/html"/>
<http:response-builder status="200" contentType="text/html" doc:name="HTTP Response Builder"/>
<http:http-response-to-object-transformer returnClass="org.mule.entities.Pedido" encoding="UTF-8" mimeType="text/html" doc:name="HTTP Response to Object"/>
</flow>
Anyone can help me?

Your payload is not a HTTP response, so you cannot use the http-response-to-object-transformer. This is used after calling an http:outbound-endpoint which returns a 'HTTP response'.

Related

Mule Standalone 3.8.1 ClassDefNotFoundError when sending a stream of HTTP requests with big payload at high concurrency

I'm pretty new to MuleESB. I'm using Mule Standalone 3.8.1 with a configuration to filter HTTP requests using the xpath3() function. The configuration I have used is as follows.
<http:listener-config name="HTTP_Listener_Configuration" host="localhost" port="8081" />
<http:request-config name="HTTP_Request_Configuration" host="example.com" port="8081" basePath="basePath" responseTimeout="120000" />
<custom-transformer name="XML_Transformer" class="org.mule.module.xml.transformer.XmlToOutputHandler"/>
<message-properties-transformer name="Response_Error_Transformer">
<add-message-property key="http.status" value="500"/>
<add-message-property key="Content-Type" value="text/xml" />
</message-properties-transformer>
<message-properties-transformer name="Response_Transformer">
<add-message-property key="Content-Type" value="text/xml" />
</message-properties-transformer>
<set-payload name="Create_Error_Response" value="
<PurchaseOrder PurchaseOrderNumber="99503" OrderDate="1999-10-20">
<fault>
<code>500</code>
<message>#[flowVars['errorMessage']]</message>
</fault>
</PurchaseOrder>" />
<flow name="Choice_Flow">
<http:listener config-ref="HTTP_Listener_Configuration" path="productFilter" />
<choice>
<when expression="#[xpath3('//Item[1]/ProductName') == 'Laptop']">
<transformer ref="XML_Transformer"/>
<http:request config-ref="HTTP_Request_Configuration" path="EchoService" method="POST" />
<flow-ref name="Response_Transformer" />
</when>
<otherwise>
<flow-ref name="Response_Error_Transformer" />
<set-variable variableName="errorMessage" value="First item must be a Laptop" />
<flow-ref name="Create_Error_Response" />
</otherwise>
</choice>
</flow>
When I'm sending HTTP requests at 10 threads it's working fine. But, then when I tried sending requests at 500 threads, some of the requests got failed. The request is an XML with 2500 Item elements. I don't see any descriptive errors in the logs or anywhere, but the requests got failed. After this happens, some of the requests got failed even for small thread numbers, and I couldn't find any error in files in the logs directory. Only error I see in the mule.log file is as follows. This is written at the first occurrence of this error. Then, simply, nothing.
Exception: java.lang.NoClassDefFoundError thrown from the UncaughtExceptionHandler in thread "[default].http.listener(6)"
Can someone please explain me what's going on here? How to do this without any error? Is something wrong with my configuration?

HTTP SOAP Post Request

I need to send HTTP Request to publish some data in a WS
E.g:
http://localhost:8081/hello/publishAMANSequence/filter/sequenceGenerationTime=1696-09-01T00:00:00Z&AMANId=B1&landingSequenceEntry=11234567890EST
I take this fault from server:
Parameter should be ordered in the following sequence: [sequenceGenerationTime, AMANId, landingSequenceEntry]
I'm doing something wrong in the order?
mule flow:
<jms:activemq-connector name="Active_MQ1" brokerURL="tcp://localhost:61616" validateConnections="true" doc:name="Active MQ"/>
<flow name="jmsFlow1" doc:name="jmsFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" path="hello" doc:name="HTTP"/>
<cxf:jaxws-service doc:name="SOAP" serviceClass="aero.itec.amansequenceservice.AMANSequenceInfo"/>
<component doc:name="Java" class="implementations.AMANSequenceImpl"/>
<mulexml:object-to-xml-transformer doc:name="Object to XML"/>
<jms:outbound-endpoint queue="StudioIN" connector-ref="Active_MQ1" doc:name="JMS"/>
<logger message="#[message.payload]" level="INFO" doc:name="Logger"/>
</flow>
The url which you have provided is wrong. There should be a questionmark(?) after "filter". Then only it will consider it as parameters
http://localhost:8081/hello/publishAMANSequence/filter?sequenceGenerationTime=1696-09-01T00:00:00Z&AMANId=B1&landingSequenceEntry=11234567890EST
Moreover if you are trying to access a webservice you can't do that with a HTTP GET. You need to send it as a SOAP request. You can use APIs like CXF, AXIS etc.
Following this tutorial ~
I create a flow for publish the WS , that have an inbound-endpoint where I do the request
publish.flow:
<jms:activemq-connector name="Active_MQ1" brokerURL="tcp://localhost:61616" validateConnections="true" doc:name="Active MQ"/>
<flow name="jmsFlow1" doc:name="jmsFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" path="hello" doc:name="HTTP"/>
<cxf:jaxws-service doc:name="SOAP" serviceClass="aero.itec.amansequenceservice.AMANSequenceInfo" >
<cxf:jaxb-databinding/>
<cxf:inInterceptors>
<spring:bean class="org.apache.cxf.interceptor.LoggingInInterceptor" />
</cxf:inInterceptors>
<cxf:outInterceptors>
<spring:bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
</cxf:outInterceptors>
</cxf:jaxws-service>
<component doc:name="Java" class="implementations.AMANSequenceImpl"/>
<object-to-string-transformer doc:name="Object to String"/>
<jms:outbound-endpoint queue="StudioIN" connector-ref="Active_MQ1" doc:name="JMS"/>
<logger message="#[message.payload]" level="INFO" doc:name="Logger"/>
</flow>
Then I create a client.class where I set the variable values:
client.java
public class AMANwsClient extends AbstractTransformer{
#Override
protected Object doTransform(Object src, String enc)
throws TransformerException {
AMANSequence sequence = new AMANSequence();
XMLGregorianCalendar fec;
sequence.setSequenceGenerationTime(fec);
sequence.setAMANId("AA");
System.out.println(sequence);
return sequence;
}
This class is used like a transformer, we don't need to pass parameters in the url, only need to connect to the endpoint URL
Finally, create a client.flow
<custom-transformer class="implementations.AMANwsClient" name="AMANwsClient" />
<flow name="csvPublisher">
<transformer ref="AMANwsClient" />
<object-to-string-transformer doc:name="Object to String"/>
<outbound-endpoint address="http://localhost:63081/hello" exchange-pattern="request-response">
<cxf:jaxws-client clientClass="aero.itec.amansequenceservice.AMANSequenceInfo_Service" port="AMANSequenceInfoService" operation="publishAMANSequence">
<cxf:inInterceptors>
<spring:bean class="org.apache.cxf.interceptor.LoggingInInterceptor" />
</cxf:inInterceptors>
<cxf:outInterceptors>
<spring:bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
</cxf:outInterceptors>
</cxf:jaxws-client>
</outbound-endpoint>
</flow>
Now I can save the payload into a JMS Queue and reproduce the payload from Browser, console and JMS.
If you have some suggestion to improve program performance, I'm open to listen to it.
Put http://localhost:8081/hello?wsdl in SOAPUI ... It will create the request and response there ... then you can pass the values in the request and invoke the webservice ...
Please check the following for your reference :-
http://developers-blog.org/blog/default/Webservice-testing-with-soapUI and http://quicksoftwaretesting.com/soapui-web-service-testing-tool/

Mule malformed endpoint error

I am new to Mule and trying to post a GET request using the HTTP endpoint, but I am receiving the following error
"Template Endpoint "http://api.mymemory.translated.net:80/get?q=#[message.inboundProperties.get('http.relative.path')]&langpair=EN|IT" resolved into a Malformed endpoint "http://api.mymemory.translated.net:80/get?q=hello&langpair=EN|IT". Failed to route event via endpoint: org.mule.endpoint.DynamicOutboundEndpoint"
I have tried the following configurations:
get?q=hello&langpair=EN%7CIT [WORKS]
get?q=#[message.inboundProperties.get('http.relative.path')]&langpair=EN%7CIT [DOESN'T WORK]
get?q=#[message.inboundProperties.get('http.relative.path')]&langpair=EN|IT
[DOESN'T WORK]
The stack trace seems to indicate that there is a problem with the "|" character.
My flow is as follows:
<flow name="my_first_projectFlow1" doc:name="my_first_projectFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" doc:name="HTTP"/>
<http:outbound-endpoint exchange-pattern="request-response" host="api.mymemory.translated.net" port="80" path="get?q=#[message.inboundProperties.get('http.relative.path')]&langpair=EN%7CIT" method="GET" doc:name="HTTP"/>
<echo-component doc:name="Echo"/>
</flow>
Try replacing the pipe ("|") char with MEL expression #[java.net.URLEncoder.encode('|', 'UTF-8')].

Mule - Communication between Web application and Mule ESB

My web application is on following address:
http://localhost:8080/MyProject/page-obj.html
I am calling Mule Project, from a Web Application(deployed on glassfish), having following URL in page:
`<form action="http://localhost:28146/CallObject" method="post" id="objform">`
Mule project is executing something on remote server and returning Success.
I want to redirect success to another page say
http://localhost:8080/MyProject/page-sucess.html
When redirect, i see http://localhost:28146/CallObject on address bar, instead of http://localhost:8080/MyProject/page-sucess.html. Secondly, i am unable to load CSS and JS properly. I think i am not handling this properly
Following is Mule Flow in use:
`
<http:endpoint exchange-pattern="request-response" address="http://localhost:8080/MyProject/page-sucess.html" name="page" method="POST"/>
<flow name="Create_Work_Flow" doc:name="Create_Work_Flow">
<http:inbound-endpoint exchange-pattern="request-response" address="http://localhost:28146/CallObject" contentType="text/html" doc:name="Request">
<http:body-to-parameter-map-transformer doc:name="HTMLForm-Parameters-To-Mule"/>
</http:inbound-endpoint>
<logger level="INFO" doc:name="Form-Parameters" message="#[payload]" />
<http:outbound-endpoint exchange-pattern="request-response" method="POST" doc:name="HTTP" ref="Page">
<custom-transformer class="com.ExecuteWorkflow" doc:name="Call-CreateWorkflow"/>
</http:outbound-endpoint>
</flow>`
Have your Mule flow set redirect headers in the success case and the browser should follow the redirect:
<flow name="Create_Work_Flow" doc:name="Create_Work_Flow">
<http:inbound-endpoint exchange-pattern="request-response" address="http://localhost:28146/CallObject" contentType="text/html" doc:name="Request">
<http:body-to-parameter-map-transformer doc:name="HTMLForm-Parameters-To-Mule"/>
</http:inbound-endpoint>
<logger level="INFO" doc:name="Form-Parameters" message="#[payload]" />
<http:outbound-endpoint exchange-pattern="request-response" method="POST" doc:name="HTTP" ref="Page">
<custom-transformer class="com.ExecuteWorkflow" doc:name="Call-CreateWorkflow"/>
</http:outbound-endpoint>
<set-property propertyName="http.status" value="301"/>
<set-property propertyName="Location" value="http://localhost:8080/MyProject/page-
</flow>

How to filter a single URI from a group of URI's in a Mule inbound endpoint?

I have the following code to configure a Jersey service at "http://localhost:8080/alpha":
*** my mule config ***
<flow name="flow1">
<inbound-endpoint address="http://localhost:8080/" exchange-pattern="request-response" />
<jersey:resources>
<component>
<singleton-object class="com.address.Flow1Resource"/>
</component>
</jersey:resources>
</flow>
*** Flow1Resource.java ***
#Path("/alpha")
public class Flow1Resource {...}
I want to add a new inbound-endpoint that handles all the addresses under "http://localhost:8080" except "http://localhost:8080/alpha" (e.g. "http://localhost:8080/beta"). These new addresses need a single jersey resource. For example:
*** my mule config ***
<flow name="flow1">
<inbound-endpoint address="http://localhost:8080/" exchange-pattern="request-response" />
<jersey:resources>
<component>
<singleton-object class="com.address.Flow1Resource"/>
</component>
</jersey:resources>
</flow>
<flow name="flow2">
<inbound-endpoint address="http://localhost:8080/*" exchange-pattern="request-response" />
<jersey:resources>
<component>
<singleton-object class="com.address.Flow2Resource"/>
</component>
</jersey:resources>
</flow>
*** Flow1Resource.java ***
#Path("/alpha")
public class Flow1Resource {...}
*** Flow2Resource.java ***
#Path("/")
public class Flow2Resource {
#Path("beta")
public void beta() {...}
#Path("gamma")
public void gamma() {...}
...
}
How do I set up the mule inbound-endpoint to capture all the addresses (i.e. beta & gamma), except for a specific url (i.e. alpha).
I know that I can hardcode the paths in the mule config, but this would result in duplication because each address (i.e. beta & gamma) would need its own flow and resource code, which are similar.
Please note that I used "http://localhost:8080/*" in the code above as an conceptual example. It does not work.
--- Update ---
I forgot to mention that the beta and gamma uri's also have security associated with them using:
<http:inbound-endpoint ...>
<spring-security:http-security-filter realm="mule-realm"/>
</http:inbound-endpoint>
I tried adding a 'choice' element to the endpoint, but it complained that spring-security was invalid inside the choice decision structure.
A solution would also need to accommodate this feature.
An easy way to achieve your goal is to combine your flows into one and use the choice router. In this configuration your flow will look like the following:
<flow name="stackoverflowFlow1" doc:name="stackoverflowFlow1">
<http:inbound-endpoint exchange-pattern="request-response"
host="localhost" port="8081" doc:name="HTTP" />
<logger level="ERROR" />
<choice doc:name="Choice">
<when expression="#[message.inboundProperties['http.request'] == '/']">
<processor-chain>
<logger message="/ invoked " level="ERROR" />
<jersey:resources doc:name="REST">
<component class="Resource" />
</jersey:resources>
</processor-chain>
</when>
<otherwise>
<processor-chain>
<logger message="otherwise invoked " level="ERROR" />
<jersey:resources doc:name="REST">
<component class="ApplicationsResource" />
</jersey:resources>
</processor-chain>
</otherwise>
</choice>
</flow>
As you can imagine you can take decision on the path or on top of any other http header.
You can find this router documentation here and a list of the most common http properties you can use to make your choices here

Categories