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; } }