Spring integration: how to adjust all outgoing error messages - error-handling

I need to adjust all error messages going back to the caller of my integration flows so that I do not leak information, no matter if they are thrown as exception or handled as asynchronous errors. I'd like to avoid defining a custom error channel on every message handler.
I have tried to attach a transformer to the default error channel without success:
#Bean
IntegrationFlow errorFlow() {
return IntegrationFlows.from("errorChannel")
.transform("{'status': 500, 'error': 'Internal Server Error'}")
.get();
}
Is there a central point where I can transform all outgoing error messages?

According to your logic, it looks like you deal with REST - request/reply. So, you need to return a reply to request point. This is available via replyChannel header of the request message. Such an information you can access in a MessagingException.failedMessage property of the payload in the ErrorMessage.
Summarizing all of that your .transform() must expect MessagingException as a payload and produce output message with copying headers from that failedMessage. This way the message will be sent to the reply channel of the HTTP Inbound Gateway request message.

Related

A failure to decode a rabbit message fails the reactive Reactive Messaging - readiness check

I've encountered a problem when using small rye reactive messaging with Quarkus, for a rabbit MQ incoming handler.
The message being published to rabbit has a json content type, and the method signature of the handling code is written accordingly:
#Incoming("event-name")
#Acknowledgment(Acknowledgment.Strategy.POST_PROCESSING)
public void processEvent(final JsonObject payload)
However, in the event that the message body contains bad json, that cannot be parsed successfully, this method is never invoked and a io.vertx.core.json.DecodeException is thrown, when handling the failure this calls into the io.smallrye.reactive.messaging.providers.extension.HealthCenter.reportApplicationFailure() which then means the healthcheck endpoint will product a DOWN response. The app in question runs in k8s, so the pod gets restarted, but the new instance will pick up on the same message and produce the same. The only way to deal with the issue seems to be manually remove the bad message from the queue.
Looking in the docs https://quarkus.io/guides/rabbitmq-reference#health-reporting it suggests that a failed message should be nacked and the failure-strategy should handle it, but it seems because the message isn't being parsed properly, it isn't getting as a far as the processing, the the failure strategy isn't being called.
I'm actually not certain if this is the intended behaviour in this circumstance, if I can do something about it or if it genuinely is a bug - using Quarkus 2.12.0.
My expectation is that it should be possible to handle this circumstance in some way without causing the health check to fail and dequeueing the message so that the bad message isn't picked up again and again.

Spring AMQP RabbitMQ RPC - Queue with with some messages that do not expect a response

I am trying to create a priority RPC queue that can accept some messages that expect a response and some messages that do not expect a response. The problem I am facing is that when I send messages with convertAndSend I get an error saying "org.springframework.amqp.AmqpException: Cannot determine ReplyTo message property value: Request message does not contain reply-to property, and no default response Exchange was set." I know the issue is that the RPC queue is expecting a response, and the message just stays on the queue, but for these messages I do not want/need a response. Any idea how I can work around this issue?
Thanks,
Brian
A solution recommended in this link worked for me: Single Queue, multiple #RabbitListener but different services. Basically I have a class with RabbitListener, and different methods with RabbitHandler

Worklight - Don't propagate error details to client

I would like to know if IBM Worklight has out of the box support for not propagating the error details to the client in the response.
To illustrate, let's suppose that while processing a request, per some reason something went wrong and the server responds it with a body similar to:
{"errors":["Some exception/error details go here..."],"isSuccessful":false,"warnings":[],"info":[]}
However, I don't want the consumer to be aware of the such details, neither to inflate my response with it. Does IBM Worklight provide any way to change such behaviour and, for example, send the errors array empty or at least to transform it before sending the response to the client?
Worklight server responds to requests from the client. Depending on the case, this may be a valid response to the request or an error message, in case something did not go as per plan. Note that in this case, the response flow enters the failure callback of the listener.
The error message is passed back in a format understood by the developer such that they can account for these and take corrective actions. This message is not intended for the end user, but for the developer to handle. In case the message is too descriptive ( or too technical), it is left to the developer to show a generic or proper message.
For example, instead of "An exception was thrown because the input parameter is wrong" can be presented to the end user as "Please verify your input..." .
In case the error is resulting from the adapter - when adapter receives an error from the backend, it can be checked and modified at the adapter, before passing back to the client. Similarly, if errors from exceptions at the adapter can be caught and handled, custom responses can be sent back to the client.
If the error results from exceptions or other conditions, Worklight server cannot be configured to the send errors array empty or transform the response before sending the response to the client. This is for the developer to handle at client side.

Mule:Setting Rest Call response as property in original message payload

Having a scenario where consuming a message from amqp:inboundendpoint and then requesting a call to rest service using HTTP outbound endpoint with request response message exchange pattern. I need to set properties of message payload received from amqp with certain data retrieved in HTTP outbound response. What is the best component to acheive this design. Do i need to call HTTP outbound inside an enricher and then enrich the payload with additional properties retrieved from rest call or is there any other design possible.
The message enritcher was designed exactly for this scenario please take a look a this.
Yes as Victor said, Mule Message Enricher will be a good option to be used in this kind of scenario..
What message enricher actually does is it enrich an incoming message with additional information (That's what your need ) and perform a particular task without disturbing or modifying the original payload...
So in that case, the message processor after enricher will be getting the original payload without being modified... So I can say, your approach is correct and you can go with enricher..
you can find more about enricher :- http://www.mulesoft.org/documentation/display/current/Message+Enricher
and
http://blogs.mulesoft.org/enrich-your-experience-orchestration-and-data-enrichment-with-mule-3-1/

Rabbitmq + web stomp plugin with rpc - reply-to

I'm trying to perform an RPC with RabbitMQ's STOMP adapter. As the client lib I'm using the STOMP over WebSocket (https://github.com/jmesnil/stomp-websocket/) library.
From the documentation (http://www.rabbitmq.com/stomp.html#d.tqd) I see that I have to set the reply-to header. I've done that by specifying something like "reply-to: /temp-queue/foo" and I saw in my server-side client (node-amqp) that the replyTo header is set correctly (example: replyTo: '/reply-queue/amq.gen-w2jykNGp4DNDBADm3C4Cdx'). Still in my server-side client, I can reply to the message just by publishing a message to "/reply-queue/amq.gen-w2jykNGp4DNDBADm3C4Cdx".
However, how do I get this reply it in my client code where the RPC call was initiated? The documentation states "SEND and SUBSCRIBE frames must not contain /temp-queue destinations (...) subscriptions to reply queues are created automatically."
So, how do I subscribe to the reply-to queue? How can I get the results of RPC calls?
Thanks in advance.
The answer is:
When you receive the rpc call in the server worker you get the header replyTo. That header comes like:
replyTo: '/reply-queue/[queue_name]'
for example: replyTo:'/reply-queue/amqp.fe43gggr5g54g54ggfd_'
The trick is:
you have to parse it and only answer to the queue_name [for example: amqp.fe43gggr5g54g54ggfd_]
You have to answer to the default exchange and not to any other exchange
Example of an answer in nodejs:
function onRpcReceived(message, headers, deliveryInfo, m) {
var reply_to = m.replyTo.toString().substr(13, m.replyTo.toString().length);
connection.publish(reply_to, {response:"OK", reply:"The time is 13h35m"}, {
contentType:'application/json',
contentEncoding:'utf-8',
correlationId:m. correlationId
});
}
Now i just wonder why the web-stomp-plugin adds the /reply-queue/ string to the attribute "replyTo" on the header instead of only add the queue name....! If someone knows the reason i would like to know.
The answer to the original question:
However, how do I get this reply it in my client code where the RPC
call was initiated? The documentation states "SEND and SUBSCRIBE
frames must not contain /temp-queue destinations (...) subscriptions
to reply queues are created automatically."
So, how do I subscribe to the reply-to queue? How can I get the
results of RPC calls?
Rabbit automatically subscribes the current STOMP session to the temp queue. The client doesn't know the temp queue name and cannot subscribe to it. However, when Rabbit sends a STOMP MESSAGE frame it sets the subscription header to the "reply-to" value (e.g. "/temp-queue/foo"). Although the STOMP over WebSocket client wasn't written with this in mind, a subscription could be registered as follows:
stompClient.subscriptions['/temp-queue/foo'] = function(message) {
// ...
};
I'd be happy to hear if there is another solution.
NB: There is no more '/reply-queue/' in the replyTo since RabbitMQ 3.0.0
I spent about a 4 hours to find what was the problem. Use .replace('/reply-queue/', '') instead of .substring(13)!