diff --git a/src/restli/java/azkaban/restli/ProjectManagerResource.java b/src/restli/java/azkaban/restli/ProjectManagerResource.java
new file mode 100644
index 0000000..7c862d8
--- /dev/null
+++ b/src/restli/java/azkaban/restli/ProjectManagerResource.java
@@ -0,0 +1,120 @@
+package azkaban.restli;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.servlet.ServletException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.log4j.Logger;
+
+import azkaban.project.Project;
+import azkaban.project.ProjectManager;
+import azkaban.project.ProjectManagerException;
+import azkaban.user.Permission;
+import azkaban.user.User;
+import azkaban.user.UserManagerException;
+import azkaban.utils.Utils;
+import azkaban.webapp.AzkabanWebServer;
+
+import com.linkedin.restli.server.annotations.Action;
+import com.linkedin.restli.server.annotations.ActionParam;
+import com.linkedin.restli.server.annotations.RestLiActions;
+import com.linkedin.restli.server.resources.ResourceContextHolder;
+
+@RestLiActions(name = "project", namespace = "azkaban.restli")
+public class ProjectManagerResource extends ResourceContextHolder {
+ private static final Logger logger = Logger.getLogger(ProjectManagerResource.class);
+
+ public AzkabanWebServer getAzkaban() {
+ return AzkabanWebServer.getInstance();
+ }
+
+ @Action(name = "deploy")
+ public String deploy(
+ @ActionParam("session.id") String sessionId,
+ @ActionParam("project.name") String projectName,
+ @ActionParam("package.url") String packageUrl)
+ throws ProjectManagerException, UserManagerException, ServletException, IOException {
+ logger.info("Deploy called. {session.id: " + sessionId +
+ ", project.name: " + projectName +
+ ", package.url:" + packageUrl + "}");
+
+ User user = ResourceUtils.getUserFromSessionId(sessionId);
+ ProjectManager projectManager = getAzkaban().getProjectManager();
+ Project project = projectManager.getProject(projectName);
+ if (project == null) {
+ throw new ProjectManagerException("Project '" + projectName + "' not found.");
+ }
+
+ if (!ResourceUtils.hasPermission(project, user, Permission.Type.WRITE)) {
+ logger.error("User " + user.getUserId() + " has no permission to write to project " + project.getName());
+ throw new ProjectManagerException("User '" + user + "' doesn't have permissions to deploy to " + project.getName());
+ }
+
+ // Deploy stuff here. Move the code to a more formal area later.
+ logger.info("Downloading file from " + packageUrl);
+ URL url = null;
+ InputStream in = null;
+ try {
+ url = new URL(packageUrl);
+ in = url.openStream();
+ } catch (MalformedURLException e) {
+ logger.error("Url " + packageUrl + " is malformed.", e);
+ throw new ProjectManagerException("Url " + packageUrl + " is malformed.", e);
+ } catch (IOException e) {
+ logger.error("Error opening input stream.", e);
+ throw new ProjectManagerException("Error opening input stream. Couldn't download file.", e);
+ }
+
+ String filename = getFileName(url.getFile());
+
+ BufferedInputStream buff = new BufferedInputStream(in);
+ File tempDir = Utils.createTempDir();
+ OutputStream out = null;
+
+ try {
+ logger.error("Downloading " + filename);
+ File archiveFile = new File(tempDir, filename);
+ out = new BufferedOutputStream(new FileOutputStream(archiveFile));
+ IOUtils.copy(buff, out);
+ out.close();
+
+ logger.error("Downloaded to " + archiveFile.toString() + " " + archiveFile.length() + " bytes.");
+ projectManager.uploadProject(project, archiveFile, "zip", user);
+ } catch (Exception e) {
+ logger.info("Installation Failed.", e);
+ String error = e.getMessage();
+ if (error.length() > 512) {
+ error = error.substring(0, 512) + "\nToo many errors to display.\n";
+ }
+
+ throw new ProjectManagerException("Installation failed: " + error);
+ }
+ finally {
+ if (tempDir.exists()) {
+ FileUtils.deleteDirectory(tempDir);
+ }
+ if (buff != null) {
+ buff.close();
+ }
+ if (out != null) {
+ out.close();
+ }
+ }
+
+ return Integer.toString(project.getVersion());
+ }
+
+ private String getFileName(String file) {
+ return file.substring(file.lastIndexOf("/") + 1);
+ }
+}
diff --git a/src/restli/java/azkaban/restli/ResourceUtils.java b/src/restli/java/azkaban/restli/ResourceUtils.java
new file mode 100644
index 0000000..1a8e340
--- /dev/null
+++ b/src/restli/java/azkaban/restli/ResourceUtils.java
@@ -0,0 +1,38 @@
+package azkaban.restli;
+
+import azkaban.project.Project;
+import azkaban.user.Permission;
+import azkaban.user.Role;
+import azkaban.user.User;
+import azkaban.user.UserManager;
+import azkaban.user.UserManagerException;
+import azkaban.webapp.AzkabanWebServer;
+import azkaban.webapp.session.Session;
+
+public class ResourceUtils {
+ public static boolean hasPermission(Project project, User user, Permission.Type type) {
+ UserManager userManager = AzkabanWebServer.getInstance().getUserManager();
+ if (project.hasPermission(user, type)) {
+ return true;
+ }
+
+ for (String roleName: user.getRoles()) {
+ Role role = userManager.getRole(roleName);
+ if (role.getPermission().isPermissionSet(type) ||
+ role.getPermission().isPermissionSet(Permission.Type.ADMIN)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public static User getUserFromSessionId(String sessionId) throws UserManagerException {
+ Session session = AzkabanWebServer.getInstance().getSessionCache().getSession(sessionId);
+ if (session == null) {
+ throw new UserManagerException("Invalid session. Login required");
+ }
+
+ return session.getUser();
+ }
+}
diff --git a/src/restli/java/azkaban/restli/UserManagerResource.java b/src/restli/java/azkaban/restli/UserManagerResource.java
index c4ce82c..60b3ad7 100644
--- a/src/restli/java/azkaban/restli/UserManagerResource.java
+++ b/src/restli/java/azkaban/restli/UserManagerResource.java
@@ -3,41 +3,39 @@ package azkaban.restli;
import java.util.UUID;
import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
+
+import org.apache.log4j.Logger;
import azkaban.restli.user.User;
import azkaban.user.UserManager;
import azkaban.user.UserManagerException;
-import azkaban.webapp.AzkabanServer;
import azkaban.webapp.AzkabanWebServer;
import azkaban.webapp.session.Session;
import com.linkedin.restli.server.annotations.Action;
import com.linkedin.restli.server.annotations.ActionParam;
-import com.linkedin.restli.server.annotations.Context;
import com.linkedin.restli.server.annotations.RestLiActions;
import com.linkedin.restli.server.resources.ResourceContextHolder;
@RestLiActions(name = "user", namespace = "azkaban.restli")
public class UserManagerResource extends ResourceContextHolder {
- private AzkabanServer azkaban;
-
+ private static final Logger logger = Logger.getLogger(UserManagerResource.class);
+
public AzkabanWebServer getAzkaban() {
return AzkabanWebServer.getInstance();
}
- public void setAzkaban(AzkabanServer azkaban) {
- this.azkaban = azkaban;
- }
-
@Action(name = "login")
public String login(
@ActionParam("username") String username,
@ActionParam("password") String password)
throws UserManagerException, ServletException {
String ip = this.getContext().getRequestHeaders().get("client_ip");
-
+ logger.info("Attempting to login for " + username + " from ip '" + ip + "'");
+
Session session = createSession(username, password, ip);
+
+ logger.info("Session id " + session.getSessionId() + " created for user '" + username + "' and ip " + ip);
return session.getSessionId();
}
@@ -62,7 +60,8 @@ public class UserManagerResource extends ResourceContextHolder {
String randomUID = UUID.randomUUID().toString();
Session session = new Session(randomUID, user, ip);
-
+ getAzkaban().getSessionCache().addSession(session);
+
return session;
}