From 0f15f0e4d4f71a5c5569e7d3fc8a115f22dbd22a Mon Sep 17 00:00:00 2001 From: Luca Frosini Date: Thu, 23 Nov 2017 11:33:08 +0000 Subject: [PATCH] Refs #10247: Create Resource Registry Context Client Task-Url: https://support.d4science.org/issues/10247 git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/information-system/resource-registry-context-client@158781 82a268e6-3cf1-43bd-a215-b396298e98cf --- .../ResourceRegistryContextClientImpl.java | 2 +- .../ResourceRegistryContextClientTest.java | 416 ++++++++++++++++++ .../resourceregistry/context/ScopedTest.java | 118 +++++ 3 files changed, 535 insertions(+), 1 deletion(-) create mode 100644 src/test/java/org/gcube/informationsystem/resourceregistry/context/ResourceRegistryContextClientTest.java create mode 100644 src/test/java/org/gcube/informationsystem/resourceregistry/context/ScopedTest.java diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/context/ResourceRegistryContextClientImpl.java b/src/main/java/org/gcube/informationsystem/resourceregistry/context/ResourceRegistryContextClientImpl.java index dec9415..0ba6ce5 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/context/ResourceRegistryContextClientImpl.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/context/ResourceRegistryContextClientImpl.java @@ -174,7 +174,7 @@ public class ResourceRegistryContextClientImpl implements ResourceRegistryContex @Override public boolean delete(String uuid) throws ContextNotFoundException, ResourceRegistryException { try { - logger.trace("Going to read {} with UUID {}", Context.NAME); + logger.trace("Going to delete {} with UUID {}", Context.NAME, uuid); StringWriter stringWriter = new StringWriter(); stringWriter.append(PATH_SEPARATOR); stringWriter.append(ContextPath.CONTEXT_PATH_PART); diff --git a/src/test/java/org/gcube/informationsystem/resourceregistry/context/ResourceRegistryContextClientTest.java b/src/test/java/org/gcube/informationsystem/resourceregistry/context/ResourceRegistryContextClientTest.java new file mode 100644 index 0000000..eaea9fd --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/resourceregistry/context/ResourceRegistryContextClientTest.java @@ -0,0 +1,416 @@ +package org.gcube.informationsystem.resourceregistry.context; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.gcube.common.authorization.client.Constants; +import org.gcube.common.authorization.library.AuthorizationEntry; +import org.gcube.common.authorization.library.provider.ClientInfo; +import org.gcube.common.authorization.library.provider.SecurityTokenProvider; +import org.gcube.informationsystem.impl.embedded.HeaderImpl; +import org.gcube.informationsystem.impl.entity.ContextImpl; +import org.gcube.informationsystem.impl.utils.ISMapper; +import org.gcube.informationsystem.model.ER; +import org.gcube.informationsystem.model.entity.Context; +import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextAlreadyPresentException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextNotFoundException; +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonProcessingException; + +public class ResourceRegistryContextClientTest extends ScopedTest { + + private static Logger logger = LoggerFactory.getLogger(ResourceRegistryContextClientTest.class); + + protected ResourceRegistryContextClient resourceRegistryContextClient; + + public ResourceRegistryContextClientTest(){ + resourceRegistryContextClient = ResourceRegistryContextClientFactory.create(); + } + + public static final String CTX_NAME_A = "A"; + public static final String CTX_NAME_B = "B"; + public static final String CTX_NAME_C = "C"; + + public static String getUser() { + String user = org.gcube.informationsystem.model.embedded.Header.UNKNOWN_USER; + try { + String token = SecurityTokenProvider.instance.get(); + if(token!=null) { + AuthorizationEntry authorizationEntry = Constants.authorizationService().get(token); + if (authorizationEntry != null) { + ClientInfo clientInfo = authorizationEntry.getClientInfo(); + String clientId = clientInfo.getId(); + if (clientId != null && clientId.compareTo("") != 0) { + user = clientId; + } else { + throw new Exception("Username null or empty"); + } + } + } + } catch (Exception e) { + logger.error("Unable to retrieve user. {} will be used", user); + } + return user; + } + + public static void checkHeader(ER er, UUID uuid, boolean create) { + Assert.assertTrue(er.getHeader()!=null); + Assert.assertTrue(er.getHeader().getUUID()!=null); + + if(uuid!=null) { + Assert.assertTrue(er.getHeader().getUUID().compareTo(uuid)==0); + } + + String user = getUser(); + Assert.assertTrue(er.getHeader().getModifiedBy().compareTo(user)==0); + + if(create){ + Assert.assertTrue(er.getHeader().getCreator().compareTo(user)==0); + Assert.assertTrue(er.getHeader().getCreationTime().compareTo(er.getHeader().getLastUpdateTime())==0); + }else { + Assert.assertTrue(er.getHeader().getCreationTime().before(er.getHeader().getLastUpdateTime())); + } + + } + + protected void assertions(Context pre, Context post, boolean checkParent, boolean create) { + if (checkParent) { + if (pre.getHeader() != null) { + checkHeader(post, pre.getHeader().getUUID(), create); + } else { + checkHeader(post, null, create); + } + } + + Assert.assertTrue(pre.getName().compareTo(post.getName()) == 0); + if (checkParent && pre.getParent() != null && post.getParent() != null) { + Context preParent = pre.getParent().getSource(); + Context postParent = post.getParent().getSource(); + assertions(preParent, postParent, false, false); + } + } + + protected Context read(UUID uuid) throws ResourceRegistryException, IOException { + Context c = resourceRegistryContextClient.read(uuid); + Assert.assertTrue(c.getHeader()!=null); + Assert.assertTrue(c.getHeader().getUUID()!=null); + Assert.assertTrue(c.getHeader().getUUID().compareTo(uuid)==0); + return c; + } + + protected Context create(Context context) throws ResourceRegistryException, IOException { + Context c = resourceRegistryContextClient.create(context); + assertions(context, c, true, true); + return c; + } + + protected Context update(Context context) throws ResourceRegistryException, IOException { + Context c = resourceRegistryContextClient.update(context); + assertions(context, c, true, false); + return c; + } + + protected boolean delete(UUID uuid) throws ResourceRegistryException { + boolean deleted = resourceRegistryContextClient.delete(uuid); + Assert.assertTrue(deleted); + logger.debug("Deleted {} with UUID {}", Context.NAME, uuid); + return deleted; + } + + protected boolean delete(Context context) throws ResourceRegistryException { + return delete(context.getHeader().getUUID()); + } + + protected void invalidCreate(Context context) throws ResourceRegistryException, IOException { + try { + Context c = create(context); + throw new RuntimeException(ISMapper.marshal(c) + " was created successfully. This is not what we expected"); + } catch (ContextAlreadyPresentException e) { + logger.debug("As expected {} cannot be created.", ISMapper.marshal(context)); + } + } + + protected void invalidUpdate(Context context) throws ResourceRegistryException, IOException { + try { + Context c = update(context); + throw new RuntimeException(ISMapper.marshal(c) + " was updated successfully. This is not what we expected"); + } catch (ContextAlreadyPresentException e) { + logger.debug("As expected {} cannot be updated.", ISMapper.marshal(context)); + } + } + + protected void invalidDelete(Context context) throws ResourceRegistryException, JsonProcessingException { + String contextString = ISMapper.marshal(context); + try { + delete(context); + throw new RuntimeException(contextString + " was deleted successfully. This is not what we expected"); + } catch (ContextException e) { + logger.debug("As expected {} cannot be deleted.", contextString); + } + } + + // @Test + public void readTest() throws Exception { + UUID uuid = UUID.fromString("0958c0e2-2146-4521-adea-4e73dfbf92da"); + Context gcube = read(uuid); + logger.debug(ISMapper.marshal(gcube)); + } + + + @Test + public void completeTest() throws Exception { + Context contextA1 = new ContextImpl(CTX_NAME_A); + contextA1 = create(contextA1); + // ________A1________ + + Context contextA2 = new ContextImpl(CTX_NAME_A); + contextA2.setParent(contextA1); + contextA2 = create(contextA2); + // ________A1________ + // ___A2 + + Context contextB3 = new ContextImpl(CTX_NAME_B); + contextB3.setParent(contextA2); + contextB3 = create(contextB3); + // ________A1________ + // ___A2 + // B3 + + Context contextB4 = new ContextImpl(CTX_NAME_B); + contextB4.setParent(contextA1); + contextB4 = create(contextB4); + // ________A1________ + // ___A2_______B4____ + // B3 + + Context contextA5 = new ContextImpl(CTX_NAME_A); + contextA5.setParent(contextB4); + contextA5 = create(contextA5); + // ________A1________ + // ___A2_______B4____ + // B3______________A5 + + invalidCreate(contextA1); // Trying to recreate A1. Fails + invalidCreate(contextA2); // Trying to recreate A2. Fails + invalidCreate(contextB3); // Trying to recreate B3. Fails + invalidCreate(contextB4); // Trying to recreate B4. Fails + invalidCreate(contextA5); // Trying to recreate A5. Fails + + // Trying to move A5 as child of A1. It fails due to A2. + Context nullContext = null; + contextA5.setParent(nullContext); + invalidUpdate(contextA5); + contextA5.setParent(contextB4); + // ________A1________ + // ___A2_______B4____ + // B3______________A5 + + nullContext = null; + contextB4.setParent(nullContext); + update(contextB4); + // _____A1____B4_____ + // __A2__________A5__ + // B3 + + contextB4.setParent(contextA1); + update(contextB4); + // ________A1________ + // ___A2_______B4____ + // B3______________A5 + + // Trying to rename with the new name A. It fails due to A5. + contextB3.setName(CTX_NAME_A); + update(contextB3); + // ________A1________ + // ___A2_______B4____ + // A3______________A5 + + // After Restoring name B, trying to move B3 as child of A1. It fails due to B4. + contextB3.setName(CTX_NAME_B); + contextB3.setParent(contextA1); + invalidUpdate(contextB3); + // ________A1________ + // ___A2_______B4____ + // A3______________A5 + + // Restoring A3 (was B3) as B3 and with parent A2.OK. + contextB3.setName(CTX_NAME_B); + contextB3.setParent(contextA2); + update(contextB3); + // ________A1________ + // ___A2_______B4____ + // B3______________A5 + + // This update should not has eny effects except updating the lastUpdateTime. + contextB3.setName(CTX_NAME_B); + contextB3.setParent(contextA2); + update(contextB3); + + // Trying to move A5 as child of A1. It fails due to A2. + contextA5.setParent(contextA1); + invalidUpdate(contextA5); + // Restoring A5 + contextA5.setParent(contextB4); + // ________A1________ + // ___A2_______B4____ + // B3______________A5 + + // Moving B3 as child of B4. OK. + contextB3.setParent(contextB4); + update(contextB3); + // ________A1________ + // ___A2_______B4____ + // ________B3______A5 + + // Restoring the initial situation by moving B3 as child of A2. OK. + contextB3.setParent(contextA2); + update(contextB3); + // ________A1________ + // ___A2_______B4____ + // B3______________A5 + + // Renaming B3 as C3. OK. + contextB3.setName(CTX_NAME_C); + update(contextB3); + // ________A1________ + // ___A2_______B4____ + // C3______________A5 + + // Moving C3 (was B3) as child of A1. Now it is possible. OK. + contextB3.setParent(contextA1); + update(contextB3); + // ________A1________ + // ___A2___C3___B4___ + // ________________A5 + + // Trying to rename C3 (was B3) newly to B3. Fails due to B4. + contextB3.setName(CTX_NAME_B); + invalidUpdate(contextB3); + // ________A1________ + // ___A2___C3___B4___ + // ________________A5 + + // Moving back C3 (was B3) as child of A2. OK. + contextB3.setParent(contextA2); + update(contextB3); + // ________A1________ + // ___A2_______B4____ + // C3______________A5 + + // Renaming C3 (was B3) to B3. OK. + contextB3.setName(CTX_NAME_B); + update(contextB3); + // ________A1________ + // ___A2_______B4____ + // B3______________A5 + + // The following delete are not allowed because they are not child contexts + invalidDelete(contextA1); + invalidDelete(contextA2); + invalidDelete(contextB4); + + delete(contextA5); + // ________A1________ + // ___A2_______B4____ + // B3 + + try { + delete(contextA5); + } catch (ContextNotFoundException e) { + logger.debug("The context with uuid {} was not found. (Was already deleted)", + contextA5.getHeader().getUUID()); + } + + delete(contextB3); + // ________A1________ + // ___A2_______B4____ + + delete(contextB4); + // ________A1________ + // ___A2 + + delete(contextA2); + // ________A1________ + + Context contextC = new ContextImpl(CTX_NAME_C); + contextC.setHeader(new HeaderImpl(contextA1.getHeader().getUUID())); + invalidCreate(contextC); + + delete(contextA1); + logger.debug("The DB should be now clean"); + } + + // @Test + public void createDevContext() throws Exception { + Context gcube = new ContextImpl("gcube"); + gcube = create(gcube); + + Context devsec = new ContextImpl("devsec"); + devsec.setParent(gcube); + devsec = create(devsec); + + Context devVRE = new ContextImpl("devVRE"); + devVRE.setParent(devsec); + devVRE = create(devVRE); + + Context devNext = new ContextImpl("devNext"); + devNext.setParent(gcube); + devNext = create(devNext); + + Context nextNext = new ContextImpl("NextNext"); + nextNext.setParent(devNext); + nextNext = create(nextNext); + + Context preprod = new ContextImpl("preprod"); + preprod.setParent(gcube); + preprod = create(preprod); + + Context preVRE = new ContextImpl("preVRE"); + preVRE.setParent(preprod); + preVRE = create(preVRE); + } + + // @Test + public void createPARTHENOSContext() throws Exception { + // /d4science.research-infrastructures.eu/ParthenosVO/PARTHENOS_Registry + + Context d4science = new ContextImpl("d4science.research-infrastructures.eu"); + create(d4science); + + Context parthenosVO = new ContextImpl("ParthenosVO"); + parthenosVO.setParent(d4science); + create(parthenosVO); + + Context parthenosRegistry = new ContextImpl("PARTHENOS_Registry"); + parthenosRegistry.setParent(parthenosVO); + create(parthenosRegistry); + + } + + // @Test + public void createProductionMissingContext() throws Exception { + UUID d4ResearchUUID = UUID.fromString("8b926d1c-4460-4d7a-adab-c75ad2770a21"); + UUID farmUUID = UUID.fromString("dbafdb3e-f7f9-4039-ad1c-3432c041f53c"); + + Map contexts = new HashMap<>(); + contexts.put("ICES_FIACO2017", d4ResearchUUID); + contexts.put("D4STeam", farmUUID); + + for (String contextName : contexts.keySet()) { + Context parent = read(contexts.get(contextName)); + Context context = new ContextImpl(contextName); + context.setParent(parent); + create(context); + } + + } + +} diff --git a/src/test/java/org/gcube/informationsystem/resourceregistry/context/ScopedTest.java b/src/test/java/org/gcube/informationsystem/resourceregistry/context/ScopedTest.java new file mode 100644 index 0000000..1718117 --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/resourceregistry/context/ScopedTest.java @@ -0,0 +1,118 @@ +/** + * + */ +package org.gcube.informationsystem.resourceregistry.context; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +import org.gcube.common.authorization.client.Constants; +import org.gcube.common.authorization.client.exceptions.ObjectNotFound; +import org.gcube.common.authorization.library.AuthorizationEntry; +import org.gcube.common.authorization.library.provider.SecurityTokenProvider; +import org.gcube.common.scope.api.ScopeProvider; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Luca Frosini (ISTI - CNR) + * + */ +public class ScopedTest { + + private static final Logger logger = LoggerFactory.getLogger(ScopedTest.class); + + protected static final String PROPERTIES_FILENAME = "token.properties"; + + private static final String GCUBE_DEVNEXT_VARNAME = "GCUBE_DEVNEXT"; + public static final String GCUBE_DEVNEXT; + + private static final String GCUBE_DEVNEXT_NEXTNEXT_VARNAME = "GCUBE_DEVNEXT_NEXTNEXT"; + public static final String GCUBE_DEVNEXT_NEXTNEXT; + + public static final String GCUBE_DEVSEC_VARNAME = "GCUBE_DEVSEC"; + public static final String GCUBE_DEVSEC; + + public static final String GCUBE_DEVSEC_DEVVRE_VARNAME = "GCUBE_DEVSEC_DEVVRE"; + public static final String GCUBE_DEVSEC_DEVVRE; + + public static final String GCUBE_VARNAME = "GCUBE"; + public static final String GCUBE; + + + public static final String DEFAULT_TEST_SCOPE; + public static final String ALTERNATIVE_TEST_SCOPE; + + + protected static final String REGISTRY_PROPERTIES_FILENAME = "registry.properties"; + public static final String RESOURCE_REGISTRY_URL_PROPERTY = "RESOURCE_REGISTRY_URL"; + public static final String RESOURCE_REGISTRY_URL; + + static { + Properties properties = new Properties(); + InputStream input = ScopedTest.class.getClassLoader().getResourceAsStream(PROPERTIES_FILENAME); + + try { + // load the properties file + properties.load(input); + } catch (IOException e) { + throw new RuntimeException(e); + } + + GCUBE_DEVNEXT = properties.getProperty(GCUBE_DEVNEXT_VARNAME); + GCUBE_DEVNEXT_NEXTNEXT = properties.getProperty(GCUBE_DEVNEXT_NEXTNEXT_VARNAME); + + GCUBE_DEVSEC = properties.getProperty(GCUBE_DEVSEC_VARNAME); + GCUBE_DEVSEC_DEVVRE = properties.getProperty(GCUBE_DEVSEC_DEVVRE_VARNAME); + + GCUBE = properties.getProperty(GCUBE_VARNAME); + + DEFAULT_TEST_SCOPE = GCUBE_DEVNEXT_NEXTNEXT; + ALTERNATIVE_TEST_SCOPE = GCUBE_DEVSEC_DEVVRE; + + + properties = new Properties(); + input = ScopedTest.class.getClassLoader().getResourceAsStream(REGISTRY_PROPERTIES_FILENAME); + try { + // load the properties file + properties.load(input); + } catch (IOException e) { + throw new RuntimeException(e); + } + + RESOURCE_REGISTRY_URL = properties.getProperty(RESOURCE_REGISTRY_URL_PROPERTY); + + if(RESOURCE_REGISTRY_URL!=null){ + ResourceRegistryContextClientFactory.forceToURL(RESOURCE_REGISTRY_URL); + } + + } + + public static String getCurrentScope(String token) throws ObjectNotFound, Exception{ + AuthorizationEntry authorizationEntry = Constants.authorizationService().get(token); + String context = authorizationEntry.getContext(); + logger.info("Context of token {} is {}", token, context); + return context; + } + + + public static void setContext(String token) throws ObjectNotFound, Exception{ + SecurityTokenProvider.instance.set(token); + ScopeProvider.instance.set(getCurrentScope(token)); + } + + @BeforeClass + public static void beforeClass() throws Exception{ + setContext(DEFAULT_TEST_SCOPE); + } + + @AfterClass + public static void afterClass() throws Exception{ + SecurityTokenProvider.instance.reset(); + ScopeProvider.instance.reset(); + } + +}