azkaban-aplcache
Changes
conf/azkaban.properties 3(+2 -1)
src/java/azkaban/project/Project.java 93(+92 -1)
src/java/azkaban/project/ProjectManager.java 41(+5 -36)
src/java/azkaban/user/Permission.java 72(+72 -0)
src/java/azkaban/user/User.java 25(+25 -0)
src/java/azkaban/webapp/AzkabanWebServer.java 40(+13 -27)
src/web/js/azkaban.job.view.js 31(+29 -2)
Details
conf/azkaban.properties 3(+2 -1)
diff --git a/conf/azkaban.properties b/conf/azkaban.properties
index 960d0d0..0eabd49 100644
--- a/conf/azkaban.properties
+++ b/conf/azkaban.properties
@@ -11,7 +11,8 @@ user.manager.class=azkaban.user.XmlUserManager
user.manager.xml.file=conf/azkaban-users.xml
#Loader for projects
-project.loader.class=azkaban.project.FileProjectLoader
+project.manager.class=azkaban.project.FileProjectManager
+file.project.loader.path=projects
project.global.properties=conf/global.properties
# Velocity dev mode
diff --git a/src/java/azkaban/project/FileProjectLoader.java b/src/java/azkaban/project/FileProjectLoader.java
index eb59751..373d845 100644
--- a/src/java/azkaban/project/FileProjectLoader.java
+++ b/src/java/azkaban/project/FileProjectLoader.java
@@ -4,12 +4,36 @@ import java.io.File;
import java.util.HashMap;
import java.util.Map;
+import org.apache.log4j.Logger;
+
import azkaban.utils.Props;
+/**
+ * ProjectManager that stores everything on local file system.
+ * The following global parameters should be set -
+ * file.project.loader.path - The project install path where projects will be loaded installed to.
+ */
public class FileProjectLoader implements ProjectLoader {
-
+ public static final String DIRECTORY_PARAM = "file.project.loader.path";
+ private static final Logger logger = Logger.getLogger(FileProjectLoader.class);
+ private File projectDirectory;
+
public FileProjectLoader(Props props) {
-
+ String projectDir = props.getString(DIRECTORY_PARAM);
+ logger.info("Using directory " + projectDir + " as the project directory.");
+ projectDirectory = new File(projectDir);
+ if (!projectDirectory.exists()) {
+ logger.info("Directory " + projectDir + " doesn't exist. Creating.");
+ if (projectDirectory.mkdirs()) {
+ logger.info("Directory creation was successful.");
+ }
+ else {
+ throw new RuntimeException("FileProjectLoader cannot create directory " + projectDirectory);
+ }
+ }
+ else if (projectDirectory.isFile()) {
+ throw new RuntimeException("FileProjectManager directory " + projectDirectory + " is really a file.");
+ }
}
@Override
@@ -19,8 +43,7 @@ public class FileProjectLoader implements ProjectLoader {
}
@Override
- public void addProject(Project project, File directory) {
- // TODO Auto-generated method stub
+ public void addProject(Project project) {
}
@@ -30,10 +53,5 @@ public class FileProjectLoader implements ProjectLoader {
return false;
}
- @Override
- public void init(Props props) {
- // TODO Auto-generated method stub
-
- }
}
\ No newline at end of file
diff --git a/src/java/azkaban/project/FileProjectManager.java b/src/java/azkaban/project/FileProjectManager.java
new file mode 100644
index 0000000..315cb0b
--- /dev/null
+++ b/src/java/azkaban/project/FileProjectManager.java
@@ -0,0 +1,83 @@
+package azkaban.project;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.log4j.Logger;
+
+import azkaban.user.User;
+import azkaban.utils.Props;
+
+/**
+ * A project loader that stores everything on local file system.
+ * The following global parameters should be set -
+ * file.project.loader.path - The project install path where projects will be loaded installed to.
+ */
+public class FileProjectManager implements ProjectManager {
+ public static final String DIRECTORY_PARAM = "file.project.loader.path";
+ private static final Logger logger = Logger.getLogger(FileProjectManager.class);
+ private ConcurrentHashMap<String, Project> projects = new ConcurrentHashMap<String, Project>();
+ private File projectDirectory;
+
+ public FileProjectManager(Props props) {
+ setupDirectories(props);
+ }
+
+ private void setupDirectories(Props props) {
+ String projectDir = props.getString(DIRECTORY_PARAM);
+ logger.info("Using directory " + projectDir + " as the project directory.");
+ projectDirectory = new File(projectDir);
+ if (!projectDirectory.exists()) {
+ logger.info("Directory " + projectDir + " doesn't exist. Creating.");
+ if (projectDirectory.mkdirs()) {
+ logger.info("Directory creation was successful.");
+ }
+ else {
+ throw new RuntimeException("FileProjectLoader cannot create directory " + projectDirectory);
+ }
+ }
+ else if (projectDirectory.isFile()) {
+ throw new RuntimeException("FileProjectManager directory " + projectDirectory + " is really a file.");
+ }
+ }
+
+ public List<String> getProjectNames() {
+ return new ArrayList<String>(projects.keySet());
+ }
+
+ public Project getProject(String name) {
+ return projects.get(name);
+ }
+
+ @Override
+ public synchronized Project createProjects(String projectName, String description, User creator) throws ProjectManagerException {
+ if (projectName == null || projectName.trim().isEmpty()) {
+ throw new ProjectManagerException("Project name cannot be empty.");
+ }
+ else if (description == null || description.trim().isEmpty()) {
+ throw new ProjectManagerException("Description cannot be empty.");
+ }
+ else if (creator == null) {
+ throw new ProjectManagerException("Valid creator user must be set.");
+ }
+
+ if (projects.contains(projectName)) {
+ throw new ProjectManagerException("Project already exists.");
+ }
+
+ Project project = new Project(projectName);
+ return project;
+ }
+
+ public Project loadProjects() {
+ return null;
+ }
+
+ @Override
+ public synchronized Project removeProjects(String projectName) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+}
\ No newline at end of file
src/java/azkaban/project/Project.java 93(+92 -1)
diff --git a/src/java/azkaban/project/Project.java b/src/java/azkaban/project/Project.java
index 8cb42b5..24ed79e 100644
--- a/src/java/azkaban/project/Project.java
+++ b/src/java/azkaban/project/Project.java
@@ -1,8 +1,20 @@
package azkaban.project;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import azkaban.user.Permission;
+import azkaban.user.User;
+
public class Project {
private final String name;
-
+ private String description;
+ private long createTimestamp;
+ private long lastModifiedTimestamp;
+ private HashMap<String, Permission> userToPermission = new HashMap<String, Permission>();
+
public Project(String name) {
this.name = name;
}
@@ -10,4 +22,83 @@ public class Project {
public String getName() {
return name;
}
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setUserPermission(String userid, Permission flags) {
+ userToPermission.put(userid, flags);
+ }
+
+ public Permission getUserPermission(User user) {
+ return userToPermission.get(user.getUserId());
+ }
+
+ public long getCreateTimestamp() {
+ return createTimestamp;
+ }
+
+ public void setCreateTimestamp(long createTimestamp) {
+ this.createTimestamp = createTimestamp;
+ }
+
+ public long getLastModifiedTimestamp() {
+ return lastModifiedTimestamp;
+ }
+
+ public void setLastModifiedTimestamp(long lastModifiedTimestamp) {
+ this.lastModifiedTimestamp = lastModifiedTimestamp;
+ }
+
+ public Object toObject() {
+ HashMap<String,Object> projectObject = new HashMap<String, Object>();
+ projectObject.put("name", name);
+ projectObject.put("description", description);
+ projectObject.put("createTimestamp", createTimestamp);
+ projectObject.put("lastModifiedTimestamp",lastModifiedTimestamp);
+
+ ArrayList<Map<String,Object>> users = new ArrayList<Map<String,Object>>();
+ for (Map.Entry<String, Permission> entry: userToPermission.entrySet()) {
+ HashMap<String,Object> userMap = new HashMap<String,Object>();
+ userMap.put("userid", entry.getKey());
+ userMap.put("permissions", entry.getValue().toStringArray());
+ users.add(userMap);
+ }
+
+ projectObject.put("users", users);
+ return projectObject;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Project projectFromObject(Object object) {
+ Map<String,Object> projectObject = (Map<String,Object>)object;
+ String name = (String)projectObject.get("name");
+ String description = (String)projectObject.get("description");
+ long createTimestamp = (Long)projectObject.get("createTimestamp");
+ long lastModifiedTimestamp = (Long)projectObject.get("lastModifiedTimestamp");
+
+ Project project = new Project(name);
+ project.setDescription(description);
+ project.setCreateTimestamp(createTimestamp);
+ project.setLastModifiedTimestamp(lastModifiedTimestamp);
+
+
+ List<Map<String,Object>> users = (List<Map<String,Object>>)projectObject.get("users");
+
+ for (Map<String, Object> user: users) {
+ String userid = (String)user.get("userid");
+ Permission perm = new Permission();
+ List<String> list = (List<String>)user.get("permissions");
+ perm.setPermissions(list);
+
+ project.setUserPermission(userid, perm);
+ }
+
+ return null;
+ }
}
diff --git a/src/java/azkaban/project/ProjectLoader.java b/src/java/azkaban/project/ProjectLoader.java
index 86433dc..0d6db75 100644
--- a/src/java/azkaban/project/ProjectLoader.java
+++ b/src/java/azkaban/project/ProjectLoader.java
@@ -6,11 +6,10 @@ import java.util.Map;
import azkaban.utils.Props;
public interface ProjectLoader {
- public void init(Props props);
public Map<String, Project> loadAllProjects();
- public void addProject(Project project, File directory);
+ public void addProject(Project project);
public boolean removeProject(Project project);
}
src/java/azkaban/project/ProjectManager.java 41(+5 -36)
diff --git a/src/java/azkaban/project/ProjectManager.java b/src/java/azkaban/project/ProjectManager.java
index ddc0ea3..de17ea4 100644
--- a/src/java/azkaban/project/ProjectManager.java
+++ b/src/java/azkaban/project/ProjectManager.java
@@ -1,47 +1,16 @@
package azkaban.project;
-import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.apache.log4j.Logger;
import azkaban.user.User;
-import azkaban.utils.Props;
-public class ProjectManager {
- private static final Logger logger = Logger.getLogger(ProjectManager.class);
- private ConcurrentHashMap<String, Project> projects = new ConcurrentHashMap<String, Project>();
- private ProjectLoader loader;
+public interface ProjectManager {
- public ProjectManager(Props props, ProjectLoader loader) throws Exception {
- projects.putAll(loader.loadAllProjects());
- }
-
- public List<String> getProjectNames() {
- return new ArrayList<String>(projects.keySet());
- }
+ public List<String> getProjectNames();
- public Project getProject(String name) {
- return projects.get(name);
- }
+ public Project getProject(String name);
- public Project createProjects(String projectName, String description, User creator) throws ProjectManagerException {
- if (projectName == null || projectName.trim().isEmpty()) {
- throw new ProjectManagerException("Project name cannot be empty.");
- }
- else if (description == null || description.trim().isEmpty()) {
- throw new ProjectManagerException("Description cannot be empty.");
- }
- else if (creator == null) {
- throw new ProjectManagerException("Valid creator user must be set.");
- }
-
-
- return null;
- }
+ public Project createProjects(String projectName, String description, User creator) throws ProjectManagerException;
- public Project loadProjects() {
- return null;
- }
+ public Project removeProjects(String projectName) throws ProjectManagerException;
}
\ No newline at end of file
src/java/azkaban/user/Permission.java 72(+72 -0)
diff --git a/src/java/azkaban/user/Permission.java b/src/java/azkaban/user/Permission.java
new file mode 100644
index 0000000..81e95de
--- /dev/null
+++ b/src/java/azkaban/user/Permission.java
@@ -0,0 +1,72 @@
+package azkaban.user;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+public class Permission {
+ public static final String[] PERMISSIONS = {"READ", "WRITE", "EXECUTE", "SCHEDULE", "DELETE", "ADMIN"};
+ private static final Map<String, Integer> PERMISSIONS_TO_INDEX = new HashMap<String,Integer>();
+
+ static {
+ int i = 0;
+ for (String perm: PERMISSIONS) {
+ PERMISSIONS_TO_INDEX.put(perm, i++);
+ }
+ }
+
+ private boolean[] flags;
+
+ public Permission() {
+ flags = new boolean[PERMISSIONS.length];
+ }
+
+ public void setPermissions(String ... list) {
+ for (String perm: list) {
+ Integer index = PERMISSIONS_TO_INDEX.get(perm);
+ if (index != null) {
+ flags[index] = true;
+ }
+ }
+ }
+
+ public void setPermissions(Collection<String> list) {
+ for (String perm: list) {
+ Integer index = PERMISSIONS_TO_INDEX.get(perm);
+ if (index != null) {
+ flags[index] = true;
+ }
+ }
+ }
+
+ public void unsetPermissions(String ... list) {
+ for (String perm: list) {
+ Integer index = PERMISSIONS_TO_INDEX.get(perm);
+ if (index != null) {
+ flags[index] = false;
+ }
+ }
+ }
+
+ public boolean isPermissionSet(String permission) {
+ Integer index = PERMISSIONS_TO_INDEX.get(permission);
+ if (index != null) {
+ return flags[index];
+ }
+
+ return false;
+ }
+
+ public String[] toStringArray() {
+ ArrayList<String> list = new ArrayList<String>();
+ int count = 0;
+ for (int i = 0; i < flags.length; ++i) {
+ if (flags[i]) {
+ list.add(PERMISSIONS[i]);
+ count++;
+ }
+ }
+ return list.toArray(new String[count]);
+ }
+}
src/java/azkaban/user/User.java 25(+25 -0)
diff --git a/src/java/azkaban/user/User.java b/src/java/azkaban/user/User.java
index aa965e9..2e6859b 100644
--- a/src/java/azkaban/user/User.java
+++ b/src/java/azkaban/user/User.java
@@ -54,4 +54,29 @@ public class User {
groupStr += "]";
return userid + ": " + groupStr;
}
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((userid == null) ? 0 : userid.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ User other = (User) obj;
+ if (userid == null) {
+ if (other.userid != null)
+ return false;
+ } else if (!userid.equals(other.userid))
+ return false;
+ return true;
+ }
}
diff --git a/src/java/azkaban/user/XmlUserManager.java b/src/java/azkaban/user/XmlUserManager.java
index 8b91fe3..8e0b30e 100644
--- a/src/java/azkaban/user/XmlUserManager.java
+++ b/src/java/azkaban/user/XmlUserManager.java
@@ -48,7 +48,7 @@ public class XmlUserManager implements UserManager {
private HashMap<String, String> userPassword;
/**
- * The constructor. Takes
+ * The constructor.
*
* @param props
*/
src/java/azkaban/webapp/AzkabanWebServer.java 40(+13 -27)
diff --git a/src/java/azkaban/webapp/AzkabanWebServer.java b/src/java/azkaban/webapp/AzkabanWebServer.java
index ff174aa..150a962 100644
--- a/src/java/azkaban/webapp/AzkabanWebServer.java
+++ b/src/java/azkaban/webapp/AzkabanWebServer.java
@@ -36,6 +36,7 @@ import org.mortbay.jetty.servlet.ServletHolder;
import org.mortbay.thread.QueuedThreadPool;
import azkaban.project.FileProjectLoader;
+import azkaban.project.FileProjectManager;
import azkaban.project.ProjectLoader;
import azkaban.project.ProjectManager;
import azkaban.user.UserManager;
@@ -63,7 +64,7 @@ import joptsimple.OptionSpec;
* default.timezone.id - The timezone code. I.E. America/Los Angeles
*
* user.manager.class - The UserManager class used for the user manager. Default is XmlUserManager.
- * project.loader.class - The ProjectLoader class used by the ProjectManager to load classes.
+ * project.manager.class - The ProjectManager to load projects
* project.global.properties - The base properties inherited by all projects and jobs
*
* jetty.maxThreads - # of threads for jetty
@@ -86,7 +87,7 @@ public class AzkabanWebServer {
private static final int DEFAULT_THREAD_NUMBER = 10;
private static final String VELOCITY_DEV_MODE_PARAM = "velocity.dev.mode";
private static final String USER_MANAGER_CLASS_PARAM = "user.manager.class";
- private static final String PROJECT_LOADER_CLASS_PARAM = "project.loader.class";
+ private static final String PROJECT_MANAGER_CLASS_PARAM = "project.manager.class";
private static final String DEFAULT_STATIC_DIR = "";
private final VelocityEngine velocityEngine;
@@ -154,43 +155,28 @@ public class AzkabanWebServer {
}
private ProjectManager loadProjectManager(Props props) {
+ Class<?> projectManagerClass = props.getClass(PROJECT_MANAGER_CLASS_PARAM, null);
+ logger.info("Loading project manager class " + projectManagerClass.getName());
ProjectManager manager = null;
- try {
- ProjectLoader projectLoader = loadProjectLoader(props);
- manager = new ProjectManager(props, projectLoader);
- }
- catch(Exception e) {
- logger.error(e);
- throw new RuntimeException(e);
- }
-
- return manager;
- }
-
- private ProjectLoader loadProjectLoader(Props props) {
- Class<?> projectLoaderClass = props.getClass(PROJECT_LOADER_CLASS_PARAM,null);
- logger.info("Loading project loader class " + projectLoaderClass.getName());
- ProjectLoader loader = null;
- if (projectLoaderClass != null
- && projectLoaderClass.getConstructors().length > 0) {
+ if (projectManagerClass != null
+ && projectManagerClass.getConstructors().length > 0) {
try {
- Constructor<?> projectLoaderConstructor = projectLoaderClass.getConstructor(Props.class);
- loader = (ProjectLoader)projectLoaderConstructor.newInstance(props);
+ Constructor<?> projectManagerConstructor = projectManagerClass.getConstructor(Props.class);
+ manager = (ProjectManager)projectManagerConstructor.newInstance(props);
}
catch (Exception e) {
- logger.error("Could not instantiate UserManager "
- + projectLoaderClass.getName());
+ logger.error("Could not instantiate ProjectManager "
+ + projectManagerClass.getName());
throw new RuntimeException(e);
}
} else {
- logger.info("By default, using FileProjectLoader");
- loader = new FileProjectLoader(props);
+ manager = new FileProjectManager(props);
}
- return loader;
+ return manager;
}
/**
diff --git a/src/java/azkaban/webapp/servlet/AzkabanServletContextListener.java b/src/java/azkaban/webapp/servlet/AzkabanServletContextListener.java
index 3877adb..e1e99f7 100644
--- a/src/java/azkaban/webapp/servlet/AzkabanServletContextListener.java
+++ b/src/java/azkaban/webapp/servlet/AzkabanServletContextListener.java
@@ -44,5 +44,4 @@ public class AzkabanServletContextListener implements ServletContextListener {
event.getServletContext().setAttribute(AZKABAN_SERVLET_CONTEXT_KEY, this.app);
}
-
}
diff --git a/src/java/azkaban/webapp/servlet/LoginAbstractAzkabanServlet.java b/src/java/azkaban/webapp/servlet/LoginAbstractAzkabanServlet.java
index 1c915d8..76ec115 100644
--- a/src/java/azkaban/webapp/servlet/LoginAbstractAzkabanServlet.java
+++ b/src/java/azkaban/webapp/servlet/LoginAbstractAzkabanServlet.java
@@ -1,6 +1,7 @@
package azkaban.webapp.servlet;
import java.io.IOException;
+import java.io.Writer;
import java.util.UUID;
import javax.servlet.ServletException;
@@ -74,8 +75,7 @@ public abstract class LoginAbstractAzkabanServlet extends
private void handleLogin(HttpServletRequest req, HttpServletResponse resp,
String errorMsg) throws ServletException, IOException {
- Page page = newPage(req, resp,
- "azkaban/webapp/servlet/velocity/login.vm");
+ Page page = newPage(req, resp, "azkaban/webapp/servlet/velocity/login.vm");
if (errorMsg != null) {
page.add("errorMsg", errorMsg);
}
@@ -109,12 +109,24 @@ public abstract class LoginAbstractAzkabanServlet extends
getApplication().getSessionCache().addSession(session);
handleGet(req, resp, session);
} else {
- handleLogin(req, resp, "Enter username and password");
+ if (isAjaxCall(req)) {
+ String response = createJsonResponse("error", "Incorrect Login.", "login", null);
+ writeResponse(resp, response);
+ }
+ else {
+ handleLogin(req, resp, "Enter username and password");
+ }
}
} else {
Session session = getSessionFromRequest(req);
if (session == null) {
- handleLogin(req, resp, "Invalid session");
+ if (isAjaxCall(req)) {
+ String response = createJsonResponse("error", "Invalid Session. Need to re-login", "login", null);
+ writeResponse(resp, response);
+ }
+ else {
+ handleLogin(req, resp, "Enter username and password");
+ }
} else {
handlePost(req, resp, session);
}
@@ -122,13 +134,35 @@ public abstract class LoginAbstractAzkabanServlet extends
} else {
Session session = getSessionFromRequest(req);
if (session == null) {
- handleLogin(req, resp);
+ if (isAjaxCall(req)) {
+ String response = createJsonResponse("error", "Invalid Session. Need to re-login", "login", null);
+ writeResponse(resp, response);
+ }
+ else {
+ handleLogin(req, resp, "Enter username and password");
+ }
} else {
handlePost(req, resp, session);
}
}
}
+ protected void writeResponse(HttpServletResponse resp, String response) throws IOException {
+ Writer writer = resp.getWriter();
+ writer.append(response);
+ writer.flush();
+ }
+
+ protected boolean isAjaxCall(HttpServletRequest req) throws ServletException {
+ String value = req.getHeader("X-Requested-With");
+ if (value != null) {
+ logger.info("has X-Requested-With " + value);
+ return value.equals("XMLHttpRequest");
+ }
+
+ return false;
+ }
+
/**
* The get request is handed off to the implementor after the user is logged in.
*
diff --git a/src/java/azkaban/webapp/servlet/ProjectManagerServlet.java b/src/java/azkaban/webapp/servlet/ProjectManagerServlet.java
index 77cf86f..2f52bbd 100644
--- a/src/java/azkaban/webapp/servlet/ProjectManagerServlet.java
+++ b/src/java/azkaban/webapp/servlet/ProjectManagerServlet.java
@@ -54,34 +54,36 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
private void handleCreate(HttpServletRequest req, HttpServletResponse resp,
Session session) throws ServletException {
-// String projectName = hasParam(req, "name") ? getParam(req, "name") : null;
-// String projectDescription = hasParam(req, "description") ? getParam(req, "description") : null;
-// logger.info("Create project " + projectName);
-//
-// User user = session.getUser();
-// HashMap<String, Object> responseObj = new HashMap<String, Object>();
-// String status = null;
-// String redirect = null;
-// String message = null;
-//
-// try {
-// manager.createProjects(projectName, projectDescription, user);
-// status = "success";
-// redirect = "manager?project=" + projectName;
-// } catch (ProjectManagerException e) {
-// message = e.getMessage();
-// status = "error";
-// }
-//
-// String response = createJsonResponse(status, message, redirect, null);
-// try {
-// Writer write = resp.getWriter();
-// write.append(response);
-// write.flush();
-// } catch (IOException e) {
-// // TODO Auto-generated catch block
-// e.printStackTrace();
-// }
+ String projectName = hasParam(req, "name") ? getParam(req, "name") : null;
+ String projectDescription = hasParam(req, "description") ? getParam(req, "description") : null;
+ logger.info("Create project " + projectName);
+
+ User user = session.getUser();
+
+ String status = null;
+ String action = null;
+ String message = null;
+ HashMap<String, Object> params = null;
+ try {
+ manager.createProjects(projectName, projectDescription, user);
+ status = "success";
+ action = "redirect";
+ String redirect = "manager?project=" + projectName;
+ params = new HashMap<String, Object>();
+ params.put("path", redirect);
+ } catch (ProjectManagerException e) {
+ message = e.getMessage();
+ status = "error";
+ }
+
+ String response = createJsonResponse(status, message, action, params);
+ try {
+ Writer write = resp.getWriter();
+ write.append(response);
+ write.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
}
}
diff --git a/src/java/azkaban/webapp/servlet/velocity/index.vm b/src/java/azkaban/webapp/servlet/velocity/index.vm
index 06987e7..5dbf298 100644
--- a/src/java/azkaban/webapp/servlet/velocity/index.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/index.vm
@@ -44,26 +44,31 @@
<h3>Create Project</h3>
<div id="errorMsg" class="box-error-message">$errorMsg</div>
<div class="message">
- <form id="deployform" method="post" action="$!context">
- <fieldset>
- <dl>
- <dt><label for="path">Project Name</label></dt>
- <dd><input id="path" name="project" type="text" size="20" title="The project name."/>
- </dd>
- <dt>Description</dt>
- <dd><textarea id="description" name="description" rows="2" cols="40"></textarea></dd>
-
- <input name="action" type="hidden" value="create" />
- <input name="redirect" type="hidden" value="$!context/" />
- </dl>
- </fieldset>
- </form>
+ <fieldset>
+ <dl>
+ <dt><label for="path">Project Name</label></dt>
+ <dd><input id="path" name="project" type="text" size="20" title="The project name."/>
+ </dd>
+ <dt>Description</dt>
+ <dd><textarea id="description" name="description" rows="2" cols="40"></textarea></dd>
+
+ <input name="action" type="hidden" value="create" />
+ <input name="redirect" type="hidden" value="$!context/" />
+ </dl>
+ </fieldset>
</div>
<div class="actions">
<a class="yes btn2" id="create-btn" href="#">Create Project</a>
<a class="no simplemodal-close btn3" href="#">Cancel</a>
</div>
</div>
+ <div id="invalid-session" class="modal">
+ <h3>Invalid Session</h3>
+ <p>Session has expired. Please re-login.</p>
+ <div class="actions">
+ <a class="yes btn2" id="login-btn" href="#">Re-login</a>
+ </div>
+ </div>
</html>
src/web/js/azkaban.job.view.js 31(+29 -2)
diff --git a/src/web/js/azkaban.job.view.js b/src/web/js/azkaban.job.view.js
index b89abfb..2670304 100644
--- a/src/web/js/azkaban.job.view.js
+++ b/src/web/js/azkaban.job.view.js
@@ -63,8 +63,35 @@ azkaban.CreateProjectView= Backbone.View.extend({
$("#errorMsg").hide();
},
handleCreateProject : function(evt) {
- console.log("Deploying");
- $("#deployform").submit();
+ // First make sure we can upload
+ var projectName = $('#path').val();
+ var description = $('#description').val();
+
+ console.log("Creating");
+ $.ajax({
+ async: "false",
+ url: "manager",
+ dataType: "json",
+ type: "POST",
+ data: {action:"create", name:projectName, description:description},
+ success: function(data) {
+ if (data.status == "success") {
+ if (data.action == "redirect") {
+ window.location = data.path;
+ }
+ }
+ else {
+ if (data.action == "login") {
+ window.location = "";
+ }
+ else {
+ $("#errorMsg").text("ERROR: " + data.message);
+ $("#errorMsg").slideDown("fast");
+ }
+ }
+ }
+ });
+
},
render: function() {
}