aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrikBuhr <patrik.buhr@est.tech>2021-09-21 14:47:59 +0200
committerPatrikBuhr <patrik.buhr@est.tech>2021-09-22 18:06:39 +0200
commitd279ef72d0b634f9fa57b4bce9dffebebf010d83 (patch)
tree5ef174d6ccbfe5d33681e97cf728aaf6afe31808
parent65cf80bbd2eba0ab60d174c04f981ff6cf929e36 (diff)
Create a json schema for validation of the configuration of the A1 PMS - A1 Jakarta
To create a json schema to be used for validation of the PMS configuration. The schema shall be used by PMS. It can also be used by the end user. The documentation should be updated on how can be done. Issue-ID: CCSDK-3468 Signed-off-by: PatrikBuhr <patrik.buhr@est.tech> Change-Id: I9932fa42ff40681098764c8dc84ac201bb3fabaf
-rw-r--r--a1-policy-management/config/application.yaml1
-rw-r--r--a1-policy-management/config/application_configuration.json6
-rw-r--r--a1-policy-management/pom.xml8
-rw-r--r--a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfig.java4
-rw-r--r--a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfigParser.java41
-rw-r--r--a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConfigurationController.java17
-rw-r--r--a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTask.java2
-rw-r--r--a1-policy-management/src/main/resources/application_configuration_schema.json151
-rw-r--r--a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfigParserTest.java22
-rw-r--r--a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConfigurationControllerTest.java7
-rw-r--r--a1-policy-management/src/test/resources/test_application_configuration.json6
-rw-r--r--a1-policy-management/src/test/resources/test_application_configuration_with_dmaap_config.json1
-rw-r--r--csit/scripts/healthcheck/config/application_configuration.json.nosdnc6
13 files changed, 252 insertions, 20 deletions
diff --git a/a1-policy-management/config/application.yaml b/a1-policy-management/config/application.yaml
index a40f172f..e1a778c3 100644
--- a/a1-policy-management/config/application.yaml
+++ b/a1-policy-management/config/application.yaml
@@ -74,4 +74,5 @@ app:
http.proxy-type: HTTP
# path where the service can store data
vardata-directory: /var/policy-management-service
+ config-file-schema-path:
diff --git a/a1-policy-management/config/application_configuration.json b/a1-policy-management/config/application_configuration.json
index 6c21b166..6187c866 100644
--- a/a1-policy-management/config/application_configuration.json
+++ b/a1-policy-management/config/application_configuration.json
@@ -1,6 +1,6 @@
{
- "config": {
- "//description": "Application configuration",
+ "description": "Application configuration",
+ "config": {
"controller": [
{
"name": "controller1",
@@ -21,4 +21,4 @@
}
]
}
-} \ No newline at end of file
+}
diff --git a/a1-policy-management/pom.xml b/a1-policy-management/pom.xml
index 4e3a9bd7..221cc081 100644
--- a/a1-policy-management/pom.xml
+++ b/a1-policy-management/pom.xml
@@ -223,6 +223,12 @@
<version>${commons-io.version}</version>
<scope>test</scope>
</dependency>
+ <!-- https://mvnrepository.com/artifact/com.github.erosb/everit-json-schema -->
+ <dependency>
+ <groupId>com.github.erosb</groupId>
+ <artifactId>everit-json-schema</artifactId>
+ <version>1.13.0</version>
+ </dependency>
</dependencies>
<build>
<plugins>
@@ -427,4 +433,4 @@
</plugin>
</plugins>
</build>
-</project>
+</project> \ No newline at end of file
diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfig.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfig.java
index 3a245190..40988e44 100644
--- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfig.java
+++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfig.java
@@ -45,6 +45,10 @@ public class ApplicationConfig {
private String localConfigurationFilePath;
@Getter
+ @Value("${app.config-file-schema-path:\"\"}")
+ private String configurationFileSchemaPath;
+
+ @Getter
@Value("${app.vardata-directory:null}")
private String vardataDirectory;
diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfigParser.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfigParser.java
index a6af2023..3cab8aa0 100644
--- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfigParser.java
+++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfigParser.java
@@ -24,6 +24,10 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -38,6 +42,7 @@ import javax.validation.constraints.NotNull;
import org.immutables.gson.Gson;
import org.immutables.value.Value;
+import org.json.JSONObject;
import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -50,6 +55,11 @@ public class ApplicationConfigParser {
private static final String CONFIG = "config";
private static final String CONTROLLER = "controller";
+ private final ApplicationConfig applicationConfig;
+
+ public ApplicationConfigParser(ApplicationConfig applicationConfig) {
+ this.applicationConfig = applicationConfig;
+ }
@Value.Immutable
@Gson.TypeAdapters
@@ -66,6 +76,8 @@ public class ApplicationConfigParser {
public ConfigParserResult parse(JsonObject root) throws ServiceException {
+ validateJsonObjectAgainstSchema(root);
+
String dmaapProducerTopicUrl = "";
String dmaapConsumerTopicUrl = "";
@@ -97,6 +109,35 @@ public class ApplicationConfigParser {
.build();
}
+ private void validateJsonObjectAgainstSchema(Object object) throws ServiceException {
+ if (applicationConfig.getConfigurationFileSchemaPath() == null
+ || applicationConfig.getConfigurationFileSchemaPath().isEmpty()) {
+ return;
+ }
+
+ try {
+ String schemaAsString = readSchemaFile();
+
+ JSONObject schemaJSON = new JSONObject(schemaAsString);
+ var schema = org.everit.json.schema.loader.SchemaLoader.load(schemaJSON);
+
+ String objectAsString = object.toString();
+ JSONObject json = new JSONObject(objectAsString);
+ schema.validate(json);
+ } catch (Exception e) {
+ throw new ServiceException("Json schema validation failure: " + e.toString());
+ }
+ }
+
+ private String readSchemaFile() throws IOException {
+ ClassLoader classLoader = getClass().getClassLoader();
+ String filePath = applicationConfig.getConfigurationFileSchemaPath();
+ URL url = classLoader.getResource(filePath);
+ File file = new File(url.getFile());
+ return new String(Files.readAllBytes(file.toPath()));
+
+ }
+
private void checkConfigurationConsistency(List<RicConfig> ricConfigs,
Map<String, ControllerConfig> controllerConfigs) throws ServiceException {
Set<String> ricUrls = new HashSet<>();
diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConfigurationController.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConfigurationController.java
index b677a405..e07ea284 100644
--- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConfigurationController.java
+++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConfigurationController.java
@@ -33,6 +33,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import java.io.IOException;
import java.util.Optional;
+import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig;
import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfigParser;
import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ConfigurationFile;
import org.onap.ccsdk.oran.a1policymanagementservice.controllers.VoidResponse;
@@ -57,11 +58,17 @@ public class ConfigurationController {
public static final String API_NAME = "Management of configuration";
public static final String API_DESCRIPTION = "";
- @Autowired
- ConfigurationFile configurationFile;
+ private final ConfigurationFile configurationFile;
+ private final RefreshConfigTask refreshConfigTask;
+ private final ApplicationConfig applicationConfig;
- @Autowired
- RefreshConfigTask refreshConfigTask;
+ ConfigurationController(@Autowired ConfigurationFile configurationFile,
+ @Autowired RefreshConfigTask refreshConfigTask, @Autowired ApplicationConfig applicationConfig) {
+ this.configurationFile = configurationFile;
+ this.refreshConfigTask = refreshConfigTask;
+ this.applicationConfig = applicationConfig;
+
+ }
private static Gson gson = new GsonBuilder() //
.create(); //
@@ -85,7 +92,7 @@ public class ConfigurationController {
validateConfigFileIsUsed();
String configAsString = gson.toJson(configuration);
JsonObject configJson = JsonParser.parseString(configAsString).getAsJsonObject();
- ApplicationConfigParser configParser = new ApplicationConfigParser();
+ ApplicationConfigParser configParser = new ApplicationConfigParser(applicationConfig);
configParser.parse(configJson);
configurationFile.writeFile(configJson);
logger.info("Configuration changed through REST call.");
diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTask.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTask.java
index 30279815..6177ee1b 100644
--- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTask.java
+++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTask.java
@@ -189,7 +189,7 @@ public class RefreshConfigTask {
private Mono<ApplicationConfigParser.ConfigParserResult> parseConfiguration(JsonObject jsonObject) {
try {
- ApplicationConfigParser parser = new ApplicationConfigParser();
+ ApplicationConfigParser parser = new ApplicationConfigParser(this.appConfig);
return Mono.just(parser.parse(jsonObject));
} catch (Exception e) {
String str = e.toString();
diff --git a/a1-policy-management/src/main/resources/application_configuration_schema.json b/a1-policy-management/src/main/resources/application_configuration_schema.json
new file mode 100644
index 00000000..05135e7c
--- /dev/null
+++ b/a1-policy-management/src/main/resources/application_configuration_schema.json
@@ -0,0 +1,151 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "type": "object",
+ "properties": {
+ "config": {
+ "type": "object",
+ "properties": {
+ "//description": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "controller": {
+ "type": "array",
+ "items": [
+ {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "baseUrl": {
+ "type": "string"
+ },
+ "userName": {
+ "type": "string"
+ },
+ "password": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "name",
+ "baseUrl",
+ "userName",
+ "password"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "ric": {
+ "type": "array",
+ "items": [
+ {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "baseUrl": {
+ "type": "string"
+ },
+ "controller": {
+ "type": "string"
+ },
+ "managedElementIds": {
+ "type": "array",
+ "items": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "required": [
+ "name",
+ "baseUrl",
+ "managedElementIds"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "streams_publishes": {
+ "type": "object",
+ "properties": {
+ "dmaap_publisher": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string"
+ },
+ "dmaap_info": {
+ "type": "object",
+ "properties": {
+ "topic_url": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "topic_url"
+ ]
+ }
+ },
+ "required": [
+ "type",
+ "dmaap_info"
+ ]
+ }
+ },
+ "required": [
+ "dmaap_publisher"
+ ]
+ },
+ "streams_subscribes": {
+ "type": "object",
+ "properties": {
+ "dmaap_subscriber": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string"
+ },
+ "dmaap_info": {
+ "type": "object",
+ "properties": {
+ "topic_url": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "topic_url"
+ ]
+ }
+ },
+ "required": [
+ "type",
+ "dmaap_info"
+ ]
+ }
+ },
+ "required": [
+ "dmaap_subscriber"
+ ]
+ }
+ },
+ "required": [
+ "ric"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "required": [
+ "config"
+ ]
+} \ No newline at end of file
diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfigParserTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfigParserTest.java
index 5e218582..d12fd6bc 100644
--- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfigParserTest.java
+++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfigParserTest.java
@@ -20,8 +20,11 @@
package org.onap.ccsdk.oran.a1policymanagementservice.configuration;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
import com.google.common.base.Charsets;
import com.google.common.io.Resources;
@@ -44,12 +47,16 @@ import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.ServiceException
class ApplicationConfigParserTest {
- ApplicationConfigParser parserUnderTest = new ApplicationConfigParser();
+ ApplicationConfig applicationConfigMock = spy(new ApplicationConfig());
+ ApplicationConfigParser parserUnderTest = new ApplicationConfigParser(applicationConfigMock);
@Test
void whenCorrectConfig() throws Exception {
JsonObject jsonRootObject = getJsonRootObject();
+ when(applicationConfigMock.getConfigurationFileSchemaPath())
+ .thenReturn("application_configuration_schema.json");
+
ApplicationConfigParser.ConfigParserResult result = parserUnderTest.parse(jsonRootObject);
String topicUrl = result.dmaapProducerTopicUrl();
@@ -153,6 +160,19 @@ class ApplicationConfigParserTest {
assertEquals(message, actualException.getMessage(), "Wrong error message when wrong member name in object");
}
+ @Test
+ void schemaValidationError() throws Exception {
+ when(applicationConfigMock.getConfigurationFileSchemaPath())
+ .thenReturn("application_configuration_schema.json");
+ JsonObject jsonRootObject = getJsonRootObject();
+ JsonObject json = jsonRootObject.getAsJsonObject("config");
+ json.remove("ric");
+
+ Exception actualException = assertThrows(ServiceException.class, () -> parserUnderTest.parse(jsonRootObject));
+
+ assertThat(actualException.getMessage()).contains("Json schema validation failure");
+ }
+
JsonObject getDmaapInfo(JsonObject jsonRootObject, String streamsPublishesOrSubscribes,
String dmaapPublisherOrSubscriber) throws Exception {
return jsonRootObject.getAsJsonObject("config").getAsJsonObject(streamsPublishesOrSubscribes)
diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConfigurationControllerTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConfigurationControllerTest.java
index adb29a70..d2805556 100644
--- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConfigurationControllerTest.java
+++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConfigurationControllerTest.java
@@ -60,7 +60,9 @@ import reactor.test.StepVerifier;
@TestPropertySource(properties = { //
"server.ssl.key-store=./config/keystore.jks", //
"app.webclient.trust-store=./config/truststore.jks", //
- "app.vardata-directory=./target"})
+ "app.vardata-directory=./target", //
+ "app.config-file-schema-path=application_configuration_schema.json" //
+})
class ConfigurationControllerTest {
@Autowired
ApplicationContext context;
@@ -135,8 +137,7 @@ class ConfigurationControllerTest {
String url = "a1-policy/v2/configuration";
// Valid JSON but invalid configuration.
- testErrorCode(restClient().put(url, "{\"error\":\"error\"}"), HttpStatus.BAD_REQUEST,
- "Missing root configuration");
+ testErrorCode(restClient().put(url, "{\"error\":\"error\"}"), HttpStatus.BAD_REQUEST, "");
}
private void testErrorCode(Mono<?> request, HttpStatus expStatus, String responseContains) {
diff --git a/a1-policy-management/src/test/resources/test_application_configuration.json b/a1-policy-management/src/test/resources/test_application_configuration.json
index 3cbc371c..959f53fd 100644
--- a/a1-policy-management/src/test/resources/test_application_configuration.json
+++ b/a1-policy-management/src/test/resources/test_application_configuration.json
@@ -1,6 +1,6 @@
-{
+{
"config": {
- "//description": "Application configuration",
+ "description": "Application configuration",
"ric": [
{
"name": "ric1",
@@ -36,4 +36,4 @@
}
}
}
-} \ No newline at end of file
+}
diff --git a/a1-policy-management/src/test/resources/test_application_configuration_with_dmaap_config.json b/a1-policy-management/src/test/resources/test_application_configuration_with_dmaap_config.json
index ed1501dd..b00720c3 100644
--- a/a1-policy-management/src/test/resources/test_application_configuration_with_dmaap_config.json
+++ b/a1-policy-management/src/test/resources/test_application_configuration_with_dmaap_config.json
@@ -1,5 +1,6 @@
{
"config": {
+ "//description" : "Test",
"controller": [
{
"name": "controller1",
diff --git a/csit/scripts/healthcheck/config/application_configuration.json.nosdnc b/csit/scripts/healthcheck/config/application_configuration.json.nosdnc
index deb88a08..800a54ec 100644
--- a/csit/scripts/healthcheck/config/application_configuration.json.nosdnc
+++ b/csit/scripts/healthcheck/config/application_configuration.json.nosdnc
@@ -1,6 +1,6 @@
{
- "config":{
- "//description":"Application configuration",
+ "description":"Application configuration",
+ "config":{
"ric":[
{
"name":"ric1",
@@ -36,4 +36,4 @@
}
}
}
- } \ No newline at end of file
+ }