VERP with JavaMail and Postfix, How To? - java

First of all, Greetings!
I am about to Develop a a custom newsletter application in Java using the Javax.mail API.
So I need to Develop a Verp technique in order to track bounces.
So far I have Override the javax.mail.internet.MimeMessage Just to handle my own Mail headers.
class CustomMailMessage extends MimeMessage
...
public void setCustomHeader(key, value)
{
setHeader(key, value);
updateHeaders();
}
...
So this seems to work with any header that I set except the Return-Path.
...
setCustomHeader("Return-Path",verpAddr);
...
Resulting a VERP failure. I have track the value of this header just before and after I call
...
Transport.send(message);
...
and it seems that the value is the same as I have set it. Yet, at the received mail the return-path is changed to the sender address (From:). unlike the rest of the headers are as they were set. And so the bounce notification is delivered to the sender rather than my bounce+usermail=host#mydomain.com .
I think that this failure is on postfix site.
Note that the server is set by Plesk, and my domain.com is shared on my server.
So I please anyone that may assist me. Or can provide me more info on how to achieve differently a Verp technique.
Thx in Advance & Cheers!

The Return-Path header is set by the receiver, not the sender.
You want to set the "envelope from" address. See the javadocs for the com.sun.mail.smtp package for the property to set, and see the SMTPMessage class as another way to set this information.
Note also that you don't need to subclass MimeMessage just to set custom headers. You can call the setHeader method directly and updateHeaders will be called before the message is sent. (And updateHeaders won't do anything with these custom headers anyway.)

Related

Java Mail API: Callbacks

Context:
I am working on a piece of Java code where I am reading mails from an array (which works fine). I was wondering if someone can help me with the callback in order to show a fancy message like Your email was sent.
Questions:
How do I implement this?
Is there any way to get any Boolean type return value from javax.mail to check if the message was sent or not?
Maybe I should create a pool? If yes, how do I do that? Is there any signal to kill the pool?
Code:
// addressTo is the array.
Transport t = sesion.getTransport(this.beanMail.getProtocolo());
t.connect(this.beanMail.getUsuario(), this.beanMail.getPassword());
t.sendMessage(mensaje, addressTo);
t.close();
Quoting from the JavaMail API FAQ (in the context of tracking bounced messages):
While there is an Internet standard for reporting such errors (the multipart/report MIME type, see RFC1892), it is not widely implemented yet. RFC1211 discusses this problem in depth, including numerous examples.In Internet email, the existence of a particular mailbox or user name can only be determined by the ultimate server that would deliver the message. The message may pass through several relay servers (that are not able to detect the error) before reaching the end server. Typically, when the end server detects such an error, it will return a message indicating the reason for the failure to the sender of the original message. There are many Internet standards covering such Delivery Status Notifications but a large number of servers don't support these new standards, instead using ad hoc techniques for returning such failure messages. This makes it very difficult to correlate a "bounced" message with the original message that caused the problem. (Note that this problem is completely independent of JavaMail.)
Source

Apache Camel multicast routes interfering with each other

I am using a multicast in Camel DSL because I need to send a copy of the same message to two different endpoints. However, it seems that the routes are interfering with each other. Have I got the syntax wrong, or some other issue?
from("{{in.endpoint}}")
.routeId(this.getClass().getSimpleName())
.multicast().parallelProcessing()
.to("{{update.in}}", "{{add.ibmmq.topic}});
where
in.endpoint = seda:addOrder?waitForTaskToComplete=Never
update.in = seda:updateData?waitForTaskToComplete=Never
add.ibmmq.topic = an ibmmq topic
I expect the 'update' route to receive the 'in' message, and the 'ibmmq topic' to receive the same message, presumably cloned. However, in the logs I am getting exceptions like:
Exchange[
Id ID-slon12d10628-1228-1386074869307-0-44746
ExchangePattern InOnly
Headers {breadcrumbId=ID-slon12d10628-1228-1386074869307-0-41682, calendar=null, CamelMyBatisResult=[integration.model.EInquiry#19eb77c, integration.model.EInquiry#12059ce, xxxxxxx
BodyType message.BulkAddOrderMsg
Body message.BulkAddBondOrderMsg#77df22
]
but the EInquiry objects are read in by a completely separate route, nothing to do with this route except it, too, sends messages to 'in.endpoint'.
The other thing is because I read from Tibco and send to IBMMQ, I have to clear the JMS header codes because they are not compatible, so I have put:
exchange.getIn().getHeaders().clear();
in my 'update' route. Could this be clearing Camel's exchange tracing headers and causing this issue, basically like some weird concurrency issue?
Its hard to find the error without full source code, but bear in mind that multicast does not do deep copy.
If you have child objects in the Order object they are not duplicated and they are shared between both SEDA routes.
Probably you will have to make a custom deep clone of the object
The body of your Exchange is a custom POJO: message.BulkAddBondOrderMsg#77df22... which means there is no deep cloning available unless you add it. Same thing would happen if the body were DOM XML node...
Serialize the POJO to a String prior to the multicast so it can be shared across Exchanges.

boolean is set to false by default when passed in SOAP request

Situation : I am coding a web service in which soap client sends the request to web service which will update the database.
Suppose, there is a table project_team_members and service will be updating info of individual team member.
There is a column in table IS_TEAM_LEADER which can have '0' or '1' as value.
Problem: When updating TL info, if I am not sending IS_TL field from SOUP UI (A SOAP Client), it is automatically received as 'false' by default in java code.
How can i know if user is sending it or not, i mean i am not able to send null in case of boolean data-type from SOAP client
Revisiting my own question after so many years.
Giving response to myself at 2012 :)
One option can be, to send whatever is there in the database as it is, back to the server. But for this prior read call is necessary.
Another option is given by Jesse's(comment under question) as an answer/solution
If there is any field, e.g. Foo, there is often an associated
IsFooSpecified property to determine if the value was set or not. If
there an IsIsTeamLeadSpecified property you can access?
PS: There wasn't any field as suggested by Jesse but this can help someone else.

Send ProtocolBuffer Message.Builder to another machine via RMI

I have the following pesudocode:
public void sendPB(ObjectId userId, Message.Builder mb) {
if (userId is logged in to server) {
set mb.ackId to random chars
lookup socket and send mb.build()
}
else {
forward message to user's server via RMI
}
}
The problem is Message.Builders do not implement Serializable, so you cannot send it directly via RMI.
Is there an easy way to do this?
I've tried building partial PB from the builder and sending that over, but in order to reconstruct it you need to know the type or the Descriptor. Descriptor doesn't implement Serializable either.
Thanks
Any reason you can't call build(), get a Message, and send it across in whatever the correct format is (e.g., toString()). At the other end, you can inflate it back into a Message, and make it back into a builder with toBuilder() if that's required.
You may also just convert the message to binary format and send that.
Maybe I'm misunderstanding -- the whole point of ProtocolBuffers is to get Messages into a wire representation, so there are a number of ways to do that (most of which are either Serializable or trivially wrapped to be.)
I got it working... I had to include a typeID field in the RMI message. Then, I could take the typeID and resolve it to a Message Builder, and then mergeFrom the bytes of the partially built message.

Work around for MessageNotReadableException in Java

I am building a small api around the JMS API for a project of mine. Essentially, we are building code that will handle the connection logic, and will simplify publishing messages by providing a method like Client.send(String message).
One of the ideas being discussed right now is that we provide a means for the users to attach interceptors to this client. We will apply the interceptors after preparing the JMS message and before publishing it.
For example, if we want to timestamp a message and wrote an interceptor for that, then this is how we would apply that
...some code ...
Message message = session.createMessage()
..do all the current processing on the message and set the body
for(interceptor:listOfInterceptors){
interceptor.apply(message)
}
One of the intrerceptors we though of was to compress the message body. But when we try to read the body of the message in the interceptor, we are getting a MessageNotReadableException. In the past, I normally compressed the content before setting it as the body of the message - so never had to worry about this exception.
Is there any way of getting around this exception?
It looks like your JMS client attempts to read a write-only message. Your interceptor cannot work this way, please elaborate how you were compressing message earlier.

Categories