summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authora.sreekumar <ajith.sreekumar@bell.ca>2022-07-19 11:49:57 +0100
committerRam Krishna Verma <ram_krishna.verma@bell.ca>2022-08-01 15:14:31 +0000
commitf3f82982bb09ba650e4eaa1214dae35dbab71d55 (patch)
tree43ab3ccb3e8d73de43a3f6805432981f9272a92b /plugins
parentc6c3fed415006c2ea5c5af21fe9a53936fc8800b (diff)
Adding JSON Schema support in APEX-PDP
More details can be found here: https://wiki.onap.org/display/DW/JSON+Schema+support+in+APEX-PDP A separate review will be raised as part of POLICY-4292 with a reference example on how to use the JSON Schema. Change-Id: I903d48969c6c5a24c63b8465b2412ed0b75b9351 Issue-ID: POLICY-4291 Signed-off-by: a.sreekumar <ajith.sreekumar@bell.ca> (cherry picked from commit c354fba3fb87ebe21a7fbb2a15268ccc9d033fbd)
Diffstat (limited to 'plugins')
-rw-r--r--plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/pom.xml44
-rw-r--r--plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/main/java/org/onap/policy/apex/plugins/context/schema/json/JsonSchemaHelper.java122
-rw-r--r--plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/main/java/org/onap/policy/apex/plugins/context/schema/json/JsonSchemaHelperParameters.java30
-rw-r--r--plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/java/org/onap/policy/apex/plugins/context/schema/json/CommonTestData.java115
-rw-r--r--plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/java/org/onap/policy/apex/plugins/context/schema/json/JsonSchemaHelperMarshalTest.java133
-rw-r--r--plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/java/org/onap/policy/apex/plugins/context/schema/json/JsonSchemaHelperUnmarshalTest.java166
-rw-r--r--plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/resources/data/commonHeader.json6
-rw-r--r--plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/resources/data/measurementGroups.json34
-rw-r--r--plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/resources/schema/commonHeaderTypeWithOptional.json23
-rw-r--r--plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/resources/schema/commonHeaderType_draft04.json24
-rw-r--r--plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/resources/schema/commonHeaderType_draft07.json52
-rw-r--r--plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/resources/schema/measurementGroupsType.json61
-rw-r--r--plugins/plugins-context/plugins-context-schema/pom.xml8
13 files changed, 815 insertions, 3 deletions
diff --git a/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/pom.xml b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/pom.xml
new file mode 100644
index 000000000..979ab49cf
--- /dev/null
+++ b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/pom.xml
@@ -0,0 +1,44 @@
+<!--
+ ============LICENSE_START=======================================================
+ Copyright (C) 2022 Bell Canada. 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=========================================================
+-->
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.onap.policy.apex-pdp.plugins.plugins-context.plugins-context-schema</groupId>
+ <artifactId>plugins-context-schema</artifactId>
+ <version>2.5.5-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>plugins-context-schema-json</artifactId>
+ <name>${project.artifactId}</name>
+ <description>[${project.parent.artifactId}] Plugin for schemas using JSON</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.worldturner.medeia</groupId>
+ <artifactId>medeia-validator-gson</artifactId>
+ <version>1.1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/main/java/org/onap/policy/apex/plugins/context/schema/json/JsonSchemaHelper.java b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/main/java/org/onap/policy/apex/plugins/context/schema/json/JsonSchemaHelper.java
new file mode 100644
index 000000000..4896e5d4a
--- /dev/null
+++ b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/main/java/org/onap/policy/apex/plugins/context/schema/json/JsonSchemaHelper.java
@@ -0,0 +1,122 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Bell Canada. 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.plugins.context.schema.json;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import com.worldturner.medeia.api.SchemaSource;
+import com.worldturner.medeia.api.StringInputSource;
+import com.worldturner.medeia.api.StringSchemaSource;
+import com.worldturner.medeia.api.gson.MedeiaGsonApi;
+import com.worldturner.medeia.schema.validation.SchemaValidator;
+import java.io.StringWriter;
+import java.util.List;
+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.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+
+/**
+ * This class is the implementation of the {@link org.onap.policy.apex.context.SchemaHelper} interface for JSON schema.
+ */
+public class JsonSchemaHelper extends AbstractSchemaHelper {
+
+ private static final Gson gson = new Gson();
+
+ private MedeiaGsonApi api = new MedeiaGsonApi();
+ private SchemaValidator validator;
+
+ @Override
+ public void init(final AxKey userKey, final AxContextSchema schema) {
+ super.init(userKey, schema);
+
+ try {
+ SchemaSource source = new StringSchemaSource(schema.getSchema());
+ validator = api.loadSchema(source);
+ } catch (final Exception e) {
+ final String resultSting = userKey.getId() + ": json context schema \"" + schema.getId()
+ + "\" schema is invalid, schema: " + schema.getSchema();
+ throw new ContextRuntimeException(resultSting, e);
+ }
+ }
+
+ @Override
+ public Object createNewInstance(final String stringValue) {
+ return unmarshal(stringValue);
+ }
+
+ @Override
+ public Object createNewInstance(final Object incomingObject) {
+ if (incomingObject instanceof JsonElement) {
+ final var elementJsonString = gson.toJson((JsonElement) incomingObject);
+
+ return createNewInstance(elementJsonString);
+ } else {
+ final var returnString =
+ getUserKey().getId() + ": the object \"" + incomingObject + "\" is not an instance of JsonObject";
+ throw new ContextRuntimeException(returnString);
+ }
+ }
+
+ @Override
+ public Object unmarshal(Object object) {
+ // If an object is already in the correct format, just carry on
+ if (passThroughObject(object)) {
+ return object;
+ }
+ var objectString = (String) object;
+ JsonReader reader = api.createJsonReader(validator, new StringInputSource(objectString));
+ return gson.fromJson(reader, Object.class);
+ }
+
+ @Override
+ public String marshal2String(Object schemaObject) {
+ StringWriter stringWriter = new StringWriter();
+ validateAndDecode(schemaObject, stringWriter);
+ return stringWriter.toString();
+ }
+
+ @Override
+ public Object marshal2Object(Object schemaObject) {
+ return validateAndDecode(schemaObject, new StringWriter());
+ }
+
+ private JsonElement validateAndDecode(Object schemaObject, StringWriter stringWriter) {
+ JsonWriter jsonWriter = api.createJsonWriter(validator, stringWriter);
+ jsonWriter.setIndent(" "); // to enable pretty print
+ JsonElement jsonObj = gson.toJsonTree(schemaObject);
+ gson.toJson(jsonObj, jsonWriter);
+ return jsonObj;
+ }
+
+ /**
+ * Check if we can pass this object straight through encoding or decoding.
+ *
+ * @param object the object to check
+ * @return true if it's a straight pass through
+ */
+ private boolean passThroughObject(final Object object) {
+ return (object instanceof JsonElement || object instanceof Map || object instanceof List);
+ }
+}
diff --git a/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/main/java/org/onap/policy/apex/plugins/context/schema/json/JsonSchemaHelperParameters.java b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/main/java/org/onap/policy/apex/plugins/context/schema/json/JsonSchemaHelperParameters.java
new file mode 100644
index 000000000..0e275130d
--- /dev/null
+++ b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/main/java/org/onap/policy/apex/plugins/context/schema/json/JsonSchemaHelperParameters.java
@@ -0,0 +1,30 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Bell Canada. 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.plugins.context.schema.json;
+
+import org.onap.policy.apex.context.parameters.SchemaHelperParameters;
+
+public class JsonSchemaHelperParameters extends SchemaHelperParameters {
+
+ public JsonSchemaHelperParameters() {
+ this.setSchemaHelperPluginClass(JsonSchemaHelper.class.getName());
+ }
+}
diff --git a/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/java/org/onap/policy/apex/plugins/context/schema/json/CommonTestData.java b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/java/org/onap/policy/apex/plugins/context/schema/json/CommonTestData.java
new file mode 100644
index 000000000..ce03678c9
--- /dev/null
+++ b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/java/org/onap/policy/apex/plugins/context/schema/json/CommonTestData.java
@@ -0,0 +1,115 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Bell Canada. 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.plugins.context.schema.json;
+
+import java.io.IOException;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.onap.policy.apex.context.SchemaHelper;
+import org.onap.policy.apex.context.impl.schema.SchemaHelperFactory;
+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.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.service.ModelService;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas;
+import org.onap.policy.common.parameters.ParameterService;
+import org.onap.policy.common.utils.coder.StandardCoder;
+import org.onap.policy.common.utils.resources.TextFileUtils;
+
+public class CommonTestData {
+
+ protected static final String VERSION = "0.0.1";
+ protected static final String JSON = "JSON";
+ protected static final String TEST_ID = "testId";
+ protected final AxKey testKey = new AxArtifactKey("JsonTest", VERSION);
+ protected AxContextSchemas schemas;
+ protected final StandardCoder coder = new StandardCoder();
+
+ protected static final String BOOLEAN_SCHEMA =
+ "{\"$schema\": \"http://json-schema.org/draft-07/schema#\",\"type\": \"boolean\"}";
+ protected static final String BOOLEAN_DATA = "true";
+ protected static final String NULL_SCHEMA =
+ "{\"$schema\":\"http://json-schema.org/draft-07/schema#\",\"type\":\"null\"}";
+ protected static final String NULL_DATA = "null";
+ protected static String COMMONHEADERTYPE_DRAFT04;
+ protected static String COMMONHEADERTYPE_DRAFT07;
+ protected static String COMMONHEADERTYPE_WITH_OPTIONAL;
+ protected static String COMMONHEADER;
+ protected static String MEASUREMENTGROUPS_TYPE;
+ protected static String MEASUREMENTGROUPS;
+
+ /**
+ * Setup before all tests.
+ */
+ @BeforeClass
+ public static void setUpBeforeClass() throws IOException {
+ COMMONHEADERTYPE_DRAFT04 =
+ TextFileUtils.getTextFileAsString("src/test/resources/schema/commonHeaderType_draft04.json");
+ COMMONHEADERTYPE_DRAFT07 =
+ TextFileUtils.getTextFileAsString("src/test/resources/schema/commonHeaderType_draft07.json");
+ COMMONHEADERTYPE_WITH_OPTIONAL =
+ TextFileUtils.getTextFileAsString("src/test/resources/schema/commonHeaderTypeWithOptional.json");
+ COMMONHEADER =
+ TextFileUtils.getTextFileAsString("src/test/resources/data/commonHeader.json").replaceAll("\r", "").trim();
+ MEASUREMENTGROUPS_TYPE =
+ TextFileUtils.getTextFileAsString("src/test/resources/schema/measurementGroupsType.json");
+ MEASUREMENTGROUPS = TextFileUtils.getTextFileAsString("src/test/resources/data/measurementGroups.json")
+ .replaceAll("\r", "").trim();
+ }
+
+ /**
+ * Setup before test.
+ */
+ @Before
+ public void setUp() {
+ schemas = new AxContextSchemas(new AxArtifactKey("JsonSchema", VERSION));
+ ModelService.registerModel(AxContextSchemas.class, schemas);
+
+ SchemaParameters schemaParameters = new SchemaParameters();
+ schemaParameters.setName(ContextParameterConstants.SCHEMA_GROUP_NAME);
+ schemaParameters.getSchemaHelperParameterMap().put(JSON, new JsonSchemaHelperParameters());
+ ParameterService.register(schemaParameters);
+ }
+
+ /**
+ * Teardown after test.
+ */
+ @After
+ public void tearDown() {
+ ParameterService.deregister(ContextParameterConstants.SCHEMA_GROUP_NAME);
+ ModelService.clear();
+ }
+
+ /**
+ * Method to create JsonSchemaHelper instance from schema content.
+ *
+ * @param schema the schema content as string
+ * @return schemaHelper instance
+ */
+ protected SchemaHelper createSchema(String schema) {
+ final AxContextSchema jsonSchema = new AxContextSchema(new AxArtifactKey("SchemaTest", VERSION), JSON, schema);
+ schemas.getSchemasMap().put(jsonSchema.getKey(), jsonSchema);
+ return new SchemaHelperFactory().createSchemaHelper(testKey, jsonSchema.getKey());
+ }
+}
diff --git a/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/java/org/onap/policy/apex/plugins/context/schema/json/JsonSchemaHelperMarshalTest.java b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/java/org/onap/policy/apex/plugins/context/schema/json/JsonSchemaHelperMarshalTest.java
new file mode 100644
index 000000000..15458199a
--- /dev/null
+++ b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/java/org/onap/policy/apex/plugins/context/schema/json/JsonSchemaHelperMarshalTest.java
@@ -0,0 +1,133 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Bell Canada. 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.plugins.context.schema.json;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.worldturner.medeia.api.ValidationFailedException;
+import java.util.ArrayList;
+import java.util.Map;
+import org.junit.Test;
+import org.onap.policy.common.utils.coder.CoderException;
+
+public class JsonSchemaHelperMarshalTest extends CommonTestData {
+
+ /**
+ * Test Boolean.
+ */
+ @Test
+ public void testBooleanMarshal() {
+ var schemaHelper = createSchema(BOOLEAN_SCHEMA);
+ assertThat(schemaHelper.marshal2String(Boolean.TRUE)).isEqualTo("true");
+ }
+
+ /**
+ * Test null.
+ */
+ @Test
+ public void testNullMarshal() {
+ var schemaHelper = createSchema(NULL_SCHEMA);
+ assertThat(schemaHelper.marshal2String(null)).isEqualTo("null");
+ }
+
+ /**
+ * Test Array.
+ *
+ * @throws CoderException the coder exception
+ */
+ @Test
+ public void testArrayMarshal() throws CoderException {
+ var schemaHelper = createSchema(MEASUREMENTGROUPS_TYPE);
+ var object = coder.decode(MEASUREMENTGROUPS, Object.class);
+ assertThat(object).isInstanceOf(ArrayList.class);
+ var marshalledString = schemaHelper.marshal2String(object);
+ assertThat(marshalledString).isEqualTo(MEASUREMENTGROUPS);
+ var marshalledObject = schemaHelper.marshal2Object(object);
+ assertThat(marshalledObject).isInstanceOf(JsonArray.class);
+ }
+
+ /**
+ * Test Object marshal valid scenario using JSON Schema draft 04.
+ *
+ * @throws CoderException the coderException
+ */
+ @Test
+ public void testObjectSchemaDraft04_valid() throws CoderException {
+ var dataAsObject = coder.decode(COMMONHEADER, Map.class);
+ var dataReturned = validateAndMarshal(COMMONHEADERTYPE_DRAFT04, dataAsObject, true);
+ assertThat(dataReturned).isEqualTo(COMMONHEADER);
+ }
+
+ /**
+ * Test Object marshal valid scenario using JSON Schema draft 07.
+ *
+ * @throws CoderException the coderException
+ */
+ @Test
+ public void testObjectSchemaDraft07_valid() throws CoderException {
+ var dataAsObject = coder.decode(COMMONHEADER, Map.class);
+ var dataReturned = validateAndMarshal(COMMONHEADERTYPE_DRAFT07, dataAsObject, true);
+ assertThat(dataReturned).isEqualTo(COMMONHEADER);
+ assertThat(validateAndMarshal(COMMONHEADERTYPE_DRAFT07, dataAsObject, false)).isInstanceOf(JsonObject.class);
+ }
+
+ /**
+ * Test Object marshal invalid - required field missing scenario.
+ *
+ * @throws CoderException the coderException
+ */
+ @Test
+ public void testObjectSchema_fieldMissing() throws CoderException {
+ var dataAsObject = coder.decode(COMMONHEADER, Map.class);
+ dataAsObject.remove(TEST_ID);
+ assertThatThrownBy(() -> validateAndMarshal(COMMONHEADERTYPE_DRAFT07, dataAsObject, true))
+ .isInstanceOf(ValidationFailedException.class)
+ .hasMessageContaining("Required property testId is missing from object");
+ }
+
+ /**
+ * Test Object marshal with optional field.
+ *
+ * @throws CoderException the coderException
+ */
+ @Test
+ public void testObjectSchema_OptionalField() throws CoderException {
+ var dataAsObject = coder.decode(COMMONHEADER, Map.class);
+ var dataAsjsonObject = coder.decode(COMMONHEADER, JsonObject.class);
+ dataAsObject.remove(TEST_ID);
+ dataAsjsonObject.remove(TEST_ID);
+ var dataReturned = validateAndMarshal(COMMONHEADERTYPE_WITH_OPTIONAL, dataAsObject, false);
+ assertThat(dataReturned).isEqualTo(dataAsjsonObject);
+ }
+
+ private Object validateAndMarshal(String schemaDef, Object obj, boolean marshalAsString) {
+ var schemaHelper = createSchema(schemaDef);
+ if (marshalAsString) {
+ return schemaHelper.marshal2String(obj);
+ } else {
+ return schemaHelper.marshal2Object(obj);
+ }
+ }
+
+}
diff --git a/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/java/org/onap/policy/apex/plugins/context/schema/json/JsonSchemaHelperUnmarshalTest.java b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/java/org/onap/policy/apex/plugins/context/schema/json/JsonSchemaHelperUnmarshalTest.java
new file mode 100644
index 000000000..11c8638de
--- /dev/null
+++ b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/java/org/onap/policy/apex/plugins/context/schema/json/JsonSchemaHelperUnmarshalTest.java
@@ -0,0 +1,166 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Bell Canada. 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.plugins.context.schema.json;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import com.google.gson.JsonObject;
+import com.worldturner.medeia.api.ValidationFailedException;
+import java.util.ArrayList;
+import java.util.Map;
+import org.junit.Test;
+import org.onap.policy.apex.context.ContextRuntimeException;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.common.utils.coder.CoderException;
+
+public class JsonSchemaHelperUnmarshalTest extends CommonTestData {
+
+ /**
+ * Test Boolean.
+ */
+ @Test
+ public void testBooleanUnmarshal() {
+ var schemaHelper = createSchema(BOOLEAN_SCHEMA);
+ assertThat(schemaHelper.createNewInstance(BOOLEAN_DATA)).isInstanceOf(Boolean.class).isEqualTo(Boolean.TRUE);
+ }
+
+ /**
+ * Test null.
+ */
+ @Test
+ public void testNullUnmarshal() {
+ var schemaHelper = createSchema(NULL_SCHEMA);
+ assertThat(schemaHelper.createNewInstance(NULL_DATA)).isEqualTo(null);
+ }
+
+ /**
+ * Test Array.
+ */
+ @Test
+ public void testArrayUnmarshal() {
+ var schemaHelper = createSchema(MEASUREMENTGROUPS_TYPE);
+ var obj = schemaHelper.createNewInstance(MEASUREMENTGROUPS);
+ assertThat(obj).isInstanceOf(ArrayList.class);
+ }
+
+ /**
+ * Test invlaid schema.
+ */
+ @Test
+ public void testSchemaInvalid() {
+ String schemaDef = "{\"type\": \"object\"}";
+ final AxContextSchema jsonSchema =
+ new AxContextSchema(new AxArtifactKey("JsonObject", VERSION), JSON, schemaDef);
+ assertThatThrownBy(() -> new JsonSchemaHelper().init(testKey, jsonSchema))
+ .isInstanceOf(ContextRuntimeException.class).hasMessageContaining("schema is invalid");
+ }
+
+ /**
+ * Test Object unmarshal valid scenario using JSON Schema draft 04.
+ *
+ * @throws CoderException the coderException
+ */
+ @Test
+ public void testObjectSchemaDraft04_valid() throws CoderException {
+ var dataAsObject = coder.decode(COMMONHEADER, Map.class);
+ var dataReturned = validateAndUnmarshal(COMMONHEADERTYPE_DRAFT04, COMMONHEADER);
+ assertThat(dataReturned).isEqualTo(dataAsObject);
+ }
+
+ /**
+ * Test Object unmarshal valid scenario using JSON Schema draft 07.
+ *
+ * @throws CoderException the coderException
+ */
+ @Test
+ public void testObjectSchemaDraft07_valid() throws CoderException {
+ var dataAsObject = coder.decode(COMMONHEADER, Map.class);
+ var dataReturned = validateAndUnmarshal(COMMONHEADERTYPE_DRAFT07, COMMONHEADER);
+ assertThat(dataReturned).isEqualTo(dataAsObject);
+ }
+
+ /**
+ * Test Object unmarshal invalid scenario using JSON Schema draft 07.
+ *
+ * @throws CoderException the coderException
+ */
+ @Test
+ public void testObjectSchemaDraft07_invalid() throws CoderException {
+ var dataAsObject = coder.decode(COMMONHEADER, JsonObject.class);
+ dataAsObject.addProperty("requestId", "abcd");
+ assertThatThrownBy(() -> validateAndUnmarshal(COMMONHEADERTYPE_DRAFT07, dataAsObject))
+ .isInstanceOf(ValidationFailedException.class)
+ .hasMessageContaining("Pattern ^[0-9]*-[0-9]*$ is not contained in text");
+ }
+
+ /**
+ * Test createInstance using invalid format data.
+ *
+ * @throws CoderException the coderException
+ */
+ @Test
+ public void testCreateNewInstanceInvalid() throws CoderException {
+ var dataAsObject = coder.decode(COMMONHEADER, Map.class);
+ assertThatThrownBy(() -> validateAndUnmarshal(COMMONHEADERTYPE_DRAFT07, dataAsObject))
+ .isInstanceOf(ContextRuntimeException.class).hasMessageContaining("not an instance of JsonObject");
+ }
+
+ /**
+ * Test Object unmarshal invalid - required field missing scenario.
+ *
+ * @throws CoderException the coderException
+ */
+ @Test
+ public void testObjectSchema_fieldMissing() throws CoderException {
+ var dataAsObject = coder.decode(COMMONHEADER, JsonObject.class);
+ dataAsObject.remove(TEST_ID);
+ assertThatThrownBy(() -> validateAndUnmarshal(COMMONHEADERTYPE_DRAFT07, dataAsObject))
+ .isInstanceOf(ValidationFailedException.class)
+ .hasMessageContaining("Required property testId is missing from object");
+ }
+
+ /**
+ * Test Object unmarshal with optional field.
+ *
+ * @throws CoderException the coderException
+ */
+ @Test
+ public void testObjectSchema_OptionalField() throws CoderException {
+ var dataAsObject = coder.decode(COMMONHEADER, Map.class);
+ var dataAsjsonObject = coder.decode(COMMONHEADER, JsonObject.class);
+ dataAsObject.remove(TEST_ID);
+ dataAsjsonObject.remove(TEST_ID);
+ var dataReturned = validateAndUnmarshal(COMMONHEADERTYPE_WITH_OPTIONAL, dataAsjsonObject);
+ assertThat(dataReturned).isEqualTo(dataAsObject);
+ }
+
+ private Object validateAndUnmarshal(String schemaDef, Object data) {
+ var schemaHelper = createSchema(schemaDef);
+ if (data instanceof String) {
+ return schemaHelper.createNewInstance((String) data);
+ } else {
+ return schemaHelper.createNewInstance(data);
+ }
+ }
+
+}
diff --git a/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/resources/data/commonHeader.json b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/resources/data/commonHeader.json
new file mode 100644
index 000000000..d3393cc63
--- /dev/null
+++ b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/resources/data/commonHeader.json
@@ -0,0 +1,6 @@
+{
+ "requestId": "123456-1000",
+ "subRequestId": "sub-123456-1000",
+ "originatorId": "sdnc",
+ "testId": 212.2
+}
diff --git a/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/resources/data/measurementGroups.json b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/resources/data/measurementGroups.json
new file mode 100644
index 000000000..e615968ac
--- /dev/null
+++ b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/resources/data/measurementGroups.json
@@ -0,0 +1,34 @@
+[
+ {
+ "measurementGroup": {
+ "measurementTypes": [
+ {
+ "measurementType": "countera"
+ },
+ {
+ "measurementType": "counterb"
+ }
+ ],
+ "managedObjectDNsBasic": [
+ {
+ "DN": "dna"
+ },
+ {
+ "DN": "dnb"
+ }
+ ]
+ }
+ },
+ {
+ "measurementGroup": {
+ "measurementTypes": [
+ {
+ "measurementType": "counterc"
+ },
+ {
+ "measurementType": "counterd"
+ }
+ ]
+ }
+ }
+]
diff --git a/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/resources/schema/commonHeaderTypeWithOptional.json b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/resources/schema/commonHeaderTypeWithOptional.json
new file mode 100644
index 000000000..d8d994fda
--- /dev/null
+++ b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/resources/schema/commonHeaderTypeWithOptional.json
@@ -0,0 +1,23 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "type": "object",
+ "properties": {
+ "requestId": {
+ "type": "string"
+ },
+ "subRequestId": {
+ "type": "string"
+ },
+ "originatorId": {
+ "type": "string"
+ },
+ "testId": {
+ "type": "integer"
+ }
+ },
+ "required": [
+ "requestId",
+ "subRequestId",
+ "originatorId"
+ ]
+}
diff --git a/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/resources/schema/commonHeaderType_draft04.json b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/resources/schema/commonHeaderType_draft04.json
new file mode 100644
index 000000000..de1c05b6f
--- /dev/null
+++ b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/resources/schema/commonHeaderType_draft04.json
@@ -0,0 +1,24 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "type": "object",
+ "properties": {
+ "requestId": {
+ "type": "string"
+ },
+ "subRequestId": {
+ "type": "string"
+ },
+ "originatorId": {
+ "type": "string"
+ },
+ "testId": {
+ "type": "number"
+ }
+ },
+ "required": [
+ "requestId",
+ "subRequestId",
+ "originatorId",
+ "testId"
+ ]
+}
diff --git a/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/resources/schema/commonHeaderType_draft07.json b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/resources/schema/commonHeaderType_draft07.json
new file mode 100644
index 000000000..94558ffe5
--- /dev/null
+++ b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/resources/schema/commonHeaderType_draft07.json
@@ -0,0 +1,52 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "Root",
+ "type": "object",
+ "required": [
+ "requestId",
+ "subRequestId",
+ "originatorId",
+ "testId"
+ ],
+ "properties": {
+ "requestId": {
+ "$id": "#root/requestId",
+ "title": "Requestid",
+ "type": "string",
+ "default": "",
+ "examples": [
+ "123456-1000"
+ ],
+ "pattern": "^[0-9]*-[0-9]*$"
+ },
+ "subRequestId": {
+ "$id": "#root/subRequestId",
+ "title": "Subrequestid",
+ "type": "string",
+ "default": "",
+ "examples": [
+ "sub-123456-1000"
+ ],
+ "pattern": "^.*$"
+ },
+ "originatorId": {
+ "$id": "#root/originatorId",
+ "title": "Originatorid",
+ "type": "string",
+ "default": "",
+ "examples": [
+ "sdnc"
+ ],
+ "pattern": "^.*$"
+ },
+ "testId": {
+ "$id": "#root/testId",
+ "title": "Testid",
+ "type": "number",
+ "examples": [
+ 212.2
+ ],
+ "default": 0
+ }
+ }
+}
diff --git a/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/resources/schema/measurementGroupsType.json b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/resources/schema/measurementGroupsType.json
new file mode 100644
index 000000000..41e598f93
--- /dev/null
+++ b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-json/src/test/resources/schema/measurementGroupsType.json
@@ -0,0 +1,61 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "type": "array",
+ "default": [],
+ "items": {
+ "type": "object",
+ "required": [
+ "measurementGroup"
+ ],
+ "properties": {
+ "measurementGroup": {
+ "type": "object",
+ "required": [
+ "measurementTypes"
+ ],
+ "properties": {
+ "measurementTypes": {
+ "type": "array",
+ "default": [],
+ "items": {
+ "type": "object",
+ "required": [
+ "measurementType"
+ ],
+ "properties": {
+ "measurementType": {
+ "type": "string",
+ "default": "",
+ "examples": [
+ "countera"
+ ],
+ "pattern": "^.*$"
+ }
+ }
+ }
+ },
+ "managedObjectDNsBasic": {
+ "type": "array",
+ "default": [],
+ "items": {
+ "type": "object",
+ "required": [
+ "DN"
+ ],
+ "properties": {
+ "DN": {
+ "type": "string",
+ "default": "",
+ "examples": [
+ "dna"
+ ],
+ "pattern": "^.*$"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/plugins-context/plugins-context-schema/pom.xml b/plugins/plugins-context/plugins-context-schema/pom.xml
index c6b2cd89b..e3f114b66 100644
--- a/plugins/plugins-context/plugins-context-schema/pom.xml
+++ b/plugins/plugins-context/plugins-context-schema/pom.xml
@@ -1,19 +1,20 @@
<!--
============LICENSE_START=======================================================
Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ Modifications Copyright (C) 2022 Bell Canada. 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=========================================================
-->
@@ -33,5 +34,6 @@
<description>Plugins for 3pps that handle context schemas</description>
<modules>
<module>plugins-context-schema-avro</module>
+ <module>plugins-context-schema-json</module>
</modules>
</project>