Mule: how to consume a service from a remote client - eclipse

I have been following this tutorial which is really great to consume wb services from WSDL http://training.middlewareschool.com/mule/consuming-wsdl-first-service/.
I have been trying to do a similar approach by generating a client web service in Eclipse using CXF and publishing the web service in Mule. My question is: if I configure for the client and mule application to have the same endpoint (for example: localhost:8082/ipsoap/test), how can I have the web service work the same way as with the tutorial.
Meaning if I test sending a request to mule from the client (in eclipse) I should receive the right response from mule. Thank you in advance for your time.
So in short:
1-I generated a client app in eclipse using the wsdl in the following link in the tutorial: http://ws.cdyne.com/ip2geo/ip2geo.asmx?wsdl
2- As a start in Mule, I added an http connector and a logger and changed the endpoint path in eclipse to the one I set on the HTTP connector on Mule. Thus, I can see that there is a payload when I am sending a request to Mule from the client in Eclipse.
3- I need to have an application, namely my client app in eclipse, consume a published service in Mule. Now I think this is achieved using the CXF component but I still fail to make it work. In fact, I wonder if this is one valid way of using Mule since I couldn't find any tutorial about what I am trying to achieve.
So here is how I test it:
I used the same endpoint I used in Mule and receive the following log:
> INFO 2014-07-07 13:19:46,124
> [[soapservice].connector.http.mule.default.receiver.02]
> org.mule.api.processor.LoggerMessageProcessor: message transformation
> <soapenv:Envelope
> xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
> xmlns:q0="http://ws.cdyne.com/"
> xmlns:xsd="http://www.w3.org/2001/XMLSchema"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
> <soapenv:Body>
> <q0:ResolveIP>
> <q0:ipAddress>173.194.36.39</q0:ipAddress>
> <q0:licenseKey/>
> </q0:ResolveIP> </soapenv:Body> </soapenv:Envelope>
>
> ERROR 2014-07-07 13:19:46,134
> [[soapservice].connector.http.mule.default.receiver.02]
> org.mule.exception.DefaultMessagingExceptionStrategy:
> ******************************************************************************** Message : wrong number of arguments. Failed to route
> event via endpoint: org.mule.module.cxf.CxfOutboundMessageProcessor.
> Message payload is of type: String Code :
> MULE_ERROR--2
> -------------------------------------------------------------------------------- Exception stack is:
> 1. wrong number of arguments (java.lang.IllegalArgumentException) sun.reflect.NativeMethodAccessorImpl:-2 (null)
> 2. wrong number of arguments. Failed to route event via endpoint: org.mule.module.cxf.CxfOutboundMessageProcessor. Message payload is of
> type: String (org.mule.api.transport.DispatchException)
> org.mule.module.cxf.CxfOutboundMessageProcessor:150
> (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transport/DispatchException.html)
> -------------------------------------------------------------------------------- Root Exception stack trace: java.lang.IllegalArgumentException: wrong
> number of arguments at
> sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
> sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
> + 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
As you can see the soap request can be seen but it is not consumed at the level of the CXF component. Here is my mule code:
<flow name="SoapService" doc:name="SoapService">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8082" path="test/cap.asmx" doc:name="HTTP"/>
<byte-array-to-string-transformer doc:name="Byte Array to String"/>
<logger message="message transformation #[message.payload]" level="INFO" doc:name="Logger"/>
<flow-ref name="RequestResponse" doc:name="Flow Reference"/>
<logger level="INFO" doc:name="Logger" message="after posting #[message.payload]"/>
<mulexml:object-to-xml-transformer doc:name="Object to XML"/>
</flow>
<flow name="RequestResponse" doc:name="RequestResponse">
<cxf:jaxws-client operation="ResolveIP" clientClass="pck.IP2Geo" port="IP2GeoSoap" wsdlLocation="file:/C:/Users/12204-hajjam1/workspace/ipgo/src/ipgeo.wsdl" doc:name="soap 2"/>
<logger message="before posting #[message.payload]" level="INFO" doc:name="Logger"/>
<http:outbound-endpoint exchange-pattern="request-response" method="POST" address="http://localhost:10387/ip2geo/ip2geo.asmx" doc:name="HTTP"/>
</flow>
Also if I add a set payload with the ip #[{'173.194.36.39',''}] (the second argument can be left empty) before the cxf component it returns a an empty element. Yet, the response should be something like this:
<pck.IPInformation>
<city>Mountain View</city>
<stateProvince>CA</stateProvince>
<country>United States</country>
<organization/>
<latitude>37.4192</latitude>
<longitude>-122.0574</longitude>
<areaCode>0</areaCode>
<timeZone/>
<hasDaylightSavings>false</hasDaylightSavings>
<certainty>90</certainty>
<regionName/>
<countryCode>US</countryCode>
</pck.IPInformation>
Thus, my problem is with the consumption and retrieval of the response.
I apologize for the length but I have been struggling with this and haven't found a solution online. Thanks in advance.

You should create an instance of the message class that as been generated for the ResolveIP method from the WSDL and use it as the message payload before the cxf:jaxws-client element.

Related

Mule Facebook Null Payload

Asked to evaluate buying Mulesoft - and produce demo that connects to facebook. Am following the two samples here:
https://github.com/mulesoft/facebook-connector/blob/master/doc/sample.md
and
http://blogs.mulesoft.com/mule-school-integration-with-social-media-part-ii-%E2%80%93-facebook/
Ran into a problem with the first sample - it wouldn't compile because the endpoint for the http connector was the same as the facebook connector. I did some research and made some changes, but I now get the error below and can't find anyone else that experienced the same:
Unable to fetch access token. Message payload is of type: NullPayload - this is on the callback page. Has anyone experienced this?
Here is my code:
<http:listener-config name="HTTP_Listener_Configuration" host="localhost" port="8099" doc:name="HTTP Listener Configuration"/>
<facebook:config-with-oauth name="Facebook-config" consumerKey="..." consumerSecret="..." scope="user_photos" doc:name="Facebook">
<facebook:oauth-callback-config domain="localhost" localPort="8099" remotePort="8099" path="callback"/>
</facebook:config-with-oauth>
<http:listener-config name="HTTP_Listener_Configuration1" host="localhost" port="8094" doc:name="HTTP Listener Configuration"/>
<flow name="Authorize">
<http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP"/>
<facebook:authorize config-ref="Facebook-config" doc:name="Facebook"/>
<set-session-variable variableName="accessTokenID" value="#[flowVars['OAuthAccessTokenId']]" doc:name="Save Access Token"/>
<flow-ref name="PhotoDownload" doc:name="Call Photo Download"/>
</flow>
<flow name="PhotoDownload">
<http:listener config-ref="HTTP_Listener_Configuration1" path="/" doc:name="HTTP"/>
<not-filter doc:name="Not">
<wildcard-filter pattern="/favicon.ico" caseSensitive="false"/>
</not-filter>
<facebook:get-user-picture config-ref="Facebook-config" user="me" accessTokenId="#[sessionVars['accessTokenId']]" doc:name="Get Profile Picture"/>
<file:outbound-endpoint path="c:\temp" outputPattern="profilepic.jpg" responseTimeout="10000" doc:name="Save The Picture "/>
<json:object-to-json-transformer doc:name="Object to JSON"/>
</flow>
Here is the stack trace:
ERROR 2015-06-10 13:47:07,731 [[internalfacebook].HTTP_Listener_Configuration.worker.01] org mule exception DefaultMessagingExceptionStrategy:
********************************************************************************
Message : Unable to fetch access token. Message payload is of type: NullPayload
Code : MULE_ERROR--2
--------------------------------------------------------------------------------
Exception stack is:
1. unable to find valid certification path to requested target (sun.security.provider.certpath.SunCertPathBuilderException)
sun.security.provider.certpath SunCertPathBuilder:-1 (null)
2. PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target (sun.security.validator ValidatorException)
sun.security.validator PKIXValidator:-1 (null)
3. sun.security.validator ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target (javax net ssl SSLHandshakeException)
sun security ssl Alerts:-1 ( java.sun com/j2ee/sdk_1.3/techdocs/api/javax/net/ssl/SSLHandshakeException html)
4. Error found while consuming http resource at https(colonslashslash) graph facebook com/oauth/access_token (java.lang.RuntimeException)
org.mule security oauth util HttpUtilImpl:93 (null)
5. Unable to fetch access token. Message payload is of type: NullPayload (org mule api MessagingException)
org.mule.security.oauth.processor.OAuth2FetchAccessTokenMessageProcessor:95 ( wwwmulesoftrog docs site current3 apidocs org mule api MessagingException html)
--------------------------------------------------------------------------------
Root Exception stack trace:
sun.security.provider certpath SunCertPathBuilderException: unable to find valid certification path to requested target
at sun security provider certpath SunCertPathBuilder engineBuild(Unknown Source)
at java.security cert CertPathBuilder build(Unknown Source)
at sun.security validator PKIXValidator doBuild(Unknown Source)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
INFO 2015-06-10 13:47:08,183 [[internalfacebook].HTTP_Listener_Configuration.worker.01] org mule module http internal listener HttpListenerRegistry: No listener found for request: (GET)/favicon ico
INFO 2015-06-10 13:47:08,184 [[internalfacebook].HTTP_Listener_Configuration.worker.01] org mule module http internal listener HttpListenerRegistry: Available listeners are: [(*)/callback/, (*)/]
Couple things might help. First off, make sure your FB App and Mule FB Config match on the "scope" Ex. "email,public_profile,user_friends".
Also, I solved part of this issue by creating a global HTTP element as the callback. The callback HTTP path needs to be "/*". Then in the Authorization FB component under the OAuth tab, I put the callback HTTP name as the HTTP Connector Reference.
<facebook:oauth-callback-config domain="localhost"
localPort="5000" remotePort="5000" connector-ref="callback"></facebook:oauth-callback-config>
</facebook:config-with-oauth>
<http:listener-config name="callback" host="0.0.0.0"
port="5000" basePath="/*" doc:name="HTTP Listener Configuration" />

Mule ESB 3.4.0CE Sending message to multiple outbound endpoints that are added/removed dynamically

I am working on a part of a Mule ESB application and the issue I am having is very analogous to a chat room.
The chat room (server, Mule ESB) can listen for many chatters (clients, external applications) and when a single chatter (c1) inputs a message, the server echos it to all the other chatters, except for c1. In my case though, I would need to also echo it to c1.
I am having a hard time wrapping my mind around some detailed aspects of how the message processing works in Mule ESB. I read the documentation about transports and believe I may need to work with Message Receivers and Message Dispatchers.
Consider the following configuration:
<mule ...>
<tcp:connector name="tcpConn" doc:name="TCP connector" clientSoTimeout="0" keepAlive="true" keepSendSocketOpen="true" receiveBacklog="0" receiveBufferSize="0" reuseAddress="true" sendBufferSize="0" serverSoTimeout="0" socketSoLinger="0" validateConnections="true">
<reconnect-forever />
<tcp:direct-protocol payloadOnly="true"/>
</tcp:connector>
</spring:beans>
<tcp:endpoint exchange-pattern="request-response" host="localhost" port="8090" name="ListenEndpoint" responseTimeout="10000" doc:name="TCP"/>
<flow name="ChatroomExampleFlow1" doc:name="ChatroomExampleFlow1">
<tcp:inbound-endpoint exchange-pattern="request-response" ref="ListenEndpoint" responseTimeout="10000" doc:name="Client Message"/>
<logger level="INFO" doc:name="Logger"/>
<all doc:name="All">
<tcp:outbound-endpoint host="${client1.host}" port="${client1.port}" responseTimeout="10000" doc:name="TCP"/>
<tcp:outbound-endpoint host="${client2.host}" port="${client2.port}" responseTimeout="10000" doc:name="TCP"/>
<tcp:outbound-endpoint host="${client3.host}" port="${client3.port}" responseTimeout="10000" doc:name="TCP"/>
</all>
</flow>
</mule>
If I know at configuration time the host and port of all clients, then this configuration holds. However, my goal is to be able to send out the messages to clients that have established a connection, which could be up to n clients. As more clients connect/disconnect, I would need to add or remove them from the list.
There exists a <recipient-list expression="#[app.registry.remoteEndpoints]"/> where the expression should evaluate to a List of endpoints and the flow will send the message to every endpoint in the collection. However, for my purposes this does not work (see answer below). See the documentation for recipient list
<mule ...>
<tcp:connector name="tcpConn" doc:name="TCP connector" clientSoTimeout="0" keepAlive="true" keepSendSocketOpen="true" receiveBacklog="0" receiveBufferSize="0" reuseAddress="true" sendBufferSize="0" serverSoTimeout="0" socketSoLinger="0" validateConnections="true">
<reconnect-forever />
<tcp:direct-protocol payloadOnly="true"/>
</tcp:connector>
<spring:beans>
<spring:bean name="remoteEndpoints" scope="singleton" class="java.util.ArrayList"/>
</spring:beans>
<tcp:endpoint host="localhost" exchange-pattern="one-way" port="8090" name="ListenEndpoint" responseTimeout="10000" doc:name="TCP"/>
<flow name="ChatroomExampleFlow1" doc:name="ChatroomExampleFlow1">
<tcp:inbound-endpoint ref="ListenEndpoint" responseTimeout="10000" doc:name="Client Message"/>
<echo-component doc:name="Echo"/>
<component class="EndpointStorer" doc:name="Java"/>
<recipient-list expression="#[app.registry.remoteEndpoints]"/>
</flow>
</mule>
And with EndpointStorer looking like this:
public Object onCall(MuleEventContext eventContext) throws Exception
{
Registry registry = eventContext.getMuleContext().getRegistry();
MuleMessage message = eventContext.getMessage();
ArrayList arrList = (ArrayList) registry.get("remoteEndpoints");
Object remoteAddress = message.getOutboundProperty("MULE_REMOTE_CLIENT_ADDRESS");
String tcpAddr = "tcp://" + remoteAddress.toString().substring(1); //substring 1 because we see the remote client address as something like /127.0.0.1:4943
if (!arrList.contains(tcpAddr))
{
arrList.add(tcpAddr);
}
return message;
}
You can't reach established inbound TCP connections, at least not using TCP outbound endpoints. It may be possible to extend the TCP connector to expose the Socket in http://github.com/mulesoft/mule/blob/mule-3.x/transports/tcp/src/main/… but it's no small feat.
You could consider using the AJAX transport.

How to forward SOAP request through ACTIVE MQ JMS to my Services with the support of MULE

We have produced JAX-WS web-services with the help of Java API and published. Now we would like to queuing the requests, which are coming for the services with the help of JMS. We chosen the ACTIVE MQ JMS Server with the combination of MULE ESB.
We have tried the proxying of webservices with the help of two Http Endpoints. It is working fine. So When i trying to test it by sending request from SOAP UI to Http inbound end point, it is forwarding request to my services and get back the response to SOAP UI.
But when we are trying to put the JMS endpoint in between these Http end points, the request is forwarded to my services, but not the message (SOAP).
Please help me to resolve the issue or suggest me the alternative way for Queuing.
Following image shows flow in MULE.
.
Following is the flow :
<jms:activemq-connector name="Active_MQ1" brokerURL="tcp://localhost:61616" validateConnections="true" doc:name="Active MQ"/>
<flow name="finalFlow1" doc:name="finalFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8888" contentType="text/xml" doc:name="HTTP"/>
<jms:outbound-endpoint exchange-pattern="request-response" queue="servicesQueue" connector-ref="Active_MQ1" doc:name="JMS"/>
<http:outbound-endpoint mimeType="text/xml" doc:name="HTTP" exchange-pattern="request-response" method="POST" path="MyServices" host="localhost" port="5050" />
</flow>
Actually MyServices is produced at http://localhost:5050/MyServices
The problem is probably due to that you are expecting a string payload in your JMS queue and the http:inbound-endpoint produces a stream payload.
Try putting <object-to-string-transformer/> before the jms:outbound-endpoint.

Mule ESB How to dump POST payload to a file

I am getting started with Mule ESB. I am trying to build a SOAP proxy service that receives a SOAP request and redirects it to a SOAP service.
A simple example like this works fine -
<flow name="http_redirectFlow1" doc:name="http_redirectFlow1">
<http:inbound-endpoint exchange-pattern="request-response" address="http://localhost:8092/HelloProxyService" doc:name="HTTP"/>
<http:outbound-endpoint exchange-pattern="request-response" method="POST" address="http://localhost:8080/soapsvc/hello" contentType="text/xml" doc:name="HTTP"/>
</flow>
Now I want to dump the contents of the request to a file. Which is the best way to do it? I tried to use the File connector by inserting this segment between the inbound and outbound endpoints -
<file:outbound-endpoint path="c:/temp" outputPattern="temp.txt" responseTimeout="10000" doc:name="File"/>
But that doesn't seem to work. I get an exception that says "Content must be set before entity is written". Not sure what it is, but I may be completely wrong in how I am doing. Please help....
Figured it out myself. I had to translate the DOM to XML using the dom-to-xml transformer. The XML dump is done as follows :-
<mulexml:dom-to-xml-transformer returnClass="java.lang.String"></mulexml:dom-to-xml-transformer>
<file:outbound-endpoint path="c:/temp" outputPattern="Dump_Rcvd.txt" responseTimeout="10000" doc:name="File" />
Thanks !
Alternately you can use <object-to-string-transformer doc:name="Object to String"/> before file:outbound-endpoint that will make the payload as a String format and can be written into a file easily
Use File Connector and Transformers involving Bytearray.

How to transform javax.mail.internet.MimeMessage to java.io.InputStream in Mule

I tried to read a file and email through Mule. But it throws the following exception.
org.mule.api.transformer.TransformerException: Could not find a transformer to transform "SimpleDataType{type=javax.mail.internet.MimeMessage, mimeType='*/*'}" to "SimpleDataType{type=java.io.InputStream, mimeType='*/*'}".
at org.mule.registry.MuleRegistryHelper.lookupTransformer(MuleRegistryHelper.java:252)
at org.mule.DefaultMuleMessage.getPayload(DefaultMuleMessage.java:355)
at org.mule.DefaultMuleMessage.getPayload(DefaultMuleMessage.java:313)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
My mule file is as follows:
<flow name="Exception_HandlingFlow1" doc:name="Exception_HandlingFlow1">
<file:inbound-endpoint path="D:\WorkArea\COPA\In" responseTimeout="10000" doc:name="File Writer">
<file:file-to-string-transformer/>
</file:inbound-endpoint>
<component doc:name="Java" class="com.exhnlr.Handler.ExceptionHandler"/>
<smtps:outbound-endpoint host="192.168.131.139" responseTimeout="10000" doc:name="SMTP"
from="anbu1#bibs.com" subject="test" to="anbu1#bibs.com" user="anbu1" mimeType="text/plain">
<email:string-to-email-transformer/>
</smtps:outbound-endpoint>
</flow>
I have read a similiar link How to parse inbound e-mail when using Mule's IMAP transport?, but it didn't work for me.
Please help.
Add an <object-to-string-transformer /> after the file inbound endpoint.