public static TermsOfUseAccessRequirement newAccessRequirement(UserGroup principal, Node node)
     throws DatastoreException {
   TermsOfUseAccessRequirement accessRequirement = new TermsOfUseAccessRequirement();
   accessRequirement.setCreatedBy(principal.getId());
   accessRequirement.setCreatedOn(new Date());
   accessRequirement.setModifiedBy(principal.getId());
   accessRequirement.setModifiedOn(new Date());
   accessRequirement.setEtag("10");
   accessRequirement.setAccessType(ACCESS_TYPE.DOWNLOAD);
   accessRequirement.setEntityIds(
       Arrays.asList(
           new String[] {
             node.getId(), node.getId()
           })); // test that repeated IDs doesn't break anything
   accessRequirement.setEntityType("com.sagebionetworks.repo.model.TermsOfUseAccessRequirements");
   return accessRequirement;
 }
 @After
 public void tearDown() throws Exception {
   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;
   }
   individualGroup = userGroupDAO.findGroup(TEST_USER_NAME, true);
   if (individualGroup != null) {
     userGroupDAO.delete(individualGroup.getId());
   }
 }
  @Test
  public void testCRUD() throws Exception {
    // Create a new object
    accessRequirement = newAccessRequirement(individualGroup, node);
    // PLFM-1477, we have to check that retrieval works when there is another access requirement
    accessRequirement2 = newAccessRequirement(individualGroup, node2);

    long initialCount = accessRequirementDAO.getCount();

    // Create it
    TermsOfUseAccessRequirement accessRequirementCopy =
        accessRequirementDAO.create(accessRequirement);
    accessRequirement = accessRequirementCopy;
    assertNotNull(accessRequirementCopy.getId());

    assertEquals(1 + initialCount, accessRequirementDAO.getCount());

    // Fetch it
    // PLFM-1477, we have to check that retrieval works when there is another access requirement
    accessRequirement2 = accessRequirementDAO.create(accessRequirement2);
    AccessRequirement clone = accessRequirementDAO.get(accessRequirement.getId().toString());
    assertNotNull(clone);
    assertEquals(accessRequirement, clone);

    // Get by Node Id
    Collection<AccessRequirement> ars = accessRequirementDAO.getForNode(node.getId());
    assertEquals(1, ars.size());
    assertEquals(accessRequirement, ars.iterator().next());

    // update it
    clone = ars.iterator().next();
    clone.setAccessType(ACCESS_TYPE.READ);
    AccessRequirement updatedAR = accessRequirementDAO.update(clone);
    assertEquals(clone.getAccessType(), updatedAR.getAccessType());

    assertTrue(
        "etags should be different after an update", !clone.getEtag().equals(updatedAR.getEtag()));

    try {
      ((TermsOfUseAccessRequirement) clone).setTermsOfUse("bar");
      accessRequirementDAO.update(clone);
      fail("conflicting update exception not thrown");
    } catch (ConflictingUpdateException e) {
      // We expected this exception
    }

    try {
      // Update from a backup.
      updatedAR = accessRequirementDAO.updateFromBackup(clone);
      assertEquals(clone.getEtag(), updatedAR.getEtag());
    } catch (ConflictingUpdateException e) {
      fail("Update from backup should not generate exception even if the e-tag is different.");
    }

    QueryResults<MigratableObjectData> migrationData =
        accessRequirementDAO.getMigrationObjectData(0, 10000, true);

    List<MigratableObjectData> results = migrationData.getResults();
    assertEquals(1 + 1 + initialCount, results.size()); // "+1" for extra AR added to test PLFM-1477
    assertEquals(migrationData.getTotalNumberOfResults(), results.size());

    boolean foundAr = false;
    for (MigratableObjectData od : results) {
      MigratableObjectDescriptor obj = od.getId();
      assertNotNull(obj.getId());
      assertNotNull(od.getEtag());
      assertEquals(MigratableObjectType.ACCESSREQUIREMENT, obj.getType());
      assertNotNull(od.getDependencies());
      if (obj.getId().equals(clone.getId().toString())) {
        foundAr = true;
        Collection<MigratableObjectDescriptor> deps = od.getDependencies();
        assertTrue(deps.size() > 0); // is dependent on 'node'
        boolean foundNode = false;
        for (MigratableObjectDescriptor d : deps) {
          if (d.getId().equals(node.getId())) {
            foundNode = true;
          }
          assertEquals(MigratableObjectType.ENTITY, d.getType());
        }
        assertTrue("dependencies: " + deps, foundNode);
      }
    }
    assertTrue(foundAr);

    // Delete it
    accessRequirementDAO.delete(accessRequirement.getId().toString());
    accessRequirementDAO.delete(accessRequirement2.getId().toString());

    assertEquals(initialCount, accessRequirementDAO.getCount());
  }