Mule method cannot be cast to string - mule

i'm very new to mule studio.
This is the environements setup.
VM1 = Windows 7, Visual Studio 2012, IIS 7.
A .net 4.5 WCF webservice hosted in IIS7 that has an operation that accepts a string and returns a string.
VM2 = Ubuntu 13.4 OpenJDK 1.7.0_25 Mule Studio 3.5 Community Edition.
I created a JAXWS-Client with an outbound endpoint, I did this by clicking the generate from WSDL and entering the url of the .net WCF webservice hosted in IIS on VM1. That was fine.
I then created an inbound endpoint with a jaxws-Service in-between the inbound service and the outbound client there is a logger and an object to string.
If I setup a vanilla inbound endpoint (no soap) and use a simple html form to post it all works fine and I get a string back to the browser. But adding the Soap Component causes the dispatcherexception when the flow hits the Soap Component just prior to the outbound endpoint.
org.mule.api.transport.DispatchException: java.lang.reflect.Method
cannot be cast to java.lang.String. Failed to route event via
endpoint: org.mule.module.cxf.CxfOutboundMessageProcessor. Message
payload is of type: String
<flow name="testtwoFlow1" doc:name="testtwoFlow1">
<http:inbound-endpoint exchange-pattern="request-response" path="SimplePing" doc:name="HTTP" host="0.0.0.0" port="8081"/>
<cxf:jaxws-service serviceClass="TestTwo.IPing" doc:name="SOAP" />
<logger level="INFO" doc:name="Logger"/>
<object-to-string-transformer doc:name="Object to String"/>
<flow-ref name="testtwoFlow3" doc:name="Flow Reference"/>
</flow>
<sub-flow name="testtwoFlow3" doc:name="testtwoFlow3">
<cxf:jaxws-client operation="SimplePing" serviceClass="TestTwo.IPing" enableMuleSoapHeaders="true" doc:name="SOAP"/>
<logger level="INFO" doc:name="Logger"/>
<http:outbound-endpoint exchange-pattern="request-response" host="192.168.0.2" port="80" path="MuleExperiments/Ping.svc" method="POST" doc:name="HTTP" />
</sub-flow>
I Have googled extensively and I haven been much in the way if examples that show an inbound service interacting with an outbound client. Or descriptions of the exception thrown, what causes it and how to address it. I'm guessing pretty much its because the service and the client are generated from the same WSDL, but I wouldn't have thought that would be a real issue. Or that in my cxf:jaxws-service & cxf:jaxws-service the service class is the same.
What my goal is, at this juncture, is to have a simple in/out of a string

My client was wrongly configured. It should have been clientClass, not serviceClass, and the port needed to be set as well. Once I made these changes, I got it working.
<cxf:jaxws-client
operation="SimplePing"
enableMuleSoapHeaders="true"
doc:name="SOAP"
clientClass="TestTwo.PingService"
port="BasicHttpBinding_IPing"
/>

Related

Migrating to the New HTTP Connector

I've upgraded from Mule 3.3.x to 3.6.x and since the old http endpoint is deprecated in 3.6.x I wanted to migrate to the new HTTP connector.
Here is the original code for calling a webservice and healthcheck
Webservice
<http:outbound-endpoint connector-ref="NoSessionConnector"
address="${testmigrationapp.endpoint.url}"
responseTimeout="${testmigrationapp.endpoint.timeout}" keep-alive="true"
responseTransformer-refs="errorHandler">
<jms:transaction action="ALWAYS_JOIN"/>
Healthcheck
<http:inbound-endpoint exchange-pattern="request-response" address="${testmigrationapp.healthcheck.address}" doc:name="HTTP"/>
How would I implement this using the new HTTP connector?
Thanks
An HTTP outbound endpoint would translate to an HTTP request. You will need to define a request-config specifying the host, port and persistent connections (because of the keep-alive=true). Then you can replace the outbound endpoint with a request element specifying the URL path and the response timeout. For example:
<http:request-config name="persistentRequestConfig" usePersistentConnections="true" host="example.com" port="80" />
<flow name="persistent">
<http:request config-ref="persistentRequestConfig" path="/" responseTimeout="30" />
</flow>
An HTTP inbound endpoint would translate to an HTTP listener. You will need to define a listener-config specifying the host and port. Then you can replace the inbound endpoint for a listener element specifying the URL path. For example:
<http:listener-config name="listenerConfig" host="0.0.0.0" port="8081"/>
<flow name="testFlow">
<http:listener config-ref="listenerConfig" path="/"/>
<echo-component/>
</flow>
For more details you can checkout our docs regarding the migration.

How to Intercept incoming call in Mule

Hi I am working with Mule Any Point platform i am using composite source which is listening from HTTP and JMS both. I want to identify the incoming call coming from HTTP or JMS and i want to print using the logger. How to do that ?
Try the following way of using logger inside your endpoints.
<composite-source doc:name="Composite Source">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" doc:name="HTTP">
<logger message="Request coming from HTTP endpoint."></logger>
<set-variable value="HTTP" variableName="myVar"></set-variable>
</http:inbound-endpoint>
<jms:inbound-endpoint doc:name="JMS" queue="in">
<logger message="Request coming from JMS endpoint."></logger>
<set-variable value="JMS" variableName="myVar"></set-variable>
</jms:inbound-endpoint>
</composite-source>
In the flow when you have to chekc a condition, you can use the flow variable "myVar" to check whether the message came from HTTP or JMS endpoint.
Hope this helps.

Getting the object out of the http response received

1st ESB App: HTTP Inbound Endpoint(request-response) -> javaComponent1 -> http outbound endpoint(request-response) -> JavaComponent2.
2nd ESB app: HTTP Inbound Endpoint(request-response) -> javacomponent3
In my case HTTP Inbound Endpoint(request-response) of 2nd ESB app sends the response back to the http outbound endpoint(request-response) of 1st ESB App.
My problem and query: HTTP Inbound Endpoint(request-response) of 2nd ESB app should send a java object as payload of the request that is being sent back to the http outbound endpoint(request-response) of 1st ESB App. The JavaComponent2 should be able to read the object received by the http outbound endpoint(request-response) of 1st ESB App and process it further.
How should I send my Java object from the http endpoint of the second app to the http outbound endpoint of the first app? I cannot use serialization here.
You can use object to bytearray transformer before sending the object from the 2nd Mule app . Then you use bytearray to Object transformer after the http outbound endpoint in the 1st mule app, while you are receiving the response from the 2nd mule app
First App
<flow name="test_serializableFlow1" doc:name="test_serializableFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" doc:name="HTTP"/>
<http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="8082" method="POST" doc:name="HTTP"/>
<logger message="Before transformer #[payload]" level="INFO" doc:name="Logger"/>
<byte-array-to-object-transformer doc:name="Byte Array to Object"/>
<logger message="After transformer #[payload]" level="INFO" doc:name="Logger"/>
</flow>
Second app
<flow name="ssFlow1" doc:name="ssFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8082" doc:name="HTTP"/>
<component class="Test" doc:name="Java"/>
<object-to-byte-array-transformer doc:name="Object to Byte Array"/>
</flow>

Why won't a REST component not receive a call made internal to an app when multiple Global HTTP Connectors are Configured?

I'm struggling to configure and deploy to CloudHub an app with multiple Global HTTP Connectors and a REST component.
My application has two flows: one polls an RSS feed for news and posts a json representation of that feed to an http inbound endpoint in the same app (endpoint resides on second flow). The second flow receives that post, does some magic, including persisting the item to storage, and then notifies via an http outbound endpoint an external node.js web app to push the item via web sockets to active clients.
I have tried what feels like dozens of different configurations involving a variety of HTTP Global Connectors and http in and outbound endpoints, but I can't get everything to work. I currently have:
A Polling HTTP Connector
An HTTP endpoint referencing above polling http connector to get RSS Feed
One Global Connector (we'll call HTTP_ONE) to receive messages at localhost:${http.port}
An http oubound endpoint configured referencing HTTP_ONE and configured to post an activity to /api/v1/activity
An http inbound endpoint configured to receive messages for /api/v1 and a Jersey controller sitting just behind this endpoint which takes /activity.
Another Global Connector (HTTP_TWO) with an external host set as the proxy host name (e.g. somehost.somewhere.com).
An http outbound endpoint configured to post messages to somehost.somewhere.com
On my localhost, I've had to use various properties to allow for all of this activity on multiple ports on my laptop.
On CloudHub, I'm using localhost and ${http.port} everywhere except in the oubound endpoint that calls to an external web service.
I can get one flow or the other working, but not both.... My problem seems to be with the posting a given news item from the RSS feed to the Inbound HTTP Endpoint. It is sending the post to http://localhost:80/api/v1/activity, but the connector says that no such path exists (it only lists /api/v1 as an option), which makes me think that the call is not getting as far as the Jersey Controller which sits behind the Global Connector and the http inbound endpoint for /api/v1/activity. Is this behavior an inherent flaw in using the REST Component and multiple global http connectors? Also, why do we have to reference a Global HTTP Connector when making an outbound call? Why can't we use the default HTTP Connector? (Maybe the last two questions should go in a subsequent post...)
Here's most of the relevant config for the two flows:
Global Connectors
<http:polling-connector name="PollingHttpConnector" pollingFrequency="60000" doc:name="HTTP Polling" clientSoTimeout="10000" cookieSpec="netscape" receiveBacklog="0" receiveBufferSize="0" sendBufferSize="0" serverSoTimeout="10000" socketSoLinger="0" validateConnections="true"/>
<http:connector name="EduStream_HTTP" cookieSpec="netscape" validateConnections="true" sendBufferSize="0" receiveBufferSize="0" receiveBacklog="0" clientSoTimeout="10000" serverSoTimeout="10000" socketSoLinger="0" proxyHostname="${edustream.host}" doc:name="HTTP\HTTPS" proxyPort="80"/>
<http:connector name="EduStreamESB_HTTP" cookieSpec="netscape" validateConnections="true" sendBufferSize="0" receiveBufferSize="0" receiveBacklog="0" clientSoTimeout="10000" serverSoTimeout="10000" socketSoLinger="0" proxyHostname="localhost" proxyPort="${http.port}" doc:name="HTTP\HTTPS"/>
News RSS Feed Flow
<flow name="ucdNewsConsumer" doc:name="ucdNewsConsumer">
<http:inbound-endpoint address="http://news.ucdavis.edu/xml/getnews.php/rss/category/General%20Interest"
connector-ref="PollingHttpConnector" doc:name="HTTP" exchange-pattern="one-way"/>
<rss:feed-splitter/>
<rss:entry-last-updated-filter/>
<component class="edu.ucdavis.edustream.esb.news.rss.EntryReceiver" doc:name="Java"/>
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
<http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="${http.port}" path="api/v1/activity" doc:name="HTTP" mimeType="application/json" connector-ref="EduStreamESB_HTTP" />
<logger message="Payload is: #[payload] Inbound Headers: #[headers:INBOUND:*] Outbound Headers: #[headers:OUTBOUND:*] Exception is: #[exception]" level="INFO" doc:name="Logger"/>
</flow>
Activity Publication Service -- Core Flow
<flow name="edustreamesbFlow1" doc:name="edustreamesbFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="${http.port}" doc:name="HTTP" contentType="application/json" mimeType="application/json" path="api/v1" connector-ref="EduStreamESB_HTTP"/>
<jersey:resources doc:name="REST">
<component class="edu.ucdavis.edustream.esb.activity.restapi.ActivityController"/>
</jersey:resources>
<component class="edu.ucdavis.edustream.esb.activity.restapi.JerseyResponseTransformer" doc:name="JerseyRespTrans"/>
<flow-ref name="PublishActivity" doc:name="Publish Activity"/>
</flow>
<sub-flow name="PublishActivity" doc:name="PublishActivity">
<component doc:name="ActivityService">
<spring-object bean="activityService"/>
</component>
<logger message="#[payload] #[message]" level="INFO" doc:name="Logger"/>
<http:outbound-endpoint exchange-pattern="request-response" host="${edustream.host}" port="80" path="api/v1/activity" mimeType="application/json" contentType="application/json" doc:name="HTTP" connector-ref="EduStream_HTTP"/>
</sub-flow>
I do not get why proxyHostname and proxyPort are configured on both EduStream_HTTP and EduStreamESB_HTTP connectors while the HTTP endpoints from these connectors target the same host/port as their destination address. This doesn't make any sense to me.
Are you really sure you need to use proxies?
For EduStreamESB_HTTP the answer is clearly no: you're calling CloudHub from CloudHub, so no need for a proxy.
For EduStreamESB_HTTP, maybe... but that still seems very strange.

Timed Mule Web Service Client Flow

I've searched the forums for an answer to this. I found one almost identical question, though the answer left me still wondering.
An almost identical post was found here:
Mule - Schedule a flow to consume a web service
This poster stated the problem I am having very well.
I am also new to Mule and am trying to do the very same thing. I didnt realize I needed a payload since I thought the operation specification was essentially the payload.
Notice that I have a flow that includes cxf:jaxws-client and that client specifies a URL for the service and an operation "listTest".
What other payload do i need to specify in order to actually execute the service request?
I tried to add a dummy payload to the event generator (as suggested in referenced post), and that doesnt make a difference.
When I execute the mule application, and monitor the "test auditor web service" (using wireshark) i see four requests go out for the wsdl, and i see that wsdl returned, but i dont actually see the listTest operation getting invoked.
My flow is:
<http:connector name="HTTP_HTTPS" cookieSpec="netscape"
validateConnections="true" sendBufferSize="0" receiveBufferSize="0"
receiveBacklog="0" clientSoTimeout="10000" serverSoTimeout="10000"
socketSoLinger="0" doc:name="HTTP\HTTPS" />
<flow name="TestAuditorClient_CheckerFlow1" doc:name="TestAuditorClient_CheckerFlow1">
<quartz:outbound-endpoint jobName="GetTestList"
repeatInterval="10000" responseTimeout="10000" doc:name="Quartz">
<quartz:event-generator-job jobGroupName="GetTestList" />
</quartz:outbound-endpoint>
<cxf:jaxws-client operation="listTest"
clientClass="server.TestService_Service" port="TestServicePort"
wsdlLocation="http://192.168.66.7:8080/TestAuditorWebApp/TestService?wsdl"
doc:name="SOAPY" />
<outbound-endpoint
address="http://192.168.66.7:8080/TestAuditorWebApp/TestService"
doc:name="HTTP" />
<logger message="Received HTTP Response #[payload]" level="INFO"
doc:name="Logger" />
<!-- <outbound-endpoint exchange-pattern="request-response" address="http://192.168.66.17:8080/TestAuditorWebApp/TestService"
doc:name="HTTP"/> -->
<file:outbound-endpoint path="C:\tmp"
outputPattern="#[function:datestamp:dd-MM-yy]_#[function:systime].txt"
responseTimeout="10000" doc:name="Output File" />
</flow>
I am not only new to mule, but as well to stack overflow. So if there was a better way for me to ask a related question, please advise and excuse.
Thanks in advance.
Instead of Quartz, you can use a poll message processor to generate the instances of ListTest you need.
Assuming this class FQDN is server.TestService.ListTest (you didn't tell), the following should work:
<flow name="TestAuditorClient_CheckerFlow1">
<poll frequency="10000">
<set-payload value="#[lt=new server.TestService.ListTest(); lt.aField='aValue'; lt]" />
</poll>
...
Notice how you can set values on the POJO directly from the expression that creates it.