Пример #1
0
 public void updateProjectPermission(
     Project project, String name, Permission perm, boolean group, User modifier)
     throws ProjectManagerException {
   logger.info(
       "User "
           + modifier.getUserId()
           + " updating permissions for project "
           + project.getName()
           + " for "
           + name
           + " "
           + perm.toString());
   projectLoader.updatePermission(project, name, perm, group);
   if (group) {
     projectLoader.postEvent(
         project,
         EventType.GROUP_PERMISSION,
         modifier.getUserId(),
         "Permission for group " + name + " set to " + perm.toString());
   } else {
     projectLoader.postEvent(
         project,
         EventType.USER_PERMISSION,
         modifier.getUserId(),
         "Permission for user " + name + " set to " + perm.toString());
   }
 }
Пример #2
0
 public void updateProjectDescription(Project project, String description, User modifier)
     throws ProjectManagerException {
   projectLoader.updateDescription(project, description, modifier.getUserId());
   projectLoader.postEvent(
       project,
       EventType.DESCRIPTION,
       modifier.getUserId(),
       "Description changed to " + description);
 }
Пример #3
0
  public synchronized Project removeProject(Project project, User deleter)
      throws ProjectManagerException {
    projectLoader.removeProject(project, deleter.getUserId());
    projectLoader.postEvent(project, EventType.DELETED, deleter.getUserId(), null);

    projectsByName.remove(project.getName());
    projectsById.remove(project.getId());

    return project;
  }
Пример #4
0
  public boolean hasPermission(User user, Type type) {
    Permission perm = userPermissionMap.get(user.getUserId());
    if (perm != null && (perm.isPermissionSet(Type.ADMIN) || perm.isPermissionSet(type))) {
      return true;
    }

    return hasGroupPermission(user, type);
  }
Пример #5
0
  public void removeProjectProxyUser(Project project, String proxyName, User modifier)
      throws ProjectManagerException {
    logger.info(
        "User "
            + modifier.getUserId()
            + " removing proxy user "
            + proxyName
            + " from project "
            + project.getName());
    project.removeProxyUser(proxyName);

    projectLoader.postEvent(
        project,
        EventType.PROXY_USER,
        modifier.getUserId(),
        "Proxy user " + proxyName + " has been removed form the project.");
    updateProjectSetting(project);
  }
Пример #6
0
  public void addProjectProxyUser(Project project, String proxyName, User modifier)
      throws ProjectManagerException {
    logger.info(
        "User "
            + modifier.getUserId()
            + " adding proxy user "
            + proxyName
            + " to project "
            + project.getName());
    project.addProxyUser(proxyName);

    projectLoader.postEvent(
        project,
        EventType.PROXY_USER,
        modifier.getUserId(),
        "Proxy user " + proxyName + " is added to project.");
    updateProjectSetting(project);
  }
Пример #7
0
 /**
  * Permanently delete all project files and properties data for all versions of a project and log
  * event in project_events table
  *
  * @param project
  * @param deleter
  * @return
  * @throws ProjectManagerException
  */
 public synchronized Project purgeProject(Project project, User deleter)
     throws ProjectManagerException {
   projectLoader.cleanOlderProjectVersion(project.getId(), project.getVersion() + 1);
   projectLoader.postEvent(
       project,
       EventType.PURGE,
       deleter.getUserId(),
       String.format("Purged versions before %d", project.getVersion() + 1));
   return project;
 }
Пример #8
0
  public Project createProject(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.");
    } else if (!projectName.matches("[a-zA-Z][a-zA-Z_0-9|-]*")) {
      throw new ProjectManagerException(
          "Project names must start with a letter, followed by any number of letters, digits, '-' or '_'.");
    }

    if (projectsByName.contains(projectName)) {
      throw new ProjectManagerException("Project already exists.");
    }

    logger.info("Trying to create " + projectName + " by user " + creator.getUserId());
    Project newProject = projectLoader.createNewProject(projectName, description, creator);
    projectsByName.put(newProject.getName(), newProject);
    projectsById.put(newProject.getId(), newProject);

    if (creatorDefaultPermissions) {
      // Add permission to project
      projectLoader.updatePermission(
          newProject, creator.getUserId(), new Permission(Permission.Type.ADMIN), false);

      // Add proxy user
      newProject.getProxyUsers().add(creator.getUserId());
      try {
        updateProjectSetting(newProject);
      } catch (ProjectManagerException e) {
        e.printStackTrace();
        throw e;
      }
    }

    projectLoader.postEvent(newProject, EventType.CREATED, creator.getUserId(), null);

    return newProject;
  }
Пример #9
0
  public boolean hasUserPermission(User user, Type type) {
    Permission perm = userPermissionMap.get(user.getUserId());
    if (perm == null) {
      // Check group
      return false;
    }

    if (perm.isPermissionSet(Type.ADMIN) || perm.isPermissionSet(type)) {
      return true;
    }

    return false;
  }
Пример #10
0
 public void removeProjectPermission(Project project, String name, boolean group, User modifier)
     throws ProjectManagerException {
   logger.info(
       "User "
           + modifier.getUserId()
           + " removing permissions for project "
           + project.getName()
           + " for "
           + name);
   projectLoader.removePermission(project, name, group);
   if (group) {
     projectLoader.postEvent(
         project,
         EventType.GROUP_PERMISSION,
         modifier.getUserId(),
         "Permission for group " + name + " removed.");
   } else {
     projectLoader.postEvent(
         project,
         EventType.USER_PERMISSION,
         modifier.getUserId(),
         "Permission for user " + name + " removed.");
   }
 }
Пример #11
0
  public Permission getCollectivePermission(User user) {
    Permission permissions = new Permission();
    Permission perm = userPermissionMap.get(user.getUserId());
    if (perm != null) {
      permissions.addPermissions(perm);
    }

    for (String group : user.getGroups()) {
      perm = groupPermissionMap.get(group);
      if (perm != null) {
        permissions.addPermissions(perm);
      }
    }

    return permissions;
  }
Пример #12
0
  public void uploadProject(Project project, File archive, String fileType, User uploader)
      throws ProjectManagerException {
    logger.info("Uploading files to " + project.getName());

    // Unzip.
    File file = null;
    try {
      if (fileType == null) {
        throw new ProjectManagerException("Unknown file type for " + archive.getName());
      } else if ("zip".equals(fileType)) {
        file = unzipFile(archive);
      } else {
        throw new ProjectManagerException("Unsupported archive type for file " + archive.getName());
      }
    } catch (IOException e) {
      throw new ProjectManagerException("Error unzipping file.", e);
    }

    logger.info("Validating Flow for upload " + archive.getName());
    DirectoryFlowLoader loader = new DirectoryFlowLoader(logger);
    loader.loadProjectFlow(file);
    if (!loader.getErrors().isEmpty()) {
      logger.error("Error found in upload to " + project.getName() + ". Cleaning up.");

      try {
        FileUtils.deleteDirectory(file);
      } catch (IOException e) {
        file.deleteOnExit();
        e.printStackTrace();
      }

      StringBuffer errorMessage = new StringBuffer();
      errorMessage.append("Error found in upload. Cannot upload.\n");
      for (String error : loader.getErrors()) {
        errorMessage.append(error);
        errorMessage.append('\n');
      }

      throw new ProjectManagerException(errorMessage.toString());
    }

    Map<String, Props> jobProps = loader.getJobProps();
    List<Props> propProps = loader.getProps();

    synchronized (project) {
      int newVersion = projectLoader.getLatestProjectVersion(project) + 1;
      Map<String, Flow> flows = loader.getFlowMap();
      for (Flow flow : flows.values()) {
        flow.setProjectId(project.getId());
        flow.setVersion(newVersion);
      }

      logger.info("Uploading file to db " + archive.getName());
      projectLoader.uploadProjectFile(
          project, newVersion, fileType, archive.getName(), archive, uploader.getUserId());
      logger.info("Uploading flow to db " + archive.getName());
      projectLoader.uploadFlows(project, newVersion, flows.values());
      logger.info("Changing project versions " + archive.getName());
      projectLoader.changeProjectVersion(project, newVersion, uploader.getUserId());
      project.setFlows(flows);
      logger.info("Uploading Job properties");
      projectLoader.uploadProjectProperties(project, new ArrayList<Props>(jobProps.values()));
      logger.info("Uploading Props properties");
      projectLoader.uploadProjectProperties(project, propProps);
    }

    logger.info("Uploaded project files. Cleaning up temp files.");
    projectLoader.postEvent(
        project,
        EventType.UPLOADED,
        uploader.getUserId(),
        "Uploaded project files zip " + archive.getName());
    try {
      FileUtils.deleteDirectory(file);
    } catch (IOException e) {
      file.deleteOnExit();
      e.printStackTrace();
    }

    logger.info(
        "Cleaning up old install files older than "
            + (project.getVersion() - projectVersionRetention));
    projectLoader.cleanOlderProjectVersion(
        project.getId(), project.getVersion() - projectVersionRetention);
  }
Пример #13
0
 public Permission getUserPermission(User user) {
   return userPermissionMap.get(user.getUserId());
 }
Пример #14
0
  public Map<String, ValidationReport> uploadProject(
      Project project, File archive, String fileType, User uploader, Props additionalProps)
      throws ProjectManagerException {
    logger.info("Uploading files to " + project.getName());

    // Unzip.
    File file = null;
    try {
      if (fileType == null) {
        throw new ProjectManagerException("Unknown file type for " + archive.getName());
      } else if ("zip".equals(fileType)) {
        file = unzipFile(archive);
      } else {
        throw new ProjectManagerException("Unsupported archive type for file " + archive.getName());
      }
    } catch (IOException e) {
      throw new ProjectManagerException("Error unzipping file.", e);
    }

    // Since props is an instance variable of ProjectManager, and each
    // invocation to the uploadProject manager needs to pass a different
    // value for the PROJECT_ARCHIVE_FILE_PATH key, it is necessary to
    // create a new instance of Props to make sure these different values
    // are isolated from each other.
    Props prop = new Props(props);
    prop.putAll(additionalProps);
    prop.put(ValidatorConfigs.PROJECT_ARCHIVE_FILE_PATH, archive.getAbsolutePath());
    // Basically, we want to make sure that for different invocations to the
    // uploadProject method,
    // the validators are using different values for the
    // PROJECT_ARCHIVE_FILE_PATH configuration key.
    // In addition, we want to reload the validator objects for each upload, so
    // that we can change the validator configuration files without having to
    // restart Azkaban web server. If the XmlValidatorManager is an instance
    // variable, 2 consecutive invocations to the uploadProject
    // method might cause the second one to overwrite the
    // PROJECT_ARCHIVE_FILE_PATH configuration parameter
    // of the first, thus causing a wrong archive file path to be passed to the
    // validators. Creating a separate XmlValidatorManager object for each
    // upload will prevent this issue without having to add
    // synchronization between uploads. Since we're already reloading the XML
    // config file and creating validator objects for each upload, this does
    // not add too much additional overhead.
    ValidatorManager validatorManager = new XmlValidatorManager(prop);
    logger.info(
        "Validating project "
            + archive.getName()
            + " using the registered validators "
            + validatorManager.getValidatorsInfo().toString());
    Map<String, ValidationReport> reports = validatorManager.validate(project, file);
    ValidationStatus status = ValidationStatus.PASS;
    for (Entry<String, ValidationReport> report : reports.entrySet()) {
      if (report.getValue().getStatus().compareTo(status) > 0) {
        status = report.getValue().getStatus();
      }
    }
    if (status == ValidationStatus.ERROR) {
      logger.error("Error found in upload to " + project.getName() + ". Cleaning up.");

      try {
        FileUtils.deleteDirectory(file);
      } catch (IOException e) {
        file.deleteOnExit();
        e.printStackTrace();
      }

      return reports;
    }

    DirectoryFlowLoader loader = (DirectoryFlowLoader) validatorManager.getDefaultValidator();
    Map<String, Props> jobProps = loader.getJobProps();
    List<Props> propProps = loader.getProps();

    synchronized (project) {
      int newVersion = projectLoader.getLatestProjectVersion(project) + 1;
      Map<String, Flow> flows = loader.getFlowMap();
      for (Flow flow : flows.values()) {
        flow.setProjectId(project.getId());
        flow.setVersion(newVersion);
      }

      logger.info("Uploading file to db " + archive.getName());
      projectLoader.uploadProjectFile(
          project, newVersion, fileType, archive.getName(), archive, uploader.getUserId());
      logger.info("Uploading flow to db " + archive.getName());
      projectLoader.uploadFlows(project, newVersion, flows.values());
      logger.info("Changing project versions " + archive.getName());
      projectLoader.changeProjectVersion(project, newVersion, uploader.getUserId());
      project.setFlows(flows);
      logger.info("Uploading Job properties");
      projectLoader.uploadProjectProperties(project, new ArrayList<Props>(jobProps.values()));
      logger.info("Uploading Props properties");
      projectLoader.uploadProjectProperties(project, propProps);
    }

    logger.info("Uploaded project files. Cleaning up temp files.");
    projectLoader.postEvent(
        project,
        EventType.UPLOADED,
        uploader.getUserId(),
        "Uploaded project files zip " + archive.getName());
    try {
      FileUtils.deleteDirectory(file);
    } catch (IOException e) {
      file.deleteOnExit();
      e.printStackTrace();
    }

    logger.info(
        "Cleaning up old install files older than "
            + (project.getVersion() - projectVersionRetention));
    projectLoader.cleanOlderProjectVersion(
        project.getId(), project.getVersion() - projectVersionRetention);

    return reports;
  }
Пример #15
0
  private synchronized Project createNewProject(
      Connection connection, String name, String description, User creator)
      throws ProjectManagerException {
    QueryRunner runner = new QueryRunner();
    ProjectResultHandler handler = new ProjectResultHandler();

    // See if it exists first.
    try {
      List<Project> project =
          runner.query(
              connection, ProjectResultHandler.SELECT_ACTIVE_PROJECT_BY_NAME, handler, name);
      if (!project.isEmpty()) {
        throw new ProjectManagerException(
            "Active project with name " + name + " already exists in db.");
      }
    } catch (SQLException e) {
      logger.error(e);
      throw new ProjectManagerException("Checking for existing project failed. " + name, e);
    }

    final String INSERT_PROJECT =
        "INSERT INTO projects ( name, active, modified_time, create_time, version, last_modified_by, description, enc_type, settings_blob) values (?,?,?,?,?,?,?,?,?)";
    // Insert project
    try {
      long time = System.currentTimeMillis();
      int i =
          runner.update(
              connection,
              INSERT_PROJECT,
              name,
              true,
              time,
              time,
              null,
              creator.getUserId(),
              description,
              defaultEncodingType.getNumVal(),
              null);
      if (i == 0) {
        throw new ProjectManagerException("No projects have been inserted.");
      }
      connection.commit();

    } catch (SQLException e) {
      logger.error(INSERT_PROJECT + " failed.");
      try {
        connection.rollback();
      } catch (SQLException e1) {
        e1.printStackTrace();
      }
      throw new ProjectManagerException("Insert project for existing project failed. " + name, e);
    }

    // Do another query to grab and return the project.
    Project project = null;
    try {
      List<Project> projects =
          runner.query(
              connection, ProjectResultHandler.SELECT_ACTIVE_PROJECT_BY_NAME, handler, name);
      if (projects.isEmpty()) {
        throw new ProjectManagerException("No active project with name " + name + " exists in db.");
      } else if (projects.size() > 1) {
        throw new ProjectManagerException("More than one active project " + name);
      }

      project = projects.get(0);
    } catch (SQLException e) {
      logger.error(e);
      throw new ProjectManagerException("Checking for existing project failed. " + name, e);
    }

    return project;
  }