diff --git a/doi/README.md b/doi/README.md index 1da3337e..0c417269 100644 --- a/doi/README.md +++ b/doi/README.md @@ -27,9 +27,6 @@ The doi.properties configures the DataCite service used to register new DOIs. # VOSpace uri to the parent DOI folder. ca.nrc.cadc.doi.vospaceParentUri = {parent folder URI} -# DOI Identifier Prefix -ca.nrc.cadc.doi.doiIdentifierPrefix = {DOI Identifier Prefix} - # Prefix to the DOI metadata file ca.nrc.cadc.doi.metaDataPrefix = {metadata file prefix} @@ -50,11 +47,12 @@ ca.nrc.cadc.doi.datacite.password = {password} # DataCite account prefix ca.nrc.cadc.doi.datacite.accountPrefix = {account prefix} + +# (optional) DOI Identifier Prefix +ca.nrc.cadc.doi.doiIdentifierPrefix = {DOI Identifier Prefix} ``` _parentUri_ is the URI to the DOI parent folder in the VOSpace service. -_doiIdentifierPrefix_ is prefix to the DOI Identifier. - _metaDataPrefix_ is the prefix prepended to the DOI name used to create the file for the DOI specific metadata stored in VOSpace. _groupPrefix_ is the prefix prepended to the DOI name to create the group name for the DOI. @@ -69,6 +67,8 @@ _password_ is the DataCite account password. _accountPrefix_ is the registered prefix for a DataCite account. +_doiIdentifierPrefix_ is prefix to the DOI Identifier. + **For Alternative DOI Settings ONLY** ``` # Publisher Group URI diff --git a/doi/src/intTest/java/ca/nrc/cadc/doi/AltStatusTest.java b/doi/src/intTest/java/ca/nrc/cadc/doi/AltStatusTest.java index 0c84921f..5ba31fc7 100644 --- a/doi/src/intTest/java/ca/nrc/cadc/doi/AltStatusTest.java +++ b/doi/src/intTest/java/ca/nrc/cadc/doi/AltStatusTest.java @@ -78,6 +78,8 @@ import org.apache.log4j.Logger; import org.junit.Assert; import org.junit.Test; +import org.opencadc.vospace.ContainerNode; +import org.opencadc.vospace.DataNode; import org.opencadc.vospace.Node; import org.opencadc.vospace.VOSURI; import org.opencadc.vospace.client.VOSpaceClient; @@ -121,6 +123,10 @@ public void testUpdateStatus() { checkPermissions(doiNode, false, false, 2,0); log.debug("submitter - checked permissions"); + // check /data files are readable by the doi group and publisher group + ContainerNode dataNode = getContainerNode(doiID + "/data", doiParentPathURI, vosClient); + checkDataNodePermission(dataNode, 2, 0); + // submitter can update status to 'in progress' from 'review ready' log.debug("submitter - update status to 'in progress'"); updateStatus(doiID, Status.DRAFT, true); @@ -132,6 +138,10 @@ public void testUpdateStatus() { checkPermissions(doiNode, false, false, 1,1); log.debug("submitter - checked permissions"); + // check /data files are readable and writeable by the doi group only + dataNode = getContainerNode(doiID + "/data", doiParentPathURI, vosClient); + checkDataNodePermission(dataNode, 1, 1); + // submitter updates status to 'review ready' so a reviewer can review log.debug("submitter - update status to 'review ready'"); updateStatus(doiID, Status.REVIEW_READY, true); @@ -307,4 +317,14 @@ void checkPermissions(Node doiNode, boolean isLocked, boolean isPublic, Assert.assertEquals(readWriteGroups, doiNode.getReadWriteGroup().size()); } + void checkDataNodePermission(ContainerNode dataNode, int readOnlyGroups, int readWriteGroups) { + for (Node child : dataNode.getNodes()) { + if (child instanceof DataNode) { + checkPermissions(child,false, false, readOnlyGroups, readWriteGroups); + } else { + checkDataNodePermission((ContainerNode) child, readOnlyGroups, readWriteGroups); + } + } + } + } diff --git a/doi/src/intTest/java/ca/nrc/cadc/doi/LifecycleTest.java b/doi/src/intTest/java/ca/nrc/cadc/doi/LifecycleTest.java index 2b136b65..dda206f3 100644 --- a/doi/src/intTest/java/ca/nrc/cadc/doi/LifecycleTest.java +++ b/doi/src/intTest/java/ca/nrc/cadc/doi/LifecycleTest.java @@ -283,6 +283,8 @@ void update(Resource expected, String doiSuffix, URL doiServiceURL) throws Excep // Update the DOI Resource actual = doUpdateTest(expected, doiURL); + log.debug("expected: " + expected); + log.debug("actual: " + actual); // tests randomly fails when the transfer to vospace is slow, hence the sleep cycles Thread.sleep(3000); compareResource(expected, actual, true); @@ -295,9 +297,11 @@ void update(Resource expected, String doiSuffix, URL doiServiceURL) throws Excep // Update the DOI actual = doUpdateTest(expected, doiURL); - log.info("expected: " + expected); - log.info("actual: " + actual); -// compareResource(expected, actual, true); + log.debug("expected: " + expected); + log.debug("actual: " + actual); + // tests randomly fails when the transfer to vospace is slow, hence the sleep cycles + Thread.sleep(3000); + compareResource(expected, actual, true); } void publish(Resource expected, String doiSuffix, DOISettingsType doiSettingsType) throws Exception { diff --git a/doi/src/intTest/java/ca/nrc/cadc/doi/TestUtil.java b/doi/src/intTest/java/ca/nrc/cadc/doi/TestUtil.java index 2a6379c1..6c44ce29 100644 --- a/doi/src/intTest/java/ca/nrc/cadc/doi/TestUtil.java +++ b/doi/src/intTest/java/ca/nrc/cadc/doi/TestUtil.java @@ -126,7 +126,7 @@ public class TestUtil { static URI DOI_ALT_VOSPACE_RESOURCE_ID; - static String DOI_ALT_IDENTIFIER_PREFIX; + static String DOI_ALT_IDENTIFIER_PREFIX = "doi-alt-"; static { diff --git a/doi/src/main/java/ca/nrc/cadc/doi/PostAction.java b/doi/src/main/java/ca/nrc/cadc/doi/PostAction.java index ae2ef2b5..cab1ff11 100644 --- a/doi/src/main/java/ca/nrc/cadc/doi/PostAction.java +++ b/doi/src/main/java/ca/nrc/cadc/doi/PostAction.java @@ -84,6 +84,7 @@ import ca.nrc.cadc.net.HttpPost; import ca.nrc.cadc.net.HttpTransfer; import ca.nrc.cadc.net.HttpUpload; +import ca.nrc.cadc.net.ResourceNotFoundException; import ca.nrc.cadc.util.Base64; import ca.nrc.cadc.util.StringUtil; import java.io.ByteArrayInputStream; @@ -560,7 +561,13 @@ private void updatePermissions(Node doiNode, Status current, Status updated) thr updateNodePermissions(doiNode, readGroups, writeGroups); // update doi metadata file and data folder permissions - updateDOIPermissions(doiSuffix, readGroups, writeGroups); + String dataPath = String.format("%s/data", doiSuffix); + VOSURI dataURI = getVOSURI(dataPath); + ContainerNode dataNode = vospaceDoiClient.getContainerNode(dataPath); + updateDOIPermissions(doiSuffix, dataURI, dataNode, readGroups, writeGroups); + + // give the publisher group read permission to files in the data folder + updateDataFilePermissions(dataURI, dataNode, readGroups); } else { throw new IllegalArgumentException("Invalid status change: 'in progress' -> 'review ready'"); } @@ -605,7 +612,13 @@ private void updatePermissions(Node doiNode, Status current, Status updated) thr updateNodePermissions(doiNode, readGroups, writeGroups); // update doi data folder permissions - updateDOIPermissions(doiSuffix, readGroups, writeGroups); + String dataPath = String.format("%s/data", doiSuffix); + VOSURI dataURI = getVOSURI(dataPath); + ContainerNode dataNode = vospaceDoiClient.getContainerNode(dataPath); + updateDOIPermissions(doiSuffix, dataURI, dataNode, readGroups, writeGroups); + + // remove publisher group read permission for files in the data folder + updateDataFilePermissions(dataURI, dataNode, readGroups); } else { String message = String.format("Status change denied: '%s' -> '%s'", current, updated); throw new IllegalArgumentException(message); @@ -646,7 +659,7 @@ private void updateNodePermissions(Node doiNode, Set readGroups, Set readGroups, Set writeGroups) throws Exception { + private void updateDOIPermissions(String doiSuffix, VOSURI dataURI, ContainerNode dataNode, Set readGroups, Set writeGroups) throws Exception { // update metadata file permissions String metadataFilename = getDoiFilename(doiSuffix); String metadataPath = String.format("%s/%s", doiSuffix, metadataFilename); @@ -656,11 +669,17 @@ private void updateDOIPermissions(String doiSuffix, Set readGroups, Se vospaceDoiClient.getVOSpaceClient().setNode(metadataVOSURI, metadataNode); // update data folder permissions - String dataPath = String.format("%s/data", doiSuffix); - VOSURI dataURI = getVOSURI(dataPath); - ContainerNode dataFolderNode = vospaceDoiClient.getContainerNode(dataPath); - updateNodePermissions(dataFolderNode, readGroups, writeGroups); - vospaceDoiClient.getVOSpaceClient().setNode(dataURI, dataFolderNode); + updateNodePermissions(dataNode, readGroups, writeGroups); + vospaceDoiClient.getVOSpaceClient().setNode(dataURI, dataNode); + } + + private void updateDataFilePermissions(VOSURI dataURI, ContainerNode dataNode, Set readGroups) + throws IOException, ResourceNotFoundException, InterruptedException { + dataNode.getReadOnlyGroup().clear(); + dataNode.getReadOnlyGroup().addAll(readGroups); + RecursiveSetNode setNode = vospaceDoiClient.getVOSpaceClient().createRecursiveSetNode(dataURI, dataNode); + setNode.setMonitor(true); + setNode.run(); } private Map getNodeProperties(JSONObject nodeData) {