RabbitMQ, How to drop a message after n re-queuing attempt - java

I am trying to build a sort of asynchronous server by using RabbitMQ along with JAVA. I have two exchanges Original_Exch and Dead_Exch, and one queue in each. Both the exchanges are declared DLX (dead letter exchange of each other's queue).
Now come to the problem, I am publishing a message to Original_Exch in the form of a json string which contains email Info ( such as To,Subject, Message body, attachment, etc ). After consuming this message from the queue bind to Original_exch, I am sending email to the specified email address. In case email is not sent successfully I am transferring this message to Dead_Exch and after 2 seconds ( using TTL for that ) the message is again being transferred to Original_Exch.
Let's assume a scenario in which a particular message is moving from one exchange to another due to continuous failure. In that case I want to make sure that if it has been transferred to Original_Exch 10 times, it should be dropped ( deleted ) from queue permanently and should not be transferred to Dead_Exch.
There are so many answers for almost similar kind of questions but none of them are satisfactory ( from a learner point of view ).
Thanks..........

Messages which have been dead-letterred have a x-death header with details about which queue(s) it went through and how many times. See an article about dead-letter exchanges on RabbitMQ website.
So you can use this header to do what you want. I see two solutions:
In your consumer, when a mail could not be delivered, look at the x-death header and decide if you want to dead-letter it (Basic.Nack with requeue set to false) or drop it (Basic.Ack).
Use a header exchange type for Dead_Exch and configure the binding to match on x-death.
Because header exchanges only do exact match on the header value, the first solution is more flexible and less error-prone.

Related

Different messages are merging under ByteBuf Object while reading it from Netty library through TCP

I have an application which processes messages which are of 3 different formats, I am using Netty client to receive messages over TCP listener.
So the issue I am facing in that is for receiving messages over TCP, I have to use ByteBuf in my Decoder class, hence messages are concatenating one after the other and I m not able to split them.
I searched over Internet and, I found we can use LineBasedFrameDecoder, DelimeterBasedFrameDecoder or FixedLengthFieldDecoder to resolve this, but the issue is in my message I don't have any fixed size, also I cannot use LineBasedFrameDecoder because LineBasedFrameDecoder splits the messages on the basis of new line i.e '\n' or '\r' and in my messages there can be new lines as well so LineBasedFrameDecoder will not work in this scenario as it will give the partial or half message, also I don't have any specific delimiter from which my messages ends and I can't use DelimeterBasedFrameDecoder
Please suggest me some approach to resolve this problem.
Also, Is there anything I can add to my pipeline for TCP so that my ByteBuf Object will not contain the concatenation of messages and for every decode method call I will have a single message so that I can parse them easily, just like in cases of UDP as they receive the Datagram packets for every single message.
Thanks in advance.

javax.mail separating email threads

I have a java application that monitors an inbox and reads new messages. I only want the latest message in a thread read, however when an email with multiple replies in the same thread is parsed, it reads the whole thing.
Is it possible to read only the latest reply in an email thread using javax.mail? Or would I need to place some logic to look at the header and determine the latest by comparing the send date?
If you have separate messages in your mailbox for each reply, you have to decide how to determine that they're part of the same "thread". There's no perfect way to do this and different mailers will do it differently. A good start is the References and In-Reply-To headers. Once you know the set of messages that are part of a single thread, you can choose the latest one by date.
If you have a single message that includes the text of previous replies in the body of the message and you want to separate the latest reply from the previous replies, you'll have to process the text in the body and decide which parts are previous replies and which part is the current reply. Again, there is no perfect solution and this will require more heuristics.

Apache MQ Scanning Message

I am new to Apache Active Message Queues.
While reading(Consuming) the messages from MQ, the de-queue count increasing and that message deleting from MQ storage.
Here, I want to scan the message without deleting the message from MQ and de-queue count as same. means, just I want scan the message and storing it local or printing it at output.
Can Any body Suggest on this? I want to implement it using java.
What you need is an ActiveMQQueueBrowser. You can find an example code here.
But you need to be careful with this approach. Messaging Queues are not designed for this kind of access, only some implementations (like ActiveMQ) provides this access-type for special use-cases. It should be used only if really necessary, and you need to understand the limitations of this:
The returned enumeration might not fetch the full content of the queue
The enumeration might contain a message that has been already dequeued by the time you process it
etc.

notification if no reply to a mail in Gmail (Java)

I would like to know if it is possible to know if a recipient has answered a definit email .
What is te best way to do this in Java ?
There are Message-ID, In-Reply-To and References headers in the e-mail message (see http://cr.yp.to/immhf/thread.html or http://wesmorgan.blogspot.ch/2012/07/understanding-email-headers-part-ii.html). You have to keep the Message-ID of an e-mail message you are interested in, and then parse the headers of the incoming messages, if they contain your ID.
As for the way to do it in Java, read the Java Mail API Tutorial and study the javax.mail JavaDoc (and sub-packages).
Warning: Athough commonly used by most e-mail clients, these headers are not mandatory, so there is no 100% secure way to do it.
Just to be sure we understand the problem, you want to know how to tell if a recipient has sent a reply to you for a message you sent to the recipient, right?
As Jozef describes, the In-Reply-To and References headers are the standard way of doing this, but some mailers don't properly include them in replies. Another approach is to include a unique ID in the Subject of the original message. Replies almost always include the original Subject without change, prepended by "Re:" or equivalent.

Camel send String to JMS queue but byte array is retrieved

I have a question related to Camel and JMS message.
My system contains a JMS topic and a JMS queue, say, TopicInput and QueueInput. A process of mine listens to QueueInput and process the message send into this queue. The result is then passed to another Topic, say, TopicOutput.
The process that processes the message uses Java and Apache Camel. The response my Camel route send out is a String. Therefore the String is sent to TopicOutput.
My problem is that when I send my message to the QueueInput directly, everything is fine, I get a String response from TopicOutput. However, if I send the request message to the TopicInput, which internally bridges to QueueInput anyway, the result I get from TopicOutput will be a byte array representation of the String.
Does anyone know how this could happen? I am not even sure whether this is the Camel's problem or JMS problem.
Any suggestions or hints will be helpful.
Many thanks.
Not quite sure what's going on exactly in your logic.
JMS has BytesMessage and TextMessage. To get a string directly, the message has to be TextMessage, otherwise a String must be constructed from a byte array, which you can retrieve from the message.
When sending messages using Camel, Camel tries to map the payload to the best JMS message type. Check this table out.
To be sure to always produce a TextMessage (that parses to String), convert the payload to String before sending it with a JMS producer. Make sure you are aware of what the message type and payload is in every step of your flow, then you should easily solve your issue.

Categories