@After
 public void tearDown() throws Exception {
   if (accessApproval != null && accessApproval.getId() != null) {
     accessApprovalDAO.delete(accessApproval.getId().toString());
   }
   if (accessApproval2 != null && accessApproval2.getId() != null) {
     accessApprovalDAO.delete(accessApproval2.getId().toString());
   }
   if (accessRequirement != null && accessRequirement.getId() != null) {
     accessRequirementDAO.delete(accessRequirement.getId().toString());
   }
   if (accessRequirement2 != null && accessRequirement2.getId() != null) {
     accessRequirementDAO.delete(accessRequirement2.getId().toString());
   }
   if (node != null && nodeDAO != null) {
     nodeDAO.delete(node.getId());
     node = null;
   }
   if (node2 != null && nodeDAO != null) {
     nodeDAO.delete(node2.getId());
     node2 = null;
   }
   if (evaluation != null && evaluationDAO != null) {
     evaluationDAO.delete(evaluation.getId());
     evaluation = null;
   }
   individualGroup = userGroupDAO.findGroup(TEST_USER_NAME, true);
   if (individualGroup != null) {
     userGroupDAO.delete(individualGroup.getId());
   }
   individualGroup2 = userGroupDAO.findGroup(TEST_USER_NAME_2, true);
   if (individualGroup2 != null) {
     userGroupDAO.delete(individualGroup2.getId());
   }
 }
  /**
   * Note: There are two types of scoring, that in which each submission is scored alone and that in
   * which the entire set of submissions is rescored whenever a new one arrives.
   *
   * @throws SynapseException
   * @throws JSONObjectAdapterException
   */
  public void execute() throws SynapseException, IOException, JSONObjectAdapterException {
    long startTime = System.currentTimeMillis();
    long total = Integer.MAX_VALUE;
    int started = 0;
    for (int offset = 0; offset < total; offset += PAGE_SIZE) {
      PaginatedResults<SubmissionBundle> submissionPGs = null;
      submissionPGs =
          synapseAdmin.getAllSubmissionBundlesByStatus(
              evaluation.getId(), SubmissionStatusEnum.RECEIVED, offset, PAGE_SIZE);
      total = (int) submissionPGs.getTotalNumberOfResults();
      List<SubmissionBundle> page = submissionPGs.getResults();
      for (int i = 0; i < page.size(); i++) {
        SubmissionBundle bundle = page.get(i);
        Submission sub = bundle.getSubmission();
        FileHandle fileHandle = getFileHandleFromEntityBundle(sub.getEntityBundleJSON());
        SubmissionStatus status = bundle.getSubmissionStatus();
        // Retrieve and run COUNT_QUERY.  If > 0 then execute Docker image
        String tableId = readStringAnnotation(status, TABLE_ID_ANNOTATION_NAME);
        String countQuery = readStringAnnotation(status, COUNT_QUERY_ANNOTATION_NAME);
        if (tableId != null && countQuery != null) {
          int count = executeCountQuery(tableId, countQuery);
          if (count == 0) {
            System.out.println("Count query returned 0: " + countQuery);
            continue; // nothing to process, so skip this submission
          }
        }
        // if no tableId or no countQuery then run the image
        // it's then the image's job to put this information in the annotations
        try {
          String dockerReference = getDockerReferenceFromFileHandle(fileHandle);
          if (readStringAnnotation(status, DOCKER_REPOSITORY_ANNOTATION_NAME) == null)
            addAnnotation(status, DOCKER_REPOSITORY_ANNOTATION_NAME, dockerReference, false);
          status.setStatus(SubmissionStatusEnum.EVALUATION_IN_PROGRESS);
          status = synapseAdmin.updateSubmissionStatus(status);
          // we run the image if either (1) there are new rows to process of (2) it hasn't been run
          // before
          runOneImage(fileHandle, sub.getId());
          // make sure that the Docker reference is in an annotation so it can be displayed
          started++;
        } catch (Exception e) {
          status = synapseAdmin.getSubmissionStatus(sub.getId());
          if (status.getStatus() != SubmissionStatusEnum.RECEIVED) {
            status.setStatus(SubmissionStatusEnum.RECEIVED);
            status = synapseAdmin.updateSubmissionStatus(status);
          }
          // TODO send failure notification to submitter
          e.printStackTrace();
        }
      }
    }

    long delta = System.currentTimeMillis() - startTime;
    System.out.println("Started " + started + " jobs.  Elapsed time: " + formatInterval(delta));
  }
  @Test
  public void testUnmetARsForEvaluation() throws Exception {
    RestrictableObjectDescriptor rod =
        AccessRequirementUtilsTest.createRestrictableObjectDescriptor(
            evaluation.getId(), RestrictableObjectType.EVALUATION);
    // Logic for unmet requirements doesn't reflect ownership at the DAO level.  It's factored in at
    // the manager level.
    // Therefore, the owner see unmet ARs for herself..
    List<Long> unmetARIds =
        accessRequirementDAO.unmetAccessRequirements(
            rod,
            Arrays.asList(new Long[] {Long.parseLong(individualGroup.getId())}),
            participateAndDownload);
    assertEquals(1, unmetARIds.size());
    assertEquals(accessRequirement2.getId(), unmetARIds.iterator().next());
    // ... just as someone else does, if they haven't signed the ToU
    unmetARIds =
        accessRequirementDAO.unmetAccessRequirements(
            rod,
            Arrays.asList(new Long[] {Long.parseLong(individualGroup2.getId())}),
            participateAndDownload);
    assertEquals(1, unmetARIds.size());
    assertEquals(accessRequirement2.getId(), unmetARIds.iterator().next());

    // Create a new object
    accessApproval2 = newAccessApproval(individualGroup2, accessRequirement2);

    // Create it
    accessApproval2 = accessApprovalDAO.create(accessApproval2);
    String id = accessApproval2.getId().toString();
    assertNotNull(id);

    // no unmet requirement anymore ...
    assertTrue(
        accessRequirementDAO
            .unmetAccessRequirements(
                rod,
                Arrays.asList(new Long[] {Long.parseLong(individualGroup2.getId())}),
                participateAndDownload)
            .isEmpty());

    // Get by evaluation Id
    Collection<AccessApproval> ars =
        accessApprovalDAO.getForAccessRequirementsAndPrincipals(
            Arrays.asList(new String[] {accessRequirement2.getId().toString()}),
            Arrays.asList(new String[] {individualGroup2.getId().toString()}));
    assertEquals(1, ars.size());
    assertEquals(accessApproval2, ars.iterator().next());
  }