From 9f71894ca874cba2ec38bd0c1f3fc273de880eec Mon Sep 17 00:00:00 2001 From: "luca.frosini" Date: Thu, 23 Feb 2017 16:02:32 +0000 Subject: [PATCH] Added exception marshalling/umarshalling via json using jackson git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/information-system/resource-registry-api@144208 82a268e6-3cf1-43bd-a215-b396298e98cf --- .../api/exceptions/AlreadyPresent.java | 5 + .../api/exceptions/ExceptionMapper.java | 147 ++++++++++++++++++ .../api/exceptions/NotFound.java | 5 + .../exceptions/ResourceRegistryException.java | 6 +- .../context/ContextNotFoundException.java | 3 +- .../entity/EntityAlreadyPresentException.java | 3 +- .../entity/EntityNotFoundException.java | 3 +- .../facet/FacetAlreadyPresentException.java | 3 +- .../entity/facet/FacetNotFoundException.java | 3 +- .../ResourceAlreadyPresentException.java | 3 +- .../resource/ResourceNotFoundException.java | 3 +- .../er/ERAlreadyPresentException.java | 4 +- .../exceptions/er/ERNotFoundException.java | 3 +- .../query/InvalidQueryException.java | 1 - .../RelationAlreadyPresentException.java | 3 +- .../relation/RelationNotFoundException.java | 3 +- .../schema/SchemaNotFoundException.java | 4 +- .../exceptions/ExceptionSerialization.java | 49 ++++++ src/test/resources/logback-test.xml | 19 +++ 19 files changed, 255 insertions(+), 15 deletions(-) create mode 100644 src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/AlreadyPresent.java create mode 100644 src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/ExceptionMapper.java create mode 100644 src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/NotFound.java create mode 100644 src/test/java/org/gcube/informationsystem/resourceregistry/api/exceptions/ExceptionSerialization.java create mode 100644 src/test/resources/logback-test.xml diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/AlreadyPresent.java b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/AlreadyPresent.java new file mode 100644 index 0000000..67cf553 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/AlreadyPresent.java @@ -0,0 +1,5 @@ +package org.gcube.informationsystem.resourceregistry.api.exceptions; + +public interface AlreadyPresent { + +} diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/ExceptionMapper.java b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/ExceptionMapper.java new file mode 100644 index 0000000..426d2bd --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/ExceptionMapper.java @@ -0,0 +1,147 @@ +package org.gcube.informationsystem.resourceregistry.api.exceptions; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; +import java.util.List; + +import org.gcube.informationsystem.impl.utils.discovery.ReflectionUtility; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +public abstract class ExceptionMapper { + + private static Logger logger = LoggerFactory.getLogger(ExceptionMapper.class); + + protected static final ObjectMapper mapper; + + /** + * @return the ObjectMapper + */ + public static ObjectMapper getObjectMapper() { + return mapper; + } + + static { + + mapper = new ObjectMapper(); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + Package p = ResourceRegistryException.class.getPackage(); + try { + List> classes = ReflectionUtility.getClassesForPackage(p); + for (Class clz : classes) { + logger.trace("Analyzing {}", clz); + + if (ResourceRegistryException.class.isAssignableFrom(clz)) { + mapper.registerSubtypes(clz); + } + + } + } catch (ClassNotFoundException e) { + logger.error("Error discovering classes inside package {}", + p.getName(), e); + throw new RuntimeException(e); + } + + + } + + /** + * Write the serialization of a given resource to a given + * {@link OutputStream} . + * + * @param resource the resource + * @param stream the stream in input + * @throws IOException + * @throws JsonMappingException + * @throws JsonGenerationException + */ + public static T marshal(RRE object, T stream) + throws JsonGenerationException, JsonMappingException, IOException { + mapper.writeValue(stream, object); + return stream; + } + + /** + * Write the serialization of a given resource to a given {@link Writer} . + * @param resource the resource + * @param writer the writer in input + * @throws IOException + * @throws JsonMappingException + * @throws JsonGenerationException + */ + public static T marshal(RRE object, T writer) + throws JsonGenerationException, JsonMappingException, IOException { + mapper.writeValue(writer, object); + return writer; + } + + /** + * Return the String serialization of a given resource + * @param object the resource + * @return the String serialization of a given resource + * @throws JsonProcessingException + */ + public static String marshal(RRE object) throws JsonProcessingException { + return mapper.writeValueAsString(object); + } + + /** + * Creates a resource of given class from its serialization in a given + * {@link Reader}. + * @param clz the class of the resource + * @param reader the reader + * @return the resource + * @throws JsonParseException + * @throws JsonMappingException + * @throws IOException + */ + public static RRE unmarshal(Class clz, Reader reader) + throws JsonParseException, JsonMappingException, IOException { + return mapper.readValue(reader, clz); + } + + /** + * Creates a resource of given class from its serialization in a given + * {@link InputStream}. + * @param clz the class of the resource + * @param stream the stream + * @return the resource + * @throws IOException + * @throws JsonMappingException + * @throws JsonParseException + */ + public static RRE unmarshal(Class clz, InputStream stream) + throws JsonParseException, JsonMappingException, IOException { + return mapper.readValue(stream, clz); + } + + /** + * Creates a resource of given class from its serialization in a given String + * @param clz the class of the resource + * @param string + * @return the resource + * @throws JsonParseException + * @throws JsonMappingException + * @throws IOException + */ + public static RRE unmarshal(Class clz, String string) + throws JsonParseException, JsonMappingException, IOException { + return mapper.readValue(string, clz); + } + + +} diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/NotFound.java b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/NotFound.java new file mode 100644 index 0000000..9c90e27 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/NotFound.java @@ -0,0 +1,5 @@ +package org.gcube.informationsystem.resourceregistry.api.exceptions; + +public interface NotFound { + +} diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/ResourceRegistryException.java b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/ResourceRegistryException.java index f2681e2..8b2c5ee 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/ResourceRegistryException.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/ResourceRegistryException.java @@ -3,10 +3,14 @@ */ package org.gcube.informationsystem.resourceregistry.api.exceptions; +import org.gcube.informationsystem.model.ISManageable; + +import com.fasterxml.jackson.annotation.JsonTypeInfo; + /** * @author Luca Frosini (ISTI - CNR) - * */ +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = ISManageable.CLASS_PROPERTY) public class ResourceRegistryException extends Exception { /** diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/context/ContextNotFoundException.java b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/context/ContextNotFoundException.java index 8c5fcc6..5ba3bd4 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/context/ContextNotFoundException.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/context/ContextNotFoundException.java @@ -1,11 +1,12 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions.context; +import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFound; /** * @author Luca Frosini (ISTI - CNR) * */ -public class ContextNotFoundException extends ContextException { +public class ContextNotFoundException extends ContextException implements NotFound { /** * Generated Serial Version UID diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/entity/EntityAlreadyPresentException.java b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/entity/EntityAlreadyPresentException.java index 163c8a3..14665c8 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/entity/EntityAlreadyPresentException.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/entity/EntityAlreadyPresentException.java @@ -1,12 +1,13 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions.entity; +import org.gcube.informationsystem.resourceregistry.api.exceptions.AlreadyPresent; import org.gcube.informationsystem.resourceregistry.api.exceptions.er.ERAlreadyPresentException; /** * @author Luca Frosini (ISTI - CNR) * */ -public class EntityAlreadyPresentException extends ERAlreadyPresentException { +public class EntityAlreadyPresentException extends ERAlreadyPresentException implements AlreadyPresent { /** * Generated Serial Version UID diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/entity/EntityNotFoundException.java b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/entity/EntityNotFoundException.java index 0118f48..fde31a7 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/entity/EntityNotFoundException.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/entity/EntityNotFoundException.java @@ -1,12 +1,13 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions.entity; +import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFound; import org.gcube.informationsystem.resourceregistry.api.exceptions.er.ERNotFoundException; /** * @author Luca Frosini (ISTI - CNR) * */ -public class EntityNotFoundException extends ERNotFoundException { +public class EntityNotFoundException extends ERNotFoundException implements NotFound { /** * Generated Serial Version UID diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/entity/facet/FacetAlreadyPresentException.java b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/entity/facet/FacetAlreadyPresentException.java index 806c6c1..2250290 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/entity/facet/FacetAlreadyPresentException.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/entity/facet/FacetAlreadyPresentException.java @@ -1,5 +1,6 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions.entity.facet; +import org.gcube.informationsystem.resourceregistry.api.exceptions.AlreadyPresent; import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.EntityAlreadyPresentException; @@ -7,7 +8,7 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.Entity * @author Luca Frosini (ISTI - CNR) * */ -public class FacetAlreadyPresentException extends EntityAlreadyPresentException { +public class FacetAlreadyPresentException extends EntityAlreadyPresentException implements AlreadyPresent { /** * Generated Serial Version UID diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/entity/facet/FacetNotFoundException.java b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/entity/facet/FacetNotFoundException.java index 5a98201..a39fb3d 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/entity/facet/FacetNotFoundException.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/entity/facet/FacetNotFoundException.java @@ -1,5 +1,6 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions.entity.facet; +import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFound; import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.EntityNotFoundException; @@ -7,7 +8,7 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.Entity * @author Luca Frosini (ISTI - CNR) * */ -public class FacetNotFoundException extends EntityNotFoundException { +public class FacetNotFoundException extends EntityNotFoundException implements NotFound { /** * Generated Serial Version UID diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/entity/resource/ResourceAlreadyPresentException.java b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/entity/resource/ResourceAlreadyPresentException.java index 661e9f0..0eee8f5 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/entity/resource/ResourceAlreadyPresentException.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/entity/resource/ResourceAlreadyPresentException.java @@ -1,5 +1,6 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions.entity.resource; +import org.gcube.informationsystem.resourceregistry.api.exceptions.AlreadyPresent; import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.EntityAlreadyPresentException; @@ -7,7 +8,7 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.Entity * @author Luca Frosini (ISTI - CNR) * */ -public class ResourceAlreadyPresentException extends EntityAlreadyPresentException { +public class ResourceAlreadyPresentException extends EntityAlreadyPresentException implements AlreadyPresent { /** * Generated Serial Version UID diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/entity/resource/ResourceNotFoundException.java b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/entity/resource/ResourceNotFoundException.java index f0fa61d..6ce985d 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/entity/resource/ResourceNotFoundException.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/entity/resource/ResourceNotFoundException.java @@ -1,5 +1,6 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions.entity.resource; +import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFound; import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.EntityNotFoundException; @@ -7,7 +8,7 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.Entity * @author Luca Frosini (ISTI - CNR) * */ -public class ResourceNotFoundException extends EntityNotFoundException { +public class ResourceNotFoundException extends EntityNotFoundException implements NotFound { /** * Generated Serial Version UID diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/er/ERAlreadyPresentException.java b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/er/ERAlreadyPresentException.java index 64660fa..60a7786 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/er/ERAlreadyPresentException.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/er/ERAlreadyPresentException.java @@ -1,12 +1,12 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions.er; - +import org.gcube.informationsystem.resourceregistry.api.exceptions.AlreadyPresent; /** * @author Luca Frosini (ISTI - CNR) * */ -public class ERAlreadyPresentException extends ERException { +public class ERAlreadyPresentException extends ERException implements AlreadyPresent { /** * Generated Serial Version UID diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/er/ERNotFoundException.java b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/er/ERNotFoundException.java index ba345b0..6cfd961 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/er/ERNotFoundException.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/er/ERNotFoundException.java @@ -1,11 +1,12 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions.er; +import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFound; /** * @author Luca Frosini (ISTI - CNR) * */ -public class ERNotFoundException extends ERException { +public class ERNotFoundException extends ERException implements NotFound { /** * Generated Serial Version UID diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/query/InvalidQueryException.java b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/query/InvalidQueryException.java index 029db02..1761dac 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/query/InvalidQueryException.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/query/InvalidQueryException.java @@ -5,7 +5,6 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegis /** * @author Luca Frosini (ISTI - CNR) - * */ public class InvalidQueryException extends ResourceRegistryException { diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/relation/RelationAlreadyPresentException.java b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/relation/RelationAlreadyPresentException.java index fa8a12e..5ea6482 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/relation/RelationAlreadyPresentException.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/relation/RelationAlreadyPresentException.java @@ -1,12 +1,13 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions.relation; +import org.gcube.informationsystem.resourceregistry.api.exceptions.AlreadyPresent; import org.gcube.informationsystem.resourceregistry.api.exceptions.er.ERAlreadyPresentException; /** * @author Luca Frosini (ISTI - CNR) * */ -public class RelationAlreadyPresentException extends ERAlreadyPresentException { +public class RelationAlreadyPresentException extends ERAlreadyPresentException implements AlreadyPresent { /** * Generated Serial Version UID diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/relation/RelationNotFoundException.java b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/relation/RelationNotFoundException.java index 4dd795e..f569a6f 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/relation/RelationNotFoundException.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/relation/RelationNotFoundException.java @@ -1,12 +1,13 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions.relation; +import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFound; import org.gcube.informationsystem.resourceregistry.api.exceptions.er.ERNotFoundException; /** * @author Luca Frosini (ISTI - CNR) * */ -public class RelationNotFoundException extends ERNotFoundException { +public class RelationNotFoundException extends ERNotFoundException implements NotFound { /** diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/schema/SchemaNotFoundException.java b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/schema/SchemaNotFoundException.java index e422d03..ecc2a8e 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/schema/SchemaNotFoundException.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/api/exceptions/schema/SchemaNotFoundException.java @@ -1,10 +1,12 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions.schema; +import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFound; + /** * @author Luca Frosini (ISTI - CNR) * */ -public class SchemaNotFoundException extends SchemaException { +public class SchemaNotFoundException extends SchemaException implements NotFound { /** * Generated Serial Version UID diff --git a/src/test/java/org/gcube/informationsystem/resourceregistry/api/exceptions/ExceptionSerialization.java b/src/test/java/org/gcube/informationsystem/resourceregistry/api/exceptions/ExceptionSerialization.java new file mode 100644 index 0000000..edb6881 --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/resourceregistry/api/exceptions/ExceptionSerialization.java @@ -0,0 +1,49 @@ +package org.gcube.informationsystem.resourceregistry.api.exceptions; + +import java.lang.reflect.Constructor; +import java.util.List; + +import org.gcube.informationsystem.impl.utils.discovery.ReflectionUtility; +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ExceptionSerialization { + + private static Logger logger = LoggerFactory.getLogger(ExceptionSerialization.class); + + public static final String MESSAGE = "Error Message to test "; + + @Test + public void testAll() throws Exception{ + Package p = ResourceRegistryException.class.getPackage(); + try { + List> classes = ReflectionUtility.getClassesForPackage(p); + for (Class clz : classes) { + + if (ResourceRegistryException.class.isAssignableFrom(clz)) { + logger.debug("Testing {}", clz); + + Constructor constructor = clz.getConstructor(String.class); + ResourceRegistryException rre = (ResourceRegistryException) constructor.newInstance(MESSAGE + clz.getSimpleName()); + + String jsonString = ExceptionMapper.marshal(rre); + + ResourceRegistryException rreUnmashalled = ExceptionMapper.unmarshal(ResourceRegistryException.class, jsonString); + + Assert.assertTrue(rre.getClass() == rreUnmashalled.getClass()); + Assert.assertTrue(rre.getMessage().compareTo(rreUnmashalled.getMessage())==0); + + logger.debug("{} successfully tested", clz); + } + + } + } catch (ClassNotFoundException e) { + logger.error("Error discovering classes inside package {}", + p.getName(), e); + throw new RuntimeException(e); + } + } + +} diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml new file mode 100644 index 0000000..b30f7fb --- /dev/null +++ b/src/test/resources/logback-test.xml @@ -0,0 +1,19 @@ + + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{0}: %msg%n + + + + + + + + + + + + \ No newline at end of file