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.
Related
Here is my Flow information. Trying to GET one issue from JIRA and want to setup that issueID to another project. Here i want to use Custom Transformer and setup all objects using JAVA coding.
<jira:config name="Jira" connectionUser="XXXXXXX" connectionPassword="XXXXX" connectionAddress="http://XXXXXXX/rpc/soap/jirasoapservice-v2" doc:name="Jira">
<jira:connection-pooling-profile initialisationPolicy="INITIALISE_ONE" exhaustedAction="WHEN_EXHAUSTED_GROW"/>
<reconnect count="3"/>
</jira:config>
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration"/>
<flow name="jira-pocFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/input" doc:name="HTTP"/>
<jira:get-issues-from-jql-search config-ref="Jira" jqlSearch="id=MRT-75" maxNumResults="100" doc:name="Jira"/>
<set-variable variableName="payload" value="#[payload[0]]" doc:name="Variable"/>
<component class="JIRATransformer" doc:name="Java"/>
<jira:create-issue-using-object config-ref="Jira" doc:name="Jira" >
<jira:issue ref="#[message.payload]"/>
</jira:create-issue-using-object>
<logger level="INFO" doc:name="Logger"/>
</flow>
I am trying to access JIRA payload object but it's throwing me Error as Type Cast Exception.
#Override
public Object transformMessage(MuleMessage message, String outputEncoding)
throws org.mule.api.transformer.TransformerException {
ArrayList<com.atlassian.jira.rpc.soap.beans.RemoteIssue> list = new ArrayList(Arrays.asList(message.getPayload()));
for(RemoteIssue q : (List<RemoteIssue>) list){
System.out.println("Print AssigneeInfo:->"+q.getAssignee());
}
}
I am getting following Errors.
ERROR 2015-04-15 19:58:59,526 [[jira-poc].HTTP_Listener_Configuration.worker.01] org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : Component that caused exception is: DefaultJavaComponent{jira-pocFlow.component.887693985}. Message payload is of type: Arrays$ArrayList
Code : MULE_ERROR--2
--------------------------------------------------------------------------------
Exception stack is:
1. java.util.Arrays$ArrayList cannot be cast to com.atlassian.jira.rpc.soap.beans.RemoteIssue (java.lang.ClassCastException)
JIRATransformer:29 (null)
2. Component that caused exception is: DefaultJavaComponent{jira-pocFlow.component.887693985}. Message payload is of type: Arrays$ArrayList (org.mule.component.ComponentException)
org.mule.component.DefaultComponentLifecycleAdapter:348 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/component/ComponentException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
java.lang.ClassCastException: java.util.Arrays$ArrayList cannot be cast to com.atlassian.jira.rpc.soap.beans.RemoteIssue
at JIRATransformer.transformMessage(JIRATransformer.java:29)
at org.mule.transformer.AbstractMessageTransformer.transform(AbstractMessageTransformer.java:141)
at org.mule.transformer.AbstractMessageTransformer.transform(AbstractMessageTransformer.java:69)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
I tried to follow this Documentation URL but couldn't able to figure it out.
http://mulesoft.github.io/jira-connector/java/com/atlassian/jira/rpc/soap/beans/RemoteIssue.html
I want to Access this Payload and want to update some details from payload object here. I can access payload using MEL expression #[payload[0]] and it automatically coverts it to com.atlassian.jira.rpc.soap.beans.RemoteIssue but using Java code i am not able to type cast it.
Can you please help me to cast this object correctly so i can access the Payload here ?
Thanks.
There's a bug in your component.
This Arrays.asList(message.getPayload()) wraps the message payload into a list. But the message payload is already a List<RemoteIssues> so this wrapping is unnecessary.
If you look at the source code of the JIRA connector, you'll see that MuleSoft prefers late casting of the RemoteIssue. I suggest you do the same:
for (Object o : ((List) message.getPayload())) {
RemoteIssue ri = (RemoteIssue) o;
...
}
I building Mule project who receive JSON by HTTPComponent and convet to object.
My problem is can't acess field in object converted.
My flux's XML is:
<flow name="RestJsonHelloWorldFlow1" doc:name="RestJsonHelloWorldFlow1"><http:inbound-endpointexchange-pattern="request-response"
host="localhost" port="8081"
path="credit/new" doc:name="HTTP"
mimeType="application/json"/> <response>
<logger message=" #[message.payload.transactionCode]" level="INFO" doc:name="Logger"/>
</response>
<json:json-to-object-transformer doc:name="JSON to Object" returnClass="com.creditmobile.domain.Request" name="request"/></flow>
My pojo is:
#JsonAutoDetect
public class Request {
private Integer transactionCode;
public Request() {
super();
}
public Integer getTransactionCode() {
return transactionCode;
}
My JSON is:
{
"transactionCode": 1
}
I got following exception:
org.mule.api.transformer.TransformerMessagingException: The object transformed is of type: "SimpleDataType{type=java.lang.String, mimeType='*/*'}", but the expected return type is "SimpleDataType{type=org.mule.api.transport.OutputHandler, mimeType='application/json'}". The current MuleMessage is null! Please report this to dev#mule.codehaus.org
at org.mule.transformer.AbstractMessageTransformer.checkReturnClass(AbstractMessageTransformer.java:183)
at org.mule.transformer.AbstractMessageTransformer.transform(AbstractMessageTransformer.java:162)
at org.mule.transformer.AbstractMessageTransformer.transform(AbstractMessageTransformer.java:73)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
I saw anothers topics with same problem, but they don't have resolution and yours suggesttion doesn't work for me.
I access field with:[message.payload.transactionCode]
Thanks.
I think your problem is in the http response phase, not in accessing the field. Mule gets confused when you try to return your Java object as an http response. Depending on your requirements, try setting the return payload to something more understandable in the response phase. For example
<set-payload value="#[payload.transactionCode.toString()]"/>
or
<json:object-to-json-transformer/>
What do you actually want to return to the user once the application exits RestJsonHelloWorldFlow1 flow?
I think as Anton Kupias said your problem is the tag. I managed to solve the exception by removing the tag, and convert the payload into an object exactly after the HTTP inbound endpoint.
Config XML
<flow name="RestJsonHelloWorldFlow1" doc:name="RestJsonHelloWorldFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" path="credit/new"
doc:name="HTTP" mimeType="application/json" />
<json:json-to-object-transformer
doc:name="JSON to Object" returnClass="com.creditmobile.domain.Request" />
<component class="com.creditmobile.domain.TransactionResponse" doc:name="Java"/>
<object-to-string-transformer doc:name="Object to String"/>
</flow>
basically you have
1) An HTTP inbound endpoint which is set to request-response
2) immediately convert the JSON to Object
3) Then I have created a java component to perform the required processing; by creating a class which implements org.mule.api.lifecycle.Callable. Got the transaction code from the payload and set the overridden method to return an object of type string
public class TransactionResponse implements Callable {
#Override
public Object onCall(MuleEventContext eventContext) throws Exception {
// Type casts payload to object Request
Request requestObject = (Request) eventContext.getMessage().getPayload();
int code = Integer.valueOf(requestObject.getTransactionCode());
String reply = "";
switch (code) {
case 1:
reply = "New";
break;
case 2:
reply = "Delete";
break;
}
return reply;
}
}
4) Then i terminated the flow by adding the Object to String component, Or place the Object to JSON component if you wish to return a JSON object to the user.
I have a main flow which begins with a http endpoint then a soap component which implements the interface and after a java component 1 that implements this interface. Now, I want to add a flow ref and after it a java component 2 that implements the same interface. I get the problem of "could not find entry point"
I am now following this tutorial blogs.mulesoft.org/mule-school-invoking-component-methods-using-entry-point-resolvers/
Given below is my flow.
<flow name="CreateAccountFlow1" doc:name="CreateAccountFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081"
doc:name="HTTP" path="bank"/>
<cxf:jaxws-service doc:name="SOAP" serviceClass="com.essai2.AccountService"/>
<component class="com.essai2.AccountRequest" doc:name="Java"/>
<logger level="INFO" doc:name="Logger"/>
<flow-ref name="Projet2Flow1" doc:name="Flow Reference"/>
<component class="com.essai2.AccountResponse" doc:name="Java"/>
<logger level="INFO" doc:name="Logger"/>
</flow>
Can anyone help me?
In mule there are many ways to invoke a Java component.
1. Entry point resolver
2. Implemnt mule Life Cycle API i.e callable
3. Invoke component.
when ever Mule finds Java component as message processors in a flow, tries to execute above three methods .
In the java component if you have created any methods with param same as mule message payload , Entry Point resolver is used.
eg : class XYZ{
method1(String s1){
}
method2(List<String> S2){
}
}
If Mule Message Payload has type String then method1 is invoked, if message payload has List of String , method2 is invoked during run time.
2. If you can invoke the Java component in the flow irrespective of type of the payload, should implement Callable interface which overrides onCall() method.
for eg : class XYS implements Callable{
#override
onCall(MuleEventConext muleEventConext){
}
using MuleEvent Conext you can extract the payload and process it.
3. Using Invoke component, you can create the object of the Class and invoke explicitly the method with appropriate Parameters passed.
I was trying to develop a Functional Test case for my mule configuration. Here is the code:
protected String getConfigResources() {
// TODO Auto-generated method stub
return "src/test/resources/employee-get-functionalTestCase-config.xml";
}
#Test
public void testMessage() throws Exception {
MuleClient client = muleContext.getClient();
client.dispatch("vm://in", "70009", null);
MuleMessage result = client.request("vm://out", 60000);
Assert.assertNotNull("Response payload was null", result);
Assert.assertNull(result.getExceptionPayload());
Assert.assertFalse(result.getPayload() instanceof NullPayload);
& here is the context of my XMl file:
<spring:beans>
<context:property-placeholder location="classpath:mule-app.properties"/>
</spring:beans>
<flow name="testFlow">
<vm:inbound-endpoint path="in"/>
<logger message="in functional-test-config.xml (v4)" level="INFO" doc:name="Logger"/>
<set-payload value="70010" doc:name="Use fixed employeeId 70010"/>
<vm:outbound-endpoint exchange-pattern="request-response" path="employee-profile-get" doc:name="VM"/>
<logger message="after employee-profile-get; payload: #[payload]" level="INFO" doc:name="Logger"/>
<vm:outbound-endpoint path="out"/>
</flow>
However when I execute this code, I get the following error:
org.mule.api.transport.NoReceiverForEndpointException: There is no receiver registered on connector "connector.VM.mule.default" for endpointUri vm://employee-profile-get
Where do I register the vm endpoint?
You must have an inbound endpoint for every exchange-pattern="request-response" vm endpoint .
When the application is run in your mule studio you may not get any error(at compile time ) but when the message is passed through the flow you will get an error of the above mentioned sort .
This is because VM is an in-memory queue ,where once you put a message, there should be a receiver to pick the message thus when not there this error pops and it is only for the exchange-pattern="request-response" because the flow from where you put the message(outbound endpoint with request-response) will wait for a response from the vm endpoint "employee-profile-get" .
To depict the same error replace the with a localhost http endpoint and try invoking the http endpoint .
To avoid this create another flow with inbound endpoint as vm with path="employee-profile-get" and return a string using set payload component .Then your test case would work.
Regards,
Naveen Raj
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) {