From debdda387705a10af0ba1c58b953c76bcc4a95df Mon Sep 17 00:00:00 2001 From: Sonia Zorba <sonia.zorba@inaf.it> Date: Tue, 9 Mar 2021 16:00:02 +0100 Subject: [PATCH] Bugfix getNodePropertyAsListByURI and added NodeUtils tests --- .../vospace/datamodel/NodeProperties.java | 91 +++----- .../oats/vospace/datamodel/NodeUtils.java | 44 ++-- .../vospace/datamodel/NodePropertiesTest.java | 28 +++ .../oats/vospace/datamodel/NodeUtilsTest.java | 208 ++++++++++++++---- 4 files changed, 248 insertions(+), 123 deletions(-) create mode 100644 src/test/java/it/inaf/oats/vospace/datamodel/NodePropertiesTest.java diff --git a/src/main/java/it/inaf/oats/vospace/datamodel/NodeProperties.java b/src/main/java/it/inaf/oats/vospace/datamodel/NodeProperties.java index fbc098a..3661f69 100644 --- a/src/main/java/it/inaf/oats/vospace/datamodel/NodeProperties.java +++ b/src/main/java/it/inaf/oats/vospace/datamodel/NodeProperties.java @@ -1,88 +1,71 @@ package it.inaf.oats.vospace.datamodel; import java.util.List; -import java.util.stream.Collectors; import net.ivoa.xml.vospace.v2.Node; import net.ivoa.xml.vospace.v2.Property; public abstract class NodeProperties { - - - private NodeProperties() { } - + + private NodeProperties() { + } + public static final String BASE_URI = "ivo://ivoa.net/vospace/core#"; public static final String AVAILABLE_SPACE_URI = "ivo://ivoa.net/vospace/core#availableSpace"; // the amount of space available within a container - public static final String INITIAL_CREATION_TIME_URI = "ivo://ivoa.net/vospace/core#btime"; // the initial creation time - public static final String CONTRIBUTOR_URI = "ivo://ivoa.net/vospace/core#contributor"; // an entity responsible for making contributions to this resource - public static final String COVERAGE_URI = "ivo://ivoa.net/vospace/core#coverage"; // a spatial or temporal topic of the resource, the spatial applicability of the resource, or the jurisdiction under which the resource is relevant - public static final String CREATOR_URI = "ivo://ivoa.net/vospace/core#creator"; // an entity primarily responsible for making the resource - public static final String STATUS_CHANGE_TIME_URI = "ivo://ivoa.net/vospace/core#ctime"; // the status change (aka metadata modification) time - public static final String DATE_URI = "ivo://ivoa.net/vospace/core#date"; // a point or period of time associated with an event in the lifecycle of the resource - public static final String DESCRIPTION_URI = "ivo://ivoa.net/vospace/core#description"; // an account of the resource - public static final String FORMAT_URI = "ivo://ivoa.net/vospace/core#format"; // the file format, physical medium or dimensions of the resource - public static final String GROUP_READ_URI = "ivo://ivoa.net/vospace/core#groupread"; // the list of groups which can only read this resource delimiter-separated - public static final String GROUP_WRITE_URI = "ivo://ivoa.net/vospace/core#groupwrite"; // the list of groups which can read and write to this resource delimiter-separated - public static final String IDENTIFIER_URI = "ivo://ivoa.net/vospace/core#identifier"; // an unambiguous reference to the resource within a given context - public static final String LANGUAGE_URI = "ivo://ivoa.net/vospace/core#language"; // a language of the resource - public static final String LENGTH_URI = "ivo://ivoa.net/vospace/core#length"; // the length or size of a resource - public static final String MODIFICATION_TIME_URI = "ivo://ivoa.net/vospace/core#mtime"; // the data modification time - public static final String PUBLIC_READ_URI = "ivo://ivoa.net/vospace/core#publicread"; // whether this resource is world readable - public static final String PUBLISHER_URI = "ivo://ivoa.net/vospace/core#publisher"; // an entity responsible for making the resource available - public static final String QUOTA_URI = "ivo://ivoa.net/vospace/core#quota"; // the value of a system quota on the resource - public static final String RELATED_RESOURCE_URI = "ivo://ivoa.net/vospace/core#relation"; // a related resource - public static final String RIGHTS_ON_URI = "ivo://ivoa.net/vospace/core#rights"; // information about rights held in and over the resource - public static final String RESOURCE_RELATED_URI = "ivo://ivoa.net/vospace/core#source"; // a related resource from which the described resource is derived - public static final String SUBJECT_URI = "ivo://ivoa.net/vospace/core#subject"; // the topic of the resource - public static final String TITLE_URI = "ivo://ivoa.net/vospace/core#title"; // a name given to the resource - public static final String TYPE_URI = "ivo://ivoa.net/vospace/core#type"; // the nature or genre of the resource + public static final String INITIAL_CREATION_TIME_URI = "ivo://ivoa.net/vospace/core#btime"; // the initial creation time + public static final String CONTRIBUTOR_URI = "ivo://ivoa.net/vospace/core#contributor"; // an entity responsible for making contributions to this resource + public static final String COVERAGE_URI = "ivo://ivoa.net/vospace/core#coverage"; // a spatial or temporal topic of the resource, the spatial applicability of the resource, or the jurisdiction under which the resource is relevant + public static final String CREATOR_URI = "ivo://ivoa.net/vospace/core#creator"; // an entity primarily responsible for making the resource + public static final String STATUS_CHANGE_TIME_URI = "ivo://ivoa.net/vospace/core#ctime"; // the status change (aka metadata modification) time + public static final String DATE_URI = "ivo://ivoa.net/vospace/core#date"; // a point or period of time associated with an event in the lifecycle of the resource + public static final String DESCRIPTION_URI = "ivo://ivoa.net/vospace/core#description"; // an account of the resource + public static final String FORMAT_URI = "ivo://ivoa.net/vospace/core#format"; // the file format, physical medium or dimensions of the resource + public static final String GROUP_READ_URI = "ivo://ivoa.net/vospace/core#groupread"; // the list of groups which can only read this resource delimiter-separated + public static final String GROUP_WRITE_URI = "ivo://ivoa.net/vospace/core#groupwrite"; // the list of groups which can read and write to this resource delimiter-separated + public static final String IDENTIFIER_URI = "ivo://ivoa.net/vospace/core#identifier"; // an unambiguous reference to the resource within a given context + public static final String LANGUAGE_URI = "ivo://ivoa.net/vospace/core#language"; // a language of the resource + public static final String LENGTH_URI = "ivo://ivoa.net/vospace/core#length"; // the length or size of a resource + public static final String MODIFICATION_TIME_URI = "ivo://ivoa.net/vospace/core#mtime"; // the data modification time + public static final String PUBLIC_READ_URI = "ivo://ivoa.net/vospace/core#publicread"; // whether this resource is world readable + public static final String PUBLISHER_URI = "ivo://ivoa.net/vospace/core#publisher"; // an entity responsible for making the resource available + public static final String QUOTA_URI = "ivo://ivoa.net/vospace/core#quota"; // the value of a system quota on the resource + public static final String RELATED_RESOURCE_URI = "ivo://ivoa.net/vospace/core#relation"; // a related resource + public static final String RIGHTS_ON_URI = "ivo://ivoa.net/vospace/core#rights"; // information about rights held in and over the resource + public static final String RESOURCE_RELATED_URI = "ivo://ivoa.net/vospace/core#source"; // a related resource from which the described resource is derived + public static final String SUBJECT_URI = "ivo://ivoa.net/vospace/core#subject"; // the topic of the resource + public static final String TITLE_URI = "ivo://ivoa.net/vospace/core#title"; // a name given to the resource + public static final String TYPE_URI = "ivo://ivoa.net/vospace/core#type"; // the nature or genre of the resource // // Non-standard properties public static final String ASYNC_TRANS_URN = "urn:async_trans"; public static final String STICKY_URN = "urn:sticky"; - - - public static String getStandardNodePropertyByName(Node node, String propertyName) { return getNodePropertyByURI(node, BASE_URI.concat(propertyName)); } - - public static String getProperty(Node node, String propertyName) { - - for (Property property : node.getProperties()) { - if (property.getUri().equals(BASE_URI.concat(propertyName))) { - return property.getValue(); - } - } - return null; - } - - public static String getNodePropertyByURI(Node node, String uri) { - + for (Property property : node.getProperties()) { if (uri.equals(property.getUri())) { return property.getValue(); } } return null; - } + // Returns all properties stored inside the node under the requested // property URI. public static List<String> getNodePropertyAsListByURI(Node node, String propertyURI) { + String property = getNodePropertyByURI(node, propertyURI); + return parsePropertyStringToList(property); + } - List<String> propertyList = node.getProperties().stream() - .filter((i) -> i.getUri() - .equals(propertyURI)) - .map((i) -> i.getValue()) - .collect(Collectors.toList()); + private static List<String> parsePropertyStringToList(String property) { - return propertyList; - } + if (property == null) { + return List.of(); + } - public static List<String> parsePropertyStringToList(String property) { // If separator changes, this method should remain consistent // For now it assumes that " " is the separator String separator = " "; @@ -93,7 +76,5 @@ public abstract class NodeProperties { } return List.of(trimmedProperty.split(separator)); - } - } diff --git a/src/main/java/it/inaf/oats/vospace/datamodel/NodeUtils.java b/src/main/java/it/inaf/oats/vospace/datamodel/NodeUtils.java index 22b131f..2021bdb 100644 --- a/src/main/java/it/inaf/oats/vospace/datamodel/NodeUtils.java +++ b/src/main/java/it/inaf/oats/vospace/datamodel/NodeUtils.java @@ -110,13 +110,11 @@ public class NodeUtils { } return resultList; - } public static boolean checkIfWritable(Node myNode, String userName, List<String> userGroups) { - return checkAccessPropery(myNode, userName, userGroups, NodeProperties.GROUP_WRITE_URI); - + return checkAccessProperty(myNode, userName, userGroups, NodeProperties.GROUP_WRITE_URI); } public static boolean checkIfReadable(Node myNode, String userName, List<String> userGroups) { @@ -125,20 +123,18 @@ public class NodeUtils { return true; } - return checkAccessPropery(myNode, userName, userGroups, NodeProperties.GROUP_READ_URI); - + return checkAccessProperty(myNode, userName, userGroups, NodeProperties.GROUP_READ_URI); } - public static boolean checkAccessPropery(Node myNode, String userName, + private static boolean checkAccessProperty(Node myNode, String userName, List<String> userGroups, String accessPropertyName) { // First check if parent node creator is == userid - List<String> nodeOwner - = NodeProperties.getNodePropertyAsListByURI(myNode, NodeProperties.CREATOR_URI); + String nodeOwner = NodeProperties.getNodePropertyByURI(myNode, NodeProperties.CREATOR_URI); if (nodeOwner == null || nodeOwner.isEmpty() - || !nodeOwner.get(0).equals(userName)) { + || !nodeOwner.equals(userName)) { // Node owner check has failed: let's check if user can write // due to group privileges @@ -157,11 +153,8 @@ public class NodeUtils { return false; } - List<String> nodeGroups - = NodeProperties.parsePropertyStringToList(groupAccessPropValues.get(0)); - - if (nodeGroups.isEmpty() - || !nodeGroups.stream() + if (groupAccessPropValues.isEmpty() + || !groupAccessPropValues.stream() .anyMatch((i) -> userGroups.contains(i))) { return false; } @@ -170,9 +163,6 @@ public class NodeUtils { return true; } - - - public static String getDbNodeType(Node node) { if (node instanceof ContainerNode) { @@ -182,7 +172,6 @@ public class NodeUtils { } throw new UnsupportedOperationException("Unable to retrieve database node type for class " + node.getClass().getCanonicalName()); } - public static String getNodeName(String path) { String[] parsedPath = path.split("/"); @@ -190,12 +179,10 @@ public class NodeUtils { return parsedPath[parsedPath.length - 1]; } - public static String getNodeName(Node myNode) { String uri = myNode.getUri(); return getNodeName(uri); } - public static boolean getIsBusy(Node myNode) { @@ -207,8 +194,7 @@ public class NodeUtils { return false; } - - + public static Node getTypedNode(String type) { Node node; switch (type) { @@ -226,14 +212,12 @@ public class NodeUtils { } return node; } - - + public static String getVosPath(Node myNode) { - - String nodeUri = myNode.getUri(); - - return nodeUri.replaceAll("vos://[^/]+", ""); - } - + + String nodeUri = myNode.getUri(); + + return nodeUri.replaceAll("vos://[^/]+", ""); + } } diff --git a/src/test/java/it/inaf/oats/vospace/datamodel/NodePropertiesTest.java b/src/test/java/it/inaf/oats/vospace/datamodel/NodePropertiesTest.java new file mode 100644 index 0000000..d1457f9 --- /dev/null +++ b/src/test/java/it/inaf/oats/vospace/datamodel/NodePropertiesTest.java @@ -0,0 +1,28 @@ +package it.inaf.oats.vospace.datamodel; + +import java.util.List; +import net.ivoa.xml.vospace.v2.DataNode; +import net.ivoa.xml.vospace.v2.Node; +import net.ivoa.xml.vospace.v2.Property; +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; + +public class NodePropertiesTest { + + @Test + public void testGetNodePropertyAsListByURI() { + + Property groupRead = new Property(); + groupRead.setUri(NodeProperties.GROUP_READ_URI); + groupRead.setValue("group1 group2"); + + Node node = new DataNode(); + node.getProperties().add(groupRead); + + List<String> values = NodeProperties.getNodePropertyAsListByURI(node, NodeProperties.GROUP_READ_URI); + + assertEquals(2, values.size()); + assertEquals("group1", values.get(0)); + assertEquals("group2", values.get(1)); + } +} diff --git a/src/test/java/it/inaf/oats/vospace/datamodel/NodeUtilsTest.java b/src/test/java/it/inaf/oats/vospace/datamodel/NodeUtilsTest.java index 065dd20..13df807 100644 --- a/src/test/java/it/inaf/oats/vospace/datamodel/NodeUtilsTest.java +++ b/src/test/java/it/inaf/oats/vospace/datamodel/NodeUtilsTest.java @@ -2,8 +2,14 @@ package it.inaf.oats.vospace.datamodel; import java.util.ArrayList; import java.util.List; +import net.ivoa.xml.vospace.v2.ContainerNode; +import net.ivoa.xml.vospace.v2.DataNode; +import net.ivoa.xml.vospace.v2.LinkNode; +import net.ivoa.xml.vospace.v2.Node; +import net.ivoa.xml.vospace.v2.Property; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; @@ -44,7 +50,7 @@ public class NodeUtilsTest { public void testIllegalQuotes() { testIllegalChars("\"'.pdf"); } - + @Test public void testIllegalSlashEncoded() { testIllegalChars("%2F.pdf"); @@ -60,77 +66,203 @@ public class NodeUtilsTest { assertTrue(exception); } - //@Test + @Test public void getPathFromRequestURLStringTest() { - - + String urlForTest = "http://server.example.com/vospace/"; String result = NodeUtils.getPathFromRequestURLString(urlForTest); assertEquals("/", result); - + urlForTest = "http://server.example.com/vospace/nodes"; result = NodeUtils.getPathFromRequestURLString(urlForTest); assertEquals("/", result); - + urlForTest = "http://server.example.com/vospace/nodes/mydata"; result = NodeUtils.getPathFromRequestURLString(urlForTest); assertEquals("/mydata", result); - + urlForTest = "http://server.example.com/vospace/nodes/mydata1/uffi/nonso/pappa.txt"; result = NodeUtils.getPathFromRequestURLString(urlForTest); assertEquals("/mydata1/uffi/nonso/pappa.txt", result); } - - /* Is it a possible case? + + // Is it a possible case? @Test public void subPathComponentsTest1() { - - //assertArrayEquals(expected, actual) String pathForTest = ""; - List result = NodeUtils.subPathComponents(pathForTest); - List expected = new ArrayList(); // expected empty - assertArrayEquals(expected.toArray(), result.toArray()); - + List<String> result = NodeUtils.subPathComponents(pathForTest); + assertTrue(result.isEmpty()); } - */ - + @Test public void subPathComponentsTest2() { - + String pathForTest = "/"; - List result = NodeUtils.subPathComponents(pathForTest); - List expected = new ArrayList(); + List<String> result = NodeUtils.subPathComponents(pathForTest); + List<String> expected = new ArrayList<>(); expected.add("/"); assertArrayEquals(expected.toArray(), result.toArray()); - - - } - - - @Test - public void subPathComponentsTest3() { - + } + + @Test + public void subPathComponentsTest3() { + String pathForTest = "/mynode1"; - List result = NodeUtils.subPathComponents(pathForTest); - List expected = new ArrayList(); + List<String> result = NodeUtils.subPathComponents(pathForTest); + List<String> expected = new ArrayList<>(); expected.add("/mynode1"); assertArrayEquals(expected.toArray(), result.toArray()); - } - - + @Test public void subPathComponentsTest4() { - - //assertArrayEquals(expected, actual) + String pathForTest = "/mydata1/uffi/nonso/pappa.txt"; - List result = NodeUtils.subPathComponents(pathForTest); - List expected = new ArrayList(); + List<String> result = NodeUtils.subPathComponents(pathForTest); + List<String> expected = new ArrayList<>(); expected.add("/mydata1"); expected.add("/mydata1/uffi"); expected.add("/mydata1/uffi/nonso"); expected.add("/mydata1/uffi/nonso/pappa.txt"); assertArrayEquals(expected.toArray(), result.toArray()); - + } + + @Test + public void testCheckReadablePublicNode() { + + Property creator = getProperty(NodeProperties.CREATOR_URI, "user1"); + Property publicRead = getProperty(NodeProperties.PUBLIC_READ_URI, "true"); + + Node node = new DataNode(); + node.getProperties().add(creator); + node.getProperties().add(publicRead); + + assertTrue(NodeUtils.checkIfReadable(node, "user3", List.of())); + } + + @Test + public void testCheckReadableCreatorOnly() { + + Property creator = getProperty(NodeProperties.CREATOR_URI, "user1"); + + Node node = new DataNode(); + node.getProperties().add(creator); + + assertTrue(NodeUtils.checkIfReadable(node, "user1", List.of())); + } + + @Test + public void testCheckReadableGroupsTrue() { + + Property creator = getProperty(NodeProperties.CREATOR_URI, "user1"); + Property groupWrite = getProperty(NodeProperties.GROUP_READ_URI, "group3 group4"); + + Node node = new DataNode(); + node.getProperties().add(creator); + node.getProperties().add(groupWrite); + + assertTrue(NodeUtils.checkIfReadable(node, "user2", List.of("group2", "group3"))); + } + + @Test + public void testCheckReadableGroupsFalse() { + + Property creator = getProperty(NodeProperties.CREATOR_URI, "user1"); + Property groupWrite = getProperty(NodeProperties.GROUP_READ_URI, "group3 group4"); + + Node node = new DataNode(); + node.getProperties().add(creator); + node.getProperties().add(groupWrite); + + assertFalse(NodeUtils.checkIfReadable(node, "user2", List.of("group5", "group6"))); + } + + @Test + public void testCheckWritableCreatorOnly() { + + Property creator = getProperty(NodeProperties.CREATOR_URI, "user1"); + + Node node = new DataNode(); + node.getProperties().add(creator); + + assertTrue(NodeUtils.checkIfWritable(node, "user1", List.of())); + } + + @Test + public void testCheckWritableGroupsTrue() { + + Property creator = getProperty(NodeProperties.CREATOR_URI, "user1"); + Property groupWrite = getProperty(NodeProperties.GROUP_WRITE_URI, "group3 group4"); + + Node node = new DataNode(); + node.getProperties().add(creator); + node.getProperties().add(groupWrite); + + assertTrue(NodeUtils.checkIfWritable(node, "user2", List.of("group2", "group3"))); + } + + @Test + public void testCheckWritableGroupsFalse() { + + Property creator = getProperty(NodeProperties.CREATOR_URI, "user1"); + Property groupWrite = getProperty(NodeProperties.GROUP_WRITE_URI, "group3 group4"); + + Node node = new DataNode(); + node.getProperties().add(creator); + node.getProperties().add(groupWrite); + + assertFalse(NodeUtils.checkIfWritable(node, "user2", List.of("group5", "group6"))); + } + + @Test + public void testCheckWritableNoGroups() { + + Property creator = getProperty(NodeProperties.CREATOR_URI, "user1"); + + Node node = new DataNode(); + node.getProperties().add(creator); + + assertFalse(NodeUtils.checkIfWritable(node, "user2", List.of())); + } + + @Test + public void testGetVosPath() { + + Node node = new DataNode(); + node.setUri("vos://example.com!vospace/mynode/child1/child2"); + + assertEquals("/mynode/child1/child2", NodeUtils.getVosPath(node)); + } + + @Test + public void testGetParentPath() { + assertEquals("/node1/node2", NodeUtils.getParentPath("/node1/node2/node2")); + } + + @Test + public void testIsBusy() { + DataNode node = new DataNode(); + node.setBusy(true); + assertTrue(NodeUtils.getIsBusy(node)); + } + + @Test + public void testIsNeverBusy() { + LinkNode node = new LinkNode(); + assertFalse(NodeUtils.getIsBusy(node)); + } + + @Test + public void testGetNodeName() { + Node node = new DataNode(); + node.setUri("vos://example.com!vospace/mynode/child1/child2"); + assertEquals("child2", NodeUtils.getNodeName(node)); + } + + private Property getProperty(String uri, String value) { + Property property = new Property(); + property.setUri(uri); + property.setValue(value); + return property; } } -- GitLab