No such operation: HTTP GET PATH_INFO: /services/EchoUMO - error-handling

I downloaded the echo sample for mule from internet. I have 1 java class
package org.mule.example.echo;
public class Echo
{
public Echo()
{
}
public String echo(String string)
{
return string;
}
}
And an xml file
<?xml version="1.0" encoding="UTF-8"?>
<mule>
<flow name="EchoFlow">
<inbound-endpoint address=":65082/services/EchoUMO" exchange-pattern="request-response"/>
<cxf:jaxws-service serviceClass="org.mule.example.echo.Echo"/>
<component>
<singleton-object class="org.mule.example.echo.Echo" />
</component>
</flow>
</mule>
When I write :65082/services/EchoUMO in my browser I don't get any good result. In my console i see this error:
WARN 2013-03-04 12:08:10,713 [[sample-echo].connector.http.mule.default.receiver.02] org.apache.cxf.phase.PhaseInterceptorChain: Interceptor for {http://echo.example.mule.org/}EchoService has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: No such operation: (HTTP GET PATH_INFO: /services/EchoUMO)
at org.apache.cxf.interceptor.URIMappingInterceptor.handleMessage(URIMappingInterceptor.java:88)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:123)
Can you explain what is going on for me?
When I write :65082/services/EchoUMO in my browser, my browser shows this page:
<soap:Envelope>
<soap:Body><soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>No such operation: (HTTP GET PATH_INFO: /services/EchoUMO)</faultstring>
</soap:Fault></soap:Body>
</soap:Envelope>

Your class does not use JAX-WS annotation therefor you get the error.
You have 2 choices:
Keep the current class and use simple service, i.e <cxf:simple-service serviceClass="org.mule.example.echo.Echo"/>
Add JAX-WS annotation to your POJO as explained here

Related

Mule XML Streaming - (Mule xmltoxmltransformation)

Trying to use the Mule XML streaming feature as have to process very large xml files. Followed the documentation, the document does not have concrete examples.
When I inspected the payload I get the XMLUtils class and not the XMLStreamReader class as stated in the documentation.
The flow is as follows have a file connector which passes payload to a custom transformer, the transformer passes the data to a spring bean which is going to have event based processing.
In the spring bean. At run time the spring bean gets the XMLUtils class and not the XMLStreamReader class.
Mule - Config:
<spring:beans>
<spring:bean id="OracleCDMMapper" class="oraclecdmstream.OracleCDMMapper">
</spring:bean>
<spring:bean id = "OraclePaySlip" class="com.nect.transform.OracleCDMPaySlip" ></spring:bean>
</spring:beans>
<flow name="mulefileconnectorexampleFlow1" >
<file:inbound-endpoint path="C:/c-OracleCloud/src/main/resources" pollingFrequency="600000" moveToDirectory="C:/c-OracleCloud/src/main/resources/back" doc:name="File Input" >
<!-- <file:filename-regex-filter pattern="(^*.xml$)" caseSensitive="false"/>
--> <file:filename-wildcard-filter pattern="*.xml"></file:filename-wildcard-filter>
</file:inbound-endpoint>
<logger message="Transferring file : #[message.inboundProperties['originalFilename']]" level="INFO" doc:name="Logger"/>
<logger message ="Logger 1 " level="INFO" doc:name ="Logger1" />
<!-- Call the XMLSTREAMER -->
**<custom-transformer name="XmlToXSR" class="org.mule.module.xml.transformer.XmlToXMLStreamReader" doc:name="XMLTOORACLE">**
</custom-transformer>
<component doc:name="Java">
<spring-object bean="OracleCDMMapper"/>
</component>
-->
<logger message ="I am Complete " level="INFO" doc:name ="LoggerMurali" />
</flow>
</mule>
Here is the Javacode:
Spring Bean
public class OracleCDMMapper implements Callable {
private final Logger logger = LoggerFactory.getLogger(OracleCDMMapper.class);
#Override
public Object onCall(MuleEventContext eventContext) throws Exception {
// TODO Auto-generated method stub
MuleMessage muleMessage = eventContext.getMessage();
logger.info("In the Spring Component");
logger.info(muleMessage.getPayload().getClass().toString());
**javax.xml.stream.XMLStreamReader xsr = (XMLStreamReader) muleMessage.getPayload(javax.xml.stream.XMLStreamReader.class);**
Any help will be much appreciated
I've verified and you are right, in the code the supposed returning class should be a DelegateXMLStreamReader class that implements XMLStreamReader, but the returned class is an anonymous inner class of XMLUtils that at runtime cannot be casted to any Stream like class. It seems to be a defect.
If you really need the control of the xml stream, you could use a custom java component:
<component class="com.foo.CustomJavaComponent" doc:name="Java"/>
.
public class CustomJavaComponent implements Callable{
#Override
public Object onCall(MuleEventContext eventContext) throws Exception {
MuleMessage muleMessage = eventContext.getMessage();
FileInputStream fis = (FileInputStream)muleMessage.getPayload();
//Do something with this stream
return "Hello world";
}
}
And get the input stream to do whatever you want.

Facing issue in mule testing

I am facing problem with mule testing. I just tries out simple functional testing example.
following is my flow
<flow name="muletestFlow1" doc:name="muletestFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" path="test" doc:name="HTTP"/>
<response>
<object-to-string-transformer />
</response>
<component class="com.org.Square" doc:name="Square"/>
<component class="com.org.Neg doc:name="Neg"/>
</flow>
and following is my testing class
#Test
public void testSquareAddInverse() throws Exception {
MuleClient client = muleContext.getClient();
MuleMessage reply = client.send ("http://localhost:8081/test", "3", null, 5000);
assertNotNull(reply);
assertNotNull(reply.getPayload());
assertTrue(reply.getPayload() instanceof String);
String result = (String)reply.getPayload();
assertEquals("-9", result);
If i run above class as junit test then got following error.
java.lang.AssertionError
at org.junit.Assert.fail(Assert.java:92)
at org.junit.Assert.assertTrue(Assert.java:43)
at org.junit.Assert.assertTrue(Assert.java:54)
at com.test.TestEx.testSquareAddInverse(TestEx.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:622)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:46)
at org.junit.internal.runners.statements.FailOnTimeout$1.run(FailOnTimeout.java:28)
What is the solution please help me.
If i comment this line
assertTrue(reply.getPayload() instanceof String);
then got following error.
java.lang.ClassCastException: org.mule.transport.http.ReleasingInputStream cannot be cast to java.lang.String
What is the wrong in this code? How can i solve this problem. please help me
Thanks in advance
Since you call the flow through http protocol, which implicitly transforms the payload type. So the reply in the unit test will not contain a String but a InputStream. This is expected so you should test for a InputStream instead of a String. To get the value as a String you can use the method MuleMessage#getPayload(java.lang.Class) that will transform the payload to a String using the registered transformers.
#Test
public void testGetNegaiveNine() throws Exception {
MuleClient client = muleContext.getClient();
MuleMessage reply = client.send ("http://localhost:8081/test", "3", null, 5000);
assertNotNull(reply);
assertNotNull(reply.getPayload());
assertTrue(reply.getPayload() instanceof InputStream);
String result = reply.getPayload(String.class);
assertEquals("-9", result);
}
The exception you get in the flow
after that.
"DefaultJavaComponent{muletestFlow1.component.3418143}. Message payload is of type: ContentLengthInputStream"
is because the components can not handle the payload that the message inside your flow has. Since you are sending a HTTP POST into the flow the payload of the incoming message is a ContenLengthInputStream and you components expects a String.
So you will have to transform the payload into a String by adding a object-to-string transformer before the components. The complete flow would then be something like this.
<flow name="muletestFlow1" doc:name="muletestFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" path="test" doc:name="HTTP"/>
<response>
<!-- Ensure that the response is a String -->
<object-to-string-transformer />
</response>
<!-- Ensure that the incoming request is a String -->
<object-to-string-transformer />
<component class="com.org.Square" doc:name="Square"/>
<component class="com.org.Neg doc:name="Neg"/>
</flow>

Accessing the MuleMessage in soap based web service

In a soap based web service i want to access the Mule message properties. Is there a way of doing this i know one way of using RequestContext.getEvent().getMessage() but this i guess is deprecated. An other way of accessing the MuleMessage properties in the web service. Can someone please provide any pointers on this.
Code Snippet
<flow name="MyWebService" doc:name="MyWebService">
<http:inbound-endpoint exchange-pattern="request-response" address="${WEB_SERVICE_PROTOCOL}://${WEB_SERVICE_HOST}:${WEB_SERVICE_PORT}/MyWebService?wsdl" tracking:enable-default-events="true">
<cxf:jaxws-service serviceClass="com.XXX.XXX.service.MyWebService" doc:name="SOAP"/>
</http:inbound-endpoint>
<component doc:name="My Web Service">
<spring-object bean="WebServiceImpl"/>
</component>
</flow>
Depending on what is your purpose for obtaining the message properties, one option is to use a cxf interceptor to access the message. See the following example.
adding the interceptor:
<cxf:jaxws-service serviceClass="org.example.HelloWorld">
<cxf:inInterceptors>
<spring:bean class="org.example.MyInterceptor"/>
</cxf:inInterceptors>
</cxf:jaxws-service>
interceptor class:
package org.example;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.Phase;
import org.mule.api.MuleEvent;
import org.mule.api.MuleMessage;
public class MyInterceptor extends AbstractSoapInterceptor {
public MyInterceptor() {
super(Phase.USER_PROTOCOL);
}
#Override
public void handleMessage(SoapMessage message) throws Fault {
MuleEvent muleEvent = (MuleEvent)message.getContextualProperty("mule.event");
MuleMessage muleMessage = muleEvent.getMessage();
System.out.println(muleMessage.toString());
}
}
You can achieve this by not implementing the service interface at all and deal with the SOAP requests as Mule messages (where properties are accessible) instead of dealing with deserialized objects in service classes.
Here is an example fragment, assuming you've generated the necessary classes and interfaces from the WSDL with wsdl2java:
<flow name="WebServiceFlow">
<http:inbound-endpoint exchange-pattern="request-response"
address="http://localhost:8080/services/some" />
<cxf:jaxws-service
serviceClass="com.amce.SomePortType" />
<choice>
<when
expression="#[cxf_operation.localPart == 'SomeOperation']">
<flow-ref name="HandleSomeOperation" />
</when>
If you have access to MuleMessage then you get the required properties by using the method
Set<String> getPropertyNames(PropertyScope scope);
available in MuleMessage class. To get the MuleMessage you would need access to MuleClient; have you got access to MuleClient? if yes, then use:
muleClient = muleContext.getClient();
MuleMessage result = muleClient.send(webaddress, "", props);
Is this what you are trying to acheive?

Null exception thrown when running mule, when a devkit 3.0.0 method that takes a #InboundAttachments param

I'm trying to make use of #attachment http properties
I have a devkit method called validate in a flow that is called like so
<http:connector name="httpConnector" doc:name="HTTP\HTTPS">
<service-overrides
messageFactory="org.mule.transport.http.HttpMultipartMuleMessageFactory" />
</http:connector>
<flow name="AttachmentTestFlow1" doc:name="AttachmentTestFlow1">
<http:inbound-endpoint connector-ref="httpConnector" doc:name="HTTP" exchange-pattern="request-response" host="localhost" port="8100"/>
<Foo:validate config-ref="TestMessageSizeHappy" />
</flow>
In Devkit:
#Processor
public Object validate(#Payload InputStream in
,#InboundAttachments("*") Map<String, DataHandler> inboundAttachments
,#OutboundAttachments Map<String, DataHandler> outboundAttachments
) {
however when running my mule application this is thrown:
ERROR 2013-07-30 09:06:39,225 [main]
org.mule.module.launcher.application.DefaultMuleApplication: null
org.xml.sax.SAXParseException: cvc-complex-type.2.4.b: The content of
element 'xmlthreatprotection:validate' is not complete. One of
'{"http://www.mulesoft.org/schema/mule/core":annotations,
"http://www.mulesoft.org/schema/mule/xmlthreatprotection":inbound-attachments}'
is expected. at
org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown
Source)
It seems to me that mule expects the attachments to be put in as an attribute some how !
When I remove the #attachment stuff I get no errors at runtime.
Are you sure this is supported by DevKit? I can not find a single integration test in the source code that exercises #InboundAttachments and #OutboundAttachments annotations, while #InboundHeaders and #OutboundHeaders are both test covered.
Alternatively you can receive the MuleEvent and access the attachments through it:
#Processor
#Inject
public Object validate(#Payload InputStream in, MuleEvent muleEvent) {

XMLStreamReader parser affects MuleEventContext

I'm using Mule Studio (Mule 3.2.1CE) to configure a proxy service which simply calls a remote web service. Everything works fine with calling and getting the proper response (using soapUI). I want to log SOAP message received within the ESB. I'm getting a DepthXMLStreamReader message as expected by the CXF component but I'm facing an odd behavior when I use XMLStreamReader object's next() method. Here is the code I use:
public Object onCall(MuleEventContext context) throws Exception {
MuleMessage message = context.getMessage();
DepthXMLStreamReader streamReader = new DepthXMLStreamReader((XMLStreamReader) message.getPayload());
while(streamReader.hasNext()){
streamReader.next();
if(streamReader.getEventType() == XMLStreamReader.START_ELEMENT)
{
System.out.println(streamReader.getLocalName());
}
}
return context.getMessageAsString();
The above code works and prints XML elements but I get the following error afterwards:
org.apache.cxf.interceptor.Fault: Failed to route event via endpoint: DefaultOutboundEndpoint{endpointUri=..., connector=HttpConnector
...
Caused by: org.mule.transport.http.HttpResponseException: Internal Server Error, code: 500
I tried using StaxUtils.nextEvent and StaxUtils.toNextElement, but no difference in result. I wonder why parsing XML by next() method affects mule context. If I use System.out.println(context.getMessageAsString()); before the return statement it prints "[Messaage could not be converted to string]" but it works before while statement in the above code.
Here is my mule config:
<flow name="wsFlow1" doc:name="wsFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8090" contentType="text/xml" doc:name="HTTP"/>
<cxf:proxy-service bindingId="..." namespace="http://..." service="..." payload="body" wsdlLocation="..." enableMuleSoapHeaders="false" doc:name="SOAP"/>
<component class="mule.ws.SoapLogging" doc:name="Java"/>
<http:outbound-endpoint exchange-pattern="request-response" address="http://..." contentType="text/xml" doc:name="HTTP"/>
</flow>
Thanks
I don't think this is related to MuleEventContext.
The in-flight payload is a XMLStreamReader. You consume this XMLStreamReader in your component then try to return a String representation of it, which is not possible anymore because you've consumed it.
Try the following in your component:
Serialize the XMLStreamReader to a String
Log this String or part thereof
Return this String from the component.