azkaban-developers
Changes
azkaban-soloserver/.gitignore 2(+1 -1)
Details
diff --git a/azkaban-common/src/main/java/azkaban/project/ProjectManager.java b/azkaban-common/src/main/java/azkaban/project/ProjectManager.java
index 9bcbf05..4af1c9e 100644
--- a/azkaban-common/src/main/java/azkaban/project/ProjectManager.java
+++ b/azkaban-common/src/main/java/azkaban/project/ProjectManager.java
@@ -80,6 +80,9 @@ public class ProjectManager {
// initialize itself.
Props prop = new Props(props);
prop.put(ValidatorConfigs.PROJECT_ARCHIVE_FILE_PATH, "initialize");
+ // By instantiating an object of XmlValidatorManager, this will verify the
+ // config files for the validators.
+ new XmlValidatorManager(prop);
loadAllProjects();
}
@@ -360,7 +363,7 @@ public class ProjectManager {
* caller of this method should call method
* {@ProjectFileHandler.deleteLocalFile}
* to delete the temporary file.
- *
+ *
* @param project
* @param version - latest version is used if value is -1
* @return ProjectFileHandler - null if can't find project zip file based on
diff --git a/azkaban-common/src/main/java/azkaban/project/validator/ValidationReport.java b/azkaban-common/src/main/java/azkaban/project/validator/ValidationReport.java
index 9cccffb..e586ca1 100644
--- a/azkaban-common/src/main/java/azkaban/project/validator/ValidationReport.java
+++ b/azkaban-common/src/main/java/azkaban/project/validator/ValidationReport.java
@@ -7,32 +7,43 @@ import java.util.Set;
* The result of a project validation generated by a {@link ProjectValidator}. It contains
* an enum of type {@link ValidationStatus} representing whether the validation passes,
* generates warnings, or generates errors. Accordingly, three sets of String are also
- * maintained, storing the messages generated by the {@link ProjectValidator} at each of
- * the 3 {@link ValidationStatus} levels, i.e., {@link ValidationStatus#PASS},
- * {@link ValidationStatus#WARN}, and {@link ValidationStatus#ERROR}.
+ * maintained, storing the messages generated by the {@link ProjectValidator} at both
+ * {@link ValidationStatus#WARN} and {@link ValidationStatus#ERROR} level, as well as
+ * information messages associated with both levels.
*/
public class ValidationReport {
protected ValidationStatus _status;
- protected Set<String> _passMsgs;
+ protected Set<String> _infoMsgs;
protected Set<String> _warningMsgs;
protected Set<String> _errorMsgs;
public ValidationReport() {
_status = ValidationStatus.PASS;
- _passMsgs = new HashSet<String>();
+ _infoMsgs = new HashSet<String>();
_warningMsgs = new HashSet<String>();
_errorMsgs = new HashSet<String>();
}
/**
- * Add a message with status level being {@link ValidationStatus#PASS}
+ * Add an information message associated with warning messages
*
* @param msgs
*/
- public void addPassMsgs(Set<String> msgs) {
- if (msgs != null) {
- _passMsgs.addAll(msgs);
+ public void addWarnLevelInfoMsg(String msg) {
+ if (msg != null) {
+ _infoMsgs.add("WARN" + msg);
+ }
+ }
+
+ /**
+ * Add an information message associated with error messages
+ *
+ * @param msgs
+ */
+ public void addErrorLevelInfoMsg(String msg) {
+ if (msg != null) {
+ _infoMsgs.add("ERROR" + msg);
}
}
@@ -74,12 +85,12 @@ public class ValidationReport {
}
/**
- * Retrieve the messages associated with status level {@link ValidationStatus#PASS}
+ * Retrieve the list of information messages.
*
* @return
*/
- public Set<String> getPassMsgs() {
- return _passMsgs;
+ public Set<String> getInfoMsgs() {
+ return _infoMsgs;
}
/**
@@ -100,4 +111,35 @@ public class ValidationReport {
return _errorMsgs;
}
+ /**
+ * Return the severity level this information message is associated with.
+ *
+ * @param msg
+ * @return
+ */
+ public static ValidationStatus getInfoMsgLevel(String msg) {
+ if (msg.startsWith("ERROR")) {
+ return ValidationStatus.ERROR;
+ }
+ if (msg.startsWith("WARN")) {
+ return ValidationStatus.WARN;
+ }
+ return ValidationStatus.PASS;
+ }
+
+ /**
+ * Get the raw information message.
+ *
+ * @param msg
+ * @return
+ */
+ public static String getInfoMsg(String msg) {
+ if (msg.startsWith("ERROR")) {
+ return msg.replaceFirst("ERROR", "");
+ }
+ if (msg.startsWith("WARN")) {
+ return msg.replaceFirst("WARN", "");
+ }
+ return msg;
+ }
}
diff --git a/azkaban-common/src/test/java/azkaban/project/validator/ValidationReportTest.java b/azkaban-common/src/test/java/azkaban/project/validator/ValidationReportTest.java
new file mode 100644
index 0000000..4b4bb18
--- /dev/null
+++ b/azkaban-common/src/test/java/azkaban/project/validator/ValidationReportTest.java
@@ -0,0 +1,59 @@
+package azkaban.project.validator;
+
+import static org.junit.Assert.*;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.junit.Test;
+
+/**
+ * Test adding messages to {@link ValidationReport}
+ */
+public class ValidationReportTest {
+
+ @Test
+ public void testAddWarnLevelInfoMsg() {
+ ValidationReport report = new ValidationReport();
+ String msg = "test warn level info message.";
+ report.addWarnLevelInfoMsg(msg);
+ for (String info : report.getInfoMsgs()) {
+ assertEquals("Info message added through addWarnLevelInfoMsg should have level set to WARN",
+ ValidationReport.getInfoMsgLevel(info), ValidationStatus.WARN);
+ assertEquals("Retrieved info message does not match the original one.",
+ ValidationReport.getInfoMsg(info), msg);
+ }
+ }
+
+ @Test
+ public void testAddErrorLevelInfoMsg() {
+ ValidationReport report = new ValidationReport();
+ String msg = "test error level error message.";
+ report.addErrorLevelInfoMsg(msg);
+ for (String info : report.getInfoMsgs()) {
+ assertEquals("Info message added through addErrorLevelInfoMsg should have level set to ERROR",
+ ValidationReport.getInfoMsgLevel(info), ValidationStatus.ERROR);
+ assertEquals("Retrieved info message does not match the original one.",
+ ValidationReport.getInfoMsg(info), msg);
+ }
+ }
+
+ @Test
+ public void testAddMsgs() {
+ ValidationReport report = new ValidationReport();
+ Set<String> msgs = new HashSet<String>();
+ msgs.add("test msg 1.");
+ msgs.add("test msg 2.");
+ report.addWarningMsgs(msgs);
+ assertEquals("Level of severity is not warn.",
+ report.getStatus(), ValidationStatus.WARN);
+ report.addErrorMsgs(msgs);
+ assertEquals("Number of error messages retrieved does not match.",
+ report.getErrorMsgs().size(), 2);
+ assertEquals("Number of warn messages retrieved does not match.",
+ report.getWarningMsgs().size(), 2);
+ assertEquals("Level of severity is not error.",
+ report.getStatus(), ValidationStatus.ERROR);
+ }
+
+}
azkaban-soloserver/.gitignore 2(+1 -1)
diff --git a/azkaban-soloserver/.gitignore b/azkaban-soloserver/.gitignore
index 5ab4d17..eb3d928 100644
--- a/azkaban-soloserver/.gitignore
+++ b/azkaban-soloserver/.gitignore
@@ -4,5 +4,5 @@ executions/
plugins/
projects/
temp/
-validators/
+validator_jars/
*.log
diff --git a/azkaban-webserver/src/main/java/azkaban/webapp/servlet/AbstractAzkabanServlet.java b/azkaban-webserver/src/main/java/azkaban/webapp/servlet/AbstractAzkabanServlet.java
index 5b54af4..12c5993 100644
--- a/azkaban-webserver/src/main/java/azkaban/webapp/servlet/AbstractAzkabanServlet.java
+++ b/azkaban-webserver/src/main/java/azkaban/webapp/servlet/AbstractAzkabanServlet.java
@@ -52,6 +52,8 @@ public abstract class AbstractAzkabanServlet extends HttpServlet {
.forPattern("z");
private static final String AZKABAN_SUCCESS_MESSAGE =
"azkaban.success.message";
+ private static final String AZKABAN_WARN_MESSAGE =
+ "azkaban.warn.message";
private static final String AZKABAN_FAILURE_MESSAGE =
"azkaban.failure.message";
@@ -222,6 +224,20 @@ public abstract class AbstractAzkabanServlet extends HttpServlet {
}
/**
+ * Sets a warning message in azkaban.warn.message in the cookie. This will
+ * be used by the web client javascript to somehow display the message
+ *
+ * @param response
+ * @param warnMsg
+ */
+ protected void setWarnMessageInCookie(HttpServletResponse response,
+ String errorMsg) {
+ Cookie cookie = new Cookie(AZKABAN_WARN_MESSAGE, errorMsg);
+ cookie.setPath("/");
+ response.addCookie(cookie);
+ }
+
+ /**
* Sets a message in azkaban.success.message in the cookie. This will be used
* by the web client javascript to somehow display the message
*
@@ -251,6 +267,21 @@ public abstract class AbstractAzkabanServlet extends HttpServlet {
}
/**
+ * Retrieves a warn message from a cookie. azkaban.warn.message
+ *
+ * @param request
+ * @return
+ */
+ protected String getWarnMessageFromCookie(HttpServletRequest request) {
+ Cookie cookie = getCookieByName(request, AZKABAN_WARN_MESSAGE);
+
+ if (cookie == null) {
+ return null;
+ }
+ return cookie.getValue();
+ }
+
+ /**
* Retrieves a success message from a cookie. azkaban.failure.message
*
* @param request
@@ -312,6 +343,11 @@ public abstract class AbstractAzkabanServlet extends HttpServlet {
: errorMsg);
setErrorMessageInCookie(resp, null);
+ String warnMsg = getWarnMessageFromCookie(req);
+ page.add("warn_message", warnMsg == null || warnMsg.isEmpty() ? "null"
+ : warnMsg);
+ setWarnMessageInCookie(resp, null);
+
String successMsg = getSuccessMessageFromCookie(req);
page.add("success_message",
successMsg == null || successMsg.isEmpty() ? "null" : successMsg);
diff --git a/azkaban-webserver/src/main/java/azkaban/webapp/servlet/ProjectManagerServlet.java b/azkaban-webserver/src/main/java/azkaban/webapp/servlet/ProjectManagerServlet.java
index e7d5883..34a8fd8 100644
--- a/azkaban-webserver/src/main/java/azkaban/webapp/servlet/ProjectManagerServlet.java
+++ b/azkaban-webserver/src/main/java/azkaban/webapp/servlet/ProjectManagerServlet.java
@@ -426,9 +426,9 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
/**
* Download project zip file from DB and send it back client.
- *
+ *
* This method requires a project name and an optional project version.
- *
+ *
* @param req
* @param resp
* @param session
@@ -1582,34 +1582,50 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
Map<String, ValidationReport> reports =
projectManager.uploadProject(project, archiveFile, type, user,
props);
- StringBuffer message = new StringBuffer();
+ StringBuffer errorMsgs = new StringBuffer();
+ StringBuffer warnMsgs = new StringBuffer();
for (Entry<String, ValidationReport> reportEntry : reports.entrySet()) {
ValidationReport report = reportEntry.getValue();
- if (!report.getPassMsgs().isEmpty()) {
- for (String msg : report.getPassMsgs()) {
- message.append(msg + "<br/>");
+ if (!report.getInfoMsgs().isEmpty()) {
+ for (String msg : report.getInfoMsgs()) {
+ switch (ValidationReport.getInfoMsgLevel(msg)) {
+ case ERROR:
+ errorMsgs.append(ValidationReport.getInfoMsg(msg) + "<br/>");
+ break;
+ case WARN:
+ warnMsgs.append(ValidationReport.getInfoMsg(msg) + "<br/>");
+ break;
+ default:
+ break;
+ }
}
- message.append("<br/>");
}
if (!report.getErrorMsgs().isEmpty()) {
- message.append("Validator " + reportEntry.getKey()
+ errorMsgs.append("Validator " + reportEntry.getKey()
+ " reports errors:<ul>");
for (String msg : report.getErrorMsgs()) {
- message.append("<li>" + msg + "</li>");
+ errorMsgs.append("<li>" + msg + "</li>");
}
- message.append("</ul>");
+ errorMsgs.append("</ul>");
}
if (!report.getWarningMsgs().isEmpty()) {
- message.append("Validator " + reportEntry.getKey()
+ warnMsgs.append("Validator " + reportEntry.getKey()
+ " reports warnings:<ul>");
for (String msg : report.getWarningMsgs()) {
- message.append("<li>" + msg + "</li>");
+ warnMsgs.append("<li>" + msg + "</li>");
}
- message.append("</ul>");
+ warnMsgs.append("</ul>");
}
}
- if (message.length() > 0) {
- ret.put("error", message.toString());
+ if (errorMsgs.length() > 0) {
+ // If putting more than 4000 characters in the cookie, the entire message
+ // will somehow get discarded.
+ ret.put("error", errorMsgs.length() > 4000 ?
+ errorMsgs.substring(0, 4000) : errorMsgs.toString());
+ }
+ if (warnMsgs.length() > 0) {
+ ret.put("warn", warnMsgs.length() > 4000 ?
+ warnMsgs.substring(0, 4000) : warnMsgs.toString());
}
} catch (Exception e) {
logger.info("Installation Failed.", e);
@@ -1643,6 +1659,10 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
setErrorMessageInCookie(resp, ret.get("error"));
}
+ if (ret.containsKey("warn")) {
+ setWarnMessageInCookie(resp, ret.get("warn"));
+ }
+
resp.sendRedirect(req.getRequestURI() + "?project=" + projectName);
}
diff --git a/azkaban-webserver/src/main/resources/azkaban/webapp/servlet/velocity/alerts.vm b/azkaban-webserver/src/main/resources/azkaban/webapp/servlet/velocity/alerts.vm
index 10831fb..1516519 100644
--- a/azkaban-webserver/src/main/resources/azkaban/webapp/servlet/velocity/alerts.vm
+++ b/azkaban-webserver/src/main/resources/azkaban/webapp/servlet/velocity/alerts.vm
@@ -21,6 +21,11 @@
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
$error_message
</div>
+#elseif ($warn_message != "null")
+ <div class="alert alert-warning alert-dismissable">
+ <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
+ $warn_message
+ </div>
#elseif ($success_message != "null")
<div class="alert alert-success">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>