package org.ovirt.engine.core.notifier.utils.sender.mail;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Map;
import javax.mail.MessagingException;
import org.apache.commons.lang.StringUtils;
import org.ovirt.engine.core.common.businessentities.event_audit_log_subscriber;
import org.ovirt.engine.core.compat.LogCompat;
import org.ovirt.engine.core.compat.LogFactoryCompat;
import org.ovirt.engine.core.notifier.utils.NotificationProperties;
import org.ovirt.engine.core.notifier.utils.sender.EventSender;
import org.ovirt.engine.core.notifier.utils.sender.EventSenderResult;
/**
* The class designed to send e-mails to subscriptions for events.<br>
* In order to define a proper mail client, the following properties should be provided:
* <li><code>MAIL_SERVER</code> mail server name
* <li><code>MAIL_PORT</code> mail server port</li><br>
* The following properties are optional: <br>
* <li><code>MAIL_USER</code> user name includes a domain (e.g. user@test.com)</li>
* <li><code>MAIL_PASSWORD</code> user's password</li>
* <ul>if failed to obtain or uses "localhost" if <code>MAIL_MACHINE_NAME</code> not provided</li>
* <li><code>MAIL_FROM</code> specifies "from" address in sent message, or uses value of property <code>MAIL_USER</code> if not provided</li>
* <ul><li>"from" address should include a domain, same as <code>MAIL_USER</code> property
* <li><code>MAIL_REPLY_TO</code> specifies "replyTo" address in outgoing message
*/
public class EventSenderMailImpl implements EventSender {
private static final LogCompat log = LogFactoryCompat.getLog(EventSenderMailImpl.class);
private JavaMailSender mailSender;
private String hostName;
private boolean isBodyHtml = false;
public EventSenderMailImpl(Map<String, String> mailProp) {
mailSender = new JavaMailSender(mailProp);
String isBodyHtmlStr = mailProp.get(NotificationProperties.HTML_MESSAGE_FORMAT);
if (StringUtils.isNotEmpty(isBodyHtmlStr)) {
isBodyHtml = Boolean.valueOf(isBodyHtmlStr);
}
try {
hostName = InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException e) {
EventSenderMailImpl.log.error("Failed to resolve machine name, using localhost instead.", e);
hostName = "localhost";
}
}
/**
* {@link #EventSender}
*/
public EventSenderResult send(event_audit_log_subscriber eventData, String methodAddress) {
EventSenderResult result = new EventSenderResult();
EventMessageContent message = new EventMessageContent();
message.prepareMessage(hostName, eventData, isBodyHtml);
String recipient = eventData.getmethod_address();
if (StringUtils.isEmpty(recipient)) {
recipient = methodAddress;
}
if ( StringUtils.isEmpty(recipient) ) {
log.error("Email recipient is not known, please check user table ( email ) or event_subscriber ( method_address ), unable to send email for subscriber " + eventData.getsubscriber_id() + ", message was " + message.getMessageSubject() + ":" + message.getMessageBody());
result.setSent(false);
return result;
}
if (log.isDebugEnabled()) {
log.debug(String.format("Send email to [%s]\n subject:\n [%s]\n body:\n [%s]",
recipient,
message.getMessageSubject(),
message.getMessageBody()));
}
boolean shouldRetry = false;
try {
mailSender.send(recipient, message.getMessageSubject(), message.getMessageBody());
} catch (MessagingException ex) {
result.setReason(ex.getMessage());
shouldRetry = true;
}
// Attempt additional 3 retries in case of failure
for (int i=0 ; i < 3 && shouldRetry ; ++i){
shouldRetry = false;
try {
// hold the next send attempt for 30 seconds in case of a busy mail server
Thread.sleep(30000);
mailSender.send(recipient, message.getMessageSubject(), message.getMessageBody());
} catch (MessagingException ex) {
result.setReason(ex.getMessage());
shouldRetry = true;
} catch (InterruptedException e) {
log.error("Failed to suspend thread for 30 seconds while trying to resend a mail message.", e);
}
}
if (shouldRetry) {
result.setSent(false);
} else {
result.setSent(true);
}
return result;
}
}