Using Mule 3.4 with the AMQP Transport plugin and RabbitMQ, I am trying to send a message to the default AMQP exchange. The documentation for the exchangeName attribute states "leave blank or omit for the default exchange". However if I (a) omit it, like so:
<amqp:outbound-endpoint routingKey="my.queue" connector-ref="amqpDefaultConnector" />
Then I get the error message:
Element amqp:outbound-endpoint{connector-ref=amqpDefaultConnector,
name=.test:outbound-endpoint.17, routingKey=process.task.complete}
must have all attributes for one of the sets: [address] [ref]
[queueName] [exchangeName] [exchangeName, queueName].
Which seems to indicate that it is not valid to omit the attribute. However, if I (b) provide it but leave it blank, like so:
<amqp:outbound-endpoint exchangeName="" routingKey="my.queue" connector-ref="amqpDefaultConnector" />
then I get the error message:
java.net.URISyntaxException: Expected authority at index 7: amqp://
I believe that the rest of my configuration and setup is correct, as using a named exchange works as expected. Any help would be appreciated.
To dispatch to the default exchange, you need to pass the queue name in queueName not routingKey:
<amqp:outbound-endpoint exchangeName=""
queueName="my.queue"
connector-ref="amqpDefaultConnector" />
Related
Using Mule 4 , im trying to publish a message to the default amqp exchange but i still got
description=Exchange was not found.
detailedDescription=Exchange was not found.
errorType=AMQP:EXCHANGE_NOT_FOUND
this is my XML code :
<amqp:publish doc:name="Publish" doc:id="7282ee0e-9188-4a8a-a1f7-eefe5b98ce40"
config-ref="AMQP_Config" exchangeName="#['']">
<amqp:routing-keys >
<amqp:routing-key value="Test" />
</amqp:routing-keys>
<amqp:message>
<amqp:properties/>
</amqp:message>
Please try creating a new exchange "testExchange", referring to the documentation provided here: https://docs.mulesoft.com/mule-runtime/4.1/migration-connectors-amqp
Using the default with rabbitMQ, the default name is 'amq.default'.
i would like to route my http:request to my main ( or secondary ) error handler in Anypoint Studio 7
i does not seem to have a clear way of doing it.
And the documentation does not have guideline for this specific case.
in my case is necessary, i need to know and send a signal to another service and communicate the error response, like: connection_timeout
You can catch the errors you want using an error-handler in your flow where you are executing the http:request. if you do not catch the error, it will bubble up to the calling flow and so on. If no error-handler is configured, the default mule one will be used which just logs the message basically.
In Mule 4 you can catch all errors in your flow like so:
<flow name="retrieveMatchingOrders">
<http:request config-ref="customersConfig" path="/customer">
</http:request>
<error-handler>
<on-error-continue>
<!-- error handling logic -->
</on-error-continue>
</error-handler>
</flow>
An on-error-continue will execute and use the result of the execution, as the result of its owner (as if the owner had actually completed the execution successfully). Any transactions at this point would be committed as well
So in there, you can set the payload to your desired message to be returned etc.
There also an on-error-propogate handler and a try scope, more information on those are available here: https://docs.mulesoft.com/mule-runtime/4.1/intro-error-handlers
All errors thrown in Mule contain meta-data including a TYPE. If you need to catch specific HTTP Errors you can configure your error-handler like so:
<error-handler>
<on-error-continue type="HTTP:TIMEOUT">
<!-- error handling logic -->
</on-error-continue>
</error-handler>
Here is a list of all specific HTTP: errors thrown by the HTTP module:
HTTP:UNSUPPORTED_MEDIA_TYPE
HTTP:CONNECTIVITY
HTTP:INTERNAL_SERVER_ERROR
HTTP:METHOD_NOT_ALLOWED
HTTP:NOT_ACCEPTABLE
HTTP:TOO_MANY_REQUESTS
HTTP:SERVICE_UNAVAILABLE
HTTP:CLIENT_SECURITY
HTTP:FORBIDDEN
HTTP:UNAUTHORIZED
HTTP:RETRY_EXHAUSTED
HTTP:NOT_FOUND
HTTP:BAD_REQUEST
HTTP:PARSING
HTTP:TIMEOUT
HTTP:SECURITY
Each module's documentation should contain all specific error types thrown by that module. Here is the HTTP one example:
https://docs.mulesoft.com/connectors/http/http-documentation#throws
And here is a full list of core error types you can catch like EXPRESSION for example:
https://docs.mulesoft.com/mule-runtime/4.1/mule-error-concept
I've seen more than a few posts about this topic, but can't seem to find a solution to my specific problem, which I think is a pretty typical one, namely: how to keep processing messages when an error occurs (Exception thrown) using a Splitter / Aggregator.
The best explanation that I have come upon is here. But there's no explanation of exactly what/how the filters/transformers work. And in the end, the author posts "That worked!" but without posting an updated SI.config.xml.
From what I understand, the idea is to use an "error gateway", which is downstream from the original calling gateway and after the Splitter. This Gateway's job would be if there is an Exception thrown, to deal with it, but to make sure (via a transformer or a filter) that all Messages make it to the Aggregator.
My very simplified SI.config.xml if more or less like this:
<int:gateway id="myGateway" ... /> // incoming gateway
<int:chain ... input-channel="in" output-channel="out">
<int:splitter ... />
<int:service-activator />
<int:aggregator />
</int:chain>
So my question is, where exactly to stick this other gateway? And how to configure filters/transformers that (from what I gather) would grab the Message which launched an Exception and put it back on the correct channel (after logging it or whatever ...) so all Messages make it to the Aggregator.
I have looked at the SI samples, on SO, and the 2 SI books (SI in Acton and Pro SI) and can't find an example of this.
The solution looks like:
<int:chain ... input-channel="in" output-channel="out">
<int:splitter ... />
<int:gateway request-channel="processChannel" errorChannel="processError"/>
<int:aggregator />
</int:chain>
<int:chain input-channel="processChannel">
<int:service-activator />
</int:chain>
The error handler on the processError channel should consult incoming ErrorMessage and returns some compensation which will be sent to the aggregator.
The ErrorMessage typically contains MessagingException with a failedMessage where error has caused. That failedMessage contains all useful headers to go ahead with a compensation. Some of them are replyChannel and errorChannel, but for your aggregator case you need all those correlationId, sequenceNumber, sequenceSize etc. In other words when you build compensation message to be sent forward to the downstream for the aggregator, you should copy all the headers from that failedMessage.
For more info: http://docs.spring.io/spring-integration/docs/4.3.5.RELEASE/reference/html/configuration.html#namespace-errorhandler
We have a spring-integration application where we would like to deal with the messages on the error channel.At a minimum we would like to extract the history and log it so we can visualise where exactly it failed etc
Here is a brief markup of just this bit
<int:poller id="defaultPoller" default="true" fixed-delay="5000" />
<int:channel id="MyCustomErrorChannel">
<int:queue capacity="10"/>
</int:channel>
<int:header-enricher id="errorMsg.HeaderEnricher"
input-channel="errorChannel"
output-channel="MyCustomErrorChannel">
<int:header name="history" expression="payload.failedMessage.headers" />
</int:header-enricher>
<int:service-activator input-channel="MyCustomErrorChannel" ref="errorLogger" method="logError"/>
<bean id="errorLogger" class="com.dataprep.util.ErrorLogger" />
The idea is to define our custom error channel MyCustomErrorChannel. Any error that ends up in the default errorChannel gets its header's enriched before being put out on MyCustomErrorChannel
Lastly we have a logger that reads the messages from MyCustomErrorChannel and logs the payload which is the underlying exception and also the history.
I notice that the history in my logger is always 3 steps
errorChannel,errorMsg.HeaderEnricher,pbSwiftRouterErrorChannel i.e nothing prior to this message landing on the errorChannel is obtainable in the history.
How do I get hold of the original message's history (i.e the history of the faulty message which somehow landed on the default error channel as a new Error Message)
Could you please take a look at my header enricher and let me know how to access the headers on the failed message and stuff it to the error message?
Is it doable at all ?
To replace existing headers you should use overwrite="true", because the history is built for the ErrorChannel, too.
You should override exactly with history header, not the whole headers. Therefore your expression must be like this:
<int:header name="history"
expression="payload.failedMessage.headers.history"
overwrite="true"/>
I am not able to get the reason of exception from the message that is in the DLQ.
These are the steps i have followed:-
Message is sent to a 'Sample' Queue.
The Message Listener throws a Runtime Exception in the onMessage Function.(throw new RuntimeException("Exception Reason Test");)
The message goes to the DLQ.
I am trying to access the Exception reason via two approaches(i pass the DLQ Name and the JMS Message ID in both):-
Spring JMSTemplate browseSelected function
(ActiveMQMessage)message.getStringProperty(ActiveMQMessage.DLQ_DELIVERY_FAILURE_CAUSE_PROPERTY);
JMX QueueViewMBean browse function via the composite data map
Map datamap = (Map)dataMap.get("StringProperties");
datamap.containsKey(ActiveMQMessage.DLQ_DELIVERY_FAILURE_CAUSE_PROPERTY);
In both cases i am getting a null value for the property DLQ_DELIVERY_FAILURE_CAUSE_PROPERTY.
Please help.
Thanks