From 10201a9ceac289852d5ab82d0b562c330f30edda Mon Sep 17 00:00:00 2001 From: Luca Frosini Date: Wed, 27 Feb 2019 12:02:20 +0000 Subject: [PATCH] Saparated REST class from Profile management and code to effectively manage profile on IS git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-publishing/gcat@177318 82a268e6-3cf1-43bd-a215-b396298e98cf --- .../org/gcube/gcat/profile/ISProfile.java | 197 +++++++++++++++++ .../java/org/gcube/gcat/rest/Profile.java | 203 +++--------------- .../org/gcube/gcat/profile/ProfileTest.java | 91 ++++++++ .../java/org/gcube/gcat/rest/ProfileTest.java | 15 +- 4 files changed, 336 insertions(+), 170 deletions(-) create mode 100644 src/main/java/org/gcube/gcat/profile/ISProfile.java create mode 100644 src/test/java/org/gcube/gcat/profile/ProfileTest.java diff --git a/src/main/java/org/gcube/gcat/profile/ISProfile.java b/src/main/java/org/gcube/gcat/profile/ISProfile.java new file mode 100644 index 0000000..0863df4 --- /dev/null +++ b/src/main/java/org/gcube/gcat/profile/ISProfile.java @@ -0,0 +1,197 @@ +package org.gcube.gcat.profile; + +import java.io.StringWriter; +import java.util.List; +import java.util.Set; + +import javax.ws.rs.InternalServerErrorException; +import javax.ws.rs.NotFoundException; +import javax.ws.rs.WebApplicationException; + +import org.gcube.common.resources.gcore.GenericResource; +import org.gcube.common.resources.gcore.Resources; +import org.gcube.datacatalogue.metadatadiscovery.reader.MetadataFormatDiscovery; +import org.gcube.datacatalogue.metadatadiscovery.reader.QueryForResourceUtil; +import org.gcube.gcat.utils.Constants; +import org.gcube.informationsystem.publisher.RegistryPublisher; +import org.gcube.informationsystem.publisher.RegistryPublisherFactory; +import org.gcube.resources.discovery.client.api.DiscoveryClient; +import org.gcube.resources.discovery.client.queries.api.Query; +import org.gcube.resources.discovery.client.queries.impl.QueryBox; +import org.gcube.resources.discovery.icclient.ICFactory; +import org.json.JSONObject; +import org.json.XML; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; + +public class ISProfile { + + public static int PRETTY_PRINT_INDENT_FACTOR = 4; + + private static Logger logger = LoggerFactory.getLogger(ISProfile.class); + + protected ObjectMapper mapper; + + public ISProfile() { + mapper = new ObjectMapper(); + } + + public ObjectMapper getMapper() { + return mapper; + } + + public ArrayNode list() { + ArrayNode arrayNode = mapper.createArrayNode(); + + try { + Set names = MetadataUtility.getInstance().getProfilesNames(); + for(String name : names) { + arrayNode.add(name); + } + return arrayNode; + } catch(Exception e) { + throw new InternalServerErrorException(e); + } + } + + /* + * TODO Check the Queries because the name in the Profile differs from the name in + * + * + */ + protected GenericResource instantiateGenericResource(String name, String xml) throws Exception { + GenericResource genericResource = new GenericResource(); + org.gcube.common.resources.gcore.GenericResource.Profile profile = genericResource.newProfile(); + profile.type(MetadataFormatDiscovery.DATA_CATALOGUE_METADATA_SECONDARY_TYPE); + profile.name(name); + profile.description("Profile create using " + Constants.CATALOGUE_NAME); + // appendXmlFragment(profile, xml); + profile.newBody(xml); + StringWriter stringWriter = new StringWriter(); + Resources.marshal(genericResource, stringWriter); + logger.debug("The generated {} is\n{}", GenericResource.class.getSimpleName(), stringWriter.toString()); + return genericResource; + } + + protected void createGenericResource(String name, String xml) throws Exception { + GenericResource genericResource = instantiateGenericResource(name, xml); + RegistryPublisher registryPublisher = RegistryPublisherFactory.create(); + genericResource = registryPublisher.create(genericResource); + StringWriter stringWriter = new StringWriter(); + Resources.marshal(genericResource, stringWriter); + logger.trace("The {} with ID {} has been created \n{}", GenericResource.class.getSimpleName(), + genericResource.id(), stringWriter.toString()); + } + + protected GenericResource getGenericResource(String name) { + String query = QueryForResourceUtil.getGcubeGenericQueryStringForSecondaryTypeAndName(name, + MetadataFormatDiscovery.DATA_CATALOGUE_METADATA_SECONDARY_TYPE); + Query q = new QueryBox(query); + DiscoveryClient client = ICFactory.clientFor(GenericResource.class); + List resources = client.submit(q); + + if(resources == null || resources.size() == 0) { + throw new InternalServerErrorException( + "No Resources with secondaryType '" + MetadataFormatDiscovery.DATA_CATALOGUE_METADATA_SECONDARY_TYPE + + "' and name '" + name + "' exists in the current context"); + } else { + if(resources.size() == 1) { + GenericResource genericResource = resources.get(0); + return genericResource; + } else { + throw new InternalServerErrorException("More than one Resource with secondaryType '" + + MetadataFormatDiscovery.DATA_CATALOGUE_METADATA_SECONDARY_TYPE + "' and name '" + name + + "' exists in the current context"); + } + } + } + + protected void updateGenericResource(String name, String xml) { + + GenericResource genericResource = getGenericResource(name); + logger.info("The {} with ID {} is going to be updated", GenericResource.class.getSimpleName(), + genericResource.id()); + + genericResource.profile().newBody(xml); + RegistryPublisher registryPublisher = RegistryPublisherFactory.create(); + registryPublisher.update(genericResource); + + StringWriter stringWriter = new StringWriter(); + Resources.marshal(genericResource, stringWriter); + logger.trace("The {} with ID {} has been updated to \n{}", GenericResource.class.getSimpleName(), + genericResource.id(), stringWriter.toString()); + + } + + protected void removeGenericResource(String name) { + GenericResource genericResource = getGenericResource(name); + RegistryPublisher registryPublisher = RegistryPublisherFactory.create(); + registryPublisher.remove(genericResource); + } + + public String read(String name, boolean xml) { + try { + String profile = MetadataUtility.getInstance().getMetadataFormat(name).getMetadataSource(); + if(profile != null) { + if(xml) { + return profile; + } else { + JSONObject xmlJSONObj = XML.toJSONObject(profile); + String jsonString = xmlJSONObj.toString(PRETTY_PRINT_INDENT_FACTOR); + return jsonString; + } + } else { + throw new NotFoundException("Profile with name " + name + " not found"); + } + } catch(WebApplicationException e) { + throw e; + } catch(Exception e) { + throw new InternalServerErrorException(e.getMessage()); + } + } + + + public boolean createOrUpdate(String name, String xml) { + try { + MetadataUtility metadataUtility = MetadataUtility.getInstance(); + metadataUtility.getDataCalogueMetadataFormatReader().validateProfile(xml); + if(metadataUtility.getMetadataFormat(name) == null) { + createGenericResource(name, xml); + return true; + } else { + updateGenericResource(name, xml); + return false; + } + } catch(WebApplicationException e) { + throw e; + } catch(Exception e) { + throw new InternalServerErrorException(e.getMessage()); + } finally { + // TOOD Actually Cache has been removed. Remove the following code if it will not be re-introduced + // Cleaning the cache + MetadataUtility.clearCache(); + } + } + + public boolean delete(String name) { + try { + MetadataUtility metadataUtility = MetadataUtility.getInstance(); + if(metadataUtility.getMetadataFormat(name) == null) { + throw new NotFoundException("Profile with name " + name + " not found"); + } else { + removeGenericResource(name); + return true; + } + } catch(WebApplicationException e) { + throw e; + } catch(Exception e) { + throw new InternalServerErrorException(e.getMessage()); + } finally { + // Cleaning the cache + MetadataUtility.clearCache(); + } + } +} diff --git a/src/main/java/org/gcube/gcat/rest/Profile.java b/src/main/java/org/gcube/gcat/rest/Profile.java index e82c0e7..8cda655 100644 --- a/src/main/java/org/gcube/gcat/rest/Profile.java +++ b/src/main/java/org/gcube/gcat/rest/Profile.java @@ -1,47 +1,26 @@ package org.gcube.gcat.rest; -import java.io.StringWriter; -import java.util.List; -import java.util.Set; - import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; import javax.ws.rs.InternalServerErrorException; -import javax.ws.rs.NotFoundException; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; -import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.UriInfo; +import javax.xml.ws.WebServiceException; -import org.gcube.common.resources.gcore.GenericResource; -import org.gcube.common.resources.gcore.Resources; -import org.gcube.datacatalogue.metadatadiscovery.reader.MetadataFormatDiscovery; -import org.gcube.datacatalogue.metadatadiscovery.reader.QueryForResourceUtil; import org.gcube.gcat.ResourceInitializer; -import org.gcube.gcat.profile.MetadataUtility; -import org.gcube.gcat.utils.Constants; -import org.gcube.informationsystem.publisher.RegistryPublisher; -import org.gcube.informationsystem.publisher.RegistryPublisherFactory; -import org.gcube.resources.discovery.client.api.DiscoveryClient; -import org.gcube.resources.discovery.client.queries.api.Query; -import org.gcube.resources.discovery.client.queries.impl.QueryBox; -import org.gcube.resources.discovery.icclient.ICFactory; -import org.json.JSONObject; -import org.json.XML; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.gcube.gcat.profile.ISProfile; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; /** @@ -50,8 +29,6 @@ import com.fasterxml.jackson.databind.node.ArrayNode; @Path(Profile.PROFILES) public class Profile extends BaseREST implements org.gcube.gcat.api.interfaces.Profile { - private static Logger logger = LoggerFactory.getLogger(Profile.class); - public static final String PROFILE_NAME_PARAMETER = "PROFILE_NAME"; @Context @@ -61,18 +38,14 @@ public class Profile extends BaseREST implements org.gcube.gcat.api.interfaces.P @Produces(MediaType.APPLICATION_JSON) public String list() { setCalledMethod("GET /" + PROFILES); - - ObjectMapper mapper = new ObjectMapper(); - ArrayNode arrayNode = mapper.createArrayNode(); - try { - Set names = MetadataUtility.getInstance().getProfilesNames(); - for(String name : names) { - arrayNode.add(name); - } - return mapper.writeValueAsString(arrayNode); + ISProfile isProfile = new ISProfile(); + ArrayNode arrayNode = isProfile.list(); + return isProfile.getMapper().writeValueAsString(arrayNode); + } catch(WebServiceException e) { + throw e; } catch(Exception e) { - throw new InternalServerErrorException(e.getMessage()); + throw new InternalServerErrorException(e); } } @@ -85,115 +58,19 @@ public class Profile extends BaseREST implements org.gcube.gcat.api.interfaces.P @DefaultValue(MediaType.APPLICATION_XML) @HeaderParam("Accept") String accept) { setCalledMethod("GET /" + PROFILES + "/{" + PROFILE_NAME_PARAMETER + "}"); try { - String profile = MetadataUtility.getInstance().getMetadataFormat(name).getMetadataSource(); - if(profile != null) { - if(accept.startsWith(MediaType.APPLICATION_XML)) { - return profile; - } else { - JSONObject xmlJSONObj = XML.toJSONObject(profile); - String jsonString = xmlJSONObj.toString(PRETTY_PRINT_INDENT_FACTOR); - return jsonString; - } - } else { - throw new NotFoundException("Profile with name " + name + " not found"); + ISProfile isProfile = new ISProfile(); + boolean xml = false; + if(accept.startsWith(MediaType.APPLICATION_XML)) { + xml = true; } - } catch(WebApplicationException e) { + return isProfile.read(name, xml); + } catch(WebServiceException e) { throw e; } catch(Exception e) { - throw new InternalServerErrorException(e.getMessage()); + throw new InternalServerErrorException(e); } } - - /* - public static void appendXmlFragment(org.gcube.common.resources.gcore.GenericResource.Profile profile, String xml) throws Exception { - try { - DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - Element elem = profile.newBody(); - Node fragmentNode = docBuilder.parse(new InputSource(new StringReader(xml))).getDocumentElement(); - fragmentNode = elem.getOwnerDocument().importNode(fragmentNode, true); - elem.appendChild(fragmentNode); - } catch (Exception e) { - profile.newBody(xml); - } - - } - */ - - /* - * TODO Check the Queries because the name in the Profile differs from the name in - * - * - */ - protected GenericResource instantiateGenericResource(String name, String xml) throws Exception { - GenericResource genericResource = new GenericResource(); - org.gcube.common.resources.gcore.GenericResource.Profile profile = genericResource.newProfile(); - profile.type(MetadataFormatDiscovery.DATA_CATALOGUE_METADATA_SECONDARY_TYPE); - profile.name(name); - profile.description("Profile create using " + Constants.CATALOGUE_NAME); - // appendXmlFragment(profile, xml); - profile.newBody(xml); - StringWriter stringWriter = new StringWriter(); - Resources.marshal(genericResource, stringWriter); - logger.debug("The generated {} is\n{}", GenericResource.class.getSimpleName(), stringWriter.toString()); - return genericResource; - } - - protected void createGenericResource(String name, String xml) throws Exception { - GenericResource genericResource = instantiateGenericResource(name, xml); - RegistryPublisher registryPublisher = RegistryPublisherFactory.create(); - genericResource = registryPublisher.create(genericResource); - StringWriter stringWriter = new StringWriter(); - Resources.marshal(genericResource, stringWriter); - logger.trace("The {} with ID {} has been created \n{}", GenericResource.class.getSimpleName(), - genericResource.id(), stringWriter.toString()); - } - - protected GenericResource getGenericResource(String name) { - String query = QueryForResourceUtil.getGcubeGenericQueryStringForSecondaryTypeAndName(name, - MetadataFormatDiscovery.DATA_CATALOGUE_METADATA_SECONDARY_TYPE); - Query q = new QueryBox(query); - DiscoveryClient client = ICFactory.clientFor(GenericResource.class); - List resources = client.submit(q); - - if(resources == null || resources.size() == 0) { - throw new InternalServerErrorException( - "No Resources with secondaryType '" + MetadataFormatDiscovery.DATA_CATALOGUE_METADATA_SECONDARY_TYPE - + "' and name '" + name + "' exists in the current context"); - } else { - if(resources.size() == 1) { - GenericResource genericResource = resources.get(0); - return genericResource; - } else { - throw new InternalServerErrorException("More than one Resource with secondaryType '" - + MetadataFormatDiscovery.DATA_CATALOGUE_METADATA_SECONDARY_TYPE + "' and name '" + name - + "' exists in the current context"); - } - } - } - - protected void updateGenericResource(String name, String xml) { - - GenericResource genericResource = getGenericResource(name); - logger.info("The {} with ID {} is going to be updated", GenericResource.class.getSimpleName(), - genericResource.id()); - - genericResource.profile().newBody(xml); - RegistryPublisher registryPublisher = RegistryPublisherFactory.create(); - registryPublisher.update(genericResource); - - StringWriter stringWriter = new StringWriter(); - Resources.marshal(genericResource, stringWriter); - logger.trace("The {} with ID {} has been updated to \n{}", GenericResource.class.getSimpleName(), - genericResource.id(), stringWriter.toString()); - - } - - protected void removeGenericResource(String name) { - GenericResource genericResource = getGenericResource(name); - RegistryPublisher registryPublisher = RegistryPublisherFactory.create(); - registryPublisher.remove(genericResource); - } - + @PUT @Path("/{" + PROFILE_NAME_PARAMETER + "}") @Consumes(MediaType.APPLICATION_XML) @@ -201,26 +78,21 @@ public class Profile extends BaseREST implements org.gcube.gcat.api.interfaces.P public Response createOrUpdate(@PathParam(PROFILE_NAME_PARAMETER) String name, String xml) { setCalledMethod("PUT /" + PROFILES + "/{" + PROFILE_NAME_PARAMETER + "}"); try { - MetadataUtility metadataUtility = MetadataUtility.getInstance(); - metadataUtility.getDataCalogueMetadataFormatReader().validateProfile(xml); - if(metadataUtility.getMetadataFormat(name) == null) { - createGenericResource(name, xml); - ResponseBuilder responseBuilder = Response.status(Status.CREATED).entity(xml); + ISProfile isProfile = new ISProfile(); + boolean created = isProfile.createOrUpdate(name, xml); + ResponseBuilder responseBuilder = null; + if(created) { + responseBuilder = Response.status(Status.CREATED); responseBuilder.header(LOCATION_HEADER, uriInfo.getAbsolutePath()); - return responseBuilder.type(MediaType.APPLICATION_XML).build(); - } else { - updateGenericResource(name, xml); - ResponseBuilder responseBuilder = Response.status(Status.OK).entity(xml); - return responseBuilder.type(MediaType.APPLICATION_XML).build(); + }else { + responseBuilder = Response.status(Status.OK); } - } catch(WebApplicationException e) { + responseBuilder.entity(xml); + return responseBuilder.type(MediaType.APPLICATION_XML).build(); + } catch(WebServiceException e) { throw e; } catch(Exception e) { - throw new InternalServerErrorException(e.getMessage()); - }finally { - // TOOD Actually Cache has been removed. Remove the following code if it will not be re-introduced - // Cleaning the cache - MetadataUtility.clearCache(); + throw new InternalServerErrorException(e); } } @@ -229,23 +101,16 @@ public class Profile extends BaseREST implements org.gcube.gcat.api.interfaces.P public Response delete(@PathParam(PROFILE_NAME_PARAMETER) String name) { setCalledMethod("DELETE /" + PROFILES + "/{" + PROFILE_NAME_PARAMETER + "}"); try { - MetadataUtility metadataUtility = MetadataUtility.getInstance(); - if(metadataUtility.getMetadataFormat(name) == null) { - throw new NotFoundException("Profile with name " + name + " not found"); - } else { - removeGenericResource(name); - return Response.status(Status.NO_CONTENT).build(); - } - } catch(WebApplicationException e) { + ISProfile isProfile = new ISProfile(); + isProfile.delete(name); + return Response.status(Status.NO_CONTENT).build(); + } catch(WebServiceException e) { throw e; } catch(Exception e) { - throw new InternalServerErrorException(e.getMessage()); - } finally { - // Cleaning the cache - MetadataUtility.clearCache(); + throw new InternalServerErrorException(e); } } - + @Override public Response create(String name, String xml) { return createOrUpdate(name, xml); @@ -261,5 +126,5 @@ public class Profile extends BaseREST implements org.gcube.gcat.api.interfaces.P public String update(String name, String xml) { return createOrUpdate(name, xml).getEntity().toString(); } - + } diff --git a/src/test/java/org/gcube/gcat/profile/ProfileTest.java b/src/test/java/org/gcube/gcat/profile/ProfileTest.java new file mode 100644 index 0000000..33a32c5 --- /dev/null +++ b/src/test/java/org/gcube/gcat/profile/ProfileTest.java @@ -0,0 +1,91 @@ +package org.gcube.gcat.profile; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Iterator; +import java.util.stream.Collectors; + +import org.gcube.gcat.ContextTest; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; + +public class ProfileTest extends ContextTest { + + private static Logger logger = LoggerFactory.getLogger(ProfileTest.class); + + @Test + public void list() throws Exception { + ISProfile profile = new ISProfile(); + ArrayNode arrayNode = profile.list(); + logger.debug("{}", arrayNode); + } + + + @Test + public void read() throws Exception { + String profileID = "EmptyProfile"; + ISProfile profile = new ISProfile(); + boolean xml = true; + String ret = profile.read(profileID, xml); + logger.debug("XML :\n{}", ret); + xml = false; + ret = profile.read(profileID, xml); + logger.debug("JSON : \n{}", ret); + } + + @Test + public void listRead() throws Exception { + ISProfile profile = new ISProfile(); + ArrayNode arrayNode = profile.list(); + logger.debug("Found {} profiles", arrayNode.size()); + Iterator iterator = arrayNode.iterator(); + while(iterator.hasNext()) { + String profileID = iterator.next().asText(); + boolean xml = true; + String ret = profile.read(profileID, xml); + logger.debug("XML :\n{}", ret); + xml = false; + ret = profile.read(profileID, xml); + logger.debug("JSON : \n{}", ret); + } + } + + @Test + public void testCreateOrUpdate() throws Exception { + String xml = "testfalseString1Test FieldPopulationfalseString*The population of the modelonValueonFieldName_onValue"; + ISProfile profile = new ISProfile(); + profile.createOrUpdate("TestProfile", xml); + } + + @Test + public void testDelete() throws Exception { + ISProfile profile = new ISProfile(); + profile.delete("TestProfile"); + } + + public static String PROFILE_EXAMPLE_FILENAME = "EmptyProfileExample.xml"; + + public static String PROFILE_NAME_EXAMPLE = "EmptyProfile"; + + @Test + public void testCreateUpdateDeleteGenericResource() throws Exception { + InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(PROFILE_EXAMPLE_FILENAME); + String xml = new BufferedReader(new InputStreamReader(inputStream)).lines() + .collect(Collectors.joining("\n")); + logger.debug("Body\n{}", xml); + ISProfile profile = new ISProfile(); + profile.createOrUpdate(PROFILE_NAME_EXAMPLE, xml); + /* + Thread.sleep(TimeUnit.SECONDS.toMillis(30)); + profile.createOrUpdate(PROFILE_NAME_EXAMPLE, ""); + Thread.sleep(TimeUnit.SECONDS.toMillis(30)); + profile.delete(PROFILE_NAME_EXAMPLE); + */ + } + +} diff --git a/src/test/java/org/gcube/gcat/rest/ProfileTest.java b/src/test/java/org/gcube/gcat/rest/ProfileTest.java index 0533dfd..2b8b0af 100644 --- a/src/test/java/org/gcube/gcat/rest/ProfileTest.java +++ b/src/test/java/org/gcube/gcat/rest/ProfileTest.java @@ -31,7 +31,7 @@ public class ProfileTest extends ContextTest { @Test public void read() throws Exception { - String profileID = "SoBigData.eu: Dataset Metadata NextNext"; + String profileID = "EmptyProfile"; Profile profile = new Profile(); String ret = profile.read(profileID, MediaType.APPLICATION_XML); logger.debug("XML :\n{}", ret); @@ -56,6 +56,19 @@ public class ProfileTest extends ContextTest { } } + @Test + public void testCreateOrUpdate() throws Exception { + String xml = "testfalseString1Test FieldPopulationfalseString*The population of the modelonValueonFieldName_onValue"; + Profile profile = new Profile(); + profile.create("TestProfile", xml); + } + + @Test + public void testDelete() throws Exception { + Profile profile = new Profile(); + profile.delete("TestProfile"); + } + public static String PROFILE_EXAMPLE_FILENAME = "EmptyProfileExample.xml"; public static String PROFILE_NAME_EXAMPLE = "EmptyProfile";