diff options
author | liamfallon <liam.fallon@ericsson.com> | 2018-09-26 18:30:37 +0100 |
---|---|---|
committer | liamfallon <liam.fallon@ericsson.com> | 2018-09-26 18:53:29 +0100 |
commit | 3db2feb37ac427a09790fef1ba637c16c3187ed6 (patch) | |
tree | 04d4ac3f0cb845c4f3b37996aafffe02b66ce0ef /context/context-management/src | |
parent | cad13bc9dbd2eaebf91fcde1a0aa03dc179f4795 (diff) |
Allow custom JSON adapter specification
In order to decode and encode complex Java POJOs with GSON,
type adapters must be specified. This change allows specification
of GSON type adapters for decoding and encoding of JSON in apex.
Issue-ID: POLICY-954
Change-Id: Ib402d4e82c4f22fa4d532c016f77fb8e7bb568d3
Signed-off-by: liamfallon <liam.fallon@ericsson.com>
Diffstat (limited to 'context/context-management/src')
11 files changed, 768 insertions, 68 deletions
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelper.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelper.java index 7a903e9d1..8b61f718a 100644 --- a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelper.java +++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelper.java @@ -21,6 +21,7 @@ package org.onap.policy.apex.context.impl.schema.java; import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; import java.lang.reflect.Constructor; @@ -29,16 +30,19 @@ import java.util.Map; import org.onap.policy.apex.context.ContextRuntimeException; import org.onap.policy.apex.context.impl.schema.AbstractSchemaHelper; +import org.onap.policy.apex.context.parameters.ContextParameterConstants; +import org.onap.policy.apex.context.parameters.SchemaParameters; import org.onap.policy.apex.model.basicmodel.concepts.AxKey; import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema; import org.onap.policy.apex.model.utilities.typeutils.TypeBuilder; +import org.onap.policy.common.parameters.ParameterService; import org.slf4j.ext.XLogger; import org.slf4j.ext.XLoggerFactory; /** - * This class implements translation to and from Apex distributed objects and Java objects when a - * Java schema is used. It creates schema items as Java objects and marshals and unmarshals these - * objects in various formats. All objects must be of the type of Java class defined in the schema. + * This class implements translation to and from Apex distributed objects and Java objects when a Java schema is used. + * It creates schema items as Java objects and marshals and unmarshals these objects in various formats. All objects + * must be of the type of Java class defined in the schema. * * @author Liam Fallon (liam.fallon@ericsson.com) */ @@ -66,10 +70,8 @@ public class JavaSchemaHelper extends AbstractSchemaHelper { /* * (non-Javadoc) * - * @see - * org.onap.policy.apex.context.impl.schema.AbstractSchemaHelper#init(org.onap.policy.apex.model - * .basicmodel. concepts. AxKey, - * org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema) + * @see org.onap.policy.apex.context.impl.schema.AbstractSchemaHelper#init(org.onap.policy.apex.model .basicmodel. + * concepts. AxKey, org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema) */ @Override public void init(final AxKey userKey, final AxContextSchema schema) { @@ -83,7 +85,7 @@ public class JavaSchemaHelper extends AbstractSchemaHelper { } catch (final IllegalArgumentException e) { String resultSting = userKey.getId() + ": class/type " + schema.getSchema() + " for context schema \"" - + schema.getId() + "\" not found."; + + schema.getId() + "\" not found."; if (JavaSchemaHelper.BUILT_IN_MAP.get(javatype) != null) { resultSting += " Primitive types are not supported. Use the appropriate Java boxing type instead."; } else { @@ -106,15 +108,15 @@ public class JavaSchemaHelper extends AbstractSchemaHelper { } if (getSchemaClass() == null) { - final String returnString = - getUserKey().getId() + ": could not create an instance, schema class for the schema is null"; + final String returnString = getUserKey().getId() + + ": could not create an instance, schema class for the schema is null"; LOGGER.warn(returnString); throw new ContextRuntimeException(returnString); } if (incomingObject instanceof JsonElement) { - final String elementJsonString = new Gson().toJson((JsonElement) incomingObject); - return new Gson().fromJson(elementJsonString, this.getSchemaClass()); + final String elementJsonString = getGson().toJson((JsonElement) incomingObject); + return getGson().fromJson(elementJsonString, this.getSchemaClass()); } if (getSchemaClass().isAssignableFrom(incomingObject.getClass())) { @@ -122,9 +124,9 @@ public class JavaSchemaHelper extends AbstractSchemaHelper { } final String returnString = getUserKey().getId() + ": the object \"" + incomingObject + "\" of type \"" - + incomingObject.getClass().getCanonicalName() - + "\" is not an instance of JsonObject and is not assignable to \"" - + getSchemaClass().getCanonicalName() + "\""; + + incomingObject.getClass().getCanonicalName() + + "\" is not an instance of JsonObject and is not assignable to \"" + + getSchemaClass().getCanonicalName() + "\""; LOGGER.warn(returnString); throw new ContextRuntimeException(returnString); } @@ -171,11 +173,11 @@ public class JavaSchemaHelper extends AbstractSchemaHelper { // Check the incoming object is of a correct class if (getSchemaClass().isAssignableFrom(schemaObject.getClass())) { // Use Gson to translate the object - return new Gson().toJson(schemaObject); + return getGson().toJson(schemaObject); } else { final String returnString = getUserKey().getId() + ": object \"" + schemaObject.toString() - + "\" of class \"" + schemaObject.getClass().getCanonicalName() + "\" not compatible with class \"" - + getSchemaClass().getCanonicalName() + "\""; + + "\" of class \"" + schemaObject.getClass().getCanonicalName() + + "\" not compatible with class \"" + getSchemaClass().getCanonicalName() + "\""; LOGGER.warn(returnString); throw new ContextRuntimeException(returnString); } @@ -189,7 +191,7 @@ public class JavaSchemaHelper extends AbstractSchemaHelper { @Override public Object marshal2Object(final Object schemaObject) { // Use Gson to marshal the schema object into a Json element to return - return new Gson().toJsonTree(schemaObject, getSchemaClass()); + return getGson().toJsonTree(schemaObject, getSchemaClass()); } /** @@ -233,10 +235,49 @@ public class JavaSchemaHelper extends AbstractSchemaHelper { return stringConstructor.newInstance(object.toString()); } catch (final Exception e) { final String returnString = getUserKey().getId() + ": object \"" + object.toString() + "\" of class \"" - + object.getClass().getCanonicalName() + "\" not compatible with class \"" - + getSchemaClass().getCanonicalName() + "\""; + + object.getClass().getCanonicalName() + "\" not compatible with class \"" + + getSchemaClass().getCanonicalName() + "\""; LOGGER.warn(returnString, e); throw new ContextRuntimeException(returnString); } } + + /** + * Get a GSON instance that has the correct adaptation included. + * + * @return the GSON instance + */ + private Gson getGson() { + GsonBuilder gsonBuilder = new GsonBuilder(); + + // Get the Java schema helper parameters from the parameter service + SchemaParameters schemaParameters = ParameterService.get(ContextParameterConstants.SCHEMA_GROUP_NAME); + + JavaSchemaHelperParameters javaSchemaHelperParmeters = (JavaSchemaHelperParameters) schemaParameters + .getSchemaHelperParameterMap().get("Java"); + + if (javaSchemaHelperParmeters == null) { + javaSchemaHelperParmeters = new JavaSchemaHelperParameters(); + } + + for (JavaSchemaHelperJsonAdapterParameters jsonAdapterEntry : javaSchemaHelperParmeters.getJsonAdapters() + .values()) { + + Object adapterObject; + try { + adapterObject = jsonAdapterEntry.getAdaptorClazz().newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + final String returnString = getUserKey().getId() + ": instantiation of adapter class \"" + + jsonAdapterEntry.getAdaptorClass() + "\" to decode and encode class \"" + + jsonAdapterEntry.getAdaptedClass() + "\" failed: " + e.getMessage(); + LOGGER.warn(returnString, e); + throw new ContextRuntimeException(returnString); + } + + gsonBuilder.registerTypeAdapter(jsonAdapterEntry.getAdaptedClazz(), adapterObject); + } + + return gsonBuilder.create(); + } + } diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelperJsonAdapterParameters.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelperJsonAdapterParameters.java new file mode 100644 index 000000000..ddd14cf21 --- /dev/null +++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelperJsonAdapterParameters.java @@ -0,0 +1,199 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.context.impl.schema.java; + +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonSerializer; + +import org.onap.policy.common.parameters.GroupValidationResult; +import org.onap.policy.common.parameters.ParameterGroup; +import org.onap.policy.common.parameters.ValidationStatus; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +//@formatter:off +/** + * Event protocol parameters for JSON as an event protocol. + * + * <p>The parameters for this plugin are: + * <ol> + * <li>adaptedClass: The name of the class being adapted. + * <li>adapterClass: the JSON adapter class to use for the adapted class. + * </ol> + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +//@formatter:on +public class JavaSchemaHelperJsonAdapterParameters implements ParameterGroup { + private static final XLogger LOGGER = XLoggerFactory.getXLogger(JavaSchemaHelperJsonAdapterParameters.class); + + // Recurring string constants + private static final String ADAPTED_CLASS = "adaptedClass"; + private static final String ADAPTOR_CLASS = "adaptorClass"; + + private String adaptedClass; + private String adaptorClass; + + /** + * {@inheritDoc} + */ + @Override + public String getName() { + return getAdaptedClass(); + } + + /** + * {@inheritDoc} + */ + @Override + public void setName(String adaptedClass) { + setAdaptedClass(adaptedClass); + } + + /** + * Gets the adapted class. + * + * @return the adapted class + */ + public String getAdaptedClass() { + return adaptedClass; + } + + /** + * Gets the adapted class. + * + * @return the adapted class + */ + public Class<?> getAdaptedClazz() { + if (adaptedClass == null) { + return null; + } + + try { + return Class.forName(adaptedClass); + } catch (final ClassNotFoundException e) { + LOGGER.warn("class \"" + adaptedClass + "\" not found: ", e); + return null; + } + } + + /** + * Sets the adapted class. + * + * @param adaptedClass the new adapted class + */ + public void setAdaptedClass(String adaptedClass) { + this.adaptedClass = adaptedClass; + } + + /** + * Gets the adaptor class. + * + * @return the adaptor class + */ + public String getAdaptorClass() { + return adaptorClass; + } + + /** + * Gets the adaptor class. + * + * @return the adaptor class + */ + public Class<?> getAdaptorClazz() { + if (adaptorClass == null) { + return null; + } + + try { + return Class.forName(adaptorClass); + } catch (final ClassNotFoundException e) { + LOGGER.warn("class \"" + adaptorClass + "\" not found: ", e); + return null; + } + } + + /** + * Sets the adaptor class. + * + * @param adaptorClass the new adaptor class + */ + public void setAdaptorClass(String adaptorClass) { + this.adaptorClass = adaptorClass; + } + + /** + * {@inheritDoc} + */ + @Override + public GroupValidationResult validate() { + final GroupValidationResult result = new GroupValidationResult(this); + + getClass(ADAPTED_CLASS, adaptedClass, result); + + Class<?> adaptorClazz = getClass(ADAPTOR_CLASS, adaptorClass, result); + if (adaptorClazz != null) { + String errorMessage = null; + + if (!JsonSerializer.class.isAssignableFrom(adaptorClazz)) { + errorMessage = "class is not a JsonSerializer"; + } + + if (!JsonDeserializer.class.isAssignableFrom(adaptorClazz)) { + if (errorMessage == null) { + errorMessage = "class is not a JsonDeserializer"; + } + else { + errorMessage = "class is not a JsonSerializer or JsonDeserializer"; + } + } + + if (errorMessage != null) { + result.setResult(ADAPTOR_CLASS, ValidationStatus.INVALID, errorMessage); + } + } + + return result; + } + + /** + * Check a class exists. + * + * @param parameterName the parameter name of the class to check for existence + * @param classToCheck the class to check for existence + * @param result the result of the check + */ + private Class<?> getClass(String parameterName, String classToCheck, final GroupValidationResult result) { + if (classToCheck == null || classToCheck.trim().length() == 0) { + result.setResult(parameterName, ValidationStatus.INVALID, "parameter is null or blank"); + return null; + } + + // Get the class for the event protocol + try { + return Class.forName(classToCheck); + } catch (final ClassNotFoundException e) { + result.setResult(parameterName, ValidationStatus.INVALID, "class not found: " + e.getMessage()); + LOGGER.warn("class not found: ", e); + return null; + } + } +} diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelperParameters.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelperParameters.java index 18339d8db..01a5df20b 100644 --- a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelperParameters.java +++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelperParameters.java @@ -20,7 +20,12 @@ package org.onap.policy.apex.context.impl.schema.java; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; + import org.onap.policy.apex.context.parameters.SchemaHelperParameters; +import org.onap.policy.common.parameters.GroupValidationResult; /** * The Schema helper parameter class for the Java schema helper is an empty parameter class that acts as a placeholder. @@ -28,11 +33,48 @@ import org.onap.policy.apex.context.parameters.SchemaHelperParameters; * @author Liam Fallon (liam.fallon@ericsson.com) */ public class JavaSchemaHelperParameters extends SchemaHelperParameters { + // Map of specific type adapters for this event + private Map<String, JavaSchemaHelperJsonAdapterParameters> jsonAdapters = new LinkedHashMap<>(); /** - * The Constructor. + * Constructor for Java schema helper parameters. */ public JavaSchemaHelperParameters() { + this.setName("Java"); this.setSchemaHelperPluginClass(JavaSchemaHelper.class.getCanonicalName()); } + + /** + * Get the JSON adapters. + * + * @return the JSON adapters + */ + public Map<String, JavaSchemaHelperJsonAdapterParameters> getJsonAdapters() { + return jsonAdapters; + } + + /** + * Set JSON adapters for the schema helper. + * + * @param jsonAdapters the JSON adapters + */ + public void setJsonAdapters(Map<String, JavaSchemaHelperJsonAdapterParameters> jsonAdapters) { + this.jsonAdapters = jsonAdapters; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.parameters.ApexParameterValidator#validate() + */ + @Override + public GroupValidationResult validate() { + final GroupValidationResult result = new GroupValidationResult(this); + + for (Entry<String, JavaSchemaHelperJsonAdapterParameters> typeAdapterEntry : jsonAdapters.entrySet()) { + result.setResult("jsonAdapters", typeAdapterEntry.getKey(), typeAdapterEntry.getValue().validate()); + } + return result; + } + } diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/ContextParameters.java b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/ContextParameters.java index 80ec0eb2d..21b3a5eaf 100644 --- a/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/ContextParameters.java +++ b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/ContextParameters.java @@ -23,26 +23,26 @@ package org.onap.policy.apex.context.parameters; import org.onap.policy.common.parameters.GroupValidationResult; import org.onap.policy.common.parameters.ParameterGroup; +// @formatter:off /** - * Bean class to hold parameters for context handling in Apex. This class contains all the context - * parameters for schema handling, distribution, locking, and persistence of context albums. + * Bean class to hold parameters for context handling in Apex. This class contains all the context parameters for schema + * handling, distribution, locking, and persistence of context albums. * * <p>The following parameters are defined: * <ol> - * <li>flushPeriod: Context is flushed to any persistor plugin that is defined periodically, and the - * period for flushing is the flush period. - * <li>distributorParameters: The parameters (a {@link DistributorParameters} instance) for the - * distributor plugin that is being used for context album distribution - * <li>schemaParameters: The parameters (a {@link SchemaParameters} instance) for the schema plugin - * that is being used for context album schemas - * <li>lockManagerParameters: The parameters (a {@link LockManagerParameters} instance) for the - * locking mechanism plugin that is being used for context album locking - * <li>persistorParameters: The parameters (a {@link PersistorParameters} instance) for the - * persistence plugin that is being used for context album persistence + * <li>flushPeriod: Context is flushed to any persistor plugin that is defined periodically, and the period for flushing + * is the flush period. + * <li>distributorParameters: The parameters (a {@link DistributorParameters} instance) for the distributor plugin that + * is being used for context album distribution + * <li>schemaParameters: The parameters (a {@link SchemaParameters} instance) for the schema plugin that is being used + * for context album schemas + * <li>lockManagerParameters: The parameters (a {@link LockManagerParameters} instance) for the locking mechanism plugin + * that is being used for context album locking + * <li>persistorParameters: The parameters (a {@link PersistorParameters} instance) for the persistence plugin that is + * being used for context album persistence * </ol> - * - * @author Liam Fallon (liam.fallon@ericsson.com) */ +// @formatter:on public class ContextParameters implements ParameterGroup { // @formatter:off // Plugin Parameters @@ -54,8 +54,7 @@ public class ContextParameters implements ParameterGroup { // @formatter:on /** - * Constructor to create a context parameters instance and register the instance with the - * parameter service. + * Constructor to create a context parameters instance and register the instance with the parameter service. */ public ContextParameters() { super(); @@ -135,7 +134,7 @@ public class ContextParameters implements ParameterGroup { public void setPersistorParameters(final PersistorParameters persistorParameters) { this.persistorParameters = persistorParameters; } - + @Override public String toString() { return "ContextParameters [name=" + name + ", distributorParameters=" + distributorParameters @@ -155,6 +154,15 @@ public class ContextParameters implements ParameterGroup { @Override public GroupValidationResult validate() { - return new GroupValidationResult(this); + GroupValidationResult result = new GroupValidationResult(this); + + // @formatter:off + result.setResult("distributorParameters", distributorParameters.validate()); + result.setResult("schemaParameters", schemaParameters.validate()); + result.setResult("lockManagerParameters", lockManagerParameters.validate()); + result.setResult("persistorParameters", persistorParameters.validate()); + // @formatter:on + + return result; } } diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/SchemaParameters.java b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/SchemaParameters.java index 9992b9f3c..fb1713776 100644 --- a/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/SchemaParameters.java +++ b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/SchemaParameters.java @@ -21,6 +21,7 @@ package org.onap.policy.apex.context.parameters; import java.util.Map; +import java.util.Map.Entry; import java.util.TreeMap; import org.onap.policy.apex.context.impl.schema.java.JavaSchemaHelperParameters; @@ -28,10 +29,9 @@ import org.onap.policy.common.parameters.GroupValidationResult; import org.onap.policy.common.parameters.ParameterGroup; /** - * Bean class holding schema parameters for schemas and their helpers. As more than one schema can - * be used in Apex simultaneously, this class is used to hold the schemas that are defined in a - * given Apex system and to get the schema helper plugin parameters {@link SchemaHelperParameters} - * for each schema. + * Bean class holding schema parameters for schemas and their helpers. As more than one schema can be used in Apex + * simultaneously, this class is used to hold the schemas that are defined in a given Apex system and to get the schema + * helper plugin parameters {@link SchemaHelperParameters} for each schema. * * <p>The default {@code Java} schema is always defined and its parameters are held in a * {@link JavaSchemaHelperParameters} instance. @@ -48,8 +48,7 @@ public class SchemaParameters implements ParameterGroup { private Map<String, SchemaHelperParameters> schemaHelperParameterMap; /** - * Constructor to create a distributor parameters instance and register the instance with the - * parameter service. + * Constructor to create a distributor parameters instance and register the instance with the parameter service. */ public SchemaParameters() { super(); @@ -90,7 +89,7 @@ public class SchemaParameters implements ParameterGroup { public SchemaHelperParameters getSchemaHelperParameters(final String schemaFlavour) { return schemaHelperParameterMap.get(schemaFlavour); } - + @Override public String getName() { return name; @@ -103,6 +102,12 @@ public class SchemaParameters implements ParameterGroup { @Override public GroupValidationResult validate() { - return new GroupValidationResult(this); + final GroupValidationResult result = new GroupValidationResult(this); + + for (Entry<String, SchemaHelperParameters> schemaHelperEntry : schemaHelperParameterMap.entrySet()) { + result.setResult("schemaHelperParameterMap", schemaHelperEntry.getKey(), + schemaHelperEntry.getValue().validate()); + } + return result; } } diff --git a/context/context-management/src/test/java/org/onap/policy/apex/context/impl/schema/java/BadJsonAdapter.java b/context/context-management/src/test/java/org/onap/policy/apex/context/impl/schema/java/BadJsonAdapter.java new file mode 100644 index 000000000..fef69ac33 --- /dev/null +++ b/context/context-management/src/test/java/org/onap/policy/apex/context/impl/schema/java/BadJsonAdapter.java @@ -0,0 +1,63 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.context.impl.schema.java; + +import com.google.gson.Gson; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; + +import java.lang.reflect.Type; + +/** + * This class serialises and deserialises various type of event protocol parameters to and from + * JSON. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class BadJsonAdapter + implements JsonSerializer<String>, JsonDeserializer<String> { + + public BadJsonAdapter() throws IllegalAccessException { + throw new IllegalAccessException("Test for Bad Adapter"); + } + + /** + * {@inheritDoc} + */ + @Override + public JsonElement serialize(final String src, final Type typeOfSrc, + final JsonSerializationContext context) { + return new Gson().toJsonTree(src, String.class); + } + + /** + * {@inheritDoc} + */ + @Override + public String deserialize(final JsonElement json, final Type typeOfT, + final JsonDeserializationContext context) { + + return new Gson().fromJson(json, String.class); + } +} diff --git a/context/context-management/src/test/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelperParametersTest.java b/context/context-management/src/test/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelperParametersTest.java new file mode 100644 index 000000000..c0287bfe2 --- /dev/null +++ b/context/context-management/src/test/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelperParametersTest.java @@ -0,0 +1,101 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.context.impl.schema.java; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.junit.Test; + +/** + * Test Java schema helper parameters. + */ +public class JavaSchemaHelperParametersTest { + + @Test + public void testJavaSchemaHelperParameters() { + JavaSchemaHelperParameters pars = new JavaSchemaHelperParameters(); + + assertEquals("org.onap.policy.apex.context.impl.schema.java.JavaSchemaHelper", + pars.getSchemaHelperPluginClass()); + + assertEquals(0, pars.getJsonAdapters().size()); + + JavaSchemaHelperJsonAdapterParameters jsonPars = new JavaSchemaHelperJsonAdapterParameters(); + pars.getJsonAdapters().put("JsonAdapter0", jsonPars); + + assertFalse(pars.validate().isValid()); + + jsonPars.setAdaptedClass("AAA"); + jsonPars.setAdaptorClass("AAA"); + assertFalse(pars.validate().isValid()); + + jsonPars.setAdaptedClass("java.lang.String"); + jsonPars.setAdaptorClass("AAA"); + assertFalse(pars.validate().isValid()); + + jsonPars.setAdaptedClass("AAA"); + jsonPars.setAdaptorClass("java.lang.String"); + assertFalse(pars.validate().isValid()); + + jsonPars.setAdaptedClass("java.lang.String"); + jsonPars.setAdaptorClass("org.onap.policy.apex.context.impl.schema.java.TestJsonDeserializer"); + assertFalse(pars.validate().isValid()); + + jsonPars.setAdaptedClass("java.lang.String"); + jsonPars.setAdaptorClass("org.onap.policy.apex.context.impl.schema.java.TestJsonSerializer"); + assertFalse(pars.validate().isValid()); + + jsonPars.setAdaptedClass("java.lang.String"); + jsonPars.setAdaptorClass("org.onap.policy.apex.context.impl.schema.java.TestJsonAdapter"); + assertTrue(pars.validate().isValid()); + + Map<String, JavaSchemaHelperJsonAdapterParameters> adapterMap = new LinkedHashMap<>(); + + pars.setJsonAdapters(adapterMap); + assertTrue(pars.validate().isValid()); + } + + @Test + public void testJavaSchemaHelperJsonAdapterParameters() { + JavaSchemaHelperJsonAdapterParameters pars = new JavaSchemaHelperJsonAdapterParameters(); + + assertNull(pars.getName()); + assertNull(pars.getAdaptedClass()); + assertNull(pars.getAdaptedClazz()); + assertNull(pars.getAdaptorClass()); + assertNull(pars.getAdaptorClazz()); + + pars.setName("Zooby"); + assertEquals("Zooby", pars.getAdaptedClass()); + assertEquals("Zooby", pars.getName()); + assertNull(pars.getAdaptedClazz()); + + pars.setAdaptorClass("Zooby"); + assertEquals("Zooby", pars.getAdaptorClass()); + assertNull(pars.getAdaptorClazz()); + } +} diff --git a/context/context-management/src/test/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelperTest.java b/context/context-management/src/test/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelperTest.java index 8da6fdab9..c746198e7 100644 --- a/context/context-management/src/test/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelperTest.java +++ b/context/context-management/src/test/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelperTest.java @@ -28,16 +28,44 @@ import com.google.gson.JsonParser; import com.google.gson.JsonPrimitive; import java.math.BigDecimal; +import java.time.Instant; +import org.junit.AfterClass; +import org.junit.BeforeClass; import org.junit.Test; import org.onap.policy.apex.context.ContextRuntimeException; import org.onap.policy.apex.context.SchemaHelper; +import org.onap.policy.apex.context.parameters.ContextParameterConstants; +import org.onap.policy.apex.context.parameters.SchemaParameters; import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema; - +import org.onap.policy.common.parameters.ParameterService; public class JavaSchemaHelperTest { + /** + * Initialize JSON adapters. + */ + @BeforeClass + public static void registerParameters() { + JavaSchemaHelperParameters javaSchemaHelperPars = new JavaSchemaHelperParameters(); + + JavaSchemaHelperJsonAdapterParameters stringAdapterPars = new JavaSchemaHelperJsonAdapterParameters(); + stringAdapterPars.setAdaptedClass("java.lang.String"); + stringAdapterPars.setAdaptorClass("org.onap.policy.apex.context.impl.schema.java.TestJsonAdapter"); + + javaSchemaHelperPars.getJsonAdapters().put("String", stringAdapterPars); + + SchemaParameters schemaPars = new SchemaParameters(); + schemaPars.getSchemaHelperParameterMap().put("Java", javaSchemaHelperPars); + + ParameterService.register(schemaPars); + } + + @AfterClass + public static void deregisterParameters() { + ParameterService.clear(); + } @Test public void testJavaSchemaHelperInit() { @@ -51,7 +79,7 @@ public class JavaSchemaHelperTest { fail("test should throw an exception here"); } catch (ContextRuntimeException e) { assertEquals("UserKey:0.0.1: class/type java.lang.Rubbish for context schema" - + " \"SchemaKey:0.0.1\" not found. Check the class path of the JVM", e.getMessage()); + + " \"SchemaKey:0.0.1\" not found. Check the class path of the JVM", e.getMessage()); } AxContextSchema builtInJavaTypeSchema = new AxContextSchema(schemaKey, "Java", "short"); @@ -61,8 +89,8 @@ public class JavaSchemaHelperTest { fail("test should throw an exception here"); } catch (ContextRuntimeException e) { assertEquals("UserKey:0.0.1: class/type short for context schema " - + "\"SchemaKey:0.0.1\" not found. Primitive types are not supported." - + " Use the appropriate Java boxing type instead.", e.getMessage()); + + "\"SchemaKey:0.0.1\" not found. Primitive types are not supported." + + " Use the appropriate Java boxing type instead.", e.getMessage()); } } @@ -80,7 +108,7 @@ public class JavaSchemaHelperTest { fail("test should throw an exception here"); } catch (ContextRuntimeException e) { assertEquals("NULL:0.0.0: could not create an instance, schema class for the schema is null", - e.getMessage()); + e.getMessage()); } try { @@ -88,7 +116,7 @@ public class JavaSchemaHelperTest { fail("test should throw an exception here"); } catch (ContextRuntimeException e) { assertEquals("NULL:0.0.0: could not create an instance, schema class for the schema is null", - e.getMessage()); + e.getMessage()); } try { @@ -96,7 +124,7 @@ public class JavaSchemaHelperTest { fail("test should throw an exception here"); } catch (ContextRuntimeException e) { assertEquals("NULL:0.0.0: could not create an instance, schema class for the schema is null", - e.getMessage()); + e.getMessage()); } AxArtifactKey schemaKey = new AxArtifactKey("SchemaKey", "0.0.1"); @@ -114,7 +142,7 @@ public class JavaSchemaHelperTest { fail("test should throw an exception here"); } catch (ContextRuntimeException e) { assertEquals("UserKey:0.0.1: could not create an instance of class " - + "\"java.lang.Integer\" using the default constructor \"Integer()\"", e.getMessage()); + + "\"java.lang.Integer\" using the default constructor \"Integer()\"", e.getMessage()); } try { @@ -122,8 +150,8 @@ public class JavaSchemaHelperTest { fail("test should throw an exception here"); } catch (ContextRuntimeException e) { assertEquals("UserKey:0.0.1: the object \"1.23\" of type " - + "\"java.lang.Float\" is not an instance of JsonObject and is not " - + "assignable to \"java.lang.Integer\"", e.getMessage()); + + "\"java.lang.Float\" is not an instance of JsonObject and is not " + + "assignable to \"java.lang.Integer\"", e.getMessage()); } try { @@ -131,7 +159,7 @@ public class JavaSchemaHelperTest { fail("test should throw an exception here"); } catch (ContextRuntimeException e) { assertEquals("UserKey:0.0.1: could not create an instance of class \"java.lang.Integer\" " - + "using the string constructor \"Integer(String)\"", e.getMessage()); + + "using the string constructor \"Integer(String)\"", e.getMessage()); } JsonElement jsonIntElement = null; @@ -183,8 +211,8 @@ public class JavaSchemaHelperTest { doubleSchemaHelper.init(userKey, doubleSchema); stringSchemaHelper.init(userKey, stringSchema); - AxContextSchema myBaseClassSchema = - new AxContextSchema(schemaKey, "Java", "org.onap.policy.apex.context.impl.schema.java.MyBaseClass"); + AxContextSchema myBaseClassSchema = new AxContextSchema(schemaKey, "Java", + "org.onap.policy.apex.context.impl.schema.java.MyBaseClass"); SchemaHelper myBaseClassSchemaHelper = new JavaSchemaHelper(); myBaseClassSchemaHelper.init(userKey, myBaseClassSchema); @@ -201,7 +229,7 @@ public class JavaSchemaHelperTest { fail("test should throw an exception here"); } catch (ContextRuntimeException e) { assertEquals("UserKey:0.0.1: object \"one two three\" of class \"java.lang.String\" not " - + "compatible with class \"java.lang.Byte\"", e.getMessage()); + + "compatible with class \"java.lang.Byte\"", e.getMessage()); } assertEquals(null, shortSchemaHelper.unmarshal(null)); @@ -217,7 +245,7 @@ public class JavaSchemaHelperTest { fail("test should throw an exception here"); } catch (ContextRuntimeException e) { assertEquals("UserKey:0.0.1: object \"one two three\" of class \"java.lang.String\" not " - + "compatible with class \"java.lang.Short\"", e.getMessage()); + + "compatible with class \"java.lang.Short\"", e.getMessage()); } assertEquals(null, intSchemaHelper.unmarshal(null)); @@ -233,7 +261,7 @@ public class JavaSchemaHelperTest { fail("test should throw an exception here"); } catch (ContextRuntimeException e) { assertEquals("UserKey:0.0.1: object \"one two three\" of class \"java.lang.String\" not " - + "compatible with class \"java.lang.Integer\"", e.getMessage()); + + "compatible with class \"java.lang.Integer\"", e.getMessage()); } assertEquals(null, longSchemaHelper.unmarshal(null)); @@ -249,7 +277,7 @@ public class JavaSchemaHelperTest { fail("test should throw an exception here"); } catch (ContextRuntimeException e) { assertEquals("UserKey:0.0.1: object \"one two three\" of class \"java.lang.String\" not " - + "compatible with class \"java.lang.Long\"", e.getMessage()); + + "compatible with class \"java.lang.Long\"", e.getMessage()); } assertEquals(null, floatSchemaHelper.unmarshal(null)); @@ -265,7 +293,7 @@ public class JavaSchemaHelperTest { fail("test should throw an exception here"); } catch (ContextRuntimeException e) { assertEquals("UserKey:0.0.1: object \"one two three\" of class \"java.lang.String\" not " - + "compatible with class \"java.lang.Float\"", e.getMessage()); + + "compatible with class \"java.lang.Float\"", e.getMessage()); } assertEquals(null, doubleSchemaHelper.unmarshal(null)); @@ -282,7 +310,7 @@ public class JavaSchemaHelperTest { fail("test should throw an exception here"); } catch (ContextRuntimeException e) { assertEquals("UserKey:0.0.1: object \"one two three\" of class \"java.lang.String\" not " - + "compatible with class \"java.lang.Double\"", e.getMessage()); + + "compatible with class \"java.lang.Double\"", e.getMessage()); } assertEquals("123", stringSchemaHelper.unmarshal(123)); @@ -307,10 +335,74 @@ public class JavaSchemaHelperTest { fail("test should throw an exception here"); } catch (ContextRuntimeException e) { assertEquals("UserKey:0.0.1: object \"123.45\" of class \"java.lang.Double\" not " - + "compatible with class \"java.lang.Integer\"", e.getMessage()); + + "compatible with class \"java.lang.Integer\"", e.getMessage()); } JsonPrimitive intJsonPrimitive = (JsonPrimitive) intSchemaHelper.marshal2Object(123); assertEquals(123, intJsonPrimitive.getAsInt()); } + + @Test + public void testJavaSchemaHelperAdapters() { + AxArtifactKey schemaKey = new AxArtifactKey("SchemaKey", "0.0.1"); + AxArtifactKey userKey = new AxArtifactKey("UserKey", "0.0.1"); + + AxContextSchema stringSchema = new AxContextSchema(schemaKey, "Java", "java.lang.String"); + SchemaHelper stringSchemaHelper = new JavaSchemaHelper(); + stringSchemaHelper.init(userKey, stringSchema); + + assertEquals("null", stringSchemaHelper.marshal2String(null)); + assertEquals("\"Hello\"", stringSchemaHelper.marshal2String("Hello")); + try { + stringSchemaHelper.marshal2String(Instant.ofEpochMilli(1000)); + fail("test should throw an exception here"); + } catch (ContextRuntimeException e) { + assertEquals("UserKey:0.0.1: object \"1970-01-01T00:00:01Z\" of class \"java.time.Instant\" " + + "not compatible with class \"java.lang.String\"", e.getMessage()); + } + + JsonPrimitive stringJsonPrimitive = (JsonPrimitive) stringSchemaHelper.marshal2Object("Another String"); + assertEquals("Another String", stringJsonPrimitive.getAsString()); + } + + @Test + public void testJavaSchemaHelperBadAdapter() { + AxArtifactKey schemaKey = new AxArtifactKey("SchemaKey", "0.0.1"); + AxArtifactKey userKey = new AxArtifactKey("UserKey", "0.0.1"); + + SchemaParameters pars = ParameterService.get(ContextParameterConstants.SCHEMA_GROUP_NAME); + + JavaSchemaHelperParameters javaShPars = (JavaSchemaHelperParameters) pars.getSchemaHelperParameterMap() + .get("Java"); + javaShPars.getJsonAdapters().get("String") + .setAdaptorClass("org.onap.policy.apex.context.impl.schema.java.BadJsonAdapter"); + + AxContextSchema stringSchema = new AxContextSchema(schemaKey, "Java", "java.lang.String"); + SchemaHelper stringSchemaHelper = new JavaSchemaHelper(); + stringSchemaHelper.init(userKey, stringSchema); + + try { + stringSchemaHelper.marshal2String("Hello"); + fail("test should throw an exception"); + } catch (ContextRuntimeException pre) { + assertEquals("UserKey:0.0.1: instantiation of adapter class " + + "\"org.onap.policy.apex.context.impl.schema.java.BadJsonAdapter\" " + + "to decode and encode class \"java.lang.String\" failed: Test for Bad Adapter", + pre.getMessage()); + } + } + + @Test + public void testJavaSchemaHelperDefaultAdapter() { + SchemaParameters pars = ParameterService.get(ContextParameterConstants.SCHEMA_GROUP_NAME); + + JavaSchemaHelperParameters javaShPars = (JavaSchemaHelperParameters) pars.getSchemaHelperParameterMap() + .get("Java"); + + pars.getSchemaHelperParameterMap().clear(); + + testJavaSchemaHelperAdapters(); + + pars.getSchemaHelperParameterMap().put("Java", javaShPars); + } } diff --git a/context/context-management/src/test/java/org/onap/policy/apex/context/impl/schema/java/TestJsonAdapter.java b/context/context-management/src/test/java/org/onap/policy/apex/context/impl/schema/java/TestJsonAdapter.java new file mode 100644 index 000000000..89dfb4c2d --- /dev/null +++ b/context/context-management/src/test/java/org/onap/policy/apex/context/impl/schema/java/TestJsonAdapter.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.context.impl.schema.java; + +import com.google.gson.Gson; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; + +import java.lang.reflect.Type; + +/** + * This class serialises and deserialises various type of event protocol parameters to and from JSON. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class TestJsonAdapter implements JsonSerializer<String>, JsonDeserializer<String> { + + /** + * {@inheritDoc} + */ + @Override + public JsonElement serialize(final String src, final Type typeOfSrc, final JsonSerializationContext context) { + return new Gson().toJsonTree(src, String.class); + } + + /** + * {@inheritDoc} + */ + @Override + public String deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) { + + return new Gson().fromJson(json, String.class); + } +} diff --git a/context/context-management/src/test/java/org/onap/policy/apex/context/impl/schema/java/TestJsonDeserializer.java b/context/context-management/src/test/java/org/onap/policy/apex/context/impl/schema/java/TestJsonDeserializer.java new file mode 100644 index 000000000..463945872 --- /dev/null +++ b/context/context-management/src/test/java/org/onap/policy/apex/context/impl/schema/java/TestJsonDeserializer.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.context.impl.schema.java; + +import com.google.gson.Gson; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; + +import java.lang.reflect.Type; + +/** + * This class serialises and deserialises various type of event protocol parameters to and from JSON. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class TestJsonDeserializer implements JsonDeserializer<String> { + /** + * {@inheritDoc} + */ + @Override + public String deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) { + + return new Gson().fromJson(json, String.class); + } +} diff --git a/context/context-management/src/test/java/org/onap/policy/apex/context/impl/schema/java/TestJsonSerializer.java b/context/context-management/src/test/java/org/onap/policy/apex/context/impl/schema/java/TestJsonSerializer.java new file mode 100644 index 000000000..d58be6069 --- /dev/null +++ b/context/context-management/src/test/java/org/onap/policy/apex/context/impl/schema/java/TestJsonSerializer.java @@ -0,0 +1,50 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.context.impl.schema.java; + +import com.google.gson.JsonElement; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; + +import java.lang.reflect.Type; + +import org.onap.policy.common.parameters.ParameterRuntimeException; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * This class serialises and deserialises various type of event protocol parameters to and from JSON. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class TestJsonSerializer implements JsonSerializer<String> { + private static final XLogger LOGGER = XLoggerFactory.getXLogger(TestJsonSerializer.class); + + /** + * {@inheritDoc} + */ + @Override + public JsonElement serialize(final String src, final Type typeOfSrc, final JsonSerializationContext context) { + final String returnMessage = "serialization of Apex event protocol parameters to Json is not supported"; + LOGGER.error(returnMessage); + throw new ParameterRuntimeException(returnMessage); + } +} |