Details
diff --git a/azkaban-common/src/main/java/azkaban/utils/AbstractMailer.java b/azkaban-common/src/main/java/azkaban/utils/AbstractMailer.java
index afbf868..45ac64f 100644
--- a/azkaban-common/src/main/java/azkaban/utils/AbstractMailer.java
+++ b/azkaban-common/src/main/java/azkaban/utils/AbstractMailer.java
@@ -20,12 +20,15 @@ import java.util.Collection;
public class AbstractMailer {
private static int MB_IN_BYTES = 1048576;
+ public static final int DEFAULT_SMTP_PORT = 25;
+
private String clientHostname;
private int clientPort;
private boolean usesSSL;
private boolean usesAuth;
private String mailHost;
+ private int mailPort;
private String mailUser;
private String mailPassword;
private String mailSender;
@@ -39,6 +42,7 @@ public class AbstractMailer {
public AbstractMailer(Props props) {
this.azkabanName = props.getString("azkaban.name", "azkaban");
this.mailHost = props.getString("mail.host", "localhost");
+ this.mailPort = props.getInt("mail.port", DEFAULT_SMTP_PORT);
this.mailUser = props.getString("mail.user", "");
this.mailPassword = props.getString("mail.password", "");
this.tls = props.getString("mail.tls", "false");
@@ -71,7 +75,7 @@ public class AbstractMailer {
protected EmailMessage createEmailMessage(String subject, String mimetype,
Collection<String> emailList) {
- EmailMessage message = new EmailMessage(mailHost, mailUser, mailPassword);
+ EmailMessage message = new EmailMessage(mailHost, mailPort, mailUser, mailPassword);
message.setFromAddress(mailSender);
message.addAllToAddress(emailList);
message.setMimeType(mimetype);
@@ -107,6 +111,10 @@ public class AbstractMailer {
return mailSender;
}
+ public int getMailPort() {
+ return mailPort;
+ }
+
/**
* Attachment maximum size in bytes
*
diff --git a/azkaban-common/src/main/java/azkaban/utils/Emailer.java b/azkaban-common/src/main/java/azkaban/utils/Emailer.java
index a031e77..8e7c710 100644
--- a/azkaban-common/src/main/java/azkaban/utils/Emailer.java
+++ b/azkaban-common/src/main/java/azkaban/utils/Emailer.java
@@ -16,13 +16,6 @@
package azkaban.utils;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.mail.MessagingException;
-
-import org.apache.log4j.Logger;
-
import azkaban.alert.Alerter;
import azkaban.executor.ExecutableFlow;
import azkaban.executor.ExecutableNode;
@@ -31,6 +24,11 @@ import azkaban.executor.Status;
import azkaban.executor.mail.DefaultMailCreator;
import azkaban.executor.mail.MailCreator;
import azkaban.sla.SlaOption;
+import org.apache.log4j.Logger;
+
+import javax.mail.MessagingException;
+import java.util.ArrayList;
+import java.util.List;
public class Emailer extends AbstractMailer implements Alerter {
private static Logger logger = Logger.getLogger(Emailer.class);
@@ -46,6 +44,7 @@ public class Emailer extends AbstractMailer implements Alerter {
private String clientPortNumber;
private String mailHost;
+ private int mailPort;
private String mailUser;
private String mailPassword;
private String mailSender;
@@ -56,6 +55,7 @@ public class Emailer extends AbstractMailer implements Alerter {
super(props);
this.azkabanName = props.getString("azkaban.name", "azkaban");
this.mailHost = props.getString("mail.host", "localhost");
+ this.mailPort = props.getInt("mail.port", DEFAULT_SMTP_PORT);
this.mailUser = props.getString("mail.user", "");
this.mailPassword = props.getString("mail.password", "");
this.mailSender = props.getString("mail.sender", "");
@@ -105,7 +105,7 @@ public class Emailer extends AbstractMailer implements Alerter {
}
public void sendFirstErrorMessage(ExecutableFlow flow) {
- EmailMessage message = new EmailMessage(mailHost, mailUser, mailPassword);
+ EmailMessage message = new EmailMessage(mailHost, mailPort, mailUser, mailPassword);
message.setFromAddress(mailSender);
message.setTLS(tls);
message.setAuth(super.hasMailAuth());
@@ -132,7 +132,7 @@ public class Emailer extends AbstractMailer implements Alerter {
}
public void sendErrorEmail(ExecutableFlow flow, String... extraReasons) {
- EmailMessage message = new EmailMessage(mailHost, mailUser, mailPassword);
+ EmailMessage message = new EmailMessage(mailHost, mailPort, mailUser, mailPassword);
message.setFromAddress(mailSender);
message.setTLS(tls);
message.setAuth(super.hasMailAuth());
@@ -158,7 +158,7 @@ public class Emailer extends AbstractMailer implements Alerter {
}
public void sendSuccessEmail(ExecutableFlow flow) {
- EmailMessage message = new EmailMessage(mailHost, mailUser, mailPassword);
+ EmailMessage message = new EmailMessage(mailHost, mailPort, mailUser, mailPassword);
message.setFromAddress(mailSender);
message.setTLS(tls);
message.setAuth(super.hasMailAuth());
diff --git a/azkaban-common/src/main/java/azkaban/utils/EmailMessage.java b/azkaban-common/src/main/java/azkaban/utils/EmailMessage.java
index 0c4e208..b3b1aa5 100644
--- a/azkaban-common/src/main/java/azkaban/utils/EmailMessage.java
+++ b/azkaban-common/src/main/java/azkaban/utils/EmailMessage.java
@@ -16,14 +16,8 @@
package azkaban.utils;
-import java.io.File;
-import java.io.InputStream;
-import java.net.SocketTimeoutException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-import java.util.Properties;
+import com.sun.mail.smtp.SMTPTransport;
+import org.apache.log4j.Logger;
import javax.activation.DataHandler;
import javax.activation.DataSource;
@@ -36,10 +30,10 @@ import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
-
-import org.apache.log4j.Logger;
-
-import com.sun.mail.smtp.SMTPTransport;
+import java.io.File;
+import java.io.InputStream;
+import java.net.SocketTimeoutException;
+import java.util.*;
public class EmailMessage {
private final Logger logger = Logger.getLogger(EmailMessage.class);
@@ -47,6 +41,7 @@ public class EmailMessage {
private static String protocol = "smtp";
private List<String> _toAddress = new ArrayList<String>();
private String _mailHost;
+ private int _mailPort;
private String _mailUser;
private String _mailPassword;
private String _subject;
@@ -65,12 +60,13 @@ public class EmailMessage {
private ArrayList<BodyPart> _attachments = new ArrayList<BodyPart>();
public EmailMessage() {
- this("localhost", "", "");
+ this("localhost", AbstractMailer.DEFAULT_SMTP_PORT, "", "");
}
- public EmailMessage(String host, String user, String password) {
+ public EmailMessage(String host, int port, String user, String password) {
_mailUser = user;
_mailHost = host;
+ _mailPort = port;
_mailPassword = password;
}
@@ -201,6 +197,7 @@ public class EmailMessage {
props.put("mail." + protocol + ".auth", "false");
}
props.put("mail." + protocol + ".host", _mailHost);
+ props.put("mail." + protocol + ".port", _mailPort);
props.put("mail." + protocol + ".timeout", _mailTimeout);
props.put("mail." + protocol + ".connectiontimeout", _connectionTimeout);
props.put("mail.smtp.starttls.enable", _tls);
@@ -262,7 +259,7 @@ public class EmailMessage {
private void connectToSMTPServer(SMTPTransport t) throws MessagingException {
if (_usesAuth) {
- t.connect(_mailHost, _mailUser, _mailPassword);
+ t.connect(_mailHost, _mailPort, _mailUser, _mailPassword);
} else {
t.connect();
}
@@ -296,4 +293,8 @@ public class EmailMessage {
return _subject;
}
+ public int getMailPort(){
+ return _mailPort;
+ }
+
}
diff --git a/azkaban-common/src/test/java/azkaban/utils/AbstractMailerTest.java b/azkaban-common/src/test/java/azkaban/utils/AbstractMailerTest.java
new file mode 100644
index 0000000..5581201
--- /dev/null
+++ b/azkaban-common/src/test/java/azkaban/utils/AbstractMailerTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2017 LinkedIn Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package azkaban.utils;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class AbstractMailerTest {
+
+ List<String> senderList = new ArrayList<String>();
+
+
+ @Before
+ public void setUp() throws Exception {
+ senderList.add("sender@domain.com");
+ }
+ /**
+ * test emailMessage properties
+ */
+ @Test
+ public void testCreateEmailMessage(){
+
+ Props props = createMailProperties();
+ props.put("mail.port","445");
+ AbstractMailer mailer = new AbstractMailer(props);
+ EmailMessage emailMessage = mailer.createEmailMessage("subject","text/html",senderList);
+
+ assert emailMessage.getMailPort()==445;
+
+
+ }
+
+ @Test
+ public void testCreateDefaultEmailMessage()
+ {
+ Props defaultProps = createMailProperties();
+ AbstractMailer mailer = new AbstractMailer(defaultProps);
+ EmailMessage emailMessage = mailer.createEmailMessage("subject","text/html",senderList);
+ assert emailMessage.getMailPort()==25;
+
+ }
+
+ public static Props createMailProperties(){
+ Props props = new Props();
+ props.put("mail.user","somebody");
+ props.put("mail.password","pwd");
+ props.put("mail.sender","somebody@xxx.com");
+ props.put("server.port","114");
+ props.put("jetty.use.ssl","false");
+ props.put("server.useSSL","false");
+ props.put("jetty.port","8786");
+ return props;
+
+ }
+
+}
diff --git a/azkaban-common/src/test/java/azkaban/utils/EmailerTest.java b/azkaban-common/src/test/java/azkaban/utils/EmailerTest.java
new file mode 100644
index 0000000..95d81c2
--- /dev/null
+++ b/azkaban-common/src/test/java/azkaban/utils/EmailerTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2017 LinkedIn Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package azkaban.utils;
+
+import azkaban.executor.ExecutableFlow;
+import azkaban.flow.Flow;
+import azkaban.project.DirectoryFlowLoader;
+import azkaban.project.Project;
+import azkaban.test.executions.TestExecutions;
+import com.google.common.io.Resources;
+import org.apache.log4j.Logger;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+
+public class EmailerTest {
+
+ String host = "smtp.domain.com";//smtp server address
+ int mailPort = 25;//smtp server port
+ String sender = "somebody@domain.com";//sender email address
+ String user = "somebody@domain.com";// the sender username
+ String password = "pwd"; //the sender password
+
+ String receiveAddr = "receive@domain.com";//receiver email address
+ List<String> receiveAddrList = new ArrayList<String>();
+
+ private Project project;
+ private Props props;
+
+
+
+
+ @Before
+ public void setUp() throws Exception {
+ receiveAddrList.add(receiveAddr);
+ project = new Project(11, "myTestProject");
+ Logger logger = Logger.getLogger(this.getClass());
+
+ props = createMailProperties();
+ DirectoryFlowLoader loader = new DirectoryFlowLoader(props, logger);
+ loader.loadProjectFlow(project, TestExecutions.getFlowDir("embedded"));
+ Assert.assertEquals(0, loader.getErrors().size());
+ project.setFlows(loader.getFlowMap());
+ project.setVersion(123);
+ }
+
+
+ /**
+ * this is an integration test for Emailer sending email.
+ * if you want to run this case and send email successfully,
+ * please remove @Ignore and make sure these variable{host,mailPort,password,receiveAddr} are set to real values.
+ * the test will currently succeed because email sending errors are caught,
+ * you need to manually verify that a real email is sent and received.
+ */
+ @Ignore
+ @Test
+ public void testSendEmail() throws Exception{
+
+ Flow flow = project.getFlow("jobe");
+ flow.addFailureEmails(receiveAddrList);
+ Assert.assertNotNull(flow);
+
+ ExecutableFlow exFlow = new ExecutableFlow(project, flow);
+ Emailer emailer = new Emailer(props);
+ emailer.sendErrorEmail(exFlow);
+
+ }
+ @Test
+ public void testCreateEmailMessage(){
+ Emailer emailer = new Emailer(props);
+ EmailMessage em = emailer.createEmailMessage("subject","text/html",receiveAddrList);
+ assert em.getMailPort() == mailPort;
+
+ }
+
+
+
+
+ public Props createMailProperties(){
+ Props props = new Props();
+ props.put("mail.user",user);
+ props.put("mail.password",password);
+ props.put("mail.sender",sender);
+ props.put("mail.host",host);
+ props.put("mail.port",mailPort);
+ props.put("job.failure.email",receiveAddr);
+ props.put("server.port","114");
+ props.put("jetty.use.ssl","false");
+ props.put("server.useSSL","false");
+ props.put("jetty.port","8786");
+ return props;
+ }
+
+
+
+
+
+}
diff --git a/azkaban-common/src/test/java/azkaban/utils/EmailMessageTest.java b/azkaban-common/src/test/java/azkaban/utils/EmailMessageTest.java
index db5f00d..429c66b 100644
--- a/azkaban-common/src/test/java/azkaban/utils/EmailMessageTest.java
+++ b/azkaban-common/src/test/java/azkaban/utils/EmailMessageTest.java
@@ -16,18 +16,18 @@
package azkaban.utils;
-import java.io.IOException;
-
-import javax.mail.MessagingException;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
+import javax.mail.MessagingException;
+import java.io.IOException;
+
public class EmailMessageTest {
String host = "";
+ int port = 25;
String sender = "";
String user = "";
String password = "";
@@ -38,7 +38,7 @@ public class EmailMessageTest {
@Before
public void setUp() throws Exception {
- em = new EmailMessage(host, user, password);
+ em = new EmailMessage(host, port, user, password);
em.setFromAddress(sender);
}