package org.dataone.integration.it.testImplementations; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.math.BigInteger; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import org.dataone.client.RetryHandler; import org.dataone.client.v1.itk.D1Object; import org.dataone.client.v1.types.D1TypeBuilder; import org.dataone.integration.APITestUtils; import org.dataone.integration.ContextAwareTestCaseDataone; import org.dataone.integration.ExampleUtilities; import org.dataone.integration.adapters.CNCallAdapter; import org.dataone.integration.adapters.CommonCallAdapter; import org.dataone.integration.adapters.MNCallAdapter; import org.dataone.integration.webTest.WebTestDescription; import org.dataone.integration.webTest.WebTestName; import org.dataone.service.exceptions.BaseException; import org.dataone.service.exceptions.InvalidRequest; import org.dataone.service.exceptions.InvalidSystemMetadata; import org.dataone.service.exceptions.NotAuthorized; import org.dataone.service.exceptions.NotFound; import org.dataone.service.exceptions.ServiceFailure; import org.dataone.service.exceptions.SynchronizationFailed; import org.dataone.service.types.v1.AccessPolicy; import org.dataone.service.types.v1.AccessRule; import org.dataone.service.types.v1.Identifier; import org.dataone.service.types.v1.Node; import org.dataone.service.types.v1.NodeReference; import org.dataone.service.types.v1.NodeState; import org.dataone.service.types.v1.NodeType; import org.dataone.service.types.v1.Permission; import org.dataone.service.types.v1.Replica; import org.dataone.service.types.v1.ReplicationPolicy; import org.dataone.service.types.v1.ReplicationStatus; import org.dataone.service.types.v1.Service; import org.dataone.service.types.v1.Services; import org.dataone.service.types.v1.Subject; import org.dataone.service.types.v2.NodeList; import org.dataone.service.types.v2.SystemMetadata; import org.dataone.service.types.v2.TypeFactory; import org.dataone.service.util.Constants; public class MNUpdateSystemMetadataTestImplementations extends UpdateSystemMetadataTestImplementations { private CNCallAdapter cn; private static final long METACAT_INDEXING_WAIT = 10000; private static final long REPLICATION_WAIT = 45 * 60 * 1000; public MNUpdateSystemMetadataTestImplementations(ContextAwareTestCaseDataone catc) { super(catc); } protected MNCallAdapter getCallAdapter(Node node, String version) { return new MNCallAdapter(getSession("testRightsHolder"), node, version); } public void setup(Node cNode) { cn = new CNCallAdapter(getSession(cnSubmitter), cNode, "v2"); } @WebTestName("updateSystemMetadata - tests if the call fails with an unauthorized MN certificate subject") @WebTestDescription("this test calls updateSystemMetadata() with a non-authoritative MN certificate subject " + "and expects a NotAuthorized exception to be thrown") public void testUpdateSystemMetadata_NotAuthorizedMN(Iterator nodeIterator, String version) { while (nodeIterator.hasNext()) testUpdateSystemMetadata_NotAuthorizedMN(nodeIterator.next(), version); } // @Ignore'd in test class: No MN test certificates to test with at the moment public void testUpdateSystemMetadata_NotAuthorizedMN(Node node, String version) { assertTrue("Should be @Ignore'd", false); // String mnSubject = no MN test certs to use; // CommonCallAdapter cnCertCallAdapter = new CommonCallAdapter(getSession(cnSubmitter), node, version); // CommonCallAdapter mnCertCallAdapter = new CommonCallAdapter(getSession(mnSubject), node, version); // String currentUrl = node.getBaseURL(); // printTestHeader("testUpdateSystemMetadata_NotAuthorizedMN(...) vs. node: " + currentUrl); // currentUrl = cnCertCallAdapter.getNodeBaseServiceUrl(); // // try { // AccessRule accessRule = APITestUtils.buildAccessRule(rightsHolderSubjStr, Permission.CHANGE_PERMISSION); // Identifier pid = new Identifier(); // pid.setValue("testUpdateSystemMetadata_NotAuthorizedMN_" + ExampleUtilities.generateIdentifier()); // Identifier testObjPid = catc.procureTestObject(cnCertCallAdapter, accessRule, pid); // // SystemMetadata sysmeta = cnCertCallAdapter.getSystemMetadata(null, testObjPid); // sysmeta.setSerialVersion(sysmeta.getSerialVersion().add(BigInteger.ONE)); // mnCertCallAdapter.updateSystemMetadata(null, testObjPid , sysmeta); // handleFail(mnCertCallAdapter.getLatestRequestUrl(), "updateSystemMetadata call should fail for a connection with unauthorized certificate"); // } // catch (NotAuthorized e) { // // expected // } // catch (BaseException e) { // handleFail(cnCertCallAdapter.getLatestRequestUrl(), "Expected a NotAuthorized exception. Got: " + // e.getClass().getSimpleName() + ": " + e.getDetail_code() + ": " + e.getDescription()); // } // catch(Exception e) { // e.printStackTrace(); // handleFail(currentUrl, "Expected a NotAuthorized exception. Got: " + e.getClass().getName() + // ": " + e.getMessage()); // } } @WebTestName("updateSystemMetadata - tests that the updateSystemMetadata call works for a rights holder") @WebTestDescription("this test calls updateSystemMetadata() using an object's rights-holder " + "as the certificate subject to update the metadata, " + "checks that the call was successful, then also uses getSystemMetadata() " + "to fetch the new metadata and check that for " + "dateSysMetadataModified") public void testUpdateSystemMetadata_RightsHolder(Iterator nodeIterator, String version) { while (nodeIterator.hasNext()) testUpdateSystemMetadata_RightsHolder(nodeIterator.next(), version); } public void testUpdateSystemMetadata_RightsHolder(Node node, String version) { CommonCallAdapter callAdapter = getCallAdapter(node, version); String currentUrl = node.getBaseURL(); printTestHeader("testUpdateSystemMetadata_RightsHolder(...) vs. node: " + currentUrl); currentUrl = callAdapter.getNodeBaseServiceUrl(); try { getSession("testRightsHolder"); String rightsHolderSubjStr = catc.getSubject("testRightsHolder").getValue(); AccessRule accessRule = APITestUtils.buildAccessRule(rightsHolderSubjStr, Permission.CHANGE_PERMISSION); Identifier pid = new Identifier(); pid.setValue("testUpdateSystemMetadata_RightsHolder_" + ExampleUtilities.generateIdentifier()); Identifier testObjPid = catc.createTestObject(callAdapter, pid, accessRule); SystemMetadata sysmeta = callAdapter.getSystemMetadata(null, testObjPid); Date originalDate = sysmeta.getDateSysMetadataModified(); boolean success = callAdapter.updateSystemMetadata(null, testObjPid , sysmeta); assertTrue("Call to updateSystemMetadata() should be successful.", success); Thread.sleep(METACAT_INDEXING_WAIT); SystemMetadata fetchedSysmeta = callAdapter.getSystemMetadata(null, testObjPid); boolean dateModifiedMatches = fetchedSysmeta.getDateSysMetadataModified().after(originalDate); assertTrue("System metadata should now have updated dateSysMetadataModified", dateModifiedMatches ); } catch (ServiceFailure e) { // ServiceFailure is an allowed outcome for the MN.updateSystemMetadata() log.warn("MN.updateSystemMetadata() returned a ServiceFailure."); } catch (SynchronizationFailed e) { handleFail(callAdapter.getLatestRequestUrl(), e.getClass().getSimpleName() + ": " + "CN may throw SynchronizationFailed on a valid call to updateSystemMetadata. MN should not. " + e.getDetail_code() + ": " + e.getDescription()); } catch (BaseException e) { handleFail(callAdapter.getLatestRequestUrl(), e.getClass().getSimpleName() + ": " + e.getDetail_code() + ": " + e.getDescription()); } catch(Exception e) { e.printStackTrace(); handleFail(currentUrl, e.getClass().getName() + ": " + e.getMessage()); } } @WebTestName("updateSystemMetadata - tests that the rights holder can change mutable fields with updateSystemMetadata") @WebTestDescription("this test calls updateSystemMetadata() using an object's rights-holder " + "as the certificate subject to update the system metadata. " + "It modifies the rightsHolder field in the system metadata when making the " + "getSystemMetadata() call and verifies that no exception is thrown " + "(that the mutable field can be modified by the rights holder). ") public void testUpdateSystemMetadata_MutableRightsHolder(Iterator nodeIterator, String version) { while (nodeIterator.hasNext()) testUpdateSystemMetadata_MutableRightsHolder(nodeIterator.next(), version); } public void testUpdateSystemMetadata_MutableRightsHolder(Node node, String version) { CommonCallAdapter callAdapter = getCallAdapter(node, version); String currentUrl = node.getBaseURL(); printTestHeader("testUpdateSystemMetadata_MutableRightsHolder(...) vs. node: " + currentUrl); currentUrl = callAdapter.getNodeBaseServiceUrl(); try { getSession("testRightsHolder"); String rightsHolderSubjStr = catc.getSubject("testRightsHolder").getValue(); AccessRule accessRule = APITestUtils.buildAccessRule(rightsHolderSubjStr, Permission.CHANGE_PERMISSION); Identifier pid = new Identifier(); pid.setValue("testUpdateSystemMetadata_MutableRightsHolder_" + ExampleUtilities.generateIdentifier()); Identifier testObjPid = catc.createTestObject(callAdapter, pid, accessRule); SystemMetadata sysmeta = callAdapter.getSystemMetadata(null, testObjPid); getSession("testPerson"); sysmeta.setRightsHolder(catc.getSubject("testPerson")); boolean success = callAdapter.updateSystemMetadata(null, testObjPid , sysmeta); assertTrue("Call to updateSystemMetadata() should be successful.", success); Thread.sleep(METACAT_INDEXING_WAIT); SystemMetadata fetchedSysmeta = callAdapter.getSystemMetadata(null, testObjPid); boolean rightsHolderMatches = fetchedSysmeta.getRightsHolder().getValue().equals(sysmeta.getRightsHolder().getValue()); assertTrue("System metadata should now have updated rightsHolder", rightsHolderMatches ); } catch (ServiceFailure e) { // ServiceFailure is an allowed outcome for the MN.updateSystemMetadata() log.warn("MN.updateSystemMetadata() returned a ServiceFailure."); } catch (SynchronizationFailed e) { handleFail(callAdapter.getLatestRequestUrl(), e.getClass().getSimpleName() + ": " + "CN may throw SynchronizationFailed on a valid call to updateSystemMetadata. MN should not. " + e.getDetail_code() + ": " + e.getDescription()); } catch (BaseException e) { handleFail(callAdapter.getLatestRequestUrl(), e.getClass().getSimpleName() + ": " + e.getDetail_code() + ": " + e.getDescription()); } catch(Exception e) { e.printStackTrace(); handleFail(currentUrl, e.getClass().getName() + ": " + e.getMessage()); } } @WebTestName("updateSystemMetadata - tests that the rights holder can change mutable fields with updateSystemMetadata") @WebTestDescription("this test calls updateSystemMetadata() using an object's rights-holder " + "as the certificate subject to update the system metadata. " + "It modifies the formatId field in the system metadata when making the " + "getSystemMetadata() call and verifies that no exception is thrown " + "(that the mutable field can be modified by the rights holder). ") public void testUpdateSystemMetadata_MutableFormat(Iterator nodeIterator, String version) { while (nodeIterator.hasNext()) testUpdateSystemMetadata_MutableFormat(nodeIterator.next(), version); } public void testUpdateSystemMetadata_MutableFormat(Node node, String version) { CommonCallAdapter callAdapter = getCallAdapter(node, version); String currentUrl = node.getBaseURL(); printTestHeader("testUpdateSystemMetadata_MutableFormat(...) vs. node: " + currentUrl); currentUrl = callAdapter.getNodeBaseServiceUrl(); try { getSession("testRightsHolder"); String rightsHolderSubjStr = catc.getSubject("testRightsHolder").getValue(); AccessRule accessRule = APITestUtils.buildAccessRule(rightsHolderSubjStr, Permission.CHANGE_PERMISSION); Identifier pid = new Identifier(); pid.setValue("testUpdateSystemMetadata_MutableFormat_" + ExampleUtilities.generateIdentifier()); Identifier testObjPid = catc.createTestObject(callAdapter, pid, accessRule); SystemMetadata sysmeta = callAdapter.getSystemMetadata(null, testObjPid); sysmeta.setFormatId(D1TypeBuilder.buildFormatIdentifier("image/png")); boolean success = callAdapter.updateSystemMetadata(null, testObjPid , sysmeta); assertTrue("Call to updateSystemMetadata() should be successful.", success); Thread.sleep(METACAT_INDEXING_WAIT); SystemMetadata fetchedSysmeta = callAdapter.getSystemMetadata(null, testObjPid); boolean formatIdMatches = fetchedSysmeta.getFormatId().getValue().equals("image/png"); assertTrue("System metadata should now have updated formatId", formatIdMatches ); } catch (ServiceFailure e) { // ServiceFailure is an allowed outcome for the MN.updateSystemMetadata() log.warn("MN.updateSystemMetadata() returned a ServiceFailure."); } catch (SynchronizationFailed e) { handleFail(callAdapter.getLatestRequestUrl(), e.getClass().getSimpleName() + ": " + "CN may throw SynchronizationFailed on a valid call to updateSystemMetadata. MN should not. " + e.getDetail_code() + ": " + e.getDescription()); } catch (BaseException e) { handleFail(callAdapter.getLatestRequestUrl(), e.getClass().getSimpleName() + ": " + e.getDetail_code() + ": " + e.getDescription()); } catch(Exception e) { e.printStackTrace(); handleFail(currentUrl, e.getClass().getName() + ": " + e.getMessage()); } } @WebTestName("updateSystemMetadata - tests that the rights holder can change mutable fields with updateSystemMetadata") @WebTestDescription("this test calls updateSystemMetadata() using an object's rights-holder " + "as the certificate subject to update the system metadata. " + "It modifies the accessPolicy field in the system metadata when making the " + "getSystemMetadata() call and verifies that no exception is thrown " + "(that the mutable field can be modified by the rights holder). ") public void testUpdateSystemMetadata_MutableAccessPolicy(Iterator nodeIterator, String version) { while (nodeIterator.hasNext()) testUpdateSystemMetadata_MutableAccessPolicy(nodeIterator.next(), version); } public void testUpdateSystemMetadata_MutableAccessPolicy(Node node, String version) { CommonCallAdapter callAdapter = getCallAdapter(node, version); String currentUrl = node.getBaseURL(); printTestHeader("testUpdateSystemMetadata_MutableAccessPolicy(...) vs. node: " + currentUrl); currentUrl = callAdapter.getNodeBaseServiceUrl(); try { getSession("testRightsHolder"); String rightsHolderSubjStr = ContextAwareTestCaseDataone.getSubject("testRightsHolder").getValue(); AccessRule accessRule = APITestUtils.buildAccessRule(rightsHolderSubjStr, Permission.CHANGE_PERMISSION); Identifier pid = new Identifier(); pid.setValue("testUpdateSystemMetadata_MutableAccessPolicy_" + ExampleUtilities.generateIdentifier()); Identifier testObjPid = catc.createTestObject(callAdapter, pid, accessRule); SystemMetadata sysmeta = callAdapter.getSystemMetadata(null, testObjPid); AccessPolicy accessPolicy = new AccessPolicy(); getSession("testGroup"); String groupSubjStr = ContextAwareTestCaseDataone.getSubject("testGroup").getValue(); accessRule = APITestUtils.buildAccessRule(groupSubjStr, Permission.CHANGE_PERMISSION); accessPolicy.addAllow(accessRule); sysmeta.setAccessPolicy(accessPolicy); boolean success = callAdapter.updateSystemMetadata(null, testObjPid , sysmeta); assertTrue("Call to updateSystemMetadata() should be successful.", success); Thread.sleep(METACAT_INDEXING_WAIT); SystemMetadata fetchedSysmeta = callAdapter.getSystemMetadata(null, testObjPid); List allowList = fetchedSysmeta.getAccessPolicy().getAllowList(); assertTrue("System metadata should have an access policy with one item in its allow list.", allowList.size() == 1); AccessRule ar0 = allowList.get(0); String subjStr = ar0.getSubject(0).getValue(); Permission permission = ar0.getPermission(0); boolean accessPolicyMatches = permission == Permission.CHANGE_PERMISSION && subjStr.equals(groupSubjStr); assertTrue("System metadata should now have updated accessPolicy", accessPolicyMatches ); } catch (ServiceFailure e) { // ServiceFailure is an allowed outcome for the MN.updateSystemMetadata() log.warn("MN.updateSystemMetadata() returned a ServiceFailure."); } catch (SynchronizationFailed e) { handleFail(callAdapter.getLatestRequestUrl(), e.getClass().getSimpleName() + ": " + "CN may throw SynchronizationFailed on a valid call to updateSystemMetadata. MN should not. " + e.getDetail_code() + ": " + e.getDescription()); } catch (BaseException e) { handleFail(callAdapter.getLatestRequestUrl(), e.getClass().getSimpleName() + ": " + e.getDetail_code() + ": " + e.getDescription()); } catch(Exception e) { e.printStackTrace(); handleFail(currentUrl, e.getClass().getName() + ": " + e.getMessage()); } } @WebTestName("updateSystemMetadata - tests that the rights holder can change mutable fields with updateSystemMetadata") @WebTestDescription("this test calls updateSystemMetadata() using an object's rights-holder " + "as the certificate subject to update the system metadata. " + "It modifies the replicationPolicy field in the system metadata when making the " + "getSystemMetadata() call and verifies that no exception is thrown " + "(that the mutable field can be modified by the rights holder). ") public void testUpdateSystemMetadata_MutableReplPolicy(Iterator nodeIterator, String version) { while (nodeIterator.hasNext()) testUpdateSystemMetadata_MutableReplPolicy(nodeIterator.next(), version); } public void testUpdateSystemMetadata_MutableReplPolicy(Node node, String version) { CommonCallAdapter callAdapter = getCallAdapter(node, version); String currentUrl = node.getBaseURL(); printTestHeader("testUpdateSystemMetadata_MutableReplPolicy(...) vs. node: " + currentUrl); currentUrl = callAdapter.getNodeBaseServiceUrl(); try { getSession("testRightsHolder"); String rightsHolderSubjStr = catc.getSubject("testRightsHolder").getValue(); AccessRule accessRule = APITestUtils.buildAccessRule(rightsHolderSubjStr, Permission.CHANGE_PERMISSION); Identifier pid = new Identifier(); pid.setValue("testUpdateSystemMetadata_MutableReplPolicy_" + ExampleUtilities.generateIdentifier()); Identifier testObjPid = catc.createTestObject(callAdapter, pid, accessRule); SystemMetadata sysmeta = callAdapter.getSystemMetadata(null, testObjPid); Date nowIsh = new Date(); ReplicationPolicy replicationPolicy = new ReplicationPolicy(); replicationPolicy.setNumberReplicas(42); replicationPolicy.setReplicationAllowed(false); sysmeta.setReplicationPolicy(replicationPolicy); boolean success = callAdapter.updateSystemMetadata(null, testObjPid , sysmeta); assertTrue("Call to updateSystemMetadata() should be successful.", success); Thread.sleep(METACAT_INDEXING_WAIT); SystemMetadata fetchedSysmeta = callAdapter.getSystemMetadata(null, testObjPid); ReplicationPolicy fetchedReplPolicy = fetchedSysmeta.getReplicationPolicy(); Integer numberReplicas = fetchedReplPolicy.getNumberReplicas(); Boolean replicationAllowed = fetchedReplPolicy.getReplicationAllowed(); boolean replicationPolicyMatches = replicationAllowed == false && numberReplicas == 42; assertTrue("System metadata should now have updated replicationPolicy", replicationPolicyMatches ); } catch (ServiceFailure e) { // ServiceFailure is an allowed outcome for the MN.updateSystemMetadata() log.warn("MN.updateSystemMetadata() returned a ServiceFailure."); } catch (SynchronizationFailed e) { handleFail(callAdapter.getLatestRequestUrl(), e.getClass().getSimpleName() + ": " + "CN may throw SynchronizationFailed on a valid call to updateSystemMetadata. MN should not. " + e.getDetail_code() + ": " + e.getDescription()); } catch (BaseException e) { handleFail(callAdapter.getLatestRequestUrl(), e.getClass().getSimpleName() + ": " + e.getDetail_code() + ": " + e.getDescription()); } catch(Exception e) { e.printStackTrace(); handleFail(currentUrl, e.getClass().getName() + ": " + e.getMessage()); } } @WebTestName("updateSystemMetadata - tests that the rights holder can change mutable fields with updateSystemMetadata") @WebTestDescription("this test calls updateSystemMetadata() using an object's rights-holder " + "as the certificate subject to update the system metadata. " + "It modifies the authoritativeMemberNode field in the system metadata when making the " + "getSystemMetadata() call and verifies that no exception is thrown " + "(that the mutable field can be modified by the rights holder). ") public void testUpdateSystemMetadata_MutableAuthMN(Iterator nodeIterator, String version) { while (nodeIterator.hasNext()) testUpdateSystemMetadata_MutableAuthMN(nodeIterator.next(), version); } public void testUpdateSystemMetadata_MutableAuthMN(Node node, String version) { CommonCallAdapter callAdapter = getCallAdapter(node, version); String currentUrl = node.getBaseURL(); printTestHeader("testUpdateSystemMetadata_MutableAuthMN(...) vs. node: " + currentUrl); currentUrl = callAdapter.getNodeBaseServiceUrl(); try { getSession("testRightsHolder"); String rightsHolderSubjStr = catc.getSubject("testRightsHolder").getValue(); AccessRule accessRule = APITestUtils.buildAccessRule(rightsHolderSubjStr, Permission.CHANGE_PERMISSION); Identifier pid = new Identifier(); pid.setValue("testUpdateSystemMetadata_MutableAuthMN_" + ExampleUtilities.generateIdentifier()); Identifier testObjPid = catc.createTestObject(callAdapter, pid, accessRule); SystemMetadata sysmeta = callAdapter.getSystemMetadata(null, testObjPid); NodeList nodes = cn.listNodes(); Node diffMN = null; for (Node n : nodes.getNodeList()) { if (n.getType() == NodeType.MN && !n.getIdentifier().getValue().equals(node.getIdentifier().getValue())); diffMN = n; } assertTrue("Environment should have at least one other MN so we can test " + "changing the authoritativeMemberNode.", diffMN != null); sysmeta.setAuthoritativeMemberNode(diffMN.getIdentifier()); boolean success = callAdapter.updateSystemMetadata(null, testObjPid , sysmeta); assertTrue("Call to updateSystemMetadata() should be successful.", success); Thread.sleep(METACAT_INDEXING_WAIT); SystemMetadata fetchedSysmeta = callAdapter.getSystemMetadata(null, testObjPid); boolean authMNMatches = fetchedSysmeta.getAuthoritativeMemberNode().getValue().equals(diffMN.getIdentifier().getValue()); assertTrue("System metadata should now have updated authoritativeMemberNode", authMNMatches ); } catch (ServiceFailure e) { // ServiceFailure is an allowed outcome for the MN.updateSystemMetadata() log.warn("MN.updateSystemMetadata() returned a ServiceFailure."); } catch (SynchronizationFailed e) { handleFail(callAdapter.getLatestRequestUrl(), e.getClass().getSimpleName() + ": " + "CN may throw SynchronizationFailed on a valid call to updateSystemMetadata. MN should not. " + e.getDetail_code() + ": " + e.getDescription()); } catch (BaseException e) { handleFail(callAdapter.getLatestRequestUrl(), e.getClass().getSimpleName() + ": " + e.getDetail_code() + ": " + e.getDescription()); } catch(Exception e) { e.printStackTrace(); handleFail(currentUrl, e.getClass().getName() + ": " + e.getMessage()); } } @WebTestName("updateSystemMetadata - tests that the rights holder can change the archived field with updateSystemMetadata") @WebTestDescription("this test calls updateSystemMetadata() using an object's rights-holder " + "as the certificate subject to update the system metadata. " + "It modifies the archived field in the system metadata when making the " + "getSystemMetadata() call and verifies that no exception is thrown " + "(that the mutable field can be modified by the rights holder). ") public void testUpdateSystemMetadata_MutableArchived(Iterator nodeIterator, String version) { while (nodeIterator.hasNext()) testUpdateSystemMetadata_MutableArchived(nodeIterator.next(), version); } public void testUpdateSystemMetadata_MutableArchived(Node node, String version) { CommonCallAdapter callAdapter = getCallAdapter(node, version); String currentUrl = node.getBaseURL(); printTestHeader("testUpdateSystemMetadata_MutableArchived(...) vs. node: " + currentUrl); currentUrl = callAdapter.getNodeBaseServiceUrl(); try { getSession("testRightsHolder"); String rightsHolderSubjStr = catc.getSubject("testRightsHolder").getValue(); AccessRule accessRule = APITestUtils.buildAccessRule(rightsHolderSubjStr, Permission.CHANGE_PERMISSION); Identifier pid = new Identifier(); pid.setValue("testUpdateSystemMetadata_MutableArchived_" + ExampleUtilities.generateIdentifier()); Identifier testObjPid = catc.createTestObject(callAdapter, pid, accessRule); SystemMetadata sysmeta = callAdapter.getSystemMetadata(null, testObjPid); sysmeta.setArchived(true); boolean success = callAdapter.updateSystemMetadata(null, testObjPid , sysmeta); assertTrue("Call to updateSystemMetadata() should be successful.", success); Thread.sleep(METACAT_INDEXING_WAIT); SystemMetadata fetchedSysmeta = callAdapter.getSystemMetadata(null, testObjPid); boolean archivedMatches = fetchedSysmeta.getArchived().equals(true); assertTrue("System metadata should now have updated archived", archivedMatches ); } catch (ServiceFailure e) { // ServiceFailure is an allowed outcome for the MN.updateSystemMetadata() log.warn("MN.updateSystemMetadata() returned a ServiceFailure."); } catch (SynchronizationFailed e) { handleFail(callAdapter.getLatestRequestUrl(), e.getClass().getSimpleName() + ": " + "CN may throw SynchronizationFailed on a valid call to updateSystemMetadata. MN should not. " + e.getDetail_code() + ": " + e.getDescription()); } catch (BaseException e) { handleFail(callAdapter.getLatestRequestUrl(), e.getClass().getSimpleName() + ": " + e.getDetail_code() + ": " + e.getDescription()); } catch(Exception e) { e.printStackTrace(); handleFail(currentUrl, e.getClass().getName() + ": " + e.getMessage()); } } @WebTestName("updateSystemMetadata - tests that the rights holder cannot updateSystemMetadata on non-authoritative MN") @WebTestDescription("this test calls updateSystemMetadata() using an object's rights-holder " + "as the certificate subject to try to update the system metadata, " + "but it makes the call on a non-authoritative MN, and is expected to fail " + "with an InvalidRequest exception. ") public void testUpdateSystemMetadata_RightsHolderNonAuthMN(Iterator nodeIterator, String version) { while (nodeIterator.hasNext()) testUpdateSystemMetadata_RightsHolderNonAuthMN(nodeIterator.next(), version); } public void testUpdateSystemMetadata_RightsHolderNonAuthMN(Node node, String version) { CommonCallAdapter callAdapter = getCallAdapter(node, version); String currentUrl = node.getBaseURL(); printTestHeader("testUpdateSystemMetadata_MutableAuthMN(...) vs. node: " + currentUrl); currentUrl = callAdapter.getNodeBaseServiceUrl(); try { getSession("testRightsHolder"); String rightsHolderSubjStr = catc.getSubject("testRightsHolder").getValue(); AccessRule accessRule = APITestUtils.buildAccessRule(rightsHolderSubjStr, Permission.CHANGE_PERMISSION); Identifier pid = new Identifier(); pid.setValue("testUpdateSystemMetadata_MutableAuthMN_" + ExampleUtilities.generateIdentifier()); Identifier testObjPid = catc.createTestObject(callAdapter, pid, accessRule); SystemMetadata sysmeta = callAdapter.getSystemMetadata(null, testObjPid); sysmeta.getSerialVersion().add(BigInteger.ONE); NodeList nodes = cn.listNodes(); Node diffMN = null; for (Node n : nodes.getNodeList()) { if (n.getType() != NodeType.MN) continue; Services services = n.getServices(); if (services == null || services.sizeServiceList() == 0) continue; boolean v2Node = false; for (Service s : services.getServiceList()) if (s.getVersion().equalsIgnoreCase("v2")) { v2Node = true; break; } if (!v2Node) continue; if (!n.getIdentifier().getValue().equals(node.getIdentifier().getValue())) diffMN = n; } assertTrue("Environment should have at least one other MN " + "(fetched through CN.getNodeList()) so we can test " + "changing the authoritativeMemberNode.", diffMN != null); callAdapter = getCallAdapter(diffMN, version); callAdapter.updateSystemMetadata(null, testObjPid , sysmeta); handleFail(currentUrl, "testUpdateSystemMetadata_RightsHolderNonAuthMN: " + "call to MN.updateSystemMetadata() should fail if made to an MN " + "that is not the authoritative MN."); } catch (InvalidRequest e) { // should fail } catch (NotAuthorized e) { // should fail } catch (ServiceFailure e) { // ServiceFailure is an allowed outcome for the MN.updateSystemMetadata() log.warn("MN.updateSystemMetadata() returned a ServiceFailure, " + "was expecting an InvalidRequest or NotAuthorized."); } catch (SynchronizationFailed e) { handleFail(callAdapter.getLatestRequestUrl(), e.getClass().getSimpleName() + ": " + "CN may throw SynchronizationFailed on a valid call to updateSystemMetadata. MN should not. " + e.getDetail_code() + ": " + e.getDescription()); } catch (BaseException e) { handleFail(callAdapter.getLatestRequestUrl(), e.getClass().getSimpleName() + ": " + e.getDetail_code() + ": " + e.getDescription()); } catch(Exception e) { e.printStackTrace(); handleFail(currentUrl, e.getClass().getName() + ": " + e.getMessage()); } } @WebTestName("updateSystemMetadata - tests that a CN certificate can updateSystemMetadata on a non-authoritative MN") @WebTestDescription("this test calls updateSystemMetadata() using a CN certificate " + "to try to update the system metadata, " + "but it makes the call on a non-authoritative MN, and is expected to succeed ") public void testUpdateSystemMetadata_CNCertNonAuthMN(Iterator nodeIterator, String version) { while (nodeIterator.hasNext()) testUpdateSystemMetadata_CNCertNonAuthMN(nodeIterator.next(), version); } public void testUpdateSystemMetadata_CNCertNonAuthMN(Node node, String version) { MNCallAdapter cnCertAuthMN = new MNCallAdapter(getSession(cnSubmitter), node, version); MNCallAdapter cnCertNonAuthMN = null; String currentUrl = node.getBaseURL(); printTestHeader("testUpdateSystemMetadata_CNCertNonAuthMN(...) vs. node: " + currentUrl); currentUrl = cnCertAuthMN.getNodeBaseServiceUrl(); final Identifier pid = D1TypeBuilder.buildIdentifier("testUpdateSystemMetadata_CNCertNonAuthMN_" + ExampleUtilities.generateIdentifier()); SystemMetadata sysmeta = null; ReplicationPolicy replPolicy = null; final ArrayList replicaTargets = new ArrayList(); try { int numReplicaTargets = 0; NodeList nodes = cn.listNodes(); for (Node n : nodes.getNodeList()) { if (n.getType() != NodeType.MN) continue; log.info("testUpdateSystemMetadata_CNCertNonAuthMN: checking if valid replica target: " + n.getBaseURL()); MNCallAdapter v2mn = new MNCallAdapter(getSession(cnSubmitter), n, "v2"); Node cap = null; try { cap = v2mn.getCapabilities(); } catch (Exception e) { log.info("testUpdateSystemMetadata_CNCertNonAuthMN: unable to getCapabilities() for node " + n.getBaseURL()); continue; } List services = cap.getServices().getServiceList(); if (services != null) for (Service s : services) { if (s.getName().equalsIgnoreCase("MNReplication") && s.getVersion().equalsIgnoreCase("v2")) { log.info("testUpdateSystemMetadata_CNCertNonAuthMN: found valid replica target: " + n.getBaseURL()); replicaTargets.add(cap); numReplicaTargets++; break; } } } assertTrue("testUpdateSystemMetadata_CNCertNonAuthMN requires at least 2 total v2 MNs so there's " + "at least one replica target. Found " + numReplicaTargets + " replica targets.", numReplicaTargets >= 2); replPolicy = new ReplicationPolicy(); replPolicy.setReplicationAllowed(true); replPolicy.setNumberReplicas(numReplicaTargets-1); // -1 for current authMN AccessRule accessRule = new AccessRule(); getSession("testRightsHolder"); Subject subject = D1TypeBuilder.buildSubject(Constants.SUBJECT_PUBLIC); accessRule.addSubject(subject); accessRule.addPermission(Permission.CHANGE_PERMISSION); log.info("testUpdateSystemMetadata_CNCertNonAuthMN: creating test object: " + pid.getValue()); catc.createTestObject(cnCertAuthMN, pid, accessRule, replPolicy); } catch (BaseException e) { throw new AssertionError("Test setup failed. Couldn't create object: " + cnCertAuthMN.getLatestRequestUrl() + " : " + e.getClass().getSimpleName() + ": " + e.getDetail_code() + ": " + e.getDescription()); } catch(Exception e) { e.printStackTrace(); throw new AssertionError("Test setup failed. Couldn't create object: " + cnCertAuthMN.getLatestRequestUrl() + " : " + e.getClass().getName() + ": " + e.getMessage()); } log.info("testUpdateSystemMetadata_CNCertNonAuthMN: waiting for replication... (up to " + ((double)REPLICATION_WAIT / 60000) + " minutes)"); try { log.info("testUpdateSystemMetadata_CNCertNonAuthMN: fetching sysmeta from CN " + cn.getNodeBaseServiceUrl()); final Node authNode = node; RetryHandler getSysmetaHandler = new RetryHandler() { @Override protected SystemMetadata attempt() throws TryAgainException, Exception { try { log.info("attempting CN getSystemMEtadata..."); SystemMetadata sysmeta = cn.getSystemMetadata(null, pid); log.info("attempting to get replicas from CN sysmeta..."); List replicaList = sysmeta.getReplicaList(); if (replicaList.size() == 0) { TryAgainException f = new TryAgainException(); f.initCause(new NotFound("404", "CN sysmeta contained an empty replica list! " + cn.getLatestRequestUrl())); throw f; } Node v2ReplicaNode = null; for (Replica rep : replicaList) { for (Node v2Node : replicaTargets) if (v2Node.getIdentifier().getValue().equals( rep.getReplicaMemberNode().getValue() ) // it's one of the valid v2 replica targets && !rep.getReplicaMemberNode().getValue().equals(authNode.getIdentifier().getValue()) // it's not the auth MN && rep.getReplicationStatus() == ReplicationStatus.COMPLETED ) // it's in completed status v2ReplicaNode = v2Node; } if (v2ReplicaNode == null) { TryAgainException f = new TryAgainException(); f.initCause(new NotFound("404", "CN sysmeta contained no replica for a v2 MN! " + cn.getLatestRequestUrl())); throw f; } return sysmeta; } catch (NotFound | ServiceFailure e) { TryAgainException f = new TryAgainException(); f.initCause(e); throw f; } } }; sysmeta = getSysmetaHandler.execute(30* 1000, REPLICATION_WAIT); } catch (BaseException e) { e.printStackTrace(); throw new AssertionError("Test setup failed. Couldn't fetch sysmeta (" + pid.getValue() + ") from CN: " + cn.getLatestRequestUrl() + ", origin MN: " + cnCertAuthMN.getNodeBaseServiceUrl() + " : " + e.getClass().getSimpleName() + ": " + e.getDetail_code() + ": " + e.getDescription()); } catch(Exception e) { e.printStackTrace(); throw new AssertionError("Test setup failed. Couldn't fetch sysmeta (" + pid.getValue() + ") from CN: " + cn.getLatestRequestUrl() + ", origin MN: " + cnCertAuthMN.getNodeBaseServiceUrl() + " : " + e.getClass().getName() + ": " + e.getMessage()); } try { List replicaList = sysmeta.getReplicaList(); assertTrue("testUpdateSystemMetadata_CNCertNonAuthMN : After waiting for replication to occur, " + "fetched sysmeta should contain a non-empty replica list!", replicaList != null && replicaList.size() > 0); List successfulReplicas = new ArrayList(); String replicaStr = ""; for (Replica replica : replicaList) { replicaStr += replica.getReplicaMemberNode().getValue() + ", "; if (replica.getReplicationStatus() == ReplicationStatus.COMPLETED && !replica.getReplicaMemberNode().getValue().equals(node.getIdentifier().getValue())) successfulReplicas.add(replica); } assertTrue("testUpdateSystemMetadata_CNCertNonAuthMN : After waiting for replication to occur, " + "there should be at least one successful replica MN available! " + "Replicas: " + replicaStr, successfulReplicas.size() > 0); log.info("testUpdateSystemMetadata_CNCertNonAuthMN: checking replica list for v2 replica target nodes..."); Node nonAuthMN = null; NodeList nodes = cn.listNodes(); outerloop: for (Node n : nodes.getNodeList()) { if (n.getType() != NodeType.MN) continue; for (Replica replica : successfulReplicas) { NodeReference replicaMN = replica.getReplicaMemberNode(); if (n.getIdentifier().getValue().equals(replicaMN.getValue()) && n.getState() == NodeState.UP) { log.info("testUpdateSystemMetadata_CNCertNonAuthMN: checking replica on " + replicaMN.getValue()); // need a v2 replica MN, so we can use updateSystemMetadata() Services services = n.getServices(); if (services == null) { log.error("Node " + n.getName() + " has NULL Services!!!"); continue; } for (Service s : services.getServiceList()) { if(s.getVersion().equalsIgnoreCase("v2")) { log.info("testUpdateSystemMetadata_CNCertNonAuthMN: found v2 replica target " + n.getBaseURL()); nonAuthMN = n; break outerloop; } } } } } assertTrue("Attempted to find a replica target MN (a non-authoritative MN) but failed. " + "It has to be a v2 MN in the environment that is not the authoritative MN.", nonAuthMN != null); cnCertNonAuthMN = new MNCallAdapter(getSession(cnSubmitter), nonAuthMN, "v2"); replPolicy.setNumberReplicas(3); sysmeta.setReplicationPolicy(replPolicy); boolean success = cnCertNonAuthMN.updateSystemMetadata(null, pid , sysmeta); assertTrue("testUpdateSystemMetadata_CNCertNonAuthMN: " + "should succeed with a CN cert making the updateSystemMetadata() call " + "to a non-authoritative MN.", success); } catch (BaseException e) { handleFail(cnCertNonAuthMN.getLatestRequestUrl(), e.getClass().getSimpleName() + ": " + e.getDetail_code() + ": " + e.getDescription()); } catch(Exception e) { e.printStackTrace(); handleFail(cnCertNonAuthMN.getLatestRequestUrl(), e.getClass().getName() + ": " + e.getMessage()); } } @WebTestName("updateSystemMetadata - tests that the rights holder can't change the obsoletes field if it causes an inconsistency") @WebTestDescription("this test calls updateSystemMetadata() using an object's rights-holder " + "as the certificate subject to update the system metadata. " + "It sets up a 2-pid chain (in which they both point to each other) " + "and modifies the obsoletes field in the system metadata " + "of the first one and verifies that an exception is thrown - " + "since this would create an inconsistency in the chain.") public void testUpdateSystemMetadata_ObsoletesFail(Iterator nodeIterator, String version) { while (nodeIterator.hasNext()) testUpdateSystemMetadata_ObsoletesFail(nodeIterator.next(), version); } public void testUpdateSystemMetadata_ObsoletesFail(Node node, String version) { MNCallAdapter callAdapter = getCallAdapter(node, version); String currentUrl = node.getBaseURL(); printTestHeader("testUpdateSystemMetadata_ObsoletesFail(...) vs. node: " + currentUrl); currentUrl = callAdapter.getNodeBaseServiceUrl(); SystemMetadata v2sysmeta = null; Identifier p1 = createPid("testUpdateSystemMetadata_ObsoletesFail_" + ExampleUtilities.generateIdentifier()); Identifier p2 = createPid("testUpdateSystemMetadata_ObsoletesFail_" + ExampleUtilities.generateIdentifier()); Identifier p3 = createPid("testUpdateSystemMetadata_ObsoletesFail_" + ExampleUtilities.generateIdentifier()); try { getSession("testRightsHolder"); String rightsHolderSubjStr = catc.getSubject("testRightsHolder").getValue(); AccessRule accessRule = APITestUtils.buildAccessRule(rightsHolderSubjStr, Permission.CHANGE_PERMISSION); p1 = catc.createTestObject(callAdapter, p1, accessRule); Thread.sleep(METACAT_INDEXING_WAIT); byte[] contentBytes = ExampleUtilities.getExampleObjectOfType(ExampleUtilities.FORMAT_EML_2_0_1); ByteArrayInputStream objectInputStream = new ByteArrayInputStream(contentBytes); D1Object d1o = new D1Object(p2, contentBytes, D1TypeBuilder.buildFormatIdentifier(ExampleUtilities.FORMAT_EML_2_0_1), catc.getSubject("testRightsHolder"), D1TypeBuilder.buildNodeReference("bogusAuthoritativeNode")); v2sysmeta = TypeFactory.convertTypeFromType(d1o.getSystemMetadata(), SystemMetadata.class); v2sysmeta.setAuthoritativeMemberNode(node.getIdentifier()); p2 = d1o.getIdentifier(); callAdapter.update(null, p1, objectInputStream, p2, v2sysmeta); p3 = catc.createTestObject(callAdapter, p3, accessRule); Thread.sleep(METACAT_INDEXING_WAIT); v2sysmeta = callAdapter.getSystemMetadata(null, p2); } catch (BaseException e) { throw new AssertionError(currentUrl + " testUpdateSystemMetadata_ObsoletesFail() setup steps failed! " + e.getClass().getSimpleName() + ": " + e.getDetail_code() + ": " + e.getDescription()); } catch(Exception e) { throw new AssertionError(currentUrl + " testUpdateSystemMetadata_ObsoletesFail() setup steps failed! " + e.getClass().getName() + ": " + e.getMessage()); } try { v2sysmeta.setObsoletes(p3); callAdapter.updateSystemMetadata(null, p2 , v2sysmeta); handleFail(currentUrl, "testUpdateSystemMetadata_ObsoletesFail() expects the " + "updateSystemMetadata() call to fail with an InvalidRequest exception" + "since it's trying to overwrite the existing obsoletes field," + "but the call succeeded! (The obsoletes field can only be set once.)"); } catch (InvalidRequest e) { // expected } catch (BaseException e) { handleFail(callAdapter.getLatestRequestUrl(), "testUpdateSystemMetadata_ObsoletesFail() expected InvalidRequest but got: " + e.getClass().getSimpleName() + ": " + e.getDetail_code() + ": " + e.getDescription()); } catch(Exception e) { handleFail(currentUrl, "testUpdateSystemMetadata_ObsoletesFail() expected InvalidRequest but got: " + e.getClass().getName() + ": " + e.getMessage()); } } @WebTestName("updateSystemMetadata - tests that the rights holder can't change the obsoletedBy field if it causes an inconsistency") @WebTestDescription("this test calls updateSystemMetadata() using an object's rights-holder " + "as the certificate subject to update the system metadata. " + "It sets up a 2-pid chain (in which they both point to each other) " + "and modifies the obsoletedBy field in the system metadata " + "of the second pid and verifies that an exception is thrown - " + "since this would create an inconsistency in the chain.") public void testUpdateSystemMetadata_ObsoletedByFail(Iterator nodeIterator, String version) { while (nodeIterator.hasNext()) testUpdateSystemMetadata_ObsoletedByFail(nodeIterator.next(), version); } public void testUpdateSystemMetadata_ObsoletedByFail(Node node, String version) { MNCallAdapter callAdapter = getCallAdapter(node, version); String currentUrl = node.getBaseURL(); printTestHeader("testUpdateSystemMetadata_ObsoletedByFail(...) vs. node: " + currentUrl); currentUrl = callAdapter.getNodeBaseServiceUrl(); SystemMetadata v2sysmeta = null; Identifier p1 = createPid("testUpdateSystemMetadata_ObsoletedByFail_" + ExampleUtilities.generateIdentifier()); Identifier p2 = createPid("testUpdateSystemMetadata_ObsoletedByFail_" + ExampleUtilities.generateIdentifier()); Identifier p3 = createPid("testUpdateSystemMetadata_ObsoletedByFail_" + ExampleUtilities.generateIdentifier()); SystemMetadata p1sysmeta = null; try { getSession("testRightsHolder"); String rightsHolderSubjStr = catc.getSubject("testRightsHolder").getValue(); AccessRule accessRule = APITestUtils.buildAccessRule(rightsHolderSubjStr, Permission.CHANGE_PERMISSION); p1 = catc.createTestObject(callAdapter, p1, accessRule); Thread.sleep(METACAT_INDEXING_WAIT); byte[] contentBytes = ExampleUtilities.getExampleObjectOfType(ExampleUtilities.FORMAT_EML_2_0_1); ByteArrayInputStream objectInputStream = new ByteArrayInputStream(contentBytes); D1Object d1o = new D1Object(p2, contentBytes, D1TypeBuilder.buildFormatIdentifier(ExampleUtilities.FORMAT_EML_2_0_1), catc.getSubject("testRightsHolder"), D1TypeBuilder.buildNodeReference("bogusAuthoritativeNode")); v2sysmeta = TypeFactory.convertTypeFromType(d1o.getSystemMetadata(), SystemMetadata.class); p2 = d1o.getIdentifier(); callAdapter.update(null, p1, objectInputStream, p2, v2sysmeta); p3 = catc.createTestObject(callAdapter, p3, accessRule); Thread.sleep(METACAT_INDEXING_WAIT); p1sysmeta = callAdapter.getSystemMetadata(null, p1); } catch (BaseException e) { throw new AssertionError(currentUrl + " testUpdateSystemMetadata_ObsoletedByFail() setup steps failed! " + e.getClass().getSimpleName() + ": " + e.getDetail_code() + ": " + e.getDescription()); } catch(Exception e) { throw new AssertionError(currentUrl + " testUpdateSystemMetadata_ObsoletedByFail() setup steps failed! " + e.getClass().getName() + ": " + e.getMessage()); } try { p1sysmeta.setObsoletedBy(p3); callAdapter.updateSystemMetadata(null, p1 , p1sysmeta); handleFail(currentUrl, "testUpdateSystemMetadata_ObsoletedByFail() expects the " + "updateSystemMetadata() call to fail with an InvalidSystemMetadata exception" + "since it's trying to overwrite the existing obsoletedBy field, " + "but the call succeeded! (The obsoletes field can only be set once.)"); } catch (InvalidRequest e) { // expected } catch (BaseException e) { handleFail(callAdapter.getLatestRequestUrl(), "testUpdateSystemMetadata_ObsoletedByFail() expected InvalidRequest but got: " + e.getClass().getSimpleName() + ": " + e.getDetail_code() + ": " + e.getDescription()); } catch(Exception e) { handleFail(currentUrl, "testUpdateSystemMetadata_ObsoletedByFail() expected InvalidRequest but got: " + e.getClass().getName() + ": " + e.getMessage()); } } @WebTestName("updateSystemMetadata - tests that the rights holder can't change the obsoletes field if it causes an inconsistency") @WebTestDescription("this test calls updateSystemMetadata() using an object's rights-holder " + "as the certificate subject to update the system metadata. " + "It creates two objects (not related to each other through obsoletes / obsoletedBy) " + "and modifies the obsoletedBy field in the system metadata " + "of the first one (to point to the second) and verifies that no exception is thrown.") public void testUpdateSystemMetadata_MutableObsoletedBy(Iterator nodeIterator, String version) { while (nodeIterator.hasNext()) testUpdateSystemMetadata_MutableObsoletedBy(nodeIterator.next(), version); } public void testUpdateSystemMetadata_MutableObsoletedBy(Node node, String version) { MNCallAdapter callAdapter = getCallAdapter(node, version); String currentUrl = node.getBaseURL(); printTestHeader("testUpdateSystemMetadata_MutableObsoletedBy(...) vs. node: " + currentUrl); currentUrl = callAdapter.getNodeBaseServiceUrl(); SystemMetadata p1sysmeta = null; Identifier p1 = createPid("testUpdateSystemMetadata_MutableObsoletedBy_" + ExampleUtilities.generateIdentifier()); Identifier p2 = createPid("testUpdateSystemMetadata_MutableObsoletedBy_" + ExampleUtilities.generateIdentifier()); try { getSession("testRightsHolder"); String rightsHolderSubjStr = catc.getSubject("testRightsHolder").getValue(); AccessRule accessRule = APITestUtils.buildAccessRule(rightsHolderSubjStr, Permission.CHANGE_PERMISSION); p1 = catc.createTestObject(callAdapter, p1, accessRule); p2 = catc.createTestObject(callAdapter, p2, accessRule); Thread.sleep(METACAT_INDEXING_WAIT); p1sysmeta = callAdapter.getSystemMetadata(null, p1); } catch (BaseException e) { throw new AssertionError(currentUrl + " testUpdateSystemMetadata_MutableObsoletedBy() setup steps failed! " + e.getClass().getSimpleName() + ": " + e.getDetail_code() + ": " + e.getDescription()); } catch(Exception e) { throw new AssertionError(currentUrl + " testUpdateSystemMetadata_MutableObsoletedBy() setup steps failed! " + e.getClass().getName() + ": " + e.getMessage()); } try { p1sysmeta.setObsoletedBy(p2); p1sysmeta.setSerialVersion(p1sysmeta.getSerialVersion().add(BigInteger.ONE)); callAdapter.updateSystemMetadata(null, p1 , p1sysmeta); } catch (InvalidSystemMetadata e) { // expected } catch (BaseException e) { handleFail(callAdapter.getLatestRequestUrl(), "testUpdateSystemMetadata_MutableObsoletedBy() expected InvalidSystemMetadata but got: " + e.getClass().getSimpleName() + ": " + e.getDetail_code() + ": " + e.getDescription()); } catch(Exception e) { handleFail(currentUrl, "testUpdateSystemMetadata_MutableObsoletedBy() expected InvalidSystemMetadata but got: " + e.getClass().getName() + ": " + e.getMessage()); } } @WebTestName("updateSystemMetadata - tests that the rights holder can't change the obsoletes field if it causes an inconsistency") @WebTestDescription("this test calls updateSystemMetadata() using an object's rights-holder " + "as the certificate subject to update the system metadata. " + "It creates two objects (not related to each other through obsoletes / obsoletedBy) " + "and modifies the obsoletes field in the system metadata " + "of the second one (to point to the first) and verifies that no exception is thrown.") public void testUpdateSystemMetadata_MutableObsoletes(Iterator nodeIterator, String version) { while (nodeIterator.hasNext()) testUpdateSystemMetadata_MutableObsoletes(nodeIterator.next(), version); } public void testUpdateSystemMetadata_MutableObsoletes(Node node, String version) { MNCallAdapter callAdapter = getCallAdapter(node, version); String currentUrl = node.getBaseURL(); printTestHeader("testUpdateSystemMetadata_MutableObsoletes(...) vs. node: " + currentUrl); currentUrl = callAdapter.getNodeBaseServiceUrl(); SystemMetadata p2sysmeta = null; Identifier p1 = createPid("testUpdateSystemMetadata_MutableObsoletes_" + ExampleUtilities.generateIdentifier()); Identifier p2 = createPid("testUpdateSystemMetadata_MutableObsoletes_" + ExampleUtilities.generateIdentifier()); try { getSession("testRightsHolder"); String rightsHolderSubjStr = catc.getSubject("testRightsHolder").getValue(); AccessRule accessRule = APITestUtils.buildAccessRule(rightsHolderSubjStr, Permission.CHANGE_PERMISSION); p1 = catc.createTestObject(callAdapter, p1, accessRule); p2 = catc.createTestObject(callAdapter, p2, accessRule); Thread.sleep(METACAT_INDEXING_WAIT); p2sysmeta = callAdapter.getSystemMetadata(null, p2); } catch (BaseException e) { throw new AssertionError(currentUrl + " testUpdateSystemMetadata_MutableObsoletes() setup steps failed! " + e.getClass().getSimpleName() + ": " + e.getDetail_code() + ": " + e.getDescription()); } catch(Exception e) { throw new AssertionError(currentUrl + " testUpdateSystemMetadata_MutableObsoletes() setup steps failed! " + e.getClass().getName() + ": " + e.getMessage()); } try { p2sysmeta.setObsoletes(p1); p2sysmeta.setSerialVersion(p2sysmeta.getSerialVersion().add(BigInteger.ONE)); callAdapter.updateSystemMetadata(null, p2 , p2sysmeta); } catch (InvalidSystemMetadata e) { // expected } catch (BaseException e) { handleFail(callAdapter.getLatestRequestUrl(), "testUpdateSystemMetadata_MutableObsoletes() expected InvalidSystemMetadata but got: " + e.getClass().getSimpleName() + ": " + e.getDetail_code() + ": " + e.getDescription()); } catch(Exception e) { handleFail(currentUrl, "testUpdateSystemMetadata_MutableObsoletes() expected InvalidSystemMetadata but got: " + e.getClass().getName() + ": " + e.getMessage()); } } private Identifier createPid(String string) { try { Thread.sleep(1); // millisecond granularity isn't enough - was getting overlapping pids } catch (InterruptedException e) {} return D1TypeBuilder.buildIdentifier(string); } }