azkaban-developers
Details
diff --git a/src/java/azkaban/scheduler/ScheduledFlow.java b/src/java/azkaban/scheduler/ScheduledFlow.java
index 20a22b8..54a7211 100644
--- a/src/java/azkaban/scheduler/ScheduledFlow.java
+++ b/src/java/azkaban/scheduler/ScheduledFlow.java
@@ -103,7 +103,7 @@ public class ScheduledFlow {
DateTime firstSchedTime,
ReadablePeriod period)
{
- this(scheduleId, projectId, flowId, user, userSubmit, submitTime, firstSchedTime, new DateTime(), period);
+ this(scheduleId, projectId, flowId, user, userSubmit, submitTime, firstSchedTime, new DateTime().withZone(firstSchedTime.getZone()), period);
}
public ScheduledFlow(
@@ -115,7 +115,7 @@ public class ScheduledFlow {
DateTime submitTime,
DateTime firstSchedTime)
{
- this(scheduleId, projectId, flowId, user, userSubmit, submitTime, firstSchedTime, new DateTime(), null);
+ this(scheduleId, projectId, flowId, user, userSubmit, submitTime, firstSchedTime, new DateTime().withZone(firstSchedTime.getZone()), null);
}
/**
diff --git a/src/java/azkaban/utils/DirectoryFlowLoader.java b/src/java/azkaban/utils/DirectoryFlowLoader.java
index d376522..ff1cca2 100644
--- a/src/java/azkaban/utils/DirectoryFlowLoader.java
+++ b/src/java/azkaban/utils/DirectoryFlowLoader.java
@@ -4,6 +4,7 @@ import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -56,7 +57,7 @@ public class DirectoryFlowLoader {
nodeDependencies = new HashMap<String, Map<String, Edge>>();
// Load all the props files and create the Node objects
- loadProjectFromDir(baseDirectory.getPath(), baseDirectory);
+ loadProjectFromDir(baseDirectory.getPath(), baseDirectory, null);
// Create edges and find missing dependencies
resolveDependencies();
@@ -66,9 +67,9 @@ public class DirectoryFlowLoader {
}
- private void loadProjectFromDir(String base, File dir) {
+ private void loadProjectFromDir(String base, File dir, Props parent) {
File[] propertyFiles = dir.listFiles(new SuffixFilter(PROPERTY_SUFFIX));
- Props parent = null;
+ Arrays.sort(propertyFiles);
for (File file: propertyFiles) {
String relative = getRelativeFilePath(base, file.getPath());
@@ -85,7 +86,8 @@ public class DirectoryFlowLoader {
logger.info("Adding " + relative);
propsList.add(parent);
}
-
+
+
// Load all Job files. If there's a duplicate name, then we don't load
File[] jobFiles = dir.listFiles(new SuffixFilter(JOB_SUFFIX));
for (File file: jobFiles) {
@@ -128,7 +130,7 @@ public class DirectoryFlowLoader {
File[] subDirs = dir.listFiles(DIR_FILTER);
for (File file: subDirs) {
- loadProjectFromDir(base, file);
+ loadProjectFromDir(base, file, parent);
}
}
src/java/azkaban/utils/Mailman.java 47(+47 -0)
diff --git a/src/java/azkaban/utils/Mailman.java b/src/java/azkaban/utils/Mailman.java
index 7fc828a..094ad55 100644
--- a/src/java/azkaban/utils/Mailman.java
+++ b/src/java/azkaban/utils/Mailman.java
@@ -17,9 +17,14 @@
package azkaban.utils;
import java.util.List;
+import java.util.Properties;
+import javax.mail.Message;
import javax.mail.MessagingException;
+import javax.mail.Session;
import javax.mail.internet.AddressException;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
import org.apache.commons.mail.EmailException;
@@ -27,6 +32,8 @@ import org.apache.commons.mail.SimpleEmail;
import org.apache.log4j.Logger;
+import com.sun.mail.smtp.SMTPTransport;
+
/**
* The mailman send you mail, if you ask him
*
@@ -39,6 +46,8 @@ public class Mailman {
private final String _mailUser;
private final String _mailPassword;
private final String _mailSender;
+
+ private final String protocol = "smtp";
public Mailman(String mailHost, String mailUser, String mailPassword,
String mailSender) {
@@ -50,6 +59,44 @@ public class Mailman {
public void sendEmail(String fromAddress, List<String> toAddress,
String subject, String body) throws MessagingException {
+<<<<<<< HEAD
+=======
+
+ //session
+ Properties props = new Properties();
+ props.put("mail." + protocol + ".host", _mailHost);
+ props.put("mail." + protocol + ".auth", "true");
+
+ Session session = Session.getInstance(props, null);
+ session.setDebug(true);
+
+ //email message
+ Message msg = new MimeMessage(session);
+ msg.setFrom(new InternetAddress(fromAddress));
+ for(String str : toAddress) {
+ msg.addRecipients(Message.RecipientType.TO, InternetAddress.parse(str));
+ }
+
+ msg.setSubject(subject);
+ msg.setText(body);
+
+ //transport
+ SMTPTransport t = (SMTPTransport)session.getTransport(protocol);
+
+ try {
+ t.connect(_mailHost, _mailUser, _mailPassword);
+ t.sendMessage(msg, msg.getAllRecipients());
+ }
+ catch (Exception e) {
+ logger.error(e);
+ }
+ finally {
+ t.close();
+ }
+
+
+
+>>>>>>> 7f1fd5f465d15e01aae522eceac6fc7863031bcb
// SimpleEmail email = new SimpleEmail();
//
// try {
diff --git a/src/java/azkaban/webapp/servlet/ProjectManagerServlet.java b/src/java/azkaban/webapp/servlet/ProjectManagerServlet.java
index 720f8f5..3f9caf5 100644
--- a/src/java/azkaban/webapp/servlet/ProjectManagerServlet.java
+++ b/src/java/azkaban/webapp/servlet/ProjectManagerServlet.java
@@ -641,8 +641,20 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
}
// Resolve property dependencies
- String source = node.getPropsSource();
- page.add("properties", source);
+ ArrayList<String> source = new ArrayList<String>();
+ String nodeSource = node.getPropsSource();
+ if(nodeSource != null) {
+ source.add(nodeSource);
+ Props parent = flow.getFlowProps(nodeSource).getProps();
+ while(parent.getParent() != null) {
+ source.add(parent.getParent().getSource());
+ parent = parent.getParent();
+ }
+ }
+ if(!source.isEmpty()) {
+ page.add("properties", source);
+ }
+
ArrayList<Pair<String,String>> parameters = new ArrayList<Pair<String, String>>();
// Parameter
diff --git a/src/java/azkaban/webapp/servlet/ScheduleServlet.java b/src/java/azkaban/webapp/servlet/ScheduleServlet.java
index bafb86b..211ea49 100644
--- a/src/java/azkaban/webapp/servlet/ScheduleServlet.java
+++ b/src/java/azkaban/webapp/servlet/ScheduleServlet.java
@@ -12,6 +12,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
import org.joda.time.Months;
import org.joda.time.Weeks;
import org.joda.time.Days;
@@ -144,6 +145,8 @@ public class ScheduleServlet extends LoginAbstractAzkabanServlet {
int hour = getIntParam(req, "hour");
int minutes = getIntParam(req, "minutes");
boolean isPm = getParam(req, "am_pm").equalsIgnoreCase("pm");
+
+ DateTimeZone timezone = getParam(req, "timezone").equals("UTC") ? DateTimeZone.UTC : DateTimeZone.forID("America/Los_Angeles");
String scheduledDate = req.getParameter("date");
@@ -152,7 +155,7 @@ public class ScheduleServlet extends LoginAbstractAzkabanServlet {
day = new LocalDateTime().toDateTime();
} else {
try {
- day = DateTimeFormat.forPattern("MM/dd/yyyy").parseDateTime(scheduledDate);
+ day = DateTimeFormat.forPattern("MM/dd/yyyy").withZone(timezone).parseDateTime(scheduledDate);
} catch(IllegalArgumentException e) {
ret.put("error", "Invalid date: '" + scheduledDate + "'");
return;
@@ -175,7 +178,7 @@ public class ScheduleServlet extends LoginAbstractAzkabanServlet {
String userSubmit = user.getUserId();
String userExec = userSubmit;//getParam(req, "userExec");
String scheduleId = projectId + "." + flowId;
- DateTime submitTime = new DateTime();
+ DateTime submitTime = new DateTime().withZone(timezone);
DateTime firstSchedTime = day.withHourOfDay(hour).withMinuteOfHour(minutes).withSecondOfMinute(0);
ScheduledFlow schedFlow = scheduleManager.schedule(scheduleId, projectId, flowId, userExec, userSubmit, submitTime, firstSchedTime, thePeriod);
diff --git a/src/java/azkaban/webapp/servlet/velocity/flowpage.vm b/src/java/azkaban/webapp/servlet/velocity/flowpage.vm
index 21a4e8b..96aaedf 100644
--- a/src/java/azkaban/webapp/servlet/velocity/flowpage.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/flowpage.vm
@@ -144,7 +144,10 @@
<option>pm</option>
<option>am</option>
</select>
- $timezone
+ <select id="timezone">
+ <option>PDT</option>
+ <option>UTC</option>
+ </select>
on
<br>
<p>Date: <input type="text" id="datepicker"></p>
diff --git a/src/java/azkaban/webapp/servlet/velocity/jobpage.vm b/src/java/azkaban/webapp/servlet/velocity/jobpage.vm
index 8dd6bbb..b1f6724 100644
--- a/src/java/azkaban/webapp/servlet/velocity/jobpage.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/jobpage.vm
@@ -67,7 +67,9 @@
</td></tr>
<tr><td class="first">Properties:</td><td>
#if ($properties)
- <a>$properties</a>
+#foreach($property in $properties)
+ <a>$property</a><span>,</span>
+#end
#else
<span>No Inherited Properties</span>
#end
src/web/js/azkaban.flow.view.js 2(+2 -0)
diff --git a/src/web/js/azkaban.flow.view.js b/src/web/js/azkaban.flow.view.js
index 17b9d27..c8aef95 100644
--- a/src/web/js/azkaban.flow.view.js
+++ b/src/web/js/azkaban.flow.view.js
@@ -871,6 +871,7 @@ azkaban.ScheduleFlowView = Backbone.View.extend({
var hourVal = $('#hour').val();
var minutesVal = $('#minutes').val();
var ampmVal = $('#am_pm').val();
+ var timezoneVal = $('#timezone').val();
var dateVal = $('#datepicker').val();
var is_recurringVal = $('#is_recurring').val();
var periodVal = $('#period').val();
@@ -890,6 +891,7 @@ azkaban.ScheduleFlowView = Backbone.View.extend({
hour:hourVal,
minutes:minutesVal,
am_pm:ampmVal,
+ timezone:timezoneVal,
date:dateVal,
userExec:"dummy",
is_recurring:is_recurringVal,
diff --git a/unit/java/azkaban/test/utils/MailmanTest.java b/unit/java/azkaban/test/utils/MailmanTest.java
new file mode 100644
index 0000000..3406114
--- /dev/null
+++ b/unit/java/azkaban/test/utils/MailmanTest.java
@@ -0,0 +1,58 @@
+package azkaban.test.utils;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import azkaban.utils.Mailman;
+
+
+public class MailmanTest {
+
+ private Mailman mailer;
+
+ private String user = "cyu";
+ private String password;
+ private String host = "email.corp.linkedin.com";
+ private String mailSender = "cyu@linkedin.com";
+
+ private Logger logger = Logger.getLogger(Mailman.class);
+
+ @Before
+ public void setUp() {
+
+ mailer = new Mailman(host, user, password, mailSender);
+
+
+ }
+
+ @Test
+ public void testSendEmail() {
+
+ String fromAddress = "cyu@linkedin.com";
+ List<String> toAddress = new ArrayList<String>();
+ //toAddress.add("cyu@linkedin.com");
+ toAddress.add("azkaban-test@linkedin.com");
+
+ String subject = "Azkaban Test email subject";
+ String body = "Azkaban Test email body";
+
+ try {
+ mailer.sendEmail(fromAddress, toAddress, subject, body);
+ }
+ catch (Exception e) {
+ Assert.assertTrue(true);
+ //please check email to see if this works
+ e.printStackTrace();
+ }
+
+ }
+
+
+}