Mule: Remote Dispatcher fails on Deserialization at the Server - java

We have a Mule Service running on a server. I am developing a stand alone Mule Client that connects directly into the Mule service.
When I run the client, I am receiving the below error:
ERROR 2015-09-23 10:36:02,724 [[cheetah-web-services].connector.http.mule.default.receiver.03] org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : Failed to transform from "byte[]" to "Object"
Type : org.mule.api.transformer.TransformerException
Code : MULE_ERROR-109
JavaDoc : http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transformer/TransformerException.html
Transformer : ByteArrayToMuleMessage{this=1574dd9, name='null', ignoreBadInput=false, returnClass=SimpleDataType{type=org.mule.api.MuleMessage, mimeType='*/*'}, sourceTypes=[SimpleDataType{type=[B, mimeType='*/*'}, SimpleDataType{type=java.io.InputStream, mimeType='*/*'}]}
********************************************************************************
Exception stack is:
1. com.mycompany.myapp.service.model.ServiceSearch; class invalid for deserialization (java.io.InvalidClassException)
java.io.ObjectStreamClass$ExceptionInfo:150 (null)
2. java.io.InvalidClassException: com.mycompany.myapp.service.model.ServiceSearch; class invalid for deserialization (org.apache.commons.lang.SerializationException)
org.mule.util.SerializationUtils:85 (null)
3. Failed to transform from "byte[]" to "Object" (org.mule.api.transformer.TransformerException)
org.mule.transformer.simple.ByteArrayToSerializable:54 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transformer/TransformerException.html)
********************************************************************************
Root Exception stack trace:
java.io.InvalidClassException: com.mycompany.myapp.service.model.ServiceSearch; class invalid for deserialization
I have setup a remote dispatcher agent on the server.
<client:remote-dispatcher-agent>
<client:remote-endpoint address="http://localhost:20809" exchange-pattern="request-response" responseTimeout="10000"/>
I have created a separate mule client.
<client:remote-dispatcher-agent>
<client:remote-endpoint ref="remoteDispatcherChannel" />
<client:xml-wire-format/>
</client:remote-dispatcher-agent>
<http:endpoint name="remoteDispatcherChannel"
host="localhost"
port="20809"
path="_remoting"
exchange-pattern="request-response" />
Below is the Client Code. The ServiceSearch object implements all Serializable.
MuleClient muleClient = new MuleClient(true);
RemoteDispatcher dispatcher2 = muleClient.getRemoteDispatcher("http://127.0.0.1:20809/_remoting");
MuleMessage result = dispatcher2.sendToRemoteComponent("myAppServiceDelegate", ServiceSearch, msgMap);
Below is the Mule Service flow on the server I am trying to get into. I am coming in on the invoker step. I choice this step as I could sent the object directly to the service in the required format
<flow name="post:/service/search:my-web-services-config" initialState="started">
<logger level="INFO" doc:name="Log Request Properties" message="Request Type: #[message.inboundProperties.'http.method'], Request Path: #[message.inboundProperties.'http.request.path'], Request Params: #[message.inboundProperties.'http.query.params']" />
<json:json-to-object-transformer returnClass="com.mycompany.myapp.service.model.ServiceSearch" ignoreBadInput="true" mimeType="application/json" doc:name="Request JSON to ServiceSearch" />
<invoke object-ref="myappServiceDelegate" method="processSearch" methodArguments="#[payload],#[flowVars.'CLIENT_ID']" doc:name="Calling Search Delegate" />
<logger message="Generated DSL: #[payload.queryDSL]" level="INFO" doc:name="Log Query DSL" />
<flow-ref name="BigDataSearchFlow" doc:name="Big Data Flow" />
<exception-strategy ref="globalResponseExceptionStrategy" doc:name="Reference Exception Strategy" />
</flow>
I would appreciate some feedback on this approach and suggestions on what I should look for in the ServiceSearch object.
Russ

You are using an order/newer version of com.mycompany.myapp.service.model.ServiceSearch or none at all at the server side.
Please make sure both ends do have the very same version of the file.

Related

Catch error java response from endpoint in Mule

I have an engine set up that validates an xml at a given endpoint.
localhost/rules/my-rule, if the xml file is consistent it returns the xml content. If not however, an exception is thrown:
GeneralException: Combination missmatch
Which is an exception I declared. It's a normal Java Exception.
When I post a faulty file with a tool like postman I get this result:
Can't invoke perform method on "class %rule class%" with request data of
"%data sent to endpoint%"
(reason: ch.package.GeneralException: Combination missmatch). Combination missmatch
Which would be perfect. However upon sending it with mule I get:
Route 0: Caught exception in Exception Strategy: HTTP POST on resource 'http://localhost/rules/my-rule/executions' failed: bad request (400).
Why can't I just get the error message? There isn't more insight when looking at the log:
org.mule.runtime.core.internal.message.ErrorBuilder$ErrorImplementation
{ description=HTTP POST on resource
'http://localhost/rules/my-rule/executions'
failed: bad request (400). detailedDescription=HTTP POST on resource
'http://localhost/rules/my-rule/executions'
failed: bad request (400). errorType=HTTP:BAD_REQUEST
cause=org.mule.extension.http.api.request.validator.ResponseValidatorTypedException
errorMessage=
org.mule.runtime.core.internal.message.DefaultMessageBuilder$MessageImplementation
{
payload=org.mule.runtime.core.internal.streaming.bytes.ManagedCursorStreamProvider#3239ebf7
mediaType=text/plain; charset=UTF-8
attributes=org.mule.extension.http.api.HttpResponseAttributes {
Status Code=400 Reason Phrase= Headers=[
content-type=text/plain
transfer-encoding=chunked
date=Wed, 03 Jul 2019 07:16:19 GMT
connection=close ] } attributesMediaType=/ } childErrors=[] }] }
My flow configutation:
<scatter-gather doc:name="Distribute workload" doc:id="15151949-c61d-4629-9fd4-0a4e16d62eec" >
<route >
<!--Access to localhost/rules/my-rule>
<flow-ref doc:name="CategoryToType" doc:id="e5d39afa-3b2a-45ef-81c0-afce77a76aef" name="validateCategoryToType" />
</route>
</scatter-gather>
<error-handler>
<on-error-propagate enableNotifications="true" logException="true" doc:name="On Error Propagate" doc:id="16001c58-7609-42a6-9bfa-1cd756998f27" >
<logger level="INFO" doc:name="Logger" doc:id="8ec2af18-3e45-4d15-a373-5e9af74723d7" message='#[error]'/>
</on-error-propagate>
</error-handler>
<sub-flow name="validateCategoryToType" doc:id="da38db3a-7d51-4fd1-bd06-9e58b872d468" >
<foreach doc:name="For Each" doc:id="ff9944ba-5f87-4a5a-9392-a4b27c2f5fb0" collection="payload.Kunden" rootMessageVariableName="Kunden">
<ee:transform doc:name="Transform Message" doc:id="f33fa5ea-0b4d-4ac5-a247-90fd6978248d">
<ee:message>
<ee:set-payload>
<!--Some transformy stuff-->
</ee:set-payload>
</ee:message>
</ee:transform>
<http:request method="POST" doc:name="Request" doc:id="53df928a-4fd1-4125-88e0-be73b006beee" config-ref="HTTP_Request_configuration" path="/rules/my-rule/execution>
<http:headers><![CDATA[#[output application/java
---
{
"Content-Type" : "application/xml",
"Accept" : "application/xml"
}]]]></http:headers>
</http:request>
<logger level="INFO" doc:name="Logger" doc:id="cc02312e-b71b-461c-bba0-077bfb1e9b7e" message="#[payload]" />
</foreach>
</sub-flow>
Use Global error handler, i have composed HTTP error request for you. You can expand it to other error types like API tool kit etc..
Also, extend further error messages by creating variables and capture postman payload into a variable
<on-error-propagate type="HTTP:BAD_REQUEST"
enableNotifications="true" logException="true" doc:name="On Error Propagate"
doc:id="73b29eaf-ebcd-4857-baea-4c2fb963b055">
<set-variable value="#[400]" doc:name="HTTP Status - 400"
doc:id="4017a80c-f968-4f09-8fbb-eaa4ce5d1413" variableName="httpStatus" />
<set-variable
value="Service is unable to handle request"
doc:name="errorMessage" doc:id="9ab2b50b-7aad-4460-b276-f5d50ffd1efe"
variableName="errorMessage" />
<ee:transform doc:name="Transform Message" doc:id="df98f927-584c-454e-971e-79d2ff1e842d" >
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/json
---
error: {
errorCode: error.errorType.identifier,
errorDateTime: now() as String { format: "yyyy-MM-dd'T'HH:mm:ss" },
errorDescription: error.description
}]]></ee:set-payload>
</ee:message>
</ee:transform>
<ee:transform doc:name="Transform Message" doc:id="6e6c0017-2b23-4bfa-83ef-2f77cc25aa08" >
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/json
---
payload]]></ee:set-payload>
</ee:message>
</ee:transform>
</on-error-propagate>

Mule - Throw Exception with until-successful

This is my mule flow:
HTTP => Logger => SOAP (CXF) => Until Successful [JAVA] => LOGGER
Spring :
<spring:beans>
<spring:bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<spring:property name="locations">
<spring:list>
<spring:value>test.properties</spring:value>
</spring:list>
</spring:property>
</spring:bean>
<spring:bean id="testIntegration"
class="x.x.x.IntegrationClass" init-method="init">
<spring:property name="url" value="${destiny.url}" />
<spring:property name="username" value="${message.username}" />
<spring:property name="password" value="${message.password}" />
</spring:bean>
</spring:beans>
Flow:
<http:inbound-endpoint exchange-pattern="request-response"
host="localhost" port="8087" doc:name="HTTP" />
<logger message="#[message.payloadAs(java.lang.String)]" level="INFO" doc:name="Logger"/>
<cxf:jaxws-service doc:name="Test service"
serviceClass="dynamics.file.request.Requests" />
<until-successful maxRetries="3"
secondsBetweenRetries="60" doc:name="Until Successful" synchronous="true">
<component doc:name="Java">
<spring-object bean="testIntegration" />
</component>
</until-successful>
<logger message="#[message.payloadAs(java.lang.String)]" level="INFO"
doc:name="Logger" />
</flow>
The Java component returns a String (XML but String) and when I use until-successful it shows me this error:
Exception thrown inside until-successful org.mule.component.ComponentException: Component that caused exception is: DefaultJavaComponent{Flow_test.component.1805940825}. Message payload is of type: String
[[test_flow].connector.http.mule.default.receiver.02] org.mule.exception.DefaultSystemExceptionStrategy:
********************************************************************************
Message : Failed to find entry point for component, the following resolvers tried but failed: [
MethodHeaderPropertyEntryPointResolver: The required property "method" is not set on the event
CallableEntryPointResolver: Object "es.test.integration.testIntegration#4eb6b10c" does not implement required interface "interface org.mule.api.lifecycle.Callable"
ReflectionEntryPointResolver: Found too many possible methods on object "es.test.integration.testIntegration" that accept parameters "{class java.lang.String}", Methods matched are "[public java.lang.String es.test.integration.testIntegration.cte(java.lang.String), public java.lang.String es.test.integration.testIntegration.cancelCte(java.lang.String), public java.lang.String es.test.integration.testIntegration.newCte(java.lang.String), public java.lang.String es.test.integration.testIntegration.totalCte(java.lang.String), public java.lang.String es.test.integration.testIntegration.resultCte(java.lang.String), public java.lang.String es.test.integration.testIntegration.newCte(java.lang.String), public java.lang.String es.test.integration.testIntegration.cteAll(java.lang.String)]"
AnnotatedEntryPointResolver: Component: es.test.integration.testIntegration#4eb6b10c doesn't have any annotated methods, skipping.
]
Code : MULE_ERROR-321
at org.mule.model.resolvers.DefaultEntryPointResolverSet.invoke(DefaultEntryPointResolverSet.java:49)
at org.mule.component.DefaultComponentLifecycleAdapter.invoke(DefaultComponentLifecycleAdapter.java:339)
at org.mule.component.AbstractJavaComponent.invokeComponentInstance(AbstractJavaComponent.java:82)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
Message : Software caused connection abort: socket write error (java.net.SocketException)
Code : MULE_ERROR--2
--------------------------------------------------------------------------------
Exception stack is:
1. Software caused connection abort: socket write error (java.net.SocketException)
java.net.SocketOutputStream:-2 (null)
2. Software caused connection abort: socket write error (java.net.SocketException) (org.mule.api.DefaultMuleException)
org.mule.transport.http.HttpMessageProcessTemplate:170 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/DefaultMuleException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
With that error I suppose that I need any parameters here but correct me if I'm wrong:
public void init()
{
NtlmAuthenticator authenticator = new NtlmAuthenticator(username,password);
Authenticator.setDefault(authenticator);
Requestsservice = new Requests();
clntprt = service.getSolicitudesPort();
Client client = ClientProxy.getClient(cliente);
HTTPConduit http = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setAllowChunking(false);
http.setClient(httpClientPolicy);
BindingProvider provider = (BindingProvider) clntprt;
provider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
url);
}
Updated:
Where I have the init method I have the implemented methods (These both for example, but there are more):
#WebMethod(operationName = "CancelCte", action = "urn:microsoft-dynamics-schemas/codeunit/Requests:CancelCte")
#RequestWrapper(localName = "CancelCte", targetNamespace = "urn:microsoft-dynamics-schemas/codeunit/Requests", className = "x.x.Requests.CancelCte")
#ResponseWrapper(localName = "CancelCte_Result", targetNamespace = "urn:microsoft-dynamics-schemas/codeunit/Requests", className = "x.x.Requests.CancelCteResult")
#WebResult(name = "return_value", targetNamespace = "urn:microsoft-dynamics-schemas/codeunit/Requests")
public String CancelCte(
#WebParam(name = "xmlInput", targetNamespace = "urn:microsoft-dynamics-schemas/codeunit/Requests") String xmlInput)
{
return client.CancelCte(xmlInput);
}
#WebMethod(operationName = "newCte", action = "urn:microsoft-dynamics-schemas/codeunit/Requests:newCte")
#RequestWrapper(localName = "newCte", targetNamespace = "urn:microsoft-dynamics-schemas/codeunit/Requests", className = "x.x.Requests.newCte")
#ResponseWrapper(localName = "newCte_Result", targetNamespace = "urn:microsoft-dynamics-schemas/codeunit/Requests", className = "x.x.Requests.newCteResult")
#WebResult(name = "return_value", targetNamespace = "urn:microsoft-dynamics-schemas/codeunit/Requests")
public String newCte(
#WebParam(name = "xmlInput", targetNamespace = "urn:microsoft-dynamics-schemas/codeunit/Requests") String xmlInput)
{
return client.newCte(xmlInput);
}
Like now, automatically use the necessary method.
With the partial information you have provided, all I can say is that the source of the problem is located in:
<spring-object bean="testIntegration" />
based on: Component that caused exception is: DefaultJavaComponent{Flow_test.component.1805940825}
The main issue is that Mule can't locate a method to call on your custom component: there are two many methods of arity 1 that take String, which prevent Mule to pick an appropriate "entry point". Two solutions to fix this:
Set a property named method with the method name to call as its value before the call to the component,
Use the invoke message processor to call the desired method directly.
As a side note, it seems this component performs outbound HTTP calls: typically you want to use Mule HTTP to do this instead of doing it in custom code. First you're burying these interactions inside custom code: someone looking at the Mule config won't know that outbound HTTP call are involved. Moreover, Mule itself will not know so it can't do anything like general lifecycle and error management, stats... on these custom HTTP calls.

Polling HTTP endpoint followed by jersey REST WS does not work in Mule 3.5

I have a requirement where i need to poll a rest service and then proxy the response from this web service on to a REST web service.
I am using Mule 3.5 and my flow looks like the below.
I get the below exception where the REST service is being invoked
********************************************************************************
Message : Failed to invoke JerseyResourcesComponent{TestFlow.component.1106552446}. Component that caused exception is: JerseyResourcesComponent{TestFlow.component.1106552446}. Message payload is of type: String
Code : MULE_ERROR--2
--------------------------------------------------------------------------------
Exception stack is:
1. null (java.lang.NullPointerException)
org.mule.module.jersey.JerseyResourcesComponent:192 (null)
2. Failed to invoke JerseyResourcesComponent{TestFlow.component.1106552446}. Component that caused exception is: JerseyResourcesComponent{TestFlow.component.1106552446}. Message payload is of type: String (org.mule.component.ComponentException)
org.mule.component.AbstractComponent:144 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/component/ComponentException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
java.lang.NullPointerException
at org.mule.module.jersey.JerseyResourcesComponent.getBaseUri(JerseyResourcesComponent.java:192)
at org.mule.module.jersey.JerseyResourcesComponent.doInvoke(JerseyResourcesComponent.java:146)
at org.mule.component.AbstractComponent.invokeInternal(AbstractComponent.java:122)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
After debugging i figured out it is because Mule expects the MuleMessage inbound property for contextPath to be populated however in this case it is null.
In JerseyResourcesComponent line 117 is returned as null and hence line 195 throws a NPE.
I wanted to know if this kind of requirement/pattern is invalid or is it some kind of limitation in the way Mule is handling its messaging infrastructure ?
The flow xml just in case you want to inspect it.
<flow name="TestFlow" doc:name="TestFlow">
<poll doc:name="Poll">
<fixed-frequency-scheduler frequency="10" timeUnit="SECONDS" startDelay="10"/>
<http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="8080" doc:name="Order Generator" method="GET" contentType="application/json" path="order"/>
</poll>
<object-to-string-transformer doc:name="Object to String"/>
<jersey:resources doc:name="Tax Calculator">
<component class="org.nthdimenzion.TaxCalculator"/>
</jersey:resources>
<logger level="INFO" doc:name="Logger"/>
</flow>
PS : The work around i got was to use a java/spring component instead of a REST WS and then call the REST WS from the Java component.

In mule3, how to set a custom expression for choice-when router?

I am new to Mule, I want to validate the timestamp and nonce parameter from URI for preventing the replay attack. I use choice-when router, when the timestamp and nonce is valid(the validation process is complex), forward the request to backend rest service, otherwise return error code and message. I found a lot of MEL usage for choice-when, but can I define a custom expression use java? and there is a example available?
URI example:
http://muledemo.org/ci2/ni/del?id=0xe413&timestamp=1376022133&nonce=a03ed9c
code snippets:
<choice doc:name="Choice">
<when expression="???how to call a java validator???">
</when>
<otherwise>
<processor-chain doc:name="Processor Chain">
<echo-component doc:name="Echo" />
<http:outbound-endpoint exchange-pattern="request-response" method="POST"
address="http://localhost:8081#[message.inboundProperties['http.request']]" doc:name="HTTP" />
</processor-chain>
</otherwise>
</choice>
EDIT:
XML config:
<spring:beans>
<spring:bean id="replayAttackCheck" class="org.jamee.demo.mule.ReplayAttackCheck"/>
</spring:beans>
... ...
<when expression="#[replayAttackCheck.validate(payload)]">
<expression-component doc:name="Check Required Params"><![CDATA[payload="{\"code\":\"PA002\", \"message\":\"timestamp or nonce is illegal\"}"]]>
</expression-component>
</when>
Error log:
ERROR 2013-08-09 14:32:39,090 [[demo.router].connector.http.mule.default.receiver.02] org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : Execution of the expression "replayAttackCheck.validate(payload)" failed. (org.mule.api.expression.ExpressionRuntimeException). Message payload is of type: HashMap
Code : MULE_ERROR--2
--------------------------------------------------------------------------------
Exception stack is:
1. [Error: unresolvable property or identifier: replayAttackCheck]
[Near : {... replayAttackCheck.validate(pay ....}]
Correct MEL syntax:
<when expression="#[app.registry.replayAttackCheck.validate(payload)]">
You just use the fully qualified path
#[com.mulesoft.foo(payload, someFooVar)]
Alternatively you can define it globally for your app in your configuration and the use the "foo" function in your MEL expressions
<configuration doc:name="Config">
<expression-language autoResolveVariables="false">
<global-functions>
def foo(fooVar){
return com.mulesoft.foo(payload, fooVar);
}
</global-functions>
</expression-language>
</configuration>

How to configure 2.6 spring: Failed to create route route2 at:

I'm trying to upgrade from Camel 2.0 to 2.6
I have this in my applicationContext-camel.xml file...
<camel:route >
<camel:from uri="transactionSaleBuffer" />
<camel:policy ref="routeTransactionPolicy"/>
<camel:transacted ref="transactionManagerETL" />
<camel:to uri="detailFactProcessor" />
</camel:route>
by adding in the two lines in the middle (policy and transacted) I get the exception...
Caused by: org.apache.camel.FailedToCreateRouteException: Failed to create route route2 at: >>> From[transactionSaleBuffer] <<< in route: Route[[From[transactionSaleBuffer]] -> [Tr
ansacted[ref:trans... because of Route route2 has no output processors. You need to add outputs to the route such as to("log:foo").
I can see this is because the Camel class RouteDefinition.java makes a call to ProcessorDefinitionHelper.hasOutputs(outputs, true).
This passes in an array of one Object ([Transacted[ref:transactionManagerETL]])
This one object has one two children
[Transacted[ref:transactionManagerETL]]
CHILD-[Policy[ref:routeTransactionPolicy],
CHILD-To[detailFactProcessor]
The Policy child has no outputs, so the exception is thrown.
Yet I don't know how to add a child, my XML above matches the schema.
Maybe I'm missing something else?
My setup matches the example...Apache Camel: Book in One Page (See section: Camel 1.x - JMS Sample)
Can anyone please help me out.
Thanks!
Jeff Porter
Try as follows
<camel:route>
<camel:from uri="transactionSaleBuffer" />
<camel:transacted ref="transactionManagerETL" />
<camel:policy ref="routeTransactionPolicy">
<camel:to uri="detailFactProcessor" />
</camel:policy>
</camel:route>

Categories