summaryrefslogtreecommitdiffstats
path: root/src/test/java
diff options
context:
space:
mode:
authorPrudence Au <prudence.au@amdocs.com>2018-08-13 17:06:59 -0400
committerPierre Rioux <pierre.rioux@amdocs.com>2018-08-21 11:21:26 -0400
commitc604f64b971491f8c9b953adce54b847d7946e26 (patch)
tree134f7fc91b4da9e04c564c92337d44df420c8df0 /src/test/java
parent3baa3ebd0000b15f1c54c736f4a307731b16b923 (diff)
Initial submission for validation service
Change-Id: I9372430f1ae347373d5a9a0c7a427d7bd393d61e Issue-ID: LOG-427 Signed-off-by: Prudence Au (prudence.au@amdocs.com) Signed-off-by: Geora Barsky <georab@amdocs.com> Signed-off-by: Pierre Rioux <pierre.rioux@amdocs.com>
Diffstat (limited to 'src/test/java')
-rw-r--r--src/test/java/org/onap/aai/validation/auth/MicroServiceAuthTest.java227
-rw-r--r--src/test/java/org/onap/aai/validation/config/TestRestConfig.java79
-rw-r--r--src/test/java/org/onap/aai/validation/config/TestTopicAdminConfig.java60
-rw-r--r--src/test/java/org/onap/aai/validation/config/TestTopicConfig.java107
-rw-r--r--src/test/java/org/onap/aai/validation/config/TestValidationControllerConfig.java69
-rw-r--r--src/test/java/org/onap/aai/validation/controller/TestValidationController.java391
-rw-r--r--src/test/java/org/onap/aai/validation/data/client/TestRestClient.java74
-rw-r--r--src/test/java/org/onap/aai/validation/logging/LogReader.java101
-rw-r--r--src/test/java/org/onap/aai/validation/logging/TestApplicationLogger.java245
-rw-r--r--src/test/java/org/onap/aai/validation/modeldriven/TestModelId.java95
-rw-r--r--src/test/java/org/onap/aai/validation/modeldriven/configuration/mapping/TestFilter.java55
-rw-r--r--src/test/java/org/onap/aai/validation/modeldriven/configuration/mapping/TestModelInstanceMapper.java71
-rw-r--r--src/test/java/org/onap/aai/validation/modeldriven/configuration/mapping/TestValueConfiguration.java70
-rw-r--r--src/test/java/org/onap/aai/validation/modeldriven/parser/TestXMLModelParser.java96
-rw-r--r--src/test/java/org/onap/aai/validation/modeldriven/validator/TestInstanceReader.java236
-rw-r--r--src/test/java/org/onap/aai/validation/modeldriven/validator/TestModelDrivenValidator.java291
-rw-r--r--src/test/java/org/onap/aai/validation/modeldriven/validator/TestModelReader.java261
-rw-r--r--src/test/java/org/onap/aai/validation/publisher/MockEventPublisher.java72
-rw-r--r--src/test/java/org/onap/aai/validation/publisher/TestValidationEventPublisher.java102
-rw-r--r--src/test/java/org/onap/aai/validation/reader/TestEventReader.java270
-rw-r--r--src/test/java/org/onap/aai/validation/reader/TestJsonReader.java95
-rw-r--r--src/test/java/org/onap/aai/validation/reader/TestOxmConfigTranslator.java111
-rw-r--r--src/test/java/org/onap/aai/validation/reader/TestOxmReader.java63
-rw-r--r--src/test/java/org/onap/aai/validation/request/TestRequestHeaders.java143
-rw-r--r--src/test/java/org/onap/aai/validation/result/TestValidationResult.java444
-rw-r--r--src/test/java/org/onap/aai/validation/ruledriven/configuration/ConfigFileBuilder.java104
-rw-r--r--src/test/java/org/onap/aai/validation/ruledriven/configuration/ConfigurationExceptionMatcher.java73
-rw-r--r--src/test/java/org/onap/aai/validation/ruledriven/configuration/TestConfigFileBuilder.java59
-rw-r--r--src/test/java/org/onap/aai/validation/ruledriven/configuration/TestRulesConfigurationReader.java448
-rw-r--r--src/test/java/org/onap/aai/validation/ruledriven/mock/TestDefaultRules.java148
-rw-r--r--src/test/java/org/onap/aai/validation/ruledriven/rule/RuleHelper.java36
-rw-r--r--src/test/java/org/onap/aai/validation/ruledriven/rule/RuleTester.java47
-rw-r--r--src/test/java/org/onap/aai/validation/ruledriven/rule/TestConfigurationLoader.java190
-rw-r--r--src/test/java/org/onap/aai/validation/ruledriven/rule/TestRuleExecution.java494
-rw-r--r--src/test/java/org/onap/aai/validation/ruledriven/rule/TestRuleValidation.java229
-rw-r--r--src/test/java/org/onap/aai/validation/ruledriven/validator/TestRuleDrivenValidator.java125
-rw-r--r--src/test/java/org/onap/aai/validation/services/TestInfoService.java140
-rw-r--r--src/test/java/org/onap/aai/validation/services/TestValidateServiceImpl.java115
-rw-r--r--src/test/java/org/onap/aai/validation/test/util/RandomString.java40
-rw-r--r--src/test/java/org/onap/aai/validation/test/util/TestEntity.java88
-rw-r--r--src/test/java/org/onap/aai/validation/test/util/TestUtil.java52
-rw-r--r--src/test/java/org/onap/aai/validation/test/util/ValidationResultIsEqual.java58
-rw-r--r--src/test/java/org/onap/aai/validation/util/TestStringUtils.java170
43 files changed, 6444 insertions, 0 deletions
diff --git a/src/test/java/org/onap/aai/validation/auth/MicroServiceAuthTest.java b/src/test/java/org/onap/aai/validation/auth/MicroServiceAuthTest.java
new file mode 100644
index 0000000..f9bd177
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/auth/MicroServiceAuthTest.java
@@ -0,0 +1,227 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.auth;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.file.Paths;
+import java.security.cert.X509Certificate;
+import javax.security.auth.x500.X500Principal;
+import javax.ws.rs.core.Cookie;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onap.aai.auth.AAIAuthException;
+import org.onap.aai.auth.AAIMicroServiceAuth;
+import org.onap.aai.auth.AAIMicroServiceAuthCore;
+import org.onap.aai.validation.config.ValidationServiceAuthConfig;
+import org.springframework.mock.web.MockHttpServletRequest;
+
+/**
+ * Tests @{link AAIMicroServiceAuth}
+ */
+
+public class MicroServiceAuthTest {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ System.setProperty("CONFIG_HOME", Paths.get(System.getProperty("user.dir"), "src/test/resources").toString());
+ }
+
+ private static final String VALID_ADMIN_USER = "cn=common-name, ou=org-unit, o=org, l=location, st=state, c=us";
+ private static final String authPolicyFile = "auth_policy.json";
+
+ /**
+ * Temporarily invalidate the default policy file and then try to initialise the authorisation class using the name
+ * of a policy file that does not exist.
+ *
+ * @throws AAIAuthException
+ * @throws IOException
+ */
+ @Test(expected = AAIAuthException.class)
+ public void missingPolicyFile() throws AAIAuthException, IOException {
+ String defaultFile = AAIMicroServiceAuthCore.getDefaultAuthFileName();
+ try {
+ AAIMicroServiceAuthCore.setDefaultAuthFileName("invalid.default.file");
+ ValidationServiceAuthConfig authConfig = new ValidationServiceAuthConfig();
+ authConfig.setAuthPolicyFile("invalid.file.name");
+ new AAIMicroServiceAuth(authConfig);
+ } finally {
+ AAIMicroServiceAuthCore.setDefaultAuthFileName(defaultFile);
+ }
+ }
+
+ /**
+ * Test loading of a temporary file created with the specified roles
+ *
+ * @throws AAIAuthException
+ * @throws IOException
+ * @throws JSONException
+ */
+ @Test
+ public void createLocalAuthFile() throws AAIAuthException, IOException, JSONException {
+ JSONObject roles = createRoleObject("role", createUserObject("user"), createFunctionObject("func"));
+ AAIMicroServiceAuth auth = createAuthService(roles);
+ assertThat(auth.authUser("nosuchuser", "method:func"), is(equalTo("AAI_9101")));
+ assertThat(auth.authUser("user", "method:func"), is(equalTo("OK")));
+ }
+
+ /**
+ * Test loading of the policy file relative to CONFIG_HOME
+ *
+ * @throws AAIAuthException
+ */
+ @Test
+ public void createAuth() throws AAIAuthException {
+ AAIMicroServiceAuth auth = createStandardAuth();
+ assertAdminUserAuthorisation(auth, VALID_ADMIN_USER);
+ }
+
+ @Test
+ public void testAuthUser() throws AAIAuthException {
+ AAIMicroServiceAuth auth = createStandardAuth();
+ assertThat(auth.authUser(VALID_ADMIN_USER, "GET:actions"), is(equalTo("OK")));
+ assertThat(auth.authUser(VALID_ADMIN_USER, "WRONG:action"), is(equalTo("AAI_9101")));
+ }
+
+ @Test
+ public void testAuthCookie() throws AAIAuthException {
+ AAIMicroServiceAuth auth = createStandardAuth();
+ Cookie mockCookie = new Cookie("name", null);
+ StringBuilder user = new StringBuilder(VALID_ADMIN_USER);
+
+ assertThat(auth.authCookie(null, "GET:actions", user), is(false));
+ assertThat(auth.authCookie(null, "WRONG:action", user), is(false));
+
+ assertThat(auth.authCookie(mockCookie, "GET:actions", user), is(true));
+ assertThat(auth.authCookie(mockCookie, "WRONG:action", user), is(false));
+ }
+
+ @Test
+ public void testValidateRequests() throws AAIAuthException {
+ AAIMicroServiceAuth auth = createStandardAuth();
+ assertThat(auth.validateRequest(new MockHttpServletRequest(), null, "app/v1/service"), is(false));
+ assertThat(auth.validateRequest(createMockRequest(), "POST", "getAndPublish"), is(false));
+ assertThat(auth.validateRequest(createMockRequest(), "POST", "validate"), is(true));
+ }
+
+ private MockHttpServletRequest createMockRequest() {
+ MockHttpServletRequest servletRequest = new MockHttpServletRequest();
+ servletRequest.setSecure(true);
+ servletRequest.setScheme("https");
+ servletRequest.setServerPort(9501);
+ servletRequest.setServerName("localhost");
+ servletRequest.setRequestURI("/services/validation-service/v1/app/validate");
+
+ X509Certificate mockCertificate = Mockito.mock(X509Certificate.class);
+ Mockito.when(mockCertificate.getSubjectX500Principal())
+ .thenReturn(new X500Principal("CN=test, OU=qa, O=Test Ltd, L=London, ST=London, C=GB"));
+
+ servletRequest.setAttribute("javax.servlet.request.X509Certificate", new X509Certificate[] {mockCertificate});
+ servletRequest.setAttribute("javax.servlet.request.cipher_suite", "");
+ return servletRequest;
+ }
+
+ private AAIMicroServiceAuth createStandardAuth() throws AAIAuthException {
+ ValidationServiceAuthConfig authConfig = new ValidationServiceAuthConfig();
+ authConfig.setAuthPolicyFile(authPolicyFile);
+ return new AAIMicroServiceAuth(authConfig);
+ }
+
+ /**
+ * @param rolesJson
+ * @return
+ * @throws IOException
+ * @throws AAIAuthException
+ */
+ private AAIMicroServiceAuth createAuthService(JSONObject roles) throws IOException, AAIAuthException {
+ ValidationServiceAuthConfig authConfig = new ValidationServiceAuthConfig();
+ File file = File.createTempFile("auth-policy", "json");
+ file.deleteOnExit();
+ FileWriter fileWriter = new FileWriter(file);
+ fileWriter.write(roles.toString());
+ fileWriter.flush();
+ fileWriter.close();
+
+ authConfig.setAuthPolicyFile(file.getAbsolutePath());
+ return new AAIMicroServiceAuth(authConfig);
+ }
+
+ /**
+ * Assert authorisation results for an admin user based on the test policy file
+ *
+ * @param auth
+ * @param adminUser
+ * @throws AAIAuthException
+ */
+ private void assertAdminUserAuthorisation(AAIMicroServiceAuth auth, String adminUser) throws AAIAuthException {
+ assertThat(auth.authUser(adminUser, "GET:actions"), is(equalTo("OK")));
+ assertThat(auth.authUser(adminUser, "POST:actions"), is(equalTo("OK")));
+ assertThat(auth.authUser(adminUser, "PUT:actions"), is(equalTo("OK")));
+ assertThat(auth.authUser(adminUser, "DELETE:actions"), is(equalTo("OK")));
+ }
+
+ private JSONArray createFunctionObject(String functionName) throws JSONException {
+ JSONArray functionsArray = new JSONArray();
+ JSONObject func = new JSONObject();
+ func.put("name", functionName);
+ func.put("methods", createMethodObject("method"));
+ functionsArray.put(func);
+ return functionsArray;
+ }
+
+ private JSONArray createMethodObject(String methodName) throws JSONException {
+ JSONArray methodsArray = new JSONArray();
+ JSONObject method = new JSONObject();
+ method.put("name", methodName);
+ methodsArray.put(method);
+ return methodsArray;
+ }
+
+ private JSONArray createUserObject(String username) throws JSONException {
+ JSONArray usersArray = new JSONArray();
+ JSONObject user = new JSONObject();
+ user.put("username", username);
+ usersArray.put(user);
+ return usersArray;
+ }
+
+ private JSONObject createRoleObject(String roleName, JSONArray usersArray, JSONArray functionsArray)
+ throws JSONException {
+ JSONObject roles = new JSONObject();
+
+ JSONObject role = new JSONObject();
+ role.put("name", roleName);
+ role.put("functions", functionsArray);
+ role.put("users", usersArray);
+
+ JSONArray rolesArray = new JSONArray();
+ rolesArray.put(role);
+ roles.put("roles", rolesArray);
+
+ return roles;
+ }
+
+}
diff --git a/src/test/java/org/onap/aai/validation/config/TestRestConfig.java b/src/test/java/org/onap/aai/validation/config/TestRestConfig.java
new file mode 100644
index 0000000..313c847
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/config/TestRestConfig.java
@@ -0,0 +1,79 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.config;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import javax.inject.Inject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.aai.validation.config.RestConfig;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:/rest-config/test-validation-service-beans.xml"})
+public class TestRestConfig {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ @Inject
+ private RestConfig restConfig;
+
+ @Test
+ public void testRestConfigPopulation() throws Exception {
+ RestConfig expectedRestConfig = new RestConfig();
+
+ expectedRestConfig.setHost("localhost");
+ expectedRestConfig.setPort(8080);
+ expectedRestConfig.setProtocol("https");
+ expectedRestConfig.setBaseModelURI("${baseModelURI}");
+ expectedRestConfig.setTrustStorePath("/dir1/dir2/trustStorePath");
+ expectedRestConfig.setTrustStorePassword("70c87528c88dcd9f9c2558d30e817868");
+ expectedRestConfig.setKeyStorePath("/dir1/dir2/keyStorePath");
+ expectedRestConfig.setKeyStorePassword("70c87528c88dcd9f9c2558d30e817868");
+ expectedRestConfig.setKeyManagerFactoryAlgorithm("AES");
+ expectedRestConfig.setKeyStoreType("jks");
+ expectedRestConfig.setSecurityProtocol("TLS");
+ expectedRestConfig.setConnectionTimeout(100);
+ expectedRestConfig.setReadTimeout(200);
+
+ assertThat(expectedRestConfig, is(restConfig));
+ assertThat(expectedRestConfig.getBaseModelURI(), is(restConfig.getBaseModelURI()));
+ assertThat(expectedRestConfig.getConnectionTimeout(), is(restConfig.getConnectionTimeout()));
+ assertThat(expectedRestConfig.getHost(), is(restConfig.getHost()));
+ assertThat(expectedRestConfig.getKeyManagerFactoryAlgorithm(), is(restConfig.getKeyManagerFactoryAlgorithm()));
+ assertThat(expectedRestConfig.getKeyStorePassword(), is(restConfig.getKeyStorePassword()));
+ assertThat(expectedRestConfig.getKeyStorePath(), is(restConfig.getKeyStorePath()));
+ assertThat(expectedRestConfig.getKeyStoreType(), is(restConfig.getKeyStoreType()));
+ assertThat(expectedRestConfig.getPort(), is(restConfig.getPort()));
+ assertThat(expectedRestConfig.getProtocol(), is(restConfig.getProtocol()));
+ assertThat(expectedRestConfig.getReadTimeout(), is(restConfig.getReadTimeout()));
+ assertThat(expectedRestConfig.getSecurityProtocol(), is(restConfig.getSecurityProtocol()));
+ assertThat(expectedRestConfig.getTrustStorePassword(), is(restConfig.getTrustStorePassword()));
+ assertThat(expectedRestConfig.getTrustStorePath(), is(restConfig.getTrustStorePath()));
+ assertThat(expectedRestConfig.hashCode(), is(restConfig.hashCode()));
+ assertThat(expectedRestConfig.toString(), is(restConfig.toString()));
+ assertTrue(expectedRestConfig.equals(restConfig));
+
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/config/TestTopicAdminConfig.java b/src/test/java/org/onap/aai/validation/config/TestTopicAdminConfig.java
new file mode 100644
index 0000000..f6a6195
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/config/TestTopicAdminConfig.java
@@ -0,0 +1,60 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.config;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import javax.inject.Inject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.aai.validation.config.TopicAdminConfig;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:/topic-admin-config/test-validation-service-beans.xml"})
+public class TestTopicAdminConfig {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ @Inject
+ private TopicAdminConfig topicAdminConfig;
+
+ @Test
+ public void testTopicAdminConfigPopulation() throws Exception {
+ TopicAdminConfig expectedTopicAdminConfig = new TopicAdminConfig();
+
+ expectedTopicAdminConfig.setPublishEnable(true);
+ expectedTopicAdminConfig.setPublishRetries(3l);
+ expectedTopicAdminConfig.setConsumeEnable(true);
+ expectedTopicAdminConfig.setConsumePollingIntervalSeconds(3l);
+
+ assertThat(expectedTopicAdminConfig, is(topicAdminConfig));
+ assertThat(expectedTopicAdminConfig.hashCode(), is(topicAdminConfig.hashCode()));
+ assertThat(expectedTopicAdminConfig.toString(), is(topicAdminConfig.toString()));
+ assertThat(expectedTopicAdminConfig.getConsumePollingIntervalSeconds(),
+ is(topicAdminConfig.getConsumePollingIntervalSeconds()));
+ assertThat(expectedTopicAdminConfig.getPublishRetries(), is(topicAdminConfig.getPublishRetries()));
+ assertTrue(expectedTopicAdminConfig.equals(topicAdminConfig));
+ }
+
+}
diff --git a/src/test/java/org/onap/aai/validation/config/TestTopicConfig.java b/src/test/java/org/onap/aai/validation/config/TestTopicConfig.java
new file mode 100644
index 0000000..efe82b8
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/config/TestTopicConfig.java
@@ -0,0 +1,107 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.config;
+
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.util.List;
+import java.util.Properties;
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.aai.validation.config.TopicConfig;
+import org.onap.aai.validation.ValidationServiceApplication;
+import org.onap.aai.validation.config.TopicConfig.Topic;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:/topic-config/test-validation-service-beans.xml"})
+public class TestTopicConfig {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ @Inject
+ private TopicConfig topicConfigurations;
+
+ @Resource(name = "topicProperties")
+ private Properties topicProperties;
+
+
+ @Test
+ public void testGetTopicProperties() throws Exception {
+ assertThat(topicProperties.getProperty("aai-event.name"), is("aai-event"));
+ assertThat(topicProperties.getProperty("aai-data-export.name"), is("aai-data-export"));
+ }
+
+
+
+ @Test
+ public void testGetConsumerTopicsFromTopicConfig() throws Exception {
+ assertThat(topicConfigurations.getConsumerTopicNames(), containsInAnyOrder("aai-event", "aai-data-export"));
+ }
+
+
+ @Test
+ public void testGetConsumerTopicConfigurationObjects() throws Exception {
+ Topic eventTopic = new TopicConfig("aai-event","aai-data-integrity").new Topic();
+ eventTopic.setName("aai-event");
+ eventTopic.setHost("event-dummy-host");
+ eventTopic.setUsername("event-dummy-username");
+ eventTopic.setPassword("event-dummy-password");
+ eventTopic.setConsumerGroup("event-dummy-consumer-group");
+ eventTopic.setConsumerId("event-dummy-consumer-id");
+ eventTopic.setTransportType("event-dummy-transport-type");
+
+ Topic exportTopic = new TopicConfig("aai-data-export","aai-data-integrity").new Topic();
+ exportTopic.setName("aai-data-export");
+ exportTopic.setHost("export-dummy-host");
+ exportTopic.setUsername("export-dummy-username");
+ exportTopic.setPassword("export-dummy-password");
+ exportTopic.setConsumerGroup("export-dummy-consumer-group");
+ exportTopic.setConsumerId("export-dummy-consumer-id");
+ exportTopic.setTransportType("export-dummy-transport-type");
+
+ List<Topic> consumerTopics = topicConfigurations.getConsumerTopics();
+
+ assertThat(consumerTopics, containsInAnyOrder(eventTopic, exportTopic));
+ }
+
+ @Test
+ public void testGetPublisherTopicConfigurationObjects() throws Exception {
+ Topic integrityTopic = new TopicConfig("aai-data-export","aai-data-integrity").new Topic();
+ integrityTopic.setName("aai-data-integrity");
+ integrityTopic.setHost("integrity-dummy-host");
+ integrityTopic.setPartition("integrity-dummy-partition");
+ integrityTopic.setUsername("integrity-dummy-username");
+ integrityTopic.setPassword("integrity-dummy-password");
+ integrityTopic.setTransportType("integrity-dummy-transport-type");
+
+ List<Topic> publisherTopics = topicConfigurations.getPublisherTopics();
+
+ assertThat(publisherTopics, containsInAnyOrder(integrityTopic));
+ }
+
+
+}
diff --git a/src/test/java/org/onap/aai/validation/config/TestValidationControllerConfig.java b/src/test/java/org/onap/aai/validation/config/TestValidationControllerConfig.java
new file mode 100644
index 0000000..a8e03eb
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/config/TestValidationControllerConfig.java
@@ -0,0 +1,69 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.config;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.inject.Inject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.aai.validation.config.ValidationControllerConfig;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:/validation-controller-config/test-validation-service-beans.xml"})
+public class TestValidationControllerConfig {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ @Inject
+ private ValidationControllerConfig validationControllerConfig;
+
+ @Test
+ public void testValidationControllerConfig() {
+ ValidationControllerConfig expected = new ValidationControllerConfig();
+ List<String> excludedEventActionList = new ArrayList<String>();
+ excludedEventActionList.add("DELETE");
+
+ List<String> eventTypeRuleList = new ArrayList<String>(2);
+ eventTypeRuleList.add("AAI-EVENT");
+ eventTypeRuleList.add("AAI-DATA-EXPORT-API");
+
+ List<String> eventTypeModelList = new ArrayList<String>();
+ eventTypeModelList.add("AAI-DATA-EXPORT-NQ");
+
+ expected.setEventDomain("devINT1");
+ expected.setExcludedEventActions(excludedEventActionList);
+ expected.setEventTypeRule(eventTypeRuleList);
+ expected.setEventTypeModel(eventTypeModelList);
+ expected.setEventTypeEnd("END-EVENT");
+
+ assertThat(expected.getEventDomain(), is(validationControllerConfig.getEventDomain()));
+ assertThat(expected.getExcludedEventActions(), is(validationControllerConfig.getExcludedEventActions()));
+ assertThat(expected.getEventTypeRule(), is(validationControllerConfig.getEventTypeRule()));
+ assertThat(expected.getEventTypeModel(), is(validationControllerConfig.getEventTypeModel()));
+ assertThat(expected.getEventTypeEnd(), is(validationControllerConfig.getEventTypeEnd()));
+ }
+
+}
diff --git a/src/test/java/org/onap/aai/validation/controller/TestValidationController.java b/src/test/java/org/onap/aai/validation/controller/TestValidationController.java
new file mode 100644
index 0000000..ff67181
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/controller/TestValidationController.java
@@ -0,0 +1,391 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.controller;
+
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.aai.validation.Validator;
+import org.onap.aai.validation.config.EventReaderConfig;
+import org.onap.aai.validation.config.ValidationControllerConfig;
+import org.onap.aai.validation.controller.ValidationController;
+import org.onap.aai.validation.exception.ValidationServiceError;
+import org.onap.aai.validation.exception.ValidationServiceException;
+import org.onap.aai.validation.publisher.MessagePublisher;
+import org.onap.aai.validation.reader.EventReader;
+import org.onap.aai.validation.reader.data.Entity;
+import org.onap.aai.validation.reader.data.EntityId;
+import org.onap.aai.validation.result.ValidationResult;
+import org.onap.aai.validation.result.Violation;
+
+@RunWith(MockitoJUnitRunner.class)
+public class TestValidationController {
+
+ private static final String AAI_EVENT = "AAI-EVENT";
+ private static final String CREATE = "CREATE";
+ private static final String DELETE = "DELETE";
+ private static final String DEV_INT_1 = "devINT1";
+ private static final String ENTITY_LINK = "entityLink";
+ private static final String MODEL = "model";
+ private static final String RULE = "rule";
+ private static final String TEST = "test";
+ private static final String TESTDATA_EVENTTYPE_NAMEDQUERY = "aai named query eventtype";
+ private static final String TESTDATA_EVENTTYPE_API = "aai api eventtype";
+ private static final String TESTDATA_EVENTTYPE_AAI = "aai event eventype";
+ private static final String TESTDATA_EVENTTYPE_UNKNOWN = "unknown eventtype";
+ private static final String TESTDATA_EVENTTYPE_NULL = "event with null eventtype";
+ private static final String TESTDATA_EVENTTYPE_END_EVENT = "END-EVENT";
+ private static final String TESTDATA_DOMAIN_INVALID = "event with invalid domain";
+ private static final String TESTDATA_DOMAIN_NULL = "event with null domain";
+ private static final String TESTDATA_EVENTACTION_DELETE = "event with delete event action";
+ private static final String TESTDATA_EVENTACTION_NULL = "event with null event action";
+ private static final String TESTDATA_EXCEPTION_EVENT = "event causing exception";
+ private static final String TESTDATA_HANDLE_EXCEPTION_EXCEPTION_EVENT =
+ "event causing exception during handling of the original exception";
+ private static final String TESTDATA_VALIDATION_RESULT_PUBLISH_ERROR =
+ "event causing exception during publishing of validation result";
+ private static final String VSERVER = "vserver";
+
+ @Mock
+ private ValidationControllerConfig validationControllerConfig;
+
+ @Mock
+ private EventReader eventReader;
+
+ @Mock
+ private Validator ruleDrivenValidator;
+
+ @Mock
+ private Validator modelDrivenValidator;
+
+ @Mock
+ private MessagePublisher messagePublisher;
+
+ @InjectMocks
+ private ValidationController validationController = new ValidationController(validationControllerConfig,
+ eventReader, ruleDrivenValidator, modelDrivenValidator, messagePublisher);
+
+ @Mock
+ private Entity entity;
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ @Before
+ public void setupMocks() throws ValidationServiceException {
+
+ Map<String, List<ValidationResult>> validationResultsMap = setupTestData();
+
+ when(ruleDrivenValidator.validate(TESTDATA_EVENTTYPE_AAI))
+ .thenReturn(validationResultsMap.get(TESTDATA_EVENTTYPE_AAI));
+ when(ruleDrivenValidator.validate(TESTDATA_EVENTTYPE_API))
+ .thenReturn(validationResultsMap.get(TESTDATA_EVENTTYPE_API));
+ when(modelDrivenValidator.validate(TESTDATA_EVENTTYPE_NAMEDQUERY))
+ .thenReturn(validationResultsMap.get(TESTDATA_EVENTTYPE_NAMEDQUERY));
+ when(ruleDrivenValidator.validate(TESTDATA_EXCEPTION_EVENT))
+ .thenThrow(new RuntimeException("Failed to validate"));
+ when(ruleDrivenValidator.validate(TESTDATA_HANDLE_EXCEPTION_EXCEPTION_EVENT))
+ .thenThrow(new RuntimeException("Failed to validate"));
+ when(ruleDrivenValidator.validate(TESTDATA_VALIDATION_RESULT_PUBLISH_ERROR))
+ .thenReturn(validationResultsMap.get(TESTDATA_VALIDATION_RESULT_PUBLISH_ERROR));
+ when(ruleDrivenValidator.validate(TESTDATA_EVENTACTION_NULL))
+ .thenReturn(validationResultsMap.get(TESTDATA_EVENTTYPE_AAI));
+
+ Map<String, List<String>> eventTypeDataMap = setupEventTypeData();
+ when(validationControllerConfig.getEventTypeRule()).thenReturn(eventTypeDataMap.get(RULE));
+ when(validationControllerConfig.getEventTypeModel()).thenReturn(eventTypeDataMap.get(MODEL));
+ when(validationControllerConfig.getEventTypeEnd()).thenReturn("END-EVENT");
+
+ when(eventReader.getEventType(TESTDATA_EVENTTYPE_AAI)).thenReturn(Optional.of(AAI_EVENT));
+ when(eventReader.getEventType(TESTDATA_EVENTTYPE_API)).thenReturn(Optional.of("AAI-DATA-EXPORT-API"));
+ when(eventReader.getEventType(TESTDATA_EVENTTYPE_NAMEDQUERY)).thenReturn(Optional.of("AAI-DATA-EXPORT-NQ"));
+ when(eventReader.getEventType(TESTDATA_EVENTTYPE_UNKNOWN)).thenReturn(Optional.of("EVENTTYPE-UNKNOWN"));
+ when(eventReader.getEventType(TESTDATA_EVENTTYPE_NULL)).thenReturn(Optional.empty());
+ when(eventReader.getEventType(TESTDATA_EXCEPTION_EVENT)).thenReturn(Optional.of(AAI_EVENT));
+ when(eventReader.getEventType(TESTDATA_HANDLE_EXCEPTION_EXCEPTION_EVENT)).thenReturn(Optional.of(AAI_EVENT));
+ when(eventReader.getEventType(TESTDATA_VALIDATION_RESULT_PUBLISH_ERROR)).thenReturn(Optional.of(AAI_EVENT));
+ when(eventReader.getEventType(TESTDATA_EVENTACTION_NULL)).thenReturn(Optional.of(AAI_EVENT));
+
+ when(validationControllerConfig.getEventDomain()).thenReturn(DEV_INT_1);
+ when(eventReader.getEventDomain(TESTDATA_EVENTTYPE_AAI)).thenReturn(Optional.of(DEV_INT_1));
+ when(eventReader.getEventDomain(TESTDATA_EVENTTYPE_API)).thenReturn(Optional.of(DEV_INT_1));
+ when(eventReader.getEventDomain(TESTDATA_EVENTTYPE_NAMEDQUERY)).thenReturn(Optional.of(DEV_INT_1));
+ when(eventReader.getEventDomain(TESTDATA_EVENTTYPE_UNKNOWN)).thenReturn(Optional.of(DEV_INT_1));
+ when(eventReader.getEventDomain(TESTDATA_EVENTTYPE_NULL)).thenReturn(Optional.of(DEV_INT_1));
+ when(eventReader.getEventDomain(TESTDATA_DOMAIN_INVALID)).thenReturn(Optional.of("invalidDomain"));
+ when(eventReader.getEventDomain(TESTDATA_DOMAIN_NULL)).thenReturn(Optional.empty());
+ when(eventReader.getEventDomain(TESTDATA_EXCEPTION_EVENT)).thenReturn(Optional.of(DEV_INT_1));
+ when(eventReader.getEventDomain(TESTDATA_HANDLE_EXCEPTION_EXCEPTION_EVENT)).thenReturn(Optional.of(DEV_INT_1));
+ when(eventReader.getEventDomain(TESTDATA_VALIDATION_RESULT_PUBLISH_ERROR)).thenReturn(Optional.of(DEV_INT_1));
+ when(eventReader.getEventDomain(TESTDATA_EVENTACTION_DELETE)).thenReturn(Optional.of(DEV_INT_1));
+ when(eventReader.getEventDomain(TESTDATA_EVENTACTION_NULL)).thenReturn(Optional.of(DEV_INT_1));
+
+ List<String> excludedActions = new ArrayList<>();
+ excludedActions.add(DELETE);
+ when(validationControllerConfig.getExcludedEventActions()).thenReturn(excludedActions);
+ when(eventReader.getEventAction(TESTDATA_EVENTTYPE_AAI)).thenReturn(Optional.of(CREATE));
+ when(eventReader.getEventAction(TESTDATA_EVENTTYPE_API)).thenReturn(Optional.of(CREATE));
+ when(eventReader.getEventAction(TESTDATA_EVENTTYPE_NAMEDQUERY)).thenReturn(Optional.of(CREATE));
+ when(eventReader.getEventAction(TESTDATA_EVENTTYPE_UNKNOWN)).thenReturn(Optional.of(CREATE));
+ when(eventReader.getEventAction(TESTDATA_EVENTTYPE_NULL)).thenReturn(Optional.of(CREATE));
+ when(eventReader.getEventAction(TESTDATA_EXCEPTION_EVENT)).thenReturn(Optional.of(CREATE));
+ when(eventReader.getEventAction(TESTDATA_HANDLE_EXCEPTION_EXCEPTION_EVENT)).thenReturn(Optional.of(CREATE));
+ when(eventReader.getEventAction(TESTDATA_VALIDATION_RESULT_PUBLISH_ERROR)).thenReturn(Optional.of(CREATE));
+ when(eventReader.getEventAction(TESTDATA_EVENTACTION_DELETE)).thenReturn(Optional.of(DELETE));
+ when(eventReader.getEventAction(TESTDATA_EVENTACTION_NULL)).thenReturn(Optional.empty());
+
+ when(eventReader.getEntityType(TESTDATA_EXCEPTION_EVENT)).thenReturn(Optional.of(VSERVER));
+ when(eventReader.getEntity(TESTDATA_EXCEPTION_EVENT)).thenReturn(entity);
+ when(eventReader.getEntityType(TESTDATA_HANDLE_EXCEPTION_EXCEPTION_EVENT)).thenThrow(
+ new RuntimeException("Error during handling the exception for an event that couldn't be validated"));
+ //@formatter:off
+ Mockito.doThrow(new ValidationServiceException(ValidationServiceError.EVENT_CLIENT_PUBLISHER_INIT_ERROR))
+ .when(messagePublisher)
+ .publishMessage(
+ Mockito.contains("\"entityId\":\"[vserver-id=instanceid1]\",\"entityType\":\"entitytype1\",\"resourceVersion\":\"resourceVersion1\""));
+ //@formatter:on
+ }
+
+ private Map<String, List<String>> setupEventTypeData() {
+ Map<String, List<String>> eventTypeDataMap = new HashMap<>();
+ List<String> eventTypeRule = new ArrayList<>();
+
+ eventTypeRule.add(AAI_EVENT);
+ eventTypeRule.add("AAI-DATA-EXPORT-API");
+ eventTypeDataMap.put(RULE, eventTypeRule);
+
+ List<String> eventTypeModel = new ArrayList<>();
+ eventTypeModel.add("AAI-DATA-EXPORT-NQ");
+ eventTypeDataMap.put(MODEL, eventTypeModel);
+
+ return eventTypeDataMap;
+ }
+
+ private Map<String, List<ValidationResult>> setupTestData() throws ValidationServiceException {
+
+ Map<String, List<ValidationResult>> validationResultsMap = new HashMap<>();
+
+ List<ValidationResult> aaiEventValidationResults = new ArrayList<>();
+
+ setUpEntityMock("20160525162737-61c49d41-5338-4755-af54-06cee9fe4aca", VSERVER, "1464193654");
+
+ aaiEventValidationResults.add(new ValidationResult(entity));
+ aaiEventValidationResults.add(new ValidationResult(entity));
+ validationResultsMap.put(TESTDATA_EVENTTYPE_AAI, aaiEventValidationResults);
+
+ List<ValidationResult> apiEventValidationResults = new ArrayList<>();
+
+ setUpEntityMock("20160525162737-61c49d41-5338-4755-af54-06cee9fe4acb", VSERVER, "1464193655");
+
+ apiEventValidationResults.add(new ValidationResult(entity));
+ validationResultsMap.put(TESTDATA_EVENTTYPE_API, apiEventValidationResults);
+
+ List<ValidationResult> namedQueryEventValidationResults = new ArrayList<>();
+
+ setUpEntityMock("20160525162737-61c49d41-5338-4755-af54-06cee9fe4acc", VSERVER, "1464193656");
+
+ namedQueryEventValidationResults.add(new ValidationResult(entity));
+ validationResultsMap.put(TESTDATA_EVENTTYPE_NAMEDQUERY, namedQueryEventValidationResults);
+
+ List<ValidationResult> messagePublishExceptionValidationResults = new ArrayList<>();
+
+ setUpEntityMock("instanceid1", "entitytype1", "resourceVersion1");
+
+ messagePublishExceptionValidationResults.add(new ValidationResult(entity));
+ validationResultsMap.put(TESTDATA_VALIDATION_RESULT_PUBLISH_ERROR, messagePublishExceptionValidationResults);
+
+ return validationResultsMap;
+ }
+
+ @Test
+ public void testExecuteForAAIEvent() throws Exception {
+ // Test for AAI-EVENT
+ validationController.execute(TESTDATA_EVENTTYPE_AAI, TEST);
+ verify(ruleDrivenValidator, times(1)).validate(TESTDATA_EVENTTYPE_AAI);
+ verify(messagePublisher, times(2)).publishMessage(Mockito.contains(
+ "\"entityId\":{\"vserver-id\":\"20160525162737-61c49d41-5338-4755-af54-06cee9fe4aca\"},\"entityType\":\"vserver\",\"entityLink\":\"entityLink\",\"resourceVersion\":\"1464193654\",\"entity\":{},\"violations\":[]}"));
+ }
+
+ @Test
+ public void testExecuteForAPIEvent() throws Exception {
+ // Test for AAI-DATA-EXPORT-API
+ validationController.execute(TESTDATA_EVENTTYPE_API, TEST);
+ verify(ruleDrivenValidator, times(1)).validate(TESTDATA_EVENTTYPE_API);
+ verify(messagePublisher, times(1)).publishMessage(Mockito.contains(
+ "\"entityId\":{\"vserver-id\":\"20160525162737-61c49d41-5338-4755-af54-06cee9fe4acb\"},\"entityType\":\"vserver\",\"entityLink\":\"entityLink\",\"resourceVersion\":\"1464193655\",\"entity\":{},\"violations\":[]}"));
+ }
+
+ @Test
+ public void testExecuteForNQEvent() throws Exception {
+ // Test for AAI-DATA-EXPORT-NQ
+ validationController.execute(TESTDATA_EVENTTYPE_NAMEDQUERY, TEST);
+ verify(modelDrivenValidator, times(1)).validate(TESTDATA_EVENTTYPE_NAMEDQUERY);
+ verify(messagePublisher, times(1)).publishMessage(Mockito.contains(
+ "\"entityId\":{\"vserver-id\":\"20160525162737-61c49d41-5338-4755-af54-06cee9fe4acc\"},\"entityType\":\"vserver\",\"entityLink\":\"entityLink\",\"resourceVersion\":\"1464193656\",\"entity\":{},\"violations\":[]}"));
+ }
+
+ @Test
+ public void testExecuteForNullDomain() throws Exception {
+ doVerifyMockInteractionsTest(TESTDATA_DOMAIN_NULL, TEST);
+ }
+
+ private void doVerifyMockInteractionsTest(String event, String eventSource) throws Exception {
+ validationController.execute(event, eventSource);
+ verify(eventReader, times(1)).getEventType(Mockito.anyString());
+ verify(ruleDrivenValidator, times(0)).validate(Mockito.anyString());
+ verify(modelDrivenValidator, times(0)).validate(Mockito.anyString());
+ verify(messagePublisher, times(0)).publishMessage(Mockito.anyString());
+
+ }
+
+ @Test
+ public void testExecuteForInvalidDomain() throws Exception {
+ doVerifyMockInteractionsTest(TESTDATA_DOMAIN_INVALID, TEST);
+ }
+
+ @Test
+ public void testExecuteForExcludedAction() throws Exception {
+ doVerifyMockInteractionsTest(TESTDATA_EVENTACTION_DELETE, TEST);
+ }
+
+ @Test
+ public void testExecuteForNullAction() throws Exception {
+ validationController.execute(TESTDATA_EVENTACTION_NULL, TEST);
+ verify(eventReader, times(2)).getEventType(Mockito.anyString());
+ verify(ruleDrivenValidator, times(1)).validate(Mockito.anyString());
+ verify(modelDrivenValidator, times(0)).validate(Mockito.anyString());
+ verify(messagePublisher, times(2)).publishMessage(Mockito.anyString());
+ }
+
+
+
+ private void doEventTypeTest(String event, String eventSource, int numEventReaderInvocations) throws Exception {
+ validationController.execute(event, eventSource);
+ verify(eventReader, times(numEventReaderInvocations)).getEventType(event);
+ verify(ruleDrivenValidator, times(0)).validate(Mockito.anyString());
+ verify(modelDrivenValidator, times(0)).validate(Mockito.anyString());
+ verify(messagePublisher, times(0)).publishMessage(Mockito.anyString());
+ }
+
+ @Test
+ public void testExecuteForNullEventType() throws Exception {
+ // The implementation checks whether this is an end event
+ // Given that it is not, the event is then examined to see if it is a validation candidate
+ doEventTypeTest(TESTDATA_EVENTTYPE_NULL, TEST, 2);
+ }
+
+ @Test
+ public void testExecuteForUnknownEventType() throws Exception {
+ doEventTypeTest(TESTDATA_EVENTTYPE_UNKNOWN, TEST, 2);
+ }
+
+ @Test
+ public void testExecuteForEndEventType() throws Exception {
+ doVerifyMockInteractionsTest(TESTDATA_EVENTTYPE_END_EVENT, TEST);
+ }
+
+ @Test
+ public void testExceptionDuringValidation() throws Exception {
+ String primaryKey = "vserver-id";
+ String value = "example-vserver-id-val-34666";
+ String resourceVersion = "123456789";
+
+ EntityId entityId = new EntityId(primaryKey, value);
+
+ when(entity.getResourceVersion()).thenReturn(Optional.of(resourceVersion));
+ when(entity.getIds()).thenReturn(Collections.singletonList(entityId));
+ validationController.execute(TESTDATA_EXCEPTION_EVENT, TEST);
+ verify(ruleDrivenValidator, times(1)).validate(TESTDATA_EXCEPTION_EVENT);
+
+ // @formatter:off
+ Violation violation = new Violation.Builder(entity)
+ .category("CANNOT_VALIDATE")
+ .severity("CRITICAL")
+ .violationType("NONE")
+ .errorMessage("Failed to validate")
+ .build();
+ // @formatter:on
+
+ JsonObject violationObject = new JsonParser().parse(violation.toString()).getAsJsonObject();
+ violationObject.remove("validationRule"); // Not set
+
+ JsonObject validationResult = new JsonObject();
+ JsonObject entityIdObject = new JsonObject();
+ JsonElement entity = new JsonObject();
+ entityIdObject.addProperty(primaryKey, value);
+ validationResult.add(Violation.ENTITY_ID_PROPERTY, entityIdObject);
+ validationResult.addProperty(Violation.ENTITY_TYPE_PROPERTY, "entitytype1");
+ validationResult.addProperty(ENTITY_LINK, ENTITY_LINK);
+ validationResult.addProperty("resourceVersion", resourceVersion);
+ validationResult.add("entity", entity);
+ JsonArray violations = new JsonArray();
+ violations.add(violationObject);
+ validationResult.add("violations", violations);
+
+ String json = validationResult.toString();
+ String messageContent = json.substring(1, json.length() - 1); // Remove the { } from the JSON string
+ verify(messagePublisher).publishMessage(Mockito.contains(messageContent));
+ }
+
+ @Test
+ public void testExceptionDuringHandlingValidationException() throws Exception {
+ // Test for exception during handling of an exception scenario
+ validationController.execute(TESTDATA_HANDLE_EXCEPTION_EXCEPTION_EVENT, TEST);
+ verify(ruleDrivenValidator, times(1)).validate(TESTDATA_HANDLE_EXCEPTION_EXCEPTION_EVENT);
+ verify(messagePublisher, times(0)).publishMessage(Mockito.anyString());
+ }
+
+ @Test
+ public void testExceptionDuringMessagePublish() throws Exception {
+ // Test for exception during publishing message.
+ // Cant verify if the static application logger has been called.
+ // This test is here for code coverage.
+ validationController.execute(TESTDATA_VALIDATION_RESULT_PUBLISH_ERROR, TEST);
+ verify(ruleDrivenValidator, times(1)).validate(TESTDATA_VALIDATION_RESULT_PUBLISH_ERROR);
+ verify(messagePublisher, times(1)).publishMessage(Mockito.contains(
+ "\"entityId\":{\"vserver-id\":\"instanceid1\"},\"entityType\":\"entitytype1\",\"entityLink\":\"entityLink\",\"resourceVersion\":\"resourceVersion1\",\"entity\":{},\"violations\":[]}"));
+ }
+
+ private void setUpEntityMock(String id, String type, String resourceVersion) throws ValidationServiceException {
+ when(eventReader.getEventReaderConfig()).thenReturn(new EventReaderConfig());
+ when(entity.getType()).thenReturn(type);
+ EntityId entityId = new EntityId("vserver-id", id);
+ when(entity.getIds()).thenReturn(Collections.singletonList(entityId));
+ when(entity.getEntityLink()).thenReturn(ENTITY_LINK);
+ when(entity.getResourceVersion()).thenReturn(Optional.of(resourceVersion));
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/data/client/TestRestClient.java b/src/test/java/org/onap/aai/validation/data/client/TestRestClient.java
new file mode 100644
index 0000000..9f2807b
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/data/client/TestRestClient.java
@@ -0,0 +1,74 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.data.client;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+
+import javax.ws.rs.core.MediaType;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onap.aai.validation.config.RestConfig;
+import org.onap.aai.validation.data.client.RestClient;
+import org.onap.aai.validation.exception.ValidationServiceException;
+
+/**
+ * Simple tests for GET and POST failures so as to increase code coverage.
+ *
+ * Note that the REST client is not properly initialised.
+ *
+ */
+public class TestRestClient {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ private static final String TEST_URL = "/aai/v11";
+ private RestConfig mockRestConfig;
+
+ @Before
+ public void setUp() {
+ mockRestConfig = Mockito.mock(RestConfig.class);
+ Mockito.when(mockRestConfig.getProtocol()).thenReturn("http");
+ Mockito.when(mockRestConfig.getHost()).thenReturn("localhost");
+ Mockito.when(mockRestConfig.getPort()).thenReturn(8080);
+ }
+
+ @Test
+ public void validateConstructor() {
+ RestClient restClient = new RestClient(mockRestConfig);
+ assertNotNull(restClient);
+ assertThat(restClient.toString(), is(notNullValue()));
+ }
+
+ @Test(expected = ValidationServiceException.class)
+ public void getOperationFailure() throws ValidationServiceException {
+ RestClient restClient = new RestClient(mockRestConfig);
+ restClient.get(TEST_URL, MediaType.TEXT_PLAIN);
+ }
+
+ @Test(expected = ValidationServiceException.class)
+ public void postOperationFailure() throws ValidationServiceException {
+ RestClient restClient = new RestClient(mockRestConfig);
+ restClient.post(TEST_URL, MediaType.TEXT_PLAIN);
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/logging/LogReader.java b/src/test/java/org/onap/aai/validation/logging/LogReader.java
new file mode 100644
index 0000000..096221d
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/logging/LogReader.java
@@ -0,0 +1,101 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.logging;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+import org.apache.commons.lang.time.StopWatch;
+import org.junit.Assert;
+
+public class LogReader {
+
+ private Map<String, Path> cachedLogMap = new HashMap<>();
+ private Map<String, BufferedReader> readersMap = new HashMap<>();
+ private BufferedReader cachedReader;
+
+ public LogReader(String logDirectory, String logFilePrefix) throws IOException {
+ cachedReader = getReader(logDirectory, logFilePrefix);
+ }
+
+ private BufferedReader getReader(String logDirectory, String logFilePrefix) throws IOException {
+ BufferedReader reader = readersMap.get(logFilePrefix);
+ if (reader == null) {
+ reader = new BufferedReader(new FileReader(getLogFile(logDirectory, logFilePrefix)));
+ while (reader.readLine() != null) {
+ // Consume all lines
+ }
+ readersMap.put(logFilePrefix, reader);
+ }
+ return reader;
+ }
+
+ /**
+ * @param logDirectory
+ * @return the most recently created log file.
+ * @throws IOException
+ */
+ public File getLogFile(String logDirectory, String filenamePrefix) throws IOException {
+ Path cachedLog = cachedLogMap.get(filenamePrefix);
+
+ if (cachedLog == null) {
+ Optional<Path> latestFilePath = Files.list(Paths.get(logDirectory))
+ .filter(f -> Files.isDirectory(f) == false && f.getFileName().toString().startsWith(filenamePrefix))
+ .max(Comparator.comparingLong(f -> f.toFile().lastModified()));
+ if (latestFilePath.isPresent()) {
+ cachedLog = latestFilePath.get();
+ } else {
+ throw new IOException("No validation log files were found!");
+ }
+ }
+
+ return cachedLog.toFile();
+ }
+
+ /**
+ * @return new lines appended to the log file
+ * @throws IOException
+ */
+ public String getNewLines() throws IOException {
+ StopWatch stopwatch = new StopWatch();
+ stopwatch.start();
+
+ while (!cachedReader.ready()) {
+ if (stopwatch.getTime() > TimeUnit.SECONDS.toMillis(30)) {
+ Assert.fail("Test took too long");
+ }
+ // else keep waiting
+ }
+
+ StringBuilder lines = new StringBuilder();
+ String line;
+ while ((line = cachedReader.readLine()) != null) {
+ lines.append(line).append(System.lineSeparator());
+ }
+ return lines.toString();
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/logging/TestApplicationLogger.java b/src/test/java/org/onap/aai/validation/logging/TestApplicationLogger.java
new file mode 100644
index 0000000..d19d43d
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/logging/TestApplicationLogger.java
@@ -0,0 +1,245 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.logging;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.CoreMatchers.startsWith;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.io.IOException;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import org.apache.commons.lang.time.StopWatch;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onap.aai.cl.api.LogFields;
+import org.onap.aai.cl.api.Logger;
+import org.onap.aai.cl.mdc.MdcOverride;
+import org.onap.aai.validation.logging.ApplicationMsgs;
+import org.onap.aai.validation.logging.LogHelper;
+import org.onap.aai.validation.logging.LogHelper.TriConsumer;
+import org.springframework.http.HttpHeaders;
+
+/**
+ * Simple test to log each of the validation messages in turn.
+ *
+ * This version tests only the error logger at INFO level.
+ *
+ */
+public class TestApplicationLogger {
+
+ @BeforeClass
+ public static void setupClass() {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ /**
+ * Check that each message can be logged and that (by implication of successful logging) there is a corresponding
+ * resource (message format).
+ *
+ * @throws IOException
+ */
+ @Test
+ public void logAllMessages() throws IOException {
+ Logger logger = LogHelper.INSTANCE;
+ String logDirectory = getLogDirectory();
+ LogReader errorReader = new LogReader(logDirectory, "error");
+ LogReader debugReader = new LogReader(logDirectory, "debug");
+ String[] args = {"1", "2", "3", "4"};
+ for (ApplicationMsgs msg : Arrays.asList(ApplicationMsgs.values())) {
+ if (msg.name().endsWith("ERROR")) {
+ logger.error(msg, args);
+ validateLoggedMessage(msg, errorReader, "ERROR");
+
+ logger.error(msg, new RuntimeException("fred"), args);
+ validateLoggedMessage(msg, errorReader, "fred");
+ } else {
+ logger.info(msg, args);
+ validateLoggedMessage(msg, errorReader, "INFO");
+
+ logger.warn(msg, args);
+ validateLoggedMessage(msg, errorReader, "WARN");
+ }
+
+ logger.debug(msg, args);
+ validateLoggedMessage(msg, debugReader, "DEBUG");
+
+ // The trace level is not enabled
+ logger.trace(msg, args);
+ }
+ }
+
+ /**
+ * Check that each message can be logged and that (by implication of successful logging) there is a corresponding
+ * resource (message format).
+ *
+ * @throws IOException
+ */
+ @Test
+ public void logDebugMessages() throws IOException {
+ LogReader reader = new LogReader(getLogDirectory(), "debug");
+ LogHelper.INSTANCE.debug("a message");
+ String s = reader.getNewLines();
+ assertThat(s, is(notNullValue()));
+ }
+
+
+ /**
+ * Check logAudit with HTTP headers
+ *
+ * @throws IOException
+ */
+ @Test
+ public void logAuditMessage() throws IOException {
+ LogHelper logger = LogHelper.INSTANCE;
+ LogReader reader = new LogReader(getLogDirectory(), "audit");
+
+ HttpHeaders headers = Mockito.mock(HttpHeaders.class);
+ Mockito.when(headers.getFirst("X-ECOMP-RequestID")).thenReturn("ecomp-request-id");
+ Mockito.when(headers.getFirst("X-FromAppId")).thenReturn("app-id");
+
+ // Call logAudit without first calling startAudit
+ logger.logAuditSuccess("first call: bob");
+ String s = reader.getNewLines();
+ assertThat(s, is(notNullValue()));
+ assertThat("audit message log level", s, containsString("INFO"));
+ assertThat("audit message content", s, containsString("bob"));
+
+ // This time call the start method
+ logger.startAudit(headers, null);
+ logger.logAuditSuccess("second call: foo");
+ s = reader.getNewLines();
+ assertThat(s, is(notNullValue()));
+ assertThat("audit message log level", s, containsString("INFO"));
+ assertThat("audit message content", s, containsString("foo"));
+ assertThat("audit message content", s, containsString("ecomp-request-id"));
+ assertThat("audit message content", s, containsString("app-id"));
+ }
+
+ /**
+ * Check logAudit with no HTTP headers
+ *
+ * @throws IOException
+ */
+ @Test
+ public void logAuditMessageWithoutHeaders() throws IOException {
+ LogHelper logger = LogHelper.INSTANCE;
+ LogReader reader = new LogReader(getLogDirectory(), "audit");
+ logger.startAudit(null, null);
+ logger.logAuditSuccess("foo");
+ String s = reader.getNewLines();
+ assertThat(s, is(notNullValue()));
+ assertThat("audit message log level", s, containsString("INFO"));
+ assertThat("audit message content", s, containsString("foo"));
+ }
+
+ /**
+ * Check logMetrics
+ *
+ * @throws IOException
+ */
+ @Test
+ public void logMetricsMessage() throws IOException {
+ LogReader reader = new LogReader(getLogDirectory(), "metrics");
+ LogHelper logger = LogHelper.INSTANCE;
+ logger.logMetrics("metrics: fred");
+ String s = reader.getNewLines();
+ assertThat(s, is(notNullValue()));
+ assertThat("metrics message log level", s, containsString("INFO"));
+ assertThat("metrics message content", s, containsString("fred"));
+ }
+
+ @Test
+ public void logMetricsMessageWithStopwatch() throws IOException {
+ LogReader reader = new LogReader(getLogDirectory(), "metrics");
+ LogHelper logger = LogHelper.INSTANCE;
+ StopWatch stopWatch = new StopWatch();
+ stopWatch.start();
+ logger.logMetrics(stopWatch, "joe", "bloggs");
+ String logLine = reader.getNewLines();
+ assertThat(logLine, is(notNullValue()));
+ assertThat("metrics message log level", logLine, containsString("INFO"));
+ assertThat("metrics message content", logLine, containsString("joe"));
+ }
+
+ @Test
+ public void callUnsupportedMethods() throws IOException {
+ LogHelper logger = LogHelper.INSTANCE;
+ ApplicationMsgs dummyMsg = ApplicationMsgs.LOAD_PROPERTIES;
+ callUnsupportedOperationMethod(logger::error, dummyMsg);
+ callUnsupportedOperationMethod(logger::info, dummyMsg);
+ callUnsupportedOperationMethod(logger::warn, dummyMsg);
+ callUnsupportedOperationMethod(logger::debug, dummyMsg);
+ callUnsupportedOperationMethod(logger::trace, dummyMsg);
+ try {
+ logger.error(dummyMsg, new LogFields(), new RuntimeException("test"), "");
+ } catch (UnsupportedOperationException e) {
+ // Expected to reach here
+ }
+ try {
+ logger.info(dummyMsg, new LogFields(), new MdcOverride(), "");
+ } catch (UnsupportedOperationException e) {
+ // Expected to reach here
+ }
+ try {
+ logger.formatMsg(dummyMsg, "");
+ } catch (UnsupportedOperationException e) {
+ // Expected to reach here
+ }
+ }
+
+ private String getLogDirectory() {
+ String logDirectory = LogHelper.getLogDirectory();
+ assertThat(Paths.get(logDirectory).toAbsolutePath().toString(),
+ startsWith(Paths.get(System.getProperty("APP_HOME")).toAbsolutePath().toString()));
+ return logDirectory;
+ }
+
+ /**
+ * Call a logger method which is expected to throw an UnsupportedOperationException
+ *
+ * @param logMethod
+ * @param dummyMsg
+ */
+ private void callUnsupportedOperationMethod(TriConsumer<Enum<?>, LogFields, String[]> logMethod,
+ ApplicationMsgs dummyMsg) {
+ try {
+ logMethod.accept(dummyMsg, new LogFields(), new String[] {""});
+ org.junit.Assert.fail("method should have thrown execption"); // NOSONAR as code not reached
+ } catch (UnsupportedOperationException e) {
+ // Expected to reach here
+ }
+ }
+
+ /**
+ * Assert that a log message was logged to the expected log file at the expected severity
+ *
+ * @param msg
+ * @param reader
+ * @param severity
+ * @throws IOException
+ */
+ private void validateLoggedMessage(ApplicationMsgs msg, LogReader reader, String severity) throws IOException {
+ String s = reader.getNewLines();
+ assertThat(s, is(notNullValue()));
+ assertThat(msg.toString() + " log level", s, containsString(severity));
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/modeldriven/TestModelId.java b/src/test/java/org/onap/aai/validation/modeldriven/TestModelId.java
new file mode 100644
index 0000000..7cefede
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/modeldriven/TestModelId.java
@@ -0,0 +1,95 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.modeldriven;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Test;
+import org.onap.aai.validation.modeldriven.ModelId;
+
+public class TestModelId {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ @Test
+ public void testGettersAndSetters() {
+ String attr = null;
+ String id = null;
+ ModelId modelId = new ModelId(attr, id);
+ assertThat(modelId.getModelIdAttribute(), is(equalTo(attr)));
+ assertThat(modelId.getModelId(), is(equalTo(id)));
+ assertThat(modelId.isEmpty(), is(true));
+
+ attr = "";
+ modelId.setModelIdAttribute(attr);
+ assertThat(modelId.getModelIdAttribute(), is(equalTo(attr)));
+ assertThat(modelId.getModelId(), is(equalTo(id)));
+ assertThat(modelId.isEmpty(), is(true));
+
+ attr = "new_attr_value";
+ modelId.setModelIdAttribute(attr);
+ assertThat(modelId.getModelIdAttribute(), is(equalTo(attr)));
+ assertThat(modelId.getModelId(), is(equalTo(id)));
+ assertThat(modelId.isEmpty(), is(true));
+
+ id = "new_id";
+ modelId.setModelId(id);
+ assertThat(modelId.getModelIdAttribute(), is(equalTo(attr)));
+ assertThat(modelId.getModelId(), is(equalTo(id)));
+ assertThat(modelId.isEmpty(), is(false));
+
+ id = "";
+ modelId.setModelId(id);
+ assertThat(modelId.getModelIdAttribute(), is(equalTo(attr)));
+ assertThat(modelId.getModelId(), is(equalTo(id)));
+ assertThat(modelId.isEmpty(), is(true));
+
+ attr = null;
+ modelId.setModelIdAttribute(attr);
+ assertThat(modelId.getModelIdAttribute(), is(equalTo(attr)));
+ assertThat(modelId.getModelId(), is(equalTo(id)));
+ assertThat(modelId.isEmpty(), is(true));
+ }
+
+ @Test
+ public void testIsEmpty() {
+ assertThat(new ModelId(null, null).isEmpty(), is(true));
+ assertThat(new ModelId("", null).isEmpty(), is(true));
+ assertThat(new ModelId(null, "").isEmpty(), is(true));
+ assertThat(new ModelId("", "").isEmpty(), is(true));
+ assertThat(new ModelId("A", null).isEmpty(), is(true));
+ assertThat(new ModelId(null, "B").isEmpty(), is(true));
+ assertThat(new ModelId("A", "B").isEmpty(), is(false));
+ }
+
+ @Test
+ public void testEqualsMethod() {
+ ModelId id1 = new ModelId("a", "b");
+ ModelId id2 = new ModelId("a", "b");
+ assertThat(id1, is(equalTo(id1)));
+ assertThat(id1, is(equalTo(id2)));
+ assertThat(id1, is(not(equalTo(null))));
+ assertThat(id1.hashCode(), is(equalTo(id2.hashCode())));
+ }
+
+}
diff --git a/src/test/java/org/onap/aai/validation/modeldriven/configuration/mapping/TestFilter.java b/src/test/java/org/onap/aai/validation/modeldriven/configuration/mapping/TestFilter.java
new file mode 100644
index 0000000..c9d2688
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/modeldriven/configuration/mapping/TestFilter.java
@@ -0,0 +1,55 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.modeldriven.configuration.mapping;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.Test;
+import org.onap.aai.validation.modeldriven.configuration.mapping.Filter;
+
+public class TestFilter {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ @Test
+ public void testAllMethodsInFilterClassToImproveCodeCoverage() {
+ Filter filter1 = new Filter();
+ List<String> valid = new ArrayList<>();
+ valid.add("String 1");
+ filter1.setPath("path");
+ filter1.setValid(valid);
+
+ Filter filter2 = new Filter();
+ filter2.setPath("path");
+ filter2.setValid(valid);
+
+ assertThat(filter1, is(filter2));
+ assertThat(filter1.hashCode(), is(filter2.hashCode()));
+ assertThat(filter1.getPath(), is(filter2.getPath()));
+ assertThat(filter1.getValid(), is(filter2.getValid()));
+ assertThat(filter1.toString(), is(filter2.toString()));
+ assertTrue(filter1.equals(filter2));
+ }
+
+}
diff --git a/src/test/java/org/onap/aai/validation/modeldriven/configuration/mapping/TestModelInstanceMapper.java b/src/test/java/org/onap/aai/validation/modeldriven/configuration/mapping/TestModelInstanceMapper.java
new file mode 100644
index 0000000..7c820bb
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/modeldriven/configuration/mapping/TestModelInstanceMapper.java
@@ -0,0 +1,71 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.modeldriven.configuration.mapping;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.Test;
+import org.onap.aai.validation.modeldriven.configuration.mapping.Filter;
+import org.onap.aai.validation.modeldriven.configuration.mapping.ModelInstanceMapper;
+import org.onap.aai.validation.modeldriven.configuration.mapping.ValueConfiguration;
+import org.onap.aai.validation.modeldriven.configuration.mapping.ModelInstanceMapper.MappingType;
+
+public class TestModelInstanceMapper {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ @Test
+ public void testAllMethodsToImproveCodeCoverage() {
+ List<String> valid = new ArrayList<>();
+ valid.add("string1");
+ Filter filter = new Filter();
+ filter.setPath("testPath");
+ filter.setValid(valid);
+
+ ValueConfiguration valueConf1 = new ValueConfiguration();
+ valueConf1.setFilter(filter);
+ valueConf1.setId("id");
+ valueConf1.setOrigin("testOrigin");
+ valueConf1.setRoot("testRoot");
+ valueConf1.setValue("testValue");
+
+ ModelInstanceMapper mapper1 = new ModelInstanceMapper();
+ mapper1.setInstance(valueConf1);
+ mapper1.setMappingType(MappingType.ATTRIBUTE.toString());
+ mapper1.setModel(valueConf1);
+
+ ModelInstanceMapper mapper2 = new ModelInstanceMapper();
+ mapper2.setInstance(valueConf1);
+ mapper2.setMappingType(MappingType.ATTRIBUTE.toString());
+ mapper2.setModel(valueConf1);
+
+ assertThat(mapper1.hashCode(), is(mapper2.hashCode()));
+ assertThat(mapper1.getInstance(), is(mapper2.getInstance()));
+ assertThat(mapper1.getMappingType(), is(mapper2.getMappingType()));
+ assertThat(mapper1.getModel(), is(mapper2.getModel()));
+ assertThat(mapper1.toString(), is(mapper2.toString()));
+ assertTrue(mapper1.equals(mapper2));
+ }
+
+}
diff --git a/src/test/java/org/onap/aai/validation/modeldriven/configuration/mapping/TestValueConfiguration.java b/src/test/java/org/onap/aai/validation/modeldriven/configuration/mapping/TestValueConfiguration.java
new file mode 100644
index 0000000..80c1ab8
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/modeldriven/configuration/mapping/TestValueConfiguration.java
@@ -0,0 +1,70 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.modeldriven.configuration.mapping;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.Test;
+import org.onap.aai.validation.modeldriven.configuration.mapping.Filter;
+import org.onap.aai.validation.modeldriven.configuration.mapping.ValueConfiguration;
+
+public class TestValueConfiguration {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ @Test
+ public void testAllMethodsToImproveCodeCoverage() {
+
+ List<String> valid = new ArrayList<>();
+ valid.add("string1");
+ Filter filter = new Filter();
+ filter.setPath("testPath");
+ filter.setValid(valid);
+
+ ValueConfiguration valueConf1 = new ValueConfiguration();
+ valueConf1.setFilter(filter);
+ valueConf1.setId("id");
+ valueConf1.setOrigin("testOrigin");
+ valueConf1.setRoot("testRoot");
+ valueConf1.setValue("testValue");
+
+ ValueConfiguration valueConf2 = new ValueConfiguration();
+ valueConf2.setFilter(filter);
+ valueConf2.setId("id");
+ valueConf2.setOrigin("testOrigin");
+ valueConf2.setRoot("testRoot");
+ valueConf2.setValue("testValue");
+
+ assertThat(valueConf1, is(valueConf2));
+ assertThat(valueConf1.hashCode(), is(valueConf2.hashCode()));
+ assertThat(valueConf1.getFilter(), is(valueConf2.getFilter()));
+ assertThat(valueConf1.getId(), is(valueConf2.getId()));
+ assertThat(valueConf1.getOrigin(), is(valueConf2.getOrigin()));
+ assertThat(valueConf1.getRoot(), is(valueConf2.getRoot()));
+ assertThat(valueConf1.getValue(), is(valueConf2.getValue()));
+ assertThat(valueConf1.toString(), is(valueConf2.toString()));
+ assertTrue(valueConf1.equals(valueConf2));
+ }
+
+}
diff --git a/src/test/java/org/onap/aai/validation/modeldriven/parser/TestXMLModelParser.java b/src/test/java/org/onap/aai/validation/modeldriven/parser/TestXMLModelParser.java
new file mode 100644
index 0000000..3344193
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/modeldriven/parser/TestXMLModelParser.java
@@ -0,0 +1,96 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.modeldriven.parser;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import org.dom4j.Element;
+import org.dom4j.Node;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.onap.aai.validation.modeldriven.parser.XMLModelParser;
+
+public class TestXMLModelParser {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ private static final String CONNECTOR_MODEL_ID = "460c6de2-a92b-4e3b-9ba3-538ce782b2fa";
+ private static final String MODEL_ID_ATTRIBUTE = "model-name-version-id";
+
+ private Element modelElement;
+
+ @Rule
+ public ExpectedException exception = ExpectedException.none();
+
+ @Before
+ public void setUp() throws Exception {
+ File modelFile = new File("src/test/resources/model-validation/model-parser/all-models.xml");
+ Element modelsElement = XMLModelParser.parse(modelFile, false);
+ modelElement = XMLModelParser.getModelElementWithId(modelsElement, MODEL_ID_ATTRIBUTE, CONNECTOR_MODEL_ID);
+ }
+
+ @Test
+ public void testParseXMLModelFile() throws Exception {
+ assertEquals("Invalid model element name.", "model", modelElement.getName());
+ }
+
+ @Test
+ public void testGetAttributes() throws Exception {
+ String attrsXPath = "metadata/metadatum/metaname";
+ List<Node> attrNodes = XMLModelParser.getObjectsFromXPath(modelElement, attrsXPath);
+ assertEquals("Unexpected number of attributes.", 2, attrNodes.size());
+
+ List<String> validAttrs = new ArrayList<>();
+ validAttrs.add("a");
+ validAttrs.add("b");
+
+ List<String> actualAttrs = new ArrayList<>();
+ for (Node node : attrNodes) {
+ actualAttrs.add(node.getText());
+ }
+
+ assertTrue("Unexpected attribute names.", validAttrs.containsAll(actualAttrs));
+ }
+
+ @Test
+ public void testGetRelatedObjects() throws Exception {
+ String relObjsXPath = "model-elements/model-element";
+ List<Node> relatedNodes = XMLModelParser.getObjectsFromXPath(modelElement, relObjsXPath);
+ assertEquals("Unexpected number of related objects.", 1, relatedNodes.size());
+
+ Node relatedObjUUIDNode = relatedNodes.get(0).selectSingleNode("model-element-uuid");
+ assertEquals("Unexpected related object UUID.", "71b825be-febf-45f7-b86a-ca0e3de19c90",
+ relatedObjUUIDNode.getText());
+ }
+
+ @Test
+ public void testModelValidationFailure() throws Exception {
+ File modelFile = new File("src/test/resources/model-validation/model-parser/all-models.xml");
+
+ assertNull("Validation failure should result in null being returned.", XMLModelParser.parse(modelFile, true));
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/modeldriven/validator/TestInstanceReader.java b/src/test/java/org/onap/aai/validation/modeldriven/validator/TestInstanceReader.java
new file mode 100644
index 0000000..60588bb
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/modeldriven/validator/TestInstanceReader.java
@@ -0,0 +1,236 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.modeldriven.validator;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+
+import com.google.common.collect.Multimap;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
+import javax.inject.Inject;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.onap.aai.validation.exception.ValidationServiceException;
+import org.onap.aai.validation.modeldriven.configuration.mapping.ModelInstanceMapper;
+import org.onap.aai.validation.modeldriven.validator.InstanceReader;
+import org.onap.aai.validation.test.util.TestUtil;
+import org.onap.aai.validation.util.JsonUtil;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@TestPropertySource(properties = {"schemaIngestPropLoc = src/test/resources/oxm-reader/schemaIngest.properties"})
+@ContextConfiguration(locations = {"classpath:model-validation/instance-reader/test-validation-service-beans.xml"})
+public class TestInstanceReader {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ private static ModelInstanceMapper mapping;
+ private static ModelInstanceMapper mappingRootUnknown;
+ private static ModelInstanceMapper mappingRootMissing;
+ private static String connector;
+ private static String connectorSibling;
+ private static String expectedVirtualDataCenter;
+ private static String expectedVirtualDataCenterModelName;
+ private static String connectorModelName;
+ private static String expectedLogicalLink;
+ private static String expectedGenericVnf;
+ private static String expectedPserver;
+
+ @Inject
+ private InstanceReader instanceReader;
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ mapping = TestInstanceReader.getMapping(TestData.MAPPING.getFilename());
+ mappingRootUnknown = TestInstanceReader.getMapping(TestData.MAPPING_ROOT_UNKNOWN.getFilename());
+ mappingRootMissing = TestInstanceReader.getMapping(TestData.MAPPING_ROOT_MISSING.getFilename());
+ connector = TestUtil.getFileAsString(TestData.CONNECTOR.getFilename());
+ connectorModelName = TestUtil.getFileAsString(TestData.CONNECTOR_MODEL_NAME.getFilename());
+ connectorSibling = TestUtil.getFileAsString(TestData.CONNECTOR_SIBLING.getFilename());
+ expectedVirtualDataCenter = TestUtil.getFileAsString(TestData.EXPECTED_VDC.getFilename());
+ expectedVirtualDataCenterModelName = TestUtil.getFileAsString(TestData.EXPECTED_VDC_MODEL_NAME.getFilename());
+ expectedLogicalLink = TestUtil.getFileAsString(TestData.EXPECTED_LOGICAL_LINK.getFilename());
+ expectedGenericVnf = TestUtil.getFileAsString(TestData.EXPECTED_GENERIC_VNF.getFilename());
+ expectedPserver = TestUtil.getFileAsString(TestData.EXPECTED_PSERVER.getFilename());
+
+ }
+
+ enum TestData {
+ // @formatter:off
+ MAPPING ("model-validation/instance-reader/model-instance-mapping.json_conf"),
+ MAPPING_ROOT_UNKNOWN ("model-validation/instance-reader/model-instance-mapping-root-unknown.json_conf"),
+ MAPPING_ROOT_MISSING ("model-validation/instance-reader/model-instance-mapping-root-missing.json_conf"),
+ CONNECTOR ("model-validation/instance-reader/connector.json"),
+ CONNECTOR_MODEL_NAME ("model-validation/instance-reader/connector-model-name.json"),
+ CONNECTOR_SIBLING ("model-validation/instance-reader/connector-sibling-inventory-items.json"),
+ EXPECTED_VDC ("model-validation/instance-reader/expected-virtual-data-center.json"),
+ EXPECTED_VDC_MODEL_NAME ("model-validation/instance-reader/expected-virtual-data-center-model-name.json"),
+ EXPECTED_LOGICAL_LINK ("model-validation/instance-reader/expected-logical-link.json"),
+ EXPECTED_GENERIC_VNF ("model-validation/instance-reader/expected-generic-vnf.json"),
+ EXPECTED_PSERVER ("model-validation/instance-reader/expected-pserver.json");
+
+ private String filename;
+ TestData(String filename) {this.filename = filename;}
+ public String getFilename() {return this.filename;}
+ // @formatter:on
+ }
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void testGetValuesNoModelName() throws Exception {
+ // Set expectation
+ JsonParser jsonParser = new JsonParser();
+ JsonElement jsonElement = jsonParser.parse(expectedVirtualDataCenter);
+ String expectedValue = jsonElement.toString();
+
+ // Method under test
+ Multimap<String, String> values = instanceReader.getValues(connector, mapping);
+
+ assertFalse(values.isEmpty());
+ assertThat(values.keys().iterator().next(), is(equalTo("virtual-data-center")));
+ assertThat(values.get("virtual-data-center").iterator().next(), is(equalTo(expectedValue)));
+ }
+
+ @Test
+ public void testGetValuesWithModelName() throws Exception {
+ // Set expectation
+ JsonParser jsonParser = new JsonParser();
+ JsonElement jsonElement = jsonParser.parse(expectedVirtualDataCenterModelName);
+ String expectedValue = jsonElement.toString();
+
+ // Method under test
+ Multimap<String, String> values = instanceReader.getValues(connectorModelName, mapping);
+
+ assertFalse(values.isEmpty());
+ assertThat(values.keys().iterator().next(), is(equalTo("Test VC Model Name")));
+ assertThat(values.get("Test VC Model Name").iterator().next(), is(equalTo(expectedValue)));
+ }
+
+ @Test
+ public void testNavigateInstance() throws Exception {
+ // Set expectation
+ JsonParser jsonParser = new JsonParser();
+ JsonElement jsonElement = jsonParser.parse(expectedLogicalLink);
+ String expectedValue = jsonElement.toString();
+
+ // Method under test
+ Multimap<String, String> values = instanceReader.getValues(connector, mapping);
+
+ String virtualDataCenterInstance = values.get("virtual-data-center").iterator().next();
+
+ // Method under test
+ values = instanceReader.getValues(virtualDataCenterInstance, mapping);
+
+ assertThat(values.keys().iterator().next(), is(equalTo("Test LL Model Name")));
+ assertThat(values.get("Test LL Model Name").iterator().next(), is(equalTo(expectedValue)));
+ }
+
+ @Test
+ public void testNavigateInstanceWithSiblingInventoryItems() throws Exception {
+ // Set expectations
+ JsonParser jsonParser = new JsonParser();
+ JsonElement genericVnfJsonElement = jsonParser.parse(expectedGenericVnf);
+ String expectedGenericVnf = genericVnfJsonElement.toString();
+
+ JsonElement pserverJsonElement = jsonParser.parse(expectedPserver);
+ String expectedPserver = pserverJsonElement.toString();
+
+ // Method under test
+ Multimap<String, String> values = instanceReader.getValues(connectorSibling, mapping);
+
+ String virtualDataCenterInstance = values.get("virtual-data-center").iterator().next();
+
+ // Method under test
+ values = instanceReader.getValues(virtualDataCenterInstance, mapping);
+
+ String logicalLinkInstance = values.get("Test LL Model Name").iterator().next();
+
+ // Method under test
+ values = instanceReader.getValues(logicalLinkInstance, mapping);
+
+ assertThat(values.get("generic-vnf").iterator().next(), is(equalTo(expectedGenericVnf)));
+ assertThat(values.get("pserver").iterator().next(), is(equalTo(expectedPserver)));
+ }
+
+ @Test
+ public void testGetValuesRootUnknown() throws Exception {
+ Multimap<String, String> values = instanceReader.getValues(connector, mappingRootUnknown);
+
+ assertThat(values.isEmpty(), is(true));
+ }
+
+ @Test
+ public void testGetValuesRootMissing() throws Exception {
+ thrown.expect(ValidationServiceException.class);
+ thrown.expectMessage("VS-604");
+
+ instanceReader.getValues(connector, mappingRootMissing);
+ }
+
+ @Test
+ public void testGetInstanceTypeNoModelName() throws Exception {
+ String instanceType = instanceReader.getInstanceType(connector);
+ assertThat(instanceType, is("connector"));
+ }
+
+ @Test
+ public void testGetModelName() throws Exception {
+ String instanceType = instanceReader.getModelName(connectorModelName);
+ assertThat(instanceType, is("Test Connector Model Name"));
+ }
+
+ @Test
+ public void testGetInstanceIdNoModelName() throws Exception {
+ String instanceId = instanceReader.getInstanceId(connector);
+ assertThat(instanceId, is("c7611ebe-c324-48f1-8085-94aef0c12fd"));
+ }
+
+ @Test
+ public void testGetInstanceIdModelName() throws Exception {
+ String instanceId = instanceReader.getInstanceId(connectorModelName);
+ assertThat(instanceId, is("c7611ebe-c324-48f1-8085-94aef0c12fd"));
+ }
+
+ @Test
+ public void testGetResourceVersion() throws Exception {
+ String resourceVersion = instanceReader.getResourceVersion(connector);
+
+ assertThat(resourceVersion, is("1467975776"));
+ }
+
+ private static ModelInstanceMapper getMapping(String mappingFileName) throws Exception {
+ JSONArray jsonArray = new JSONArray(TestUtil.getFileAsString(mappingFileName));
+ JSONObject jsonObject = jsonArray.getJSONObject(0);
+
+ return JsonUtil.fromJson(jsonObject.toString(), ModelInstanceMapper.class);
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/modeldriven/validator/TestModelDrivenValidator.java b/src/test/java/org/onap/aai/validation/modeldriven/validator/TestModelDrivenValidator.java
new file mode 100644
index 0000000..cb9de43
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/modeldriven/validator/TestModelDrivenValidator.java
@@ -0,0 +1,291 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.modeldriven.validator;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
+import static org.junit.Assert.assertThat;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.inject.Inject;
+import org.dom4j.Element;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.onap.aai.validation.controller.ValidationController;
+import org.onap.aai.validation.modeldriven.ModelCacheManager;
+import org.onap.aai.validation.modeldriven.ModelId;
+import org.onap.aai.validation.modeldriven.parser.XMLModelParser;
+import org.onap.aai.validation.modeldriven.validator.ModelDrivenValidator;
+import org.onap.aai.validation.result.ValidationResult;
+import org.onap.aai.validation.result.Violation;
+import org.onap.aai.validation.test.util.TestUtil;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@TestPropertySource(properties = {"schemaIngestPropLoc = src/test/resources/oxm-reader/schemaIngest.properties"})
+@ContextConfiguration(locations = {"classpath:model-validation/instance-validator/test-validation-service-beans.xml"})
+public class TestModelDrivenValidator {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ private static final String RESOURCE_VERSION = "1467975776";
+ private static final String MODEL_ID_ATTRIBUTE_MNV = "model-name-version-id";
+ private static final String MODEL_ID_ATTRIBUTE_MID = "model-id";
+
+ @Mock
+ private ModelCacheManager mockModelCacheManager;
+
+ @InjectMocks
+ @Inject
+ private ModelDrivenValidator modelDrivenValidator;
+
+ private String objectInstance;
+ private String connectorModel;
+
+ enum INSTANCE_VALIDATION_FILE {
+ // @formatter:off
+ CONNECTOR_MODEL ("model-validation/instance-validator/connector-widget-id.xml"),
+ NO_MODEL_ID ("model-validation/instance-validator/connector-instance-no-model-id.json"),
+ UNKNOWN_MODEL_ID ("model-validation/instance-validator/connector-instance-unknown-model-id.json"),
+ ERRORS ("model-validation/instance-validator/connector-instance-errors.json"),
+ MULTIPLE_MISSING_ATTRS ("model-validation/instance-validator/connector-instance-multiple-missing-attrs.json"),
+ MULTIPLE_UNEXPECTED_ATTRS ("model-validation/instance-validator/connector-instance-multiple-unexpected-attrs.json"),
+ SUCCESS ("model-validation/instance-validator/connector-instance-success.json");
+ // @formatter:on
+
+ private String filename;
+
+ INSTANCE_VALIDATION_FILE(String filename) {
+ this.filename = filename;
+ }
+
+ public String getFilename() {
+ return this.filename;
+ }
+ }
+
+ @Before
+ public void initMocks() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ connectorModel = TestUtil.getFileAsString(INSTANCE_VALIDATION_FILE.CONNECTOR_MODEL.getFilename());
+ }
+
+ @Test
+ public void testValidateInstanceWithoutModelId() throws Exception {
+ objectInstance = TestUtil.getFileAsString(INSTANCE_VALIDATION_FILE.NO_MODEL_ID.getFilename());
+
+ ValidationResult validationResult = modelDrivenValidator.validate(objectInstance).get(0);
+ assertThatValidationResultIsValid(validationResult, "c7611ebe-c324-48f1-8085-94aef0c12fd", "connector",
+ "1467975776");
+
+ Violation violation = validationResult.getViolations().get(0);
+ Map<String, Object> details = new HashMap<>();
+ details.put("No model ID", null);
+ assertThatViolationIsValid(violation, ValidationController.VALIDATION_ERROR_SEVERITY, details,
+ "The model [null] could not be found", RESOURCE_VERSION);
+ }
+
+ @Test
+ public void testValidateInstanceWithUnknownModelId() throws Exception {
+ objectInstance = TestUtil.getFileAsString(INSTANCE_VALIDATION_FILE.UNKNOWN_MODEL_ID.getFilename());
+
+ Mockito.when(mockModelCacheManager.get(new ModelId(MODEL_ID_ATTRIBUTE_MID, "UNKNOWN-MODEL"))).thenReturn(null);
+
+ ValidationResult validationResult = modelDrivenValidator.validate(objectInstance).get(0);
+ assertThatValidationResultIsValid(validationResult, "c7611ebe-c324-48f1-8085-94aef0c12fd", "connector",
+ "1467975776");
+
+ Violation violation = validationResult.getViolations().get(0);
+ Map<String, Object> details = new HashMap<>();
+ details.put("No model ID", "UNKNOWN-MODEL");
+ assertThatViolationIsValid(violation, ValidationController.VALIDATION_ERROR_SEVERITY, details,
+ "The model [UNKNOWN-MODEL] could not be found", RESOURCE_VERSION);
+ }
+
+ @Test
+ public void testValidate() throws Exception {
+ objectInstance = TestUtil.getFileAsString(INSTANCE_VALIDATION_FILE.ERRORS.getFilename());
+
+ Element modelElement = XMLModelParser.parse(connectorModel, true);
+
+ Mockito.when(mockModelCacheManager.get(new ModelId(MODEL_ID_ATTRIBUTE_MID, "connector-widget-id")))
+ .thenReturn(modelElement);
+ Mockito.when(mockModelCacheManager
+ .get(new ModelId(MODEL_ID_ATTRIBUTE_MNV, "l2-bridge-for-wan-connector-resource-id"))).thenReturn(null);
+
+ ValidationResult validationResult = modelDrivenValidator.validate(objectInstance).get(0);
+ assertThatValidationResultIsValid(validationResult, "c7611ebe-c324-48f1-8085-94aef0c12fd", "connector",
+ "1467975776");
+
+ List<Violation> violations = validationResult.getViolations();
+
+ assertThat(violations, hasSize(3));
+ assertThat(getCategories(violations),
+ containsInAnyOrder(Arrays.asList("MISSING_ATTR", "UNEXPECTED_ATTR", "UNEXPECTED_REL").toArray()));
+
+ Violation violation = getValidationByCategory(violations, "MISSING_ATTR").get(0);
+ Map<String, Object> details = new HashMap<>();
+ details.put("MISSING ATTR", "product");
+ assertThatViolationIsValid(violation, ValidationController.VALIDATION_ERROR_SEVERITY, details,
+ "Attribute [product] is missing in the object instance", RESOURCE_VERSION);
+
+ violation = getValidationByCategory(violations, "UNEXPECTED_ATTR").get(0);
+ details = new HashMap<>();
+ details.put("UNEXPECTED ATTR", "unexpected");
+ assertThatViolationIsValid(violation, ValidationController.VALIDATION_ERROR_SEVERITY, details,
+ "Attribute [unexpected] should not be present in the object instance", RESOURCE_VERSION);
+
+ violation = getValidationByCategory(violations, "UNEXPECTED_REL").get(0);
+ details = new HashMap<>();
+ Map<String, Object> entityIdmap = new HashMap<>();
+ entityIdmap.put("vdc-id", "vdc-01");
+ details.put("entityId", entityIdmap);
+ details.put("modelName", null);
+ details.put("entityType", "virtual-data-center");
+ details.put("UNEXPECTED REL", "logical-link");
+ assertThatViolationIsValid(violation, ValidationController.VALIDATION_ERROR_SEVERITY, details,
+ "Entity [vdc-id=vdc-01] of type [virtual-data-center] must not be related to [logical-link]",
+ RESOURCE_VERSION);
+ }
+
+ @Test
+ public void testValidateMultipleMissingAttrs() throws Exception {
+ objectInstance = TestUtil.getFileAsString(INSTANCE_VALIDATION_FILE.MULTIPLE_MISSING_ATTRS.getFilename());
+
+ Element modelElement = XMLModelParser.parse(connectorModel, true);
+
+ Mockito.when(mockModelCacheManager.get(new ModelId(MODEL_ID_ATTRIBUTE_MID, "connector-widget-id")))
+ .thenReturn(modelElement);
+ Mockito.when(mockModelCacheManager
+ .get(new ModelId(MODEL_ID_ATTRIBUTE_MNV, "l2-bridge-for-wan-connector-resource-id"))).thenReturn(null);
+
+ List<Violation> violations = modelDrivenValidator.validate(objectInstance).get(0).getViolations();
+
+ assertThat(violations, hasSize(2));
+ assertThat(getCategories(violations),
+ containsInAnyOrder(Arrays.asList("MISSING_ATTR", "MISSING_ATTR").toArray()));
+
+ List<Violation> missingAttrValidations = getValidationByCategory(violations, "MISSING_ATTR");
+ String detailsAsString = getDetails(missingAttrValidations).toString();
+ assertThat(detailsAsString, containsString("{MISSING ATTR=product}"));
+ assertThat(detailsAsString, containsString("{MISSING ATTR=vpn-id}"));
+ }
+
+ @Test
+ public void testValidateMultipleUnexpectedAttrs() throws Exception {
+ objectInstance = TestUtil.getFileAsString(INSTANCE_VALIDATION_FILE.MULTIPLE_UNEXPECTED_ATTRS.getFilename());
+
+ Element modelElement = XMLModelParser.parse(connectorModel, true);
+
+ Mockito.when(mockModelCacheManager.get(new ModelId(MODEL_ID_ATTRIBUTE_MID, "connector-widget-id")))
+ .thenReturn(modelElement);
+ Mockito.when(mockModelCacheManager
+ .get(new ModelId(MODEL_ID_ATTRIBUTE_MNV, "l2-bridge-for-wan-connector-resource-id"))).thenReturn(null);
+
+ List<Violation> violations = modelDrivenValidator.validate(objectInstance).get(0).getViolations();
+
+ assertThat(violations, hasSize(2));
+ assertThat(getCategories(violations),
+ containsInAnyOrder(Arrays.asList("UNEXPECTED_ATTR", "UNEXPECTED_ATTR").toArray()));
+
+ List<Violation> missingAttrViolations = getValidationByCategory(violations, "UNEXPECTED_ATTR");
+ String detailsAsString = getDetails(missingAttrViolations).toString();
+ assertThat(detailsAsString, containsString("{UNEXPECTED ATTR=city}"));
+ assertThat(detailsAsString, containsString("{UNEXPECTED ATTR=state}"));
+ }
+
+ @Test
+ public void testValidateSuccess() throws Exception {
+ objectInstance = TestUtil.getFileAsString(INSTANCE_VALIDATION_FILE.SUCCESS.getFilename());
+
+ Element modelElement = XMLModelParser.parse(connectorModel, true);
+
+ Mockito.when(mockModelCacheManager.get(new ModelId(MODEL_ID_ATTRIBUTE_MID, "connector-widget-id")))
+ .thenReturn(modelElement);
+ Mockito.when(mockModelCacheManager
+ .get(new ModelId(MODEL_ID_ATTRIBUTE_MNV, "l2-bridge-for-wan-connector-resource-id"))).thenReturn(null);
+
+ List<Violation> violations = modelDrivenValidator.validate(objectInstance).get(0).getViolations();
+
+ assertThat(violations, is(empty()));
+ }
+
+ private void assertThatValidationResultIsValid(ValidationResult validationResult, String entityInstanceId,
+ String entityType, String resourceVersion) {
+ assertThat(
+ validationResult.getEntityId().getAsJsonObject().entrySet().iterator().next().getValue().getAsString(),
+ is(equalTo(entityInstanceId)));
+ assertThat(validationResult.getEntityType(), is(equalTo(entityType)));
+ assertThat(validationResult.getResourceVersion(), is(equalTo(resourceVersion)));
+ }
+
+ private void assertThatViolationIsValid(Violation violation, String severity, Map<String, Object> violationDetails,
+ String errorMessage, String resourceVersion) {
+ assertThat(violation.getSeverity(), is(equalTo(severity)));
+ assertThat(violation.getViolationType(), is(equalTo("Model")));
+ assertThat(violation.getViolationDetails(), is(equalTo(violationDetails)));
+ assertThat(violation.getErrorMessage(), is(equalTo(errorMessage)));
+ }
+
+ private List<String> getCategories(List<Violation> validations) {
+ List<String> categories = new ArrayList<>();
+ for (Violation validation : validations) {
+ categories.add(validation.getCategory());
+ }
+ return categories;
+ }
+
+ private List<Map<String, Object>> getDetails(List<Violation> validations) {
+ List<Map<String, Object>> details = new ArrayList<>();
+ for (Violation validation : validations) {
+ details.add(validation.getViolationDetails());
+ }
+ return details;
+ }
+
+ private List<Violation> getValidationByCategory(List<Violation> validations, String category) {
+ List<Violation> validationsByCategory = new ArrayList<>();
+ for (Violation validation : validations) {
+ if (category.equals(validation.getCategory())) {
+ validationsByCategory.add(validation);
+ }
+ }
+ return validationsByCategory;
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/modeldriven/validator/TestModelReader.java b/src/test/java/org/onap/aai/validation/modeldriven/validator/TestModelReader.java
new file mode 100644
index 0000000..d974ca2
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/modeldriven/validator/TestModelReader.java
@@ -0,0 +1,261 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.modeldriven.validator;
+
+import static org.hamcrest.Matchers.arrayContainingInAnyOrder;
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+import com.google.common.collect.Multimap;
+import java.io.File;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map.Entry;
+import javax.inject.Inject;
+import org.dom4j.Element;
+import org.dom4j.Node;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.aai.validation.exception.ValidationServiceException;
+import org.onap.aai.validation.modeldriven.ModelCacheManager;
+import org.onap.aai.validation.modeldriven.configuration.mapping.ModelInstanceMapper;
+import org.onap.aai.validation.modeldriven.parser.XMLModelParser;
+import org.onap.aai.validation.modeldriven.validator.ModelReader;
+import org.onap.aai.validation.test.util.TestUtil;
+import org.onap.aai.validation.util.JsonUtil;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:model-validation/model-reader/test-validation-service-beans.xml"})
+public class TestModelReader {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ private Element modelElement;
+ private ModelInstanceMapper mapping;
+
+ @Inject
+ private ModelCacheManager cache;
+
+ @Test
+ public void testGetValues() throws Exception {
+ mapping = getMapping("model-validation/model-reader/model-instance-mapping-attributes-1.json");
+ modelElement = XMLModelParser
+ .parse(new File("src/test/resources/model-validation/model-reader/connector-widget-id.xml"), false);
+
+ Multimap<String, Node> values = ModelReader.getValues(modelElement, mapping, cache);
+
+ assertThat(values.entries().size(), is(2));
+ assertThat(values.containsEntry("product", null), is(true));
+ assertThat(values.containsEntry("vpn-id", null), is(true));
+ }
+
+ /**
+ * @throws Exception
+ */
+ @Test(expected = ValidationServiceException.class)
+ public void testGetValuesWithUnknownPath() throws Exception {
+ mapping = getMapping("model-validation/model-reader/model-instance-mapping-attributes-2.json");
+ modelElement = XMLModelParser
+ .parse(new File("src/test/resources/model-validation/model-reader/connector-widget-id.xml"), false);
+
+ ModelReader.getValues(modelElement, mapping, cache);
+ }
+
+ @Test
+ public void testGetValuesSingleModel() throws Exception {
+ mapping = getMapping("model-validation/model-reader/model-instance-mapping-relationships.json");
+ modelElement = XMLModelParser
+ .parse(new File("src/test/resources/model-validation/model-reader/connector-widget-id.xml"), false);
+
+ List<Node> expectedModels = XMLModelParser.getObjectsFromXPath(modelElement, mapping.getModel().getRoot());
+
+ Multimap<String, Node> values = ModelReader.getValues(modelElement, mapping, cache);
+
+ Collection<Entry<String, Node>> entries = values.entries();
+ assertThat(entries.size(), is(1));
+ assertThat(values.containsEntry("virtual-data-center", expectedModels.get(0)), is(true));
+ }
+
+ @Test
+ public void testGetValuesMultipleModels() throws Exception {
+ mapping = getMapping("model-validation/model-reader/model-instance-mapping-relationships.json");
+ modelElement = XMLModelParser
+ .parse(new File("src/test/resources/model-validation/model-reader/logical-link-widget-id.xml"), false);
+
+ Multimap<String, Node> values = ModelReader.getValues(modelElement, mapping, cache);
+
+ assertThat(values.keys().toArray(new String[] {}), arrayContainingInAnyOrder(new String[] {"logical-link",}));
+
+ values = ModelReader.getValues(values.values().iterator().next(), mapping, cache);
+
+ assertThat(values.keys().toArray(new String[] {}),
+ arrayContainingInAnyOrder(new String[] {"pBgf", "vDbe", "ipe", "vSbg",}));
+ }
+
+ @Test
+ public void testGetValuesCurrentModelNoChildrenNoValues() throws Exception {
+ mapping = getMapping("model-validation/model-reader/model-instance-mapping-relationships.json");
+ modelElement = XMLModelParser.parse(
+ new File("src/test/resources/model-validation/model-reader/connector-widget-id-no-children-1.xml"),
+ false);
+
+ Multimap<String, Node> values = ModelReader.getValues(modelElement, mapping, cache);
+
+ assertThat(values.isEmpty(), is(true));
+ }
+
+ @Test
+ public void testGetValuesCurrentModelNoChildrenWithValues() throws Exception {
+ mapping = getMapping("model-validation/model-reader/model-instance-mapping-relationships.json");
+ modelElement = XMLModelParser.parse(
+ new File("src/test/resources/model-validation/model-reader/connector-widget-id-no-children-2.xml"),
+ false);
+
+ Multimap<String, Node> parentValues = ModelReader.getValues(modelElement, mapping, cache);
+
+ Multimap<String, Node> childValues =
+ ModelReader.getValues(parentValues.entries().iterator().next().getValue(), mapping, cache);
+
+ assertThat(childValues.isEmpty(), is(true));
+ }
+
+ @Test
+ public void testResourceModelType() throws Exception {
+ mapping = getMapping("model-validation/model-reader/model-instance-mapping-relationships.json");
+ modelElement = XMLModelParser.parse(
+ new File("src/test/resources/model-validation/model-reader/virtual-data-center-widget-id.xml"), false);
+
+ Multimap<String, Node> values = ModelReader.getValues(modelElement, mapping, cache);
+
+ assertThat(values.keys().toArray(new String[] {}),
+ arrayContainingInAnyOrder(new String[] {"l2-bridge-for-wan-connector",}));
+ }
+
+ @Test
+ public void testRootWithInvalidPath() throws Exception {
+ mapping = getMapping("model-validation/model-reader/model-instance-mapping-relationships-root-1.json");
+ modelElement = XMLModelParser.parse(
+ new File("src/test/resources/model-validation/model-reader/virtual-data-center-widget-id.xml"), false);
+
+ Multimap<String, Node> values = ModelReader.getValues(modelElement, mapping, cache);
+
+ assertThat(values.entries(), is(empty()));
+ }
+
+ @Test
+ public void testRootMissing() throws Exception {
+ mapping = getMapping("model-validation/model-reader/model-instance-mapping-relationships-root-2.json");
+ modelElement = XMLModelParser.parse(
+ new File("src/test/resources/model-validation/model-reader/virtual-data-center-widget-id.xml"), false);
+
+ Multimap<String, Node> values = ModelReader.getValues(modelElement, mapping, cache);
+ assertThat(values.entries(), is(empty()));
+ }
+
+ @Test
+ public void testFilterWithInvalidType() throws Exception {
+ mapping = getMapping("model-validation/model-reader/model-instance-mapping-relationships-filter-1.json");
+ modelElement = XMLModelParser
+ .parse(new File("src/test/resources/model-validation/model-reader/connector-widget-id.xml"), false);
+
+ Multimap<String, Node> values = ModelReader.getValues(modelElement, mapping, cache);
+
+ assertThat(values.entries(), is(empty()));
+ }
+
+ @Test
+ public void testFilterWithEmptyArray() throws Exception {
+ mapping = getMapping("model-validation/model-reader/model-instance-mapping-relationships-filter-2.json");
+ modelElement = XMLModelParser.parse(
+ new File("src/test/resources/model-validation/model-reader/virtual-data-center-widget-id.xml"), false);
+
+ Multimap<String, Node> values = ModelReader.getValues(modelElement, mapping, cache);
+
+ assertThat(values.entries(), is(empty()));
+ }
+
+ @Test
+ public void testFilterWithMissingValidProperty() throws Exception {
+ mapping = getMapping("model-validation/model-reader/model-instance-mapping-relationships-filter-3.json");
+ modelElement = XMLModelParser.parse(
+ new File("src/test/resources/model-validation/model-reader/virtual-data-center-widget-id.xml"), false);
+
+ Multimap<String, Node> values = ModelReader.getValues(modelElement, mapping, cache);
+
+ assertThat(values.entries(), is(empty()));
+ }
+
+ @Test
+ public void testFilterWithInvalidPath() throws Exception {
+ mapping = getMapping("model-validation/model-reader/model-instance-mapping-relationships-filter-4.json");
+ modelElement = XMLModelParser.parse(
+ new File("src/test/resources/model-validation/model-reader/virtual-data-center-widget-id.xml"), false);
+
+ Multimap<String, Node> values = ModelReader.getValues(modelElement, mapping, cache);
+
+ assertThat(values.entries(), is(empty()));
+ }
+
+ @Test
+ public void testFilterWithMissingPath() throws Exception {
+ mapping = getMapping("model-validation/model-reader/model-instance-mapping-relationships-filter-5.json");
+ modelElement = XMLModelParser.parse(
+ new File("src/test/resources/model-validation/model-reader/virtual-data-center-widget-id.xml"), false);
+
+ Multimap<String, Node> values = ModelReader.getValues(modelElement, mapping, cache);
+
+ assertThat(values.entries(), is(empty()));
+ }
+
+ @Test
+ public void testFilterMissing() throws Exception {
+ mapping = getMapping("model-validation/model-reader/model-instance-mapping-relationships-filter-6.json");
+ modelElement = XMLModelParser.parse(
+ new File("src/test/resources/model-validation/model-reader/virtual-data-center-widget-id.xml"), false);
+
+ Multimap<String, Node> values = ModelReader.getValues(modelElement, mapping, cache);
+
+ assertThat(values.keys().toArray(new String[] {}),
+ arrayContainingInAnyOrder(new String[] {"l2-bridge-for-wan-connector"}));
+ }
+
+ @Test
+ public void testGetValuesWithMultipleModelFetch() throws Exception {
+ mapping = getMapping("model-validation/model-reader/model-instance-mapping-relationships-with-id.json");
+ modelElement = XMLModelParser
+ .parse(new File("src/test/resources/model-validation/model-reader/connector-widget-id.xml"), false);
+
+ Multimap<String, Node> values = ModelReader.getValues(modelElement, mapping, cache);
+
+ assertThat(values.entries(), is(empty()));
+ }
+
+ private ModelInstanceMapper getMapping(String mappingFileName) throws Exception {
+ JSONArray jsonArray = new JSONArray(TestUtil.getFileAsString(mappingFileName));
+ JSONObject jsonObject = jsonArray.getJSONObject(0);
+
+ return JsonUtil.fromJson(jsonObject.toString(), ModelInstanceMapper.class);
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/publisher/MockEventPublisher.java b/src/test/java/org/onap/aai/validation/publisher/MockEventPublisher.java
new file mode 100644
index 0000000..d1cfae0
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/publisher/MockEventPublisher.java
@@ -0,0 +1,72 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.publisher;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.Collection;
+import org.onap.aai.validation.exception.ValidationServiceException;
+import org.onap.aai.validation.publisher.MessagePublisher;
+import org.onap.aai.validation.result.ValidationResult;
+import org.onap.aai.validation.test.util.TestEntity;
+import org.onap.aai.validation.test.util.ValidationResultIsEqual;
+
+/**
+ * Will be injected by Spring
+ *
+ */
+public class MockEventPublisher implements MessagePublisher {
+
+ private ValidationResult expectedValidationResult;
+ private String testDescription;
+ private boolean publishedMessage;
+
+ public MockEventPublisher() {
+ // Deliberately empty - no configuration needed
+ }
+
+ public void setTestEntity(TestEntity entity) throws URISyntaxException, IOException {
+ this.expectedValidationResult = entity.getExpectedValidationResult();
+ this.publishedMessage = false;
+ }
+
+ public void setTestDescription(String testDescription) {
+ this.testDescription = testDescription;
+ }
+
+ @Override
+ public void publishMessage(String message) throws ValidationServiceException {
+ ValidationResult validationResult = ValidationResult.fromJson(message);
+ assertThat(testDescription, validationResult, is(ValidationResultIsEqual.equalTo(expectedValidationResult)));
+ publishedMessage = true;
+ }
+
+ @Override
+ public void publishMessages(Collection<String> messages) throws ValidationServiceException {
+ for (String message : messages) {
+ publishMessage(message);
+ }
+ }
+
+ public boolean processedSuccessfully() {
+ return publishedMessage || expectedValidationResult == null;
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/publisher/TestValidationEventPublisher.java b/src/test/java/org/onap/aai/validation/publisher/TestValidationEventPublisher.java
new file mode 100644
index 0000000..8950e63
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/publisher/TestValidationEventPublisher.java
@@ -0,0 +1,102 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.publisher;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.onap.aai.event.client.DMaaPEventPublisher;
+import org.onap.aai.validation.config.TopicAdminConfig;
+import org.onap.aai.validation.config.TopicConfig;
+import org.onap.aai.validation.config.TopicConfig.Topic;
+import org.onap.aai.validation.factory.DMaaPEventPublisherFactory;
+import org.onap.aai.validation.publisher.ValidationEventPublisher;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class TestValidationEventPublisher {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ System.setProperty("consumer.topic.names", "poa-rule-validation");
+ System.setProperty("publisher.topic.names", "poa-audit-result");
+ }
+
+ private DMaaPEventPublisher mockEventPublisher;
+ private ValidationEventPublisher validationEventPublisher;
+ private List<Topic> topicList = new ArrayList<>();
+
+ @Before
+ public void setUp() throws Exception {
+ TopicConfig mockTopicConfig = Mockito.mock(TopicConfig.class);
+ TopicAdminConfig mockTopicAdminConfig = Mockito.mock(TopicAdminConfig.class);
+ when(mockTopicAdminConfig.isPublishEnable()).thenReturn(true);
+
+ Topic topic1 = new TopicConfig("poa-rule-validation","poa-audit-result").new Topic();
+ topic1.setName("aai-data-integrity");
+ topic1.setHost("integrity-dummy-host");
+ topic1.setPartition("integrity-dummy-partition");
+ topic1.setUsername("integrity-dummy-username");
+ topic1.setPassword("integrity-dummy-password");
+ topic1.setTransportType("integrity-dummy-transport-type");
+ topicList.add(topic1);
+
+ when(mockTopicConfig.getPublisherTopics()).thenReturn(topicList);
+ validationEventPublisher = new ValidationEventPublisher(mockTopicConfig, mockTopicAdminConfig);
+
+ mockEventPublisher = Mockito.mock(DMaaPEventPublisher.class);
+ when(mockEventPublisher.closeWithUnsent()).thenReturn(new ArrayList<>());
+
+ DMaaPEventPublisherFactory mockEventPublisherFactory = Mockito.mock(DMaaPEventPublisherFactory.class);
+ when(mockEventPublisherFactory.createEventPublisher(any(), any(), any(), any(), any()))
+ .thenReturn(mockEventPublisher);
+
+ validationEventPublisher.setEventPublisherFactory(mockEventPublisherFactory);
+ }
+
+ @Test
+ public void testPublishMessages() throws Exception {
+ Collection<String> messages = new ArrayList<>();
+ messages.add("first test message");
+ messages.add("second test message");
+ when(mockEventPublisher.sendSync(any(String.class), Mockito.<Collection<String>>any())).thenReturn(2);
+
+ validationEventPublisher.publishMessages(messages);
+ verify(mockEventPublisher, times(1)).sendSync(topicList.get(0).getPartition(), messages);
+ }
+
+ @Test
+ public void testPublishMessage() throws Exception {
+ Collection<String> messages = new ArrayList<>();
+ messages.add("first test message");
+ when(mockEventPublisher.sendSync(any(String.class), Mockito.<Collection<String>>any())).thenReturn(1);
+
+ validationEventPublisher.publishMessage(messages.iterator().next());
+ verify(mockEventPublisher, times(1)).sendSync(topicList.get(0).getPartition(), messages);
+ }
+
+}
diff --git a/src/test/java/org/onap/aai/validation/reader/TestEventReader.java b/src/test/java/org/onap/aai/validation/reader/TestEventReader.java
new file mode 100644
index 0000000..a41eb76
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/reader/TestEventReader.java
@@ -0,0 +1,270 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.reader;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import javax.inject.Inject;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.aai.validation.exception.ValidationServiceException;
+import org.onap.aai.validation.reader.EventReader;
+import org.onap.aai.validation.reader.data.Entity;
+import org.onap.aai.validation.reader.data.EntityId;
+import org.onap.aai.validation.test.util.TestUtil;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@TestPropertySource(properties = {"schemaIngestPropLoc = src/test/resources/oxm-reader/schemaIngest.properties"})
+@ContextConfiguration(locations = {"classpath:event-reader/test-validation-service-beans.xml"})
+public class TestEventReader {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ @Inject
+ private EventReader eventReader;
+
+ private static String vserverEvent;
+ private static String genericVnfEvent;
+ private static String invalidEvent1;
+ private static String invalidEvent2;
+ private static String invalidEvent3;
+ private static String invalidEvent4;
+ private static String invalidEvent5;
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ vserverEvent = TestUtil.getFileAsString(TestData.VSERVER.getFilename());
+ genericVnfEvent = TestUtil.getFileAsString(TestData.GENERIC_VNF.getFilename());
+ invalidEvent1 = TestUtil.getFileAsString(TestData.INVALID_1.getFilename());
+ invalidEvent2 = TestUtil.getFileAsString(TestData.INVALID_2.getFilename());
+ invalidEvent3 = TestUtil.getFileAsString(TestData.INVALID_3.getFilename());
+ invalidEvent4 = TestUtil.getFileAsString(TestData.INVALID_4.getFilename());
+ invalidEvent5 = TestUtil.getFileAsString(TestData.INVALID_5.getFilename());
+ }
+
+ enum TestData {
+ // @formatter:off
+ VSERVER ("event-reader/vserver-create-event.json"),
+ GENERIC_VNF ("event-reader/generic-vnf-create-event.json"),
+ INVALID_1 ("event-reader/invalid-event-1.json"),
+ INVALID_2 ("event-reader/invalid-event-2.json"),
+ INVALID_3 ("event-reader/invalid-event-3.json"),
+ INVALID_4 ("event-reader/invalid-event-4.json"),
+ INVALID_5 ("event-reader/invalid-event-5.json");
+
+ private String filename;
+ TestData(String filename) {this.filename = filename;}
+ public String getFilename() {return this.filename;}
+ // @formatter:on
+ }
+
+ @Test
+ public void testGetEventDomain() throws Exception {
+ Optional<String> eventType = eventReader.getEventDomain(vserverEvent);
+
+ assertThat(eventType.get(), is("devINT1"));
+ }
+
+ @Test
+ public void testGetEventAction() throws Exception {
+ Optional<String> action = eventReader.getEventAction(vserverEvent);
+
+ assertThat(action.get(), is("CREATE"));
+ }
+
+ @Test
+ public void testGetEventType() throws Exception {
+ Optional<String> eventType = eventReader.getEventType(vserverEvent);
+
+ assertThat(eventType.isPresent(), is(true));
+ assertThat(eventType.get(), is("AAI-EVENT"));
+ }
+
+ @Test(expected = ValidationServiceException.class)
+ public void testGetEventTypeMalformedJson() throws Exception {
+ eventReader.getEventType("this is malformed");
+ }
+
+ @Test
+ public void testGetEventTypeFromUnrecognisableEvent() throws Exception {
+ Optional<String> eventType = eventReader.getEventType("this-is-not-an-event-but-is-valid-json");
+
+ assertThat(eventType.isPresent(), is(false));
+ }
+
+ @Test
+ public void testGetEventTypeThatIsMissing() throws Exception {
+ Optional<String> eventType = eventReader.getEventType(invalidEvent1);
+
+ assertThat(eventType.isPresent(), is(false));
+ }
+
+ @Test
+ public void testGetEntityType() throws Exception {
+ Optional<String> entityType = eventReader.getEntityType(vserverEvent);
+
+ assertThat(entityType.get(), is("vserver"));
+ }
+
+ @Test
+ public void testGetEntity() throws Exception {
+ Entity entity = eventReader.getEntity(genericVnfEvent);
+
+ assertThat(entity.getType(), is("generic-vnf"));
+
+ // Dig deeper to check we have the object we want
+ JsonParser parser = new JsonParser();
+ JsonElement jsonElement = parser.parse(entity.getJson());
+ String id = jsonElement.getAsJsonObject().get("vnf-id").getAsString();
+
+ assertThat(id, is("VAPP-1581"));
+ }
+
+ @Test
+ public void testEntityLink() throws Exception {
+ Entity entity = eventReader.getEntity(vserverEvent);
+
+ assertThat(entity.getEntityLink(), is(
+ "cloud-infrastructure/cloud-regions/cloud-region/region1/AAIregion1/tenants/tenant/example-tenant-id-val-88551/vservers/vserver/example-vserver-id-val-34666"));
+ }
+
+ @Test(expected = ValidationServiceException.class)
+ public void testGetEntityWithMissingEntityType() throws Exception {
+ eventReader.getEntity(invalidEvent1);
+ }
+
+ @Test(expected = ValidationServiceException.class)
+ public void testGetEntityWithUnknownEntityType() throws Exception {
+ eventReader.getEntity(invalidEvent2);
+ }
+
+ @Test
+ public void testGetNestedEntity() throws Exception {
+ Entity entity = eventReader.getEntity(vserverEvent);
+
+ assertThat(entity.getType(), is("vserver"));
+
+ // Dig deeper to check we have the object we want
+ JsonParser parser = new JsonParser();
+ JsonElement jsonElement = parser.parse(entity.getJson());
+ String id = jsonElement.getAsJsonObject().get("vserver-id").getAsString();
+
+ assertThat(id, is("example-vserver-id-val-34666"));
+ }
+
+ @Test(expected = ValidationServiceException.class)
+ public void testTooManyNestedEntitiesThrowsException() throws Exception {
+ eventReader.getEntity(invalidEvent4);
+ }
+
+ @Test
+ public void testGetEntityIds() throws Exception {
+ Entity entity = eventReader.getEntity(vserverEvent);
+
+ List<EntityId> ids = entity.getIds();
+
+ assertThat(ids, hasSize(1));
+ EntityId entityId = ids.get(0);
+
+ assertThat(entityId.getPrimaryKey(), is("vserver-id"));
+ assertThat(entityId.getValue(), is("example-vserver-id-val-34666"));
+ }
+
+ @Test
+ public void testCompareEntityIds() throws Exception {
+ EntityId entityId = new EntityId();
+ assertThat(entityId, is(not(equalTo(null))));
+
+ entityId.setPrimaryKey("key");
+ assertThat(entityId, is(not(equalTo(null))));
+ entityId.setValue("value");
+ assertThat(entityId, is(not(equalTo(null))));
+
+ EntityId other = new EntityId();
+ assertThat(entityId, is(not(equalTo(other))));
+
+ other.setPrimaryKey("key");
+ assertThat(entityId, is(not(equalTo(other))));
+
+ other.setValue("value");
+ assertThat(entityId, is(equalTo(other)));
+
+ // Force call to hashCode()
+ assertThat(entityId.hashCode(), is(equalTo(other.hashCode())));
+ }
+
+ @Test
+ public void testGetEntityIdsForUnknownEntityType() throws Exception {
+ Entity entity = eventReader.getEntity(invalidEvent3);
+
+ List<EntityId> ids = entity.getIds();
+
+ assertThat(ids, is(empty()));
+ }
+
+ @Test
+ public void testGetResourceVersion() throws Exception {
+ Entity entity = eventReader.getEntity(vserverEvent);
+
+ Optional<String> resourceVersion = entity.getResourceVersion();
+
+ assertThat(resourceVersion.isPresent(), is(true));
+ assertThat(resourceVersion.get(), is("1464193654"));
+ }
+
+ @Test
+ public void testGetResourceVersionMissing() throws Exception {
+ Entity entity = eventReader.getEntity(invalidEvent5);
+
+ Optional<String> resourceVersion = entity.getResourceVersion();
+ assertThat(resourceVersion.isPresent(), is(false));
+ }
+
+ @Test
+ public void testGetProperty() throws Exception {
+ Entity entity = eventReader.getEntity(vserverEvent);
+
+ String resourceVersion = (String) entity.getAttributeValues(Arrays.asList("prov-status")).get("prov-status");
+
+ assertThat(resourceVersion, is("PREPROV"));
+ }
+
+ @Test
+ public void testEntityLinkIsStripped() throws Exception {
+ Entity entity = eventReader.getEntity(vserverEvent);
+ String entityLink = entity.getEntityLink();
+ assertThat(entityLink, is(
+ "cloud-infrastructure/cloud-regions/cloud-region/region1/AAIregion1/tenants/tenant/example-tenant-id-val-88551/vservers/vserver/example-vserver-id-val-34666"));
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/reader/TestJsonReader.java b/src/test/java/org/onap/aai/validation/reader/TestJsonReader.java
new file mode 100644
index 0000000..e7a906a
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/reader/TestJsonReader.java
@@ -0,0 +1,95 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.reader;
+
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.util.Arrays;
+import java.util.List;
+import org.junit.Test;
+import org.onap.aai.validation.reader.JsonReader;
+import org.onap.aai.validation.test.util.TestUtil;
+
+public class TestJsonReader {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ enum TestData {
+ // @formatter:off
+ SAMPLE_JSON ("json-reader/sample.json");
+
+ private String filename;
+ TestData(String filename) {this.filename = filename;}
+ public String getFilename() {return this.filename;}
+ // @formatter:on
+ }
+
+ @Test
+ public void testGetString() throws Exception {
+ String json = TestUtil.getFileAsString(TestData.SAMPLE_JSON.getFilename());
+ JsonReader jsonReader = new JsonReader();
+ List<String> result = jsonReader.get(json, "$.event-header.entity-type");
+ assertThat(result.get(0), is("vserver"));
+ }
+
+ @Test
+ public void testGetInteger() throws Exception {
+ String json = TestUtil.getFileAsString(TestData.SAMPLE_JSON.getFilename());
+ JsonReader jsonReader = new JsonReader();
+ List<String> result = jsonReader.get(json, "$.event-header.sample-integer");
+ assertThat(result.get(0), is("1"));
+ }
+
+ @Test
+ public void testGetBoolean() throws Exception {
+ String json = TestUtil.getFileAsString(TestData.SAMPLE_JSON.getFilename());
+ JsonReader jsonReader = new JsonReader();
+ List<String> result = jsonReader.get(json, "$.event-header.sample-boolean");
+ assertThat(result.get(0), is("true"));
+ }
+
+ @Test
+ public void testGetObjectAsString() throws Exception {
+ String json = TestUtil.getFileAsString(TestData.SAMPLE_JSON.getFilename());
+ JsonReader jsonReader = new JsonReader();
+ List<String> result = jsonReader.get(json, "$.event-header.sample-object");
+
+ assertThat(result.get(0), is("{\"property\":\"value\"}"));
+ }
+
+ @Test
+ public void testGetArrayAsString() throws Exception {
+ String json = TestUtil.getFileAsString(TestData.SAMPLE_JSON.getFilename());
+ JsonReader jsonReader = new JsonReader();
+ List<String> result = jsonReader.get(json, "$.event-header.sample-array");
+
+ assertThat(result, is(Arrays.asList("one")));
+ }
+
+ @Test
+ public void testGetWithInvalidPath() throws Exception {
+ String json = TestUtil.getFileAsString(TestData.SAMPLE_JSON.getFilename());
+ JsonReader jsonReader = new JsonReader();
+ List<String> result = jsonReader.get(json, "$.unknown");
+ assertThat(result, empty());
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/reader/TestOxmConfigTranslator.java b/src/test/java/org/onap/aai/validation/reader/TestOxmConfigTranslator.java
new file mode 100644
index 0000000..73e76db
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/reader/TestOxmConfigTranslator.java
@@ -0,0 +1,111 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.reader;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.Matchers.isEmptyString;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertThat;
+
+import java.nio.file.InvalidPathException;
+import java.util.List;
+import java.util.Map;
+import java.util.ServiceConfigurationError;
+import org.junit.Test;
+import org.onap.aai.setup.SchemaLocationsBean;
+import org.onap.aai.setup.Version;
+import org.onap.aai.validation.reader.OxmConfigTranslator;
+import org.springframework.test.util.ReflectionTestUtils;
+
+public class TestOxmConfigTranslator {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ @Test
+ public void testOxmFiles() {
+ OxmConfigTranslator translator = buildConfigTranslator("src/test/resources/oxm-reader/single/");
+ Map<Version, List<String>> latestVersion = translator.getNodeFiles();
+ assertThat(latestVersion.size(), is(3));
+ assertThat(latestVersion.values().iterator().next().size(), is(1));
+ assertThat(latestVersion.values().iterator().next().get(0), not(isEmptyString()));
+ Map<Version, List<String>> latestVersion1 = translator.getEdgeFiles();
+ assertThat(latestVersion1.size(), is(1));
+ assertThat(latestVersion1.values().iterator().next().size(), is(1));
+ assertThat(latestVersion1.values().iterator().next().get(0), not(isEmptyString()));
+ }
+
+ @Test
+ public void testMultipleOxmFilesPerVersion() {
+ OxmConfigTranslator translator = buildConfigTranslator("src/test/resources/oxm-reader/multiple");
+ Map<Version, List<String>> latestVersion = translator.getNodeFiles();
+ assertThat(latestVersion.size(), is(2));
+ assertThat(latestVersion.values().iterator().next().size(), is(2));
+ assertThat(latestVersion.values().iterator().next().get(0), not(isEmptyString()));
+ Map<Version, List<String>> latestVersion1 = translator.getEdgeFiles();
+ assertThat(latestVersion1.size(), is(0));
+ }
+
+ @Test
+ public void testZeroMatchingFiles() {
+ OxmConfigTranslator translator = buildConfigTranslator("src/test/resources/oxm-reader/");
+ Map<Version, List<String>> versionsMap = translator.getNodeFiles();
+ assertThat(versionsMap.size(), is(0));
+ }
+
+ @Test(expected = ServiceConfigurationError.class)
+ public void testNullNodesPath() {
+ buildConfigTranslator(null).getNodeFiles();
+ }
+
+ @Test(expected = ServiceConfigurationError.class)
+ public void testNullEdgesPath() {
+ buildConfigTranslator(null).getEdgeFiles();
+ }
+
+ @Test(expected = ServiceConfigurationError.class)
+ public void testNonExistentNodesPath() {
+ buildConfigTranslator("no-such-folder-exists/").getNodeFiles();
+ }
+
+ @Test(expected = ServiceConfigurationError.class)
+ public void testNonExistentEdgesPath() {
+ SchemaLocationsBean bean = new SchemaLocationsBean();
+ ReflectionTestUtils.setField(bean, "nodeDirectory", "src/test/resources/oxm-reader/");
+ ReflectionTestUtils.setField(bean, "edgeDirectory", "no-such-folder-exists/");
+ new OxmConfigTranslator(bean).getEdgeFiles();
+ }
+
+ @Test(expected = InvalidPathException.class)
+ public void testInvalidPath() {
+ buildConfigTranslator("\0").getEdgeFiles();
+ }
+
+ private OxmConfigTranslator buildConfigTranslator(String path) {
+ return new OxmConfigTranslator(createSchemaLocationsBean(path));
+ }
+
+ private SchemaLocationsBean createSchemaLocationsBean(String path) {
+ SchemaLocationsBean bean = new SchemaLocationsBean();
+ ReflectionTestUtils.setField(bean, "nodeDirectory", path);
+ ReflectionTestUtils.setField(bean, "edgeDirectory", path);
+ return bean;
+ }
+
+}
diff --git a/src/test/java/org/onap/aai/validation/reader/TestOxmReader.java b/src/test/java/org/onap/aai/validation/reader/TestOxmReader.java
new file mode 100644
index 0000000..f7f2643
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/reader/TestOxmReader.java
@@ -0,0 +1,63 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.reader;
+
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.util.List;
+import javax.inject.Inject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.aai.validation.reader.OxmReader;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@TestPropertySource(properties = {"schemaIngestPropLoc = src/test/resources/oxm-reader/schemaIngest.properties"})
+@ContextConfiguration(locations = {"classpath:oxm-reader/oxm-reader-beans.xml"})
+public class TestOxmReader {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ @Inject
+ private OxmReader oxmReader;
+
+ @Test
+ public void testGetPrimaryKeysSingleKey() throws Exception {
+ List<String> primaryKeys = oxmReader.getPrimaryKeys("connector");
+ assertThat(primaryKeys.get(0), is("resource-instance-id"));
+ }
+
+ @Test
+ public void testGetPrimaryKeysMultipleKeys() throws Exception {
+ List<String> primaryKeys = oxmReader.getPrimaryKeys("cloud-region");
+ assertThat(primaryKeys, contains("cloud-owner", "cloud-region-id"));
+ }
+
+ @Test
+ public void testGetPrimaryKeysUnknownObject() throws Exception {
+ List<String> primaryKeys = oxmReader.getPrimaryKeys("most-surely-does-not-exist");
+ assertThat(primaryKeys, empty());
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/request/TestRequestHeaders.java b/src/test/java/org/onap/aai/validation/request/TestRequestHeaders.java
new file mode 100644
index 0000000..b9ff07c
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/request/TestRequestHeaders.java
@@ -0,0 +1,143 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.request;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map.Entry;
+import javax.ws.rs.core.MultivaluedHashMap;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onap.aai.validation.services.RequestHeaders;
+import org.springframework.http.HttpHeaders;
+
+/**
+ * Test the RequestHeaders class.
+ *
+ */
+public class TestRequestHeaders {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ @Test
+ public void testONAPHeaders() {
+ String transactionId = "transaction-id";
+ String serviceInstanceId = "service-instance-id";
+
+ MultivaluedHashMap<String, String> headersMap = new MultivaluedHashMap<>();
+ headersMap.put(RequestHeaders.HEADER_REQUEST_ID, createSingletonList(transactionId));
+ headersMap.put(RequestHeaders.HEADER_SERVICE_INSTANCE_ID, createSingletonList(serviceInstanceId));
+ headersMap.put("X-FromAppId", createSingletonList("app-id"));
+ headersMap.put("Host", createSingletonList("hostname"));
+
+ HttpHeaders headers = createMockedHeaders(headersMap);
+ RequestHeaders requestHeaders = new RequestHeaders(headers);
+ assertThat(requestHeaders.getRequestId(), is(equalTo(transactionId)));
+ assertThat(requestHeaders.getInstanceId(), is(equalTo(serviceInstanceId)));
+ }
+
+ @Test
+ public void testMultipleHeaderValues() {
+ String transactionId = "transaction-id";
+ String serviceInstanceId = "service-instance-id";
+
+ MultivaluedHashMap<String, String> headersMap = new MultivaluedHashMap<>();
+ headersMap.put(RequestHeaders.HEADER_REQUEST_ID, Arrays.asList(transactionId, "fred"));
+ headersMap.put(RequestHeaders.HEADER_SERVICE_INSTANCE_ID, Arrays.asList(serviceInstanceId, "bob"));
+
+ HttpHeaders headers = createMockedHeaders(headersMap);
+ RequestHeaders requestHeaders = new RequestHeaders(headers);
+ assertThat(requestHeaders.getRequestId(), is(equalTo(transactionId)));
+ assertThat(requestHeaders.getInstanceId(), is(equalTo(serviceInstanceId)));
+ }
+
+ @Test
+ public void testStandardHeaders() {
+ MultivaluedHashMap<String, String> headersMap = new MultivaluedHashMap<>();
+ headersMap.put("X-TransactionId", createSingletonList("transaction-id"));
+ headersMap.put("X-FromAppId", createSingletonList("app-id"));
+ headersMap.put("Host", createSingletonList("hostname"));
+
+ HttpHeaders headers = createMockedHeaders(headersMap);
+ RequestHeaders requestHeaders = new RequestHeaders(headers);
+ assertThat(requestHeaders.getRequestId(), is(nullValue()));
+ assertThat(requestHeaders.getInstanceId(), is(nullValue()));
+ }
+
+ @Test
+ public void testEmptyHeaders() {
+ MultivaluedHashMap<String, String> headersMap = new MultivaluedHashMap<>();
+ headersMap.put(RequestHeaders.HEADER_REQUEST_ID, Collections.emptyList());
+ headersMap.put(RequestHeaders.HEADER_SERVICE_INSTANCE_ID, Collections.emptyList());
+
+ HttpHeaders headers = createMockedHeaders(headersMap);
+ RequestHeaders requestHeaders = new RequestHeaders(headers);
+ assertThat(requestHeaders.getRequestId(), is(nullValue()));
+ assertThat(requestHeaders.getInstanceId(), is(nullValue()));
+ }
+
+ @Test
+ public void testNullHeaders() {
+ MultivaluedHashMap<String, String> headersMap = new MultivaluedHashMap<>();
+ headersMap.put(RequestHeaders.HEADER_REQUEST_ID, Collections.emptyList());
+
+ HttpHeaders headers = createMockedHeaders(headersMap);
+ Mockito.when(headers.getFirst(RequestHeaders.HEADER_SERVICE_INSTANCE_ID)).thenReturn(null);
+
+ RequestHeaders requestHeaders = new RequestHeaders(headers);
+ assertThat(requestHeaders.getRequestId(), is(nullValue()));
+ assertThat(requestHeaders.getInstanceId(), is(nullValue()));
+ }
+
+ @Test
+ public void testToString() {
+ String transactionId = "transaction-id";
+ String serviceInstanceId = "service-instance-id";
+
+ MultivaluedHashMap<String, String> headersMap = new MultivaluedHashMap<>();
+ headersMap.put(RequestHeaders.HEADER_REQUEST_ID, createSingletonList(transactionId));
+ headersMap.put(RequestHeaders.HEADER_SERVICE_INSTANCE_ID, createSingletonList(serviceInstanceId));
+
+ HttpHeaders headers = createMockedHeaders(headersMap);
+ RequestHeaders requestHeaders = new RequestHeaders(headers);
+ assertThat(requestHeaders.toString(),
+ is(equalTo("RequestHeaders [requestId=transaction-id, instanceId=service-instance-id]")));
+ }
+
+ private HttpHeaders createMockedHeaders(MultivaluedHashMap<String, String> headersMap) {
+ HttpHeaders headers = Mockito.mock(HttpHeaders.class);
+ for (Entry<String, List<String>> entry : headersMap.entrySet()) {
+ List<String> valuesList = entry.getValue();
+ String value = valuesList == null || valuesList.isEmpty() ? null : valuesList.get(0);
+ Mockito.when(headers.getFirst(entry.getKey())).thenReturn(value);
+ }
+ return headers;
+ }
+
+ private List<String> createSingletonList(String listItem) {
+ return Collections.<String>singletonList(listItem);
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/result/TestValidationResult.java b/src/test/java/org/onap/aai/validation/result/TestValidationResult.java
new file mode 100644
index 0000000..5d02101
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/result/TestValidationResult.java
@@ -0,0 +1,444 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.result;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.time.Instant;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import javax.inject.Inject;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.aai.validation.exception.ValidationServiceException;
+import org.onap.aai.validation.reader.EventReader;
+import org.onap.aai.validation.reader.data.Entity;
+import org.onap.aai.validation.result.ValidationResult;
+import org.onap.aai.validation.result.Violation;
+import org.onap.aai.validation.result.Violation.Builder;
+import org.onap.aai.validation.result.Violation.ViolationType;
+import org.onap.aai.validation.test.util.TestUtil;
+import org.onap.aai.validation.util.JsonUtil;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@TestPropertySource(properties = {"schemaIngestPropLoc = src/test/resources/oxm-reader/schemaIngest.properties"})
+@ContextConfiguration(locations = {"classpath:validation-result/test-validation-service-beans.xml"})
+public class TestValidationResult {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ @Inject
+ private EventReader eventReader;
+
+ private static String vserverEvent;
+ private static Entity entity;
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ vserverEvent = TestUtil.getFileAsString(TestData.VSERVER.getFilename());
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ entity = eventReader.getEntity(vserverEvent);
+ }
+
+ enum TestData {
+ // @formatter:off
+ VSERVER ("validation-result/vserver-create-event.json");
+
+ private String filename;
+ TestData(String filename) {this.filename = filename;}
+ public String getFilename() {return this.filename;}
+ // @formatter:on
+ }
+
+ @Test
+ public void testValidationResultWithViolationDetailsAsString() throws Exception {
+ // Violation details
+ Map<String, Object> violationDetails = new HashMap<>();
+ violationDetails.put("attr1", "val1");
+ violationDetails.put("attr2", "val2");
+
+ ValidationResult validationResult = getValidationResult(violationDetails);
+ ValidationResult transformedVr = toAndFromJson(validationResult);
+
+ assertThatValidationResultIsValid(transformedVr);
+ Violation v = assertThatViolationIsValid(transformedVr, validationResult.getViolations().get(0));
+ assertThat(v.getViolationDetails(), is(violationDetails));
+ }
+
+ @Test
+ public void testValidationResultWithViolationDetailsIncludingNull() throws Exception {
+ // Violation details
+ Map<String, Object> violationDetails = new HashMap<>();
+ violationDetails.put("attr1", "val1");
+ violationDetails.put("attr2", null);
+
+ ValidationResult validationResult = getValidationResult(violationDetails);
+ ValidationResult transformedVr = toAndFromJson(validationResult);
+
+ // Check
+ assertThatValidationResultIsValid(transformedVr);
+ Violation v = assertThatViolationIsValid(transformedVr, validationResult.getViolations().get(0));
+ assertThat(v.getViolationDetails(), is(violationDetails));
+ }
+
+ @Test
+ public void testValidationResultWithViolationDetailsAsList() throws Exception {
+ // Violation details
+ Map<String, Object> violationDetails = new HashMap<>();
+ violationDetails.put("attr1", Arrays.asList("val1", "val2"));
+ violationDetails.put("attr2", Arrays.asList("val3", "val4"));
+
+ ValidationResult validationResult = getValidationResult(violationDetails);
+ ValidationResult transformedVr = toAndFromJson(validationResult);
+
+ // Check
+ assertThatValidationResultIsValid(transformedVr);
+ Violation v = assertThatViolationIsValid(transformedVr, validationResult.getViolations().get(0));
+ assertThat(v.getViolationDetails(), is(violationDetails));
+ }
+
+ @Test
+ public void testValidationResultWithViolationDetailsAsInt() throws Exception {
+ // Violation details
+ Map<String, Object> violationDetails = new HashMap<>();
+ violationDetails.put("attr1", 1);
+ violationDetails.put("attr2", 2);
+
+ ValidationResult validationResult = getValidationResult(violationDetails);
+ ValidationResult vr = toAndFromJson(validationResult);
+
+ // Check
+ assertThatValidationResultIsValid(vr);
+ Violation v = assertThatViolationIsValid(vr, validationResult.getViolations().get(0));
+ assertThat(v.getViolationDetails().get("attr1"), is(1.0));
+ assertThat(v.getViolationDetails().get("attr2"), is(2.0));
+ }
+
+ @Test
+ public void testValidationResultWithViolationDetailsAsObject() throws Exception {
+ // Violation details
+ JsonArray jsonArray = new JsonArray();
+ jsonArray.add("v1");
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.add("p1", jsonArray);
+ jsonObject.add("p2", jsonArray);
+ Map<String, Object> violationDetails = new HashMap<>();
+ violationDetails.put("attr1", jsonObject);
+
+ ValidationResult validationResult = getValidationResult(violationDetails);
+ ValidationResult transformedVr = toAndFromJson(validationResult);
+
+ // Check
+ assertThatValidationResultIsValid(transformedVr);
+ Violation v = assertThatViolationIsValid(transformedVr, validationResult.getViolations().get(0));
+ String jsonDetails = v.getViolationDetails().get("attr1").toString();
+ JsonParser jsonParser = new JsonParser();
+ JsonElement jsonElement = jsonParser.parse(jsonDetails);
+ assertThat(jsonObject, is(jsonElement));
+ }
+
+ @Test
+ public void testCompareObjects() throws Exception {
+ ValidationResult validationResult = new ValidationResult(entity);
+ assertThat(validationResult, is(not(equalTo(null))));
+
+ validationResult.setEntityId(new JsonObject());
+ assertThat(validationResult, is(not(equalTo(null))));
+
+ ValidationResult other = new ValidationResult(entity);
+ assertThat(validationResult, is(not(equalTo(other))));
+
+ validationResult.setEntityType("type");
+ assertThat(validationResult, is(not(equalTo(other))));
+
+ Map<String, Object> violationDetails = new HashMap<>();
+
+ //@formatter:off
+ Violation violation = new Violation.Builder(entity)
+ .category("category")
+ .severity("severity")
+ .violationType("violationType")
+ .violationDetails(violationDetails)
+ .errorMessage("errorMessage")
+ .build();
+ //@formatter:on
+
+ validationResult.addViolation(violation);
+ assertThat(validationResult, is(not(equalTo(other))));
+
+ // Force call to hashCode()
+ assertThat(validationResult.hashCode(), is(not(equalTo(other.hashCode()))));
+
+ }
+
+ /**
+ * Tests for comparing two Violation objects. The generated Violation ID must be deterministic.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testCompareViolationObjects() throws Exception {
+ // Use the standard vserver event
+ Builder builder = new Violation.Builder(entity);
+
+ // Force call to toString() for coverage only
+ assertThat(builder.toString(), is(equalTo(new Violation.Builder(entity).toString())));
+
+ // Build a blank violation
+ Violation violation = builder.build();
+
+ // Identity tests
+ assertThat(violation, is(not(equalTo(null))));
+ assertThat(violation, is(not(equalTo(1))));
+ assertThat(violation, is(equalTo(violation)));
+
+ // Ensure that any violations we build are identical
+ testViolationIdsForEquality(builder, builder, true);
+
+ // Create a copy of the vserver event and vary the resourceVersion
+ Entity entity2 = eventReader
+ .getEntity(vserverEvent.replaceFirst("resource-version\": \"1464193654", "resource-version\": \"123"));
+
+ // The violationId produced for identically built violations is the same for each builder (although the vserver
+ // events differ).
+ testViolationIdsForEquality(new Violation.Builder(entity), new Violation.Builder(entity2), true);
+
+ // The violationId produced must differ whenever the violation values differ.
+ testViolationIdsForInequality(new Violation.Builder(entity), new Violation.Builder(entity2));
+
+ // Make a new variant of the vserver event using a different entity Id
+ Entity entity3 = eventReader.getEntity(
+ vserverEvent.replaceFirst("vserver-id\": \"example-vserver-id-val-34666", "vserver-id\": \"123"));
+
+ // The violationId produced for identically built violations is now different for each builder (because the
+ // entity Ids differ).
+ testViolationIdsForEquality(new Violation.Builder(entity), new Violation.Builder(entity3), false);
+ }
+
+ /**
+ * Generate various violations using the supplied builders and assert the expected equality of the generated
+ * Violation IDs whenever the values supplied to the builders are the same.
+ *
+ * @param b1 a builder
+ * @param b2 another builder
+ * @param expectedResult whether or not the two builders should produce identical violations
+ * @throws ValidationServiceException
+ */
+ private void testViolationIdsForEquality(Builder b1, Builder b2, Boolean expectedResult)
+ throws ValidationServiceException {
+ Violation v1 = b1.build();
+ Violation v2 = b2.build();
+ assertThatViolationsAreEqual(v1, v2, expectedResult);
+
+ // Use the same category
+ String category = "INVALID OBJ";
+ v1 = b1.category(category).build();
+ v2 = b2.category(category).build();
+ assertThatViolationsAreEqual(v1, v2, expectedResult);
+
+ // Use the same severity
+ String severity = "CRITICAL";
+ v1 = b1.severity(severity).build();
+ v2 = b2.severity(severity).build();
+ assertThatViolationsAreEqual(v1, v2, expectedResult);
+
+ // Use the same violation type
+ v1 = b1.violationType(ViolationType.RULE).build();
+ v2 = b2.violationType(ViolationType.RULE).build();
+ assertThatViolationsAreEqual(v1, v2, expectedResult);
+
+ // Use the same validation rule
+ String rule = "prov-status";
+ v1 = b1.validationRule(rule).build();
+ v2 = b2.validationRule(rule).build();
+ assertThatViolationsAreEqual(v1, v2, expectedResult);
+
+ // Use the same error message
+ String errorMessage = "Invalid prov-status value. Must have a value not equal to ACTIVE/active.";
+ v1 = b1.errorMessage(errorMessage).build();
+ v2 = b2.errorMessage(errorMessage).build();
+ assertThatViolationsAreEqual(v1, v2, expectedResult);
+
+ // Use the same violation details
+ Map<String, Object> details = new HashMap<>();
+ details.put(rule, "ACTIVE");
+ v1 = b1.violationDetails(details).build();
+ v2 = b2.violationDetails(details).build();
+ assertThatViolationsAreEqual(v1, v2, expectedResult);
+ }
+
+ /**
+ * Generate violations using the supplied builders and assert that the generated Violation IDs differ whenever the
+ * values supplied to the builders differ.
+ *
+ * @param builder
+ * @param builder2
+ * @throws ValidationServiceException
+ */
+ private void testViolationIdsForInequality(Builder builder, Builder builder2) throws ValidationServiceException {
+ Violation violation;
+ Violation other;
+
+ // Vary the violation type
+ violation = builder.violationType("").build();
+ other = builder2.violationType(ViolationType.RULE).build();
+ assertThatViolationIdsDiffer(violation, other);
+
+ violation = builder.violationType(ViolationType.NONE).build();
+ other = builder2.violationType(ViolationType.RULE).build();
+ assertThatViolationIdsDiffer(violation, other);
+
+ // Vary the validation rule
+ violation = builder.validationRule(null).build();
+ other = builder2.validationRule("rule").build();
+ assertThatViolationIdsDiffer(violation, other);
+
+ violation = builder.validationRule("rule1").build();
+ other = builder2.validationRule(null).build();
+ assertThatViolationIdsDiffer(violation, other);
+
+ violation = builder.validationRule("rule1").build();
+ other = builder2.validationRule("rule2").build();
+ assertThatViolationIdsDiffer(violation, other);
+
+ // Vary the category
+ violation = builder.category(null).build();
+ other = builder2.category("category").build();
+ assertThatViolationIdsDiffer(violation, other);
+
+ violation = builder.category("category").build();
+ other = builder2.category(null).build();
+ assertThatViolationIdsDiffer(violation, other);
+
+ violation = builder.category("category1").build();
+ other = builder2.category("category2").build();
+ assertThatViolationIdsDiffer(violation, other);
+
+ // Vary the error message
+ violation = builder.validationRule("rule").build();
+ other = builder2.validationRule("rule").errorMessage("message2").build();
+ assertThatViolationIdsDiffer(violation, other);
+
+ violation = builder.validationRule("rule").errorMessage("message1").build();
+ other = builder2.validationRule("rule").errorMessage("message2").build();
+ assertThatViolationIdsDiffer(violation, other);
+
+ // Vary the severity
+ violation = builder.errorMessage("msg").build();
+ other = builder2.errorMessage("msg").severity("sev2").build();
+ assertThatViolationIdsDiffer(violation, other);
+
+ violation = builder.errorMessage("msg").severity("sev1").build();
+ other = builder2.errorMessage("msg").severity("sev2").build();
+ assertThatViolationIdsDiffer(violation, other);
+ }
+
+ private ValidationResult getValidationResult(Map<String, Object> violationDetails)
+ throws ValidationServiceException {
+ ValidationResult validationResult = new ValidationResult(entity);
+
+ //@formatter:off
+ Violation violation = new Violation.Builder(entity)
+ .category("category")
+ .severity("severity")
+ .violationType("violationType")
+ .violationDetails(violationDetails)
+ .errorMessage("errorMessage")
+ .build();
+ //@formatter:on
+
+ validationResult.addViolation(violation);
+
+ return validationResult;
+ }
+
+ private ValidationResult toAndFromJson(ValidationResult validationResult) {
+ return JsonUtil.toAnnotatedClassfromJson(validationResult.toJson(), ValidationResult.class);
+ }
+
+ private void assertThatValidationResultIsValid(ValidationResult vr) {
+ assertTrue("Expected valid UUID", isValidEventId(vr.getValidationId()));
+ assertIsValidTimestamp(vr.getValidationTimestamp());
+ JsonObject expectedEntityId = new JsonObject();
+ expectedEntityId.addProperty("vserver-id", "example-vserver-id-val-34666");
+ assertThat(vr.getEntityId(), is(expectedEntityId));
+ assertThat(vr.getEntityType(), is("vserver"));
+ assertThat(vr.getResourceVersion(), is("1464193654"));
+ assertThat(vr.getEntityLink(), is(
+ "cloud-infrastructure/cloud-regions/cloud-region/region1/AAIregion1/tenants/tenant/example-tenant-id-val-88551/vservers/vserver/example-vserver-id-val-34666"));
+ }
+
+ private Violation assertThatViolationIsValid(ValidationResult vr, Violation expectedViolation) {
+ Violation v = vr.getViolations().get(0);
+ assertThat(v.getViolationId(), is(expectedViolation.getViolationId()));
+ assertThat(v.getCategory(), is("category"));
+ assertThat(v.getSeverity(), is("severity"));
+ assertThat(v.getViolationType(), is("violationType"));
+ assertThat(v.getErrorMessage(), is("errorMessage"));
+ return v;
+ }
+
+ private void assertThatViolationsAreEqual(Violation v1, Violation v2, Boolean expectedResult) {
+ assertThat("Violation equality in error:\n" + v1 + " equals " + v2, v1.equals(v2), is(expectedResult));
+ assertThat("Violation ID equality in error:\n" + v1.getViolationId() + " equals " + v2.getViolationId(),
+ v1.getViolationId().equals(v2.getViolationId()), is(expectedResult));
+ // Force a call to toString() for code coverage only
+ assertThat(v1.toString().equals(v2.toString()), is(equalTo(expectedResult)));
+ }
+
+ private void assertThatViolationIdsDiffer(Violation violation, Violation other) {
+ assertThat(violation.getViolationId(), is(not(equalTo(other.getViolationId()))));
+ assertThat(violation, is(not(equalTo(other))));
+ }
+
+ private boolean isValidEventId(String eventId) {
+ try {
+ UUID.fromString(eventId);
+ } catch (IllegalArgumentException exception) {
+ return false;
+ }
+ return true;
+ }
+
+ private void assertIsValidTimestamp(String date) {
+ DateTimeFormatter f = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmssX").withZone(ZoneOffset.UTC);
+ Instant.from(f.parse(date));
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/ruledriven/configuration/ConfigFileBuilder.java b/src/test/java/org/onap/aai/validation/ruledriven/configuration/ConfigFileBuilder.java
new file mode 100644
index 0000000..1f87ca0
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/ruledriven/configuration/ConfigFileBuilder.java
@@ -0,0 +1,104 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.ruledriven.configuration;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.List;
+import java.util.Properties;
+import org.junit.rules.TemporaryFolder;
+import org.onap.aai.cl.api.Logger;
+import org.onap.aai.validation.logging.LogHelper;
+import org.onap.aai.validation.ruledriven.configuration.EntitySection;
+import org.onap.aai.validation.ruledriven.configuration.RulesConfigurationLoader;
+import org.onap.aai.validation.ruledriven.configuration.build.ContentBuilder;
+import org.onap.aai.validation.ruledriven.configuration.build.EntityBuilder;
+import org.onap.aai.validation.ruledriven.configuration.build.RuleBuilder;
+
+public class ConfigFileBuilder extends ContentBuilder {
+
+ private static final Logger logger = LogHelper.INSTANCE;
+
+ private static final String TMP_CONFIG_FILE = "config.txt";
+ private TemporaryFolder testFolder;
+ private File tempFile;
+
+ public ConfigFileBuilder(TemporaryFolder testFolder) {
+ super();
+ this.testFolder = testFolder;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("ConfigBuilder [").append(testFolder.getRoot().getAbsolutePath()).append(System.lineSeparator());
+ for (ContentBuilder item : items) {
+ sb.append(item).append(System.lineSeparator());
+ }
+ sb.append(System.lineSeparator()).append("]");
+ return sb.toString();
+ }
+
+ public EntityBuilder entity() {
+ EntityBuilder item = new EntityBuilder();
+ addContent(item);
+ return item;
+ }
+
+ public RuleBuilder rule() {
+ RuleBuilder item = new RuleBuilder();
+ addContent(item);
+ return item;
+ }
+
+ public void entity(Properties props) {
+ EntityBuilder entity = entity();
+ entity.appendProperties(props);
+ }
+
+ public RuleBuilder rule(String name) {
+ RuleBuilder rule = rule();
+ rule.appendValue("name", name);
+ return rule;
+ }
+
+ public List<EntitySection> loadConfiguration() throws IOException {
+ logger.debug("Configuration file: " + build());
+ return buildConfiguration(build());
+ }
+
+ private List<EntitySection> buildConfiguration(String text) throws IOException {
+ tempFile = createConfigFile(text);
+ return RulesConfigurationLoader.loadConfiguration(tempFile).getEntities();
+ }
+
+ private File createConfigFile(String configText) throws IOException {
+ tempFile = testFolder.newFile(TMP_CONFIG_FILE);
+ BufferedWriter bw = new BufferedWriter(new FileWriter(tempFile));
+ bw.write(configText);
+ bw.close();
+ return tempFile;
+ }
+
+ public void freeResources() {
+ tempFile.delete();
+ }
+
+}
diff --git a/src/test/java/org/onap/aai/validation/ruledriven/configuration/ConfigurationExceptionMatcher.java b/src/test/java/org/onap/aai/validation/ruledriven/configuration/ConfigurationExceptionMatcher.java
new file mode 100644
index 0000000..f32c5d3
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/ruledriven/configuration/ConfigurationExceptionMatcher.java
@@ -0,0 +1,73 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.ruledriven.configuration;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+import org.onap.aai.validation.ruledriven.configuration.GroovyConfigurationException;
+
+public class ConfigurationExceptionMatcher {
+ public static Matcher<GroovyConfigurationException> hasInvalidToken(final String expectedToken) {
+ return new TypeSafeMatcher<GroovyConfigurationException>() {
+ private String foundToken;
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("result from getInvalidToken() equals \"").appendText(expectedToken)
+ .appendText("\"");
+ }
+
+ @Override
+ public void describeMismatchSafely(final GroovyConfigurationException exception,
+ final Description mismatchDescription) {
+ mismatchDescription.appendText("was ").appendValue(foundToken);
+ }
+
+ @Override
+ protected boolean matchesSafely(GroovyConfigurationException exception) {
+ foundToken = exception.getInvalidToken();
+ return foundToken != null && foundToken.equalsIgnoreCase(expectedToken);
+ }
+ };
+ }
+
+ public static Matcher<GroovyConfigurationException> configTextContains(final String expectedConfigText) {
+ return new TypeSafeMatcher<GroovyConfigurationException>() {
+ private String foundConfigText;
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("result from getConfigText() containing \"").appendText(expectedConfigText)
+ .appendText("\"");
+ }
+
+ @Override
+ public void describeMismatchSafely(final GroovyConfigurationException exception,
+ final Description mismatchDescription) {
+ mismatchDescription.appendText("was ").appendValue(foundConfigText);
+ }
+
+ @Override
+ protected boolean matchesSafely(GroovyConfigurationException exception) {
+ foundConfigText = exception.getConfigText();
+ return foundConfigText != null && foundConfigText.contains(expectedConfigText);
+ }
+ };
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/ruledriven/configuration/TestConfigFileBuilder.java b/src/test/java/org/onap/aai/validation/ruledriven/configuration/TestConfigFileBuilder.java
new file mode 100644
index 0000000..6d56fa8
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/ruledriven/configuration/TestConfigFileBuilder.java
@@ -0,0 +1,59 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.ruledriven.configuration;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.onap.aai.validation.ruledriven.configuration.build.EntityBuilder;
+
+/**
+ * These tests are required to ensure code coverage by unit testing
+ *
+ */
+public class TestConfigFileBuilder {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ @Rule
+ public TemporaryFolder testFolder = new TemporaryFolder();
+
+ /**
+ * Validate that a content builder accepts a numeric value
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testNumberItem() throws Exception {
+ ConfigFileBuilder builder = new ConfigFileBuilder(testFolder);
+ EntityBuilder ab = new EntityBuilder();
+ ab.appendValue("dummy", 3);
+ ab.appendValue("dummy2", 5L);
+ builder.addContent(ab);
+ builder.toString();
+ }
+
+ @Test
+ public void testToString() throws Exception {
+ ConfigFileBuilder builder = new ConfigFileBuilder(testFolder);
+ builder.addContent(new EntityBuilder());
+ builder.toString();
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/ruledriven/configuration/TestRulesConfigurationReader.java b/src/test/java/org/onap/aai/validation/ruledriven/configuration/TestRulesConfigurationReader.java
new file mode 100644
index 0000000..c0f9f48
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/ruledriven/configuration/TestRulesConfigurationReader.java
@@ -0,0 +1,448 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.ruledriven.configuration;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TemporaryFolder;
+import org.onap.aai.validation.ruledriven.configuration.EntitySection;
+import org.onap.aai.validation.ruledriven.configuration.GroovyConfigurationException;
+import org.onap.aai.validation.ruledriven.configuration.RuleSection;
+import org.onap.aai.validation.ruledriven.configuration.SettingsSection;
+import org.onap.aai.validation.ruledriven.configuration.build.EntityBuilder;
+import org.onap.aai.validation.ruledriven.configuration.build.RuleBuilder;
+import org.onap.aai.validation.ruledriven.configuration.build.ValidationBuilder;
+import org.onap.aai.validation.test.util.RandomString;
+
+/**
+ * Tests for the Groovy classes that read and parse the rules configuration
+ *
+ */
+public class TestRulesConfigurationReader {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ @Rule
+ public TemporaryFolder testFolder = new TemporaryFolder();
+
+ /**
+ * Exception expected by Junit. This is modified per test.
+ */
+ @Rule
+ public final ExpectedException exception = ExpectedException.none();
+
+ private static final String INVALID_TOKEN = "audif";
+
+ @Test
+ public void testEmptyConfiguration() throws Exception {
+ ConfigFileBuilder builder = new ConfigFileBuilder(testFolder);
+ Collection<EntitySection> entitys = builder.loadConfiguration();
+ assertThat(entitys.size(), is(0));
+ }
+
+ /**
+ * Test for reporting of an unknown token with various syntax formatting
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testInvalidTopLevelItem() throws Exception {
+ testInvalidToken(INVALID_TOKEN);
+ testInvalidToken(INVALID_TOKEN + " { }");
+ testInvalidToken("{ " + INVALID_TOKEN + " }");
+ testInvalidToken(INVALID_TOKEN + " { ");
+ testInvalidToken(INVALID_TOKEN + " } ");
+ testInvalidToken("{} " + INVALID_TOKEN);
+ testInvalidToken("\"" + INVALID_TOKEN);
+ }
+
+ @Test
+ public void testInvalidentityItem1() throws Exception {
+ testInvalidToken("entity { invalid }", "invalid");
+ }
+
+ @Test
+ public void testInvalidentityItem2() throws Exception {
+ testInvalidToken("entity { invalid item }", "item");
+ }
+
+ @Test
+ public void testInvalidentityItem3() throws Exception {
+ testInvalidToken("entity { name name\n fred fred}", "name");
+ }
+
+ @Test
+ public void testInvalidQuery() throws Exception {
+ testInvalidToken("entity { name 'name'\n joe}", "joe");
+ }
+
+ @Test
+ public void testGenericRuleWithZeroAttributes() throws Exception {
+ ConfigFileBuilder builder = new ConfigFileBuilder(testFolder);
+ EntityBuilder entity = builder.entity();
+ entity.appendValue("name", "entity");
+ ValidationBuilder validation = entity.validation(buildProperties("type"));
+ validation.useRule("ruleZ");
+ builder.rule("ruleZ");
+
+ exception.expect(GroovyConfigurationException.class);
+ exception.expectMessage(containsString("attributes"));
+ builder.loadConfiguration();
+ }
+
+ @Test
+ public void testInvalidUseRule() throws Exception {
+ testInvalidToken("entity { validation { useRule { foo } } }", "foo");
+ }
+
+ @Test
+ public void testMissingRule() throws Exception {
+ ConfigFileBuilder builder = new ConfigFileBuilder(testFolder);
+ builder.entity().validation().useRule("missingRule");
+ exception.expect(GroovyConfigurationException.class);
+ exception.expectMessage(containsString("missingRule"));
+ builder.loadConfiguration();
+ }
+
+ @Test
+ public void testDuplicateRule() throws Exception {
+ ConfigFileBuilder builder = new ConfigFileBuilder(testFolder);
+ builder.rule("duplicateRule");
+ builder.rule("duplicateRule");
+ exception.expect(GroovyConfigurationException.class);
+ exception.expectMessage(containsString("duplicateRule"));
+ builder.loadConfiguration();
+ }
+
+ @Test
+ public void testSimpleentity() throws Exception {
+ String name = RandomString.generate();
+
+ ConfigFileBuilder builder = new ConfigFileBuilder(testFolder);
+ Properties entity = new Properties();
+ entity.put("name", name);
+ builder.entity(entity);
+
+ List<EntitySection> entities = builder.loadConfiguration();
+
+ assertThat(entities.size(), is(1));
+ EntitySection entityConf = entities.get(0);
+ assertThat(entityConf.getName(), is(equalTo(name)));
+ }
+
+ /**
+ * The Settings section is not tested elsewhere
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testGlobalSettings() throws Exception {
+ SettingsSection settings = new SettingsSection();
+ settings.toString();
+ }
+
+ @Test
+ public void testentityWithRuleUsingStrings() throws Exception {
+ String name = RandomString.generate();
+ String description = RandomString.generate();
+ String severity = RandomString.generate();
+ List<String> attributes = Arrays.asList(RandomString.generate());
+ String validate = randomValidationExpression();
+
+ Properties rule = new Properties();
+ rule.put("name", name);
+ rule.put("description", description);
+ rule.put("severity", severity);
+ rule.put("attributes", attributes);
+ rule.put("validate", validate);
+
+ String type = RandomString.generate();
+
+ Properties validation = new Properties();
+ validation.put("type", type);
+ validation.put("rule", rule);
+
+ ConfigFileBuilder builder = new ConfigFileBuilder(testFolder);
+ Properties entity = new Properties();
+ entity.put("validation", validation);
+ builder.entity(entity);
+
+ List<EntitySection> entities = builder.loadConfiguration();
+
+ assertThat(entities.size(), is(1));
+ EntitySection entityConf = entities.get(0);
+ Collection<RuleSection> rules = entityConf.getRules();
+ assertThat(rules.size(), is(1));
+
+ RuleSection ruleConfig = rules.iterator().next();
+ assertThat(ruleConfig.getName(), is(equalTo(name)));
+ assertThat(ruleConfig.getDescription(), is(equalTo(description)));
+ assertThat(ruleConfig.getSeverity(), is(equalTo(severity)));
+ assertThat(ruleConfig.getAttributes(), is(equalTo(attributes)));
+ assertThat(ruleConfig.getExpression(), is(equalTo(validate)));
+ assertThat(ruleConfig.getType(), is(equalTo(type)));
+ }
+
+ @Test
+ public void testentityWithRuleUsingBuilder() throws Exception {
+ String name = RandomString.generate();
+ String description = RandomString.generate();
+ String severity = RandomString.generate();
+ List<String> attributes = Arrays.asList(RandomString.generate());
+ String validate = randomValidationExpression();
+ String type = RandomString.generate();
+
+ ConfigFileBuilder builder = new ConfigFileBuilder(testFolder);
+ ValidationBuilder validation = builder.entity().validation();
+ validation.appendValue("type", type);
+
+ RuleBuilder rule = validation.rule(name);
+ rule.appendValue("description", description);
+ rule.appendValue("severity", severity);
+ rule.appendValue("attributes", attributes);
+ rule.appendValue("validate", validate);
+
+ List<EntitySection> entitys = builder.loadConfiguration();
+
+ assertThat(entitys.size(), is(1));
+ EntitySection entityConf = entitys.get(0);
+ Collection<RuleSection> rules = entityConf.getRules();
+ assertThat(rules.size(), is(1));
+
+ RuleSection ruleConfig = rules.iterator().next();
+ assertThat(ruleConfig.getName(), is(equalTo(name)));
+ assertThat(ruleConfig.getDescription(), is(equalTo(description)));
+ assertThat(ruleConfig.getSeverity(), is(equalTo(severity)));
+ assertThat(ruleConfig.getAttributes(), is(equalTo(attributes)));
+ assertThat(ruleConfig.getExpression(), is(equalTo(validate)));
+ assertThat(ruleConfig.getType(), is(equalTo(type)));
+ }
+
+ @Test
+ public void testentityWithEmbeddedRule() throws Exception {
+ Properties rule = buildProperties("name", "description", "severity", "validate");
+ rule.put("attributes", Arrays.asList(RandomString.generate()));
+
+ Properties validation = buildProperties("type");
+ validation.put("rule", rule);
+
+ ConfigFileBuilder builder = new ConfigFileBuilder(testFolder);
+ Properties entity = new Properties();
+ entity.put("validation", validation);
+ builder.entity(entity);
+
+ List<EntitySection> entitys = builder.loadConfiguration();
+
+ assertThat(entitys.size(), is(1));
+ EntitySection entityConf = entitys.get(0);
+ Collection<RuleSection> rules = entityConf.getRules();
+ assertThat(rules.size(), is(1));
+
+ RuleSection ruleConfig = rules.iterator().next();
+ assertThatConfigMatchesProperties(ruleConfig, rule, validation);
+ }
+
+ @Test
+ public void testEmbeddedRuleUsingString() throws Exception {
+ ConfigFileBuilder builder = new ConfigFileBuilder(testFolder);
+ builder.appendLine("entity {");
+ builder.appendLine(" type 'newvce'");
+ builder.appendLine(" validation {");
+ builder.appendLine(" rule {");
+ builder.appendLine(" name 'vnfName'");
+ builder.appendLine(
+ " description 'Validate that the vnf-name attribute matches the expected string format'");
+ builder.appendLine(" severity 'MAJOR'");
+ builder.appendLine(" attributes 'vnf-name'");
+ builder.appendLine(" validate 'vnf-name.matchesPattern(xxxxnnnvbc)'");
+ builder.appendLine(" }");
+ builder.appendLine(" }");
+ builder.appendLine("}");
+ List<EntitySection> entitys = builder.loadConfiguration();
+
+ assertThat(entitys.size(), is(1));
+ EntitySection entityConf = entitys.get(0);
+ assertThat(entityConf.getName(), is(equalTo("newvce")));
+
+ Collection<RuleSection> rules = entityConf.getRules();
+ assertThat(rules.size(), is(1));
+ RuleSection ruleConfig = rules.iterator().next();
+
+ assertThat(ruleConfig.getType(), is(equalTo("newvce")));
+ assertThat(ruleConfig.getName(), is(equalTo("vnfName")));
+ assertThat(ruleConfig.getDescription(),
+ is(equalTo("Validate that the vnf-name attribute matches the expected string format")));
+ assertThat(ruleConfig.getSeverity(), is(equalTo("MAJOR")));
+ List<String> expectedList = new ArrayList<String>();
+ expectedList.add("vnf-name");
+ assertThat(ruleConfig.getAttributes(), is(equalTo(expectedList)));
+ assertThat(ruleConfig.getExpression(), is(equalTo("vnf-name.matchesPattern(xxxxnnnvbc)")));
+ }
+
+ @Test
+ public void testGenericRuleUsingStrings() throws Exception {
+ ConfigFileBuilder builder = new ConfigFileBuilder(testFolder);
+ builder.appendLine("entity {");
+ builder.appendLine(" type 'newvce'");
+ builder.appendLine(" validation {");
+ builder.appendLine(" useRule {");
+ builder.appendLine(" name 'genericRule'");
+ builder.appendLine(" attributes 'clli'");
+ builder.appendLine(" }");
+ builder.appendLine(" }");
+ builder.appendLine("}");
+ builder.appendLine("rule {");
+ builder.appendLine(" name 'genericRule'");
+ builder.appendLine(" description 'The field (attribute) must be less than 50 characters in length'");
+ builder.appendLine(" severity 'MINOR'");
+ builder.appendLine(" validate 'attribute.size() < 50'");
+ builder.appendLine("}");
+
+ List<EntitySection> entitys = builder.loadConfiguration();
+ assertThat(entitys.size(), is(1));
+ EntitySection entityConf = entitys.get(0);
+ assertThat(entityConf.getName(), is(equalTo("newvce")));
+
+ Collection<RuleSection> rules = entityConf.getRules();
+ assertThat("Number of rules", rules.size(), is(1));
+ RuleSection ruleConfig = rules.iterator().next();
+
+ assertThat(ruleConfig.getType(), is(equalTo("newvce")));
+ assertThat(ruleConfig.getName(), is(equalTo("genericRule")));
+ assertThat(ruleConfig.getDescription(),
+ is(equalTo("The field (attribute) must be less than 50 characters in length")));
+ assertThat(ruleConfig.getSeverity(), is(equalTo("MINOR")));
+ List<String> expectedList = new ArrayList<String>();
+ expectedList.add("clli");
+ assertThat(ruleConfig.getAttributes(), is(equalTo(expectedList)));
+ assertThat(ruleConfig.getExpression(), is(equalTo("attribute.size() < 50")));
+ }
+
+ @Test
+ public void testMultipleGenericRules() throws Exception {
+ ConfigFileBuilder builder = new ConfigFileBuilder(testFolder);
+ EntityBuilder entity = builder.entity();
+ ValidationBuilder validation = entity.validation(buildProperties("type"));
+ validation.useRule("rule1");
+ validation.useRule("rule2").appendValue("attributes", "attr");
+ builder.rule("rule1").appendValue("attributes", "field").appendValue("validate", "true");
+ builder.rule("rule2").appendValue("validate", "true");
+
+ List<EntitySection> entitys = builder.loadConfiguration();
+
+ assertThat(entitys.size(), is(1));
+ EntitySection entityConf = entitys.get(0);
+ Collection<RuleSection> rules = entityConf.getRules();
+ assertThat(rules.size(), is(2));
+
+ Iterator<RuleSection> iterator = rules.iterator();
+ RuleSection ruleConfig = iterator.next();
+ assertThat(ruleConfig.getName(), is(equalTo("rule1")));
+ assertThat(ruleConfig.getAttributes(), is(Collections.singletonList("field")));
+
+ ruleConfig = iterator.next();
+ assertThat(ruleConfig.getName(), is(equalTo("rule2")));
+ assertThat(ruleConfig.getAttributes(), is(Collections.singletonList("attr")));
+ }
+
+ @Test
+ public void testGenericRuleWithMultipleAttributes() throws Exception {
+ ConfigFileBuilder builder = new ConfigFileBuilder(testFolder);
+ EntityBuilder entity = builder.entity();
+ ValidationBuilder validation = entity.validation(buildProperties("type"));
+ validation.useRule("rule").appendValue("attributes", Arrays.asList("attr1", "attr2"));
+ builder.rule("rule").appendValue("attributes", Arrays.asList("field1", "field2")).appendValue("validate",
+ "true");
+
+ List<EntitySection> entities = builder.loadConfiguration();
+
+ assertThat(entities.size(), is(1));
+ EntitySection entityConf = entities.get(0);
+ Collection<RuleSection> rules = entityConf.getRules();
+ assertThat(rules.size(), is(1));
+
+ Iterator<RuleSection> iterator = rules.iterator();
+ RuleSection ruleConfig = iterator.next();
+ assertThat(ruleConfig.getName(), is(equalTo("rule")));
+ assertThat(ruleConfig.getAttributes(), is(Arrays.asList("attr1", "attr2")));
+ }
+
+ private String randomValidationExpression() {
+ String validate = RandomString.generate();
+ while (validate.matches("^\\d+[a-fA-F]+\\D+.*") || validate.matches("0x\\D+.*")) {
+ validate = RandomString.generate();
+ }
+ return validate;
+ }
+
+ private void testInvalidToken(String configText) throws IOException {
+ testInvalidToken(configText, INVALID_TOKEN);
+ }
+
+ private void testInvalidToken(String configText, String invalidToken) throws IOException {
+ ConfigFileBuilder builder = new ConfigFileBuilder(testFolder);
+ builder.addContent(configText);
+ assertConfigurationException(invalidToken);
+ builder.loadConfiguration();
+ }
+
+ private void assertConfigurationException(String invalidToken) {
+ exception.expect(GroovyConfigurationException.class);
+ exception.expectMessage(containsString(invalidToken));
+ exception.expect(ConfigurationExceptionMatcher.hasInvalidToken(invalidToken));
+ exception.expect(ConfigurationExceptionMatcher.configTextContains(invalidToken));
+ }
+
+ private Properties buildProperties(String... strings) {
+ Properties props = new Properties();
+ for (String str : strings) {
+ props.put(str, randomValidationExpression());
+ }
+ return props;
+ }
+
+ private void assertThatConfigMatchesProperties(RuleSection ruleConfig, Properties rule, Properties validation) {
+ assertMatch(ruleConfig.getName(), rule, "name");
+ assertMatch(ruleConfig.getDescription(), rule, "description");
+ assertMatch(ruleConfig.getSeverity(), rule, "severity");
+ assertThat(ruleConfig.getAttributes(), is(equalTo(rule.get("attributes"))));
+ assertMatch(ruleConfig.getExpression(), rule, "validate");
+ assertMatch(ruleConfig.getType(), validation, "type");
+ assertMatch(ruleConfig.getObjectId(), validation, "objectId");
+ }
+
+ private void assertMatch(String value, Properties props, String key) {
+ assertThat(value, is(equalTo(props.getProperty(key))));
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/ruledriven/mock/TestDefaultRules.java b/src/test/java/org/onap/aai/validation/ruledriven/mock/TestDefaultRules.java
new file mode 100644
index 0000000..c3b36ed
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/ruledriven/mock/TestDefaultRules.java
@@ -0,0 +1,148 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.ruledriven.mock;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Matchers.anyListOf;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.when;
+
+import com.google.gson.JsonObject;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.stubbing.Answer;
+import org.onap.aai.validation.Validator;
+import org.onap.aai.validation.exception.ValidationServiceException;
+import org.onap.aai.validation.reader.EventReader;
+import org.onap.aai.validation.reader.data.AttributeValues;
+import org.onap.aai.validation.reader.data.Entity;
+import org.onap.aai.validation.reader.data.EntityId;
+import org.onap.aai.validation.result.ValidationResult;
+import org.onap.aai.validation.result.Violation;
+import org.onap.aai.validation.ruledriven.RuleDrivenValidator;
+
+/**
+ * Test that the rules present under bundleconfig/etc/rules/ can be loaded and evaluated (using a mocked event).
+ *
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class TestDefaultRules {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ enum TestCase {
+ NULL,
+ VSERVER;
+ }
+
+ // Data returned by the mocked EventReader
+ enum TestData {
+ // @formatter:off
+ ENTITTY_DATA ("vserver dummy json data"),
+ ENTITTY_TYPE ("vserver"),
+ RESOURCE_VERSION_VALUE("1476735182"),
+ VSERVER_ID_KEY ("vserver-id"),
+ VSERVER_ID_VALUE ("13b629a4-87ae-492d-943f-acb8f3d9c3d9");
+ // @formatter:on
+
+ private String value;
+
+ TestData(String value) {
+ this.value = value;
+ }
+ }
+
+ @Mock
+ private EventReader eventReader;
+
+ @Mock
+ private Entity entity;
+
+ private Validator ruleDrivenValidator;
+
+ @Before
+ public void createMockEventReader() throws ValidationServiceException {
+ when(eventReader.getEventType(TestCase.VSERVER.name())).thenReturn(Optional.of("aai-event"));
+ when(eventReader.getEventType(TestCase.NULL.name())).thenReturn(null);
+
+ when(eventReader.getEntityType(anyString())).thenReturn(Optional.of(TestData.ENTITTY_TYPE.value));
+ when(eventReader.getEntity(anyString())).thenReturn(entity);
+
+ // Mocked entity returned by the event reader
+ when(entity.getType()).thenReturn(TestData.ENTITTY_TYPE.value);
+ when(entity.getResourceVersion()).thenReturn(Optional.of(TestData.RESOURCE_VERSION_VALUE.value));
+
+ EntityId entityId = new EntityId(TestData.VSERVER_ID_KEY.value, TestData.VSERVER_ID_VALUE.value);
+ when(entity.getIds()).thenReturn(new ArrayList<>(Arrays.asList(entityId)));
+
+ // Return dummy values for any requested attributes
+ when(entity.getAttributeValues(anyListOf(String.class))).thenAnswer(new Answer<AttributeValues>() {
+ @SuppressWarnings("unchecked")
+ @Override
+ public AttributeValues answer(InvocationOnMock invocation) {
+ AttributeValues attributeValues = new AttributeValues();
+ for (String attribute : (List<String>) invocation.getArguments()[0]) {
+ if (attribute.contains("[*]")) {
+ attributeValues.put(attribute, Collections.emptyList());
+ } else {
+ attributeValues.put(attribute, "");
+ }
+ }
+ return attributeValues;
+ }
+ });
+ }
+
+ @Before
+ public void createRuleDrivenValidator() throws ValidationServiceException {
+ Path configurationPath = Paths.get("bundleconfig/etc/rules");
+ ruleDrivenValidator = new RuleDrivenValidator(configurationPath, null, eventReader, null);
+ }
+
+ @Test
+ public void testExecuteRulesForVserver() throws Exception {
+ List<ValidationResult> results = ruleDrivenValidator.validate(TestCase.VSERVER.name());
+ assertThat(results.size(), is(1));
+
+ ValidationResult validationResult = results.get(0);
+ assertThat(validationResult.getEntityType(), is(equalTo(TestData.ENTITTY_TYPE.value)));
+ JsonObject expectedEntityId = new JsonObject();
+ expectedEntityId.addProperty(TestData.VSERVER_ID_KEY.value, TestData.VSERVER_ID_VALUE.value);
+ assertThat(validationResult.getEntityId(), is(equalTo(expectedEntityId)));
+ assertThat(validationResult.getViolations().size(), is(2));
+
+ Violation violation = validationResult.getViolations().get(0);
+ assertThat(violation.getCategory(), is(equalTo("MISSING_REL")));
+ }
+
+}
diff --git a/src/test/java/org/onap/aai/validation/ruledriven/rule/RuleHelper.java b/src/test/java/org/onap/aai/validation/ruledriven/rule/RuleHelper.java
new file mode 100644
index 0000000..456d011
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/ruledriven/rule/RuleHelper.java
@@ -0,0 +1,36 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.ruledriven.rule;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import org.onap.aai.validation.reader.data.AttributeValues;
+import org.onap.aai.validation.ruledriven.rule.Rule;
+
+public class RuleHelper {
+
+ static void assertRuleResult(Rule rule, AttributeValues values, Boolean expectedResult) {
+ assertThat(rule + " failed for values [" + values + "]", rule.execute(values), is(equalTo(expectedResult)));
+ }
+
+ static void assertRuleResult(Rule rule, Object value, Boolean expectedResult) {
+ assertThat(rule + " failed for value [" + value + "]", rule.execute(value), is(equalTo(expectedResult)));
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/ruledriven/rule/RuleTester.java b/src/test/java/org/onap/aai/validation/ruledriven/rule/RuleTester.java
new file mode 100644
index 0000000..8593f93
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/ruledriven/rule/RuleTester.java
@@ -0,0 +1,47 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.ruledriven.rule;
+
+import org.onap.aai.validation.reader.data.AttributeValues;
+import org.onap.aai.validation.ruledriven.rule.Rule;
+
+/**
+ * Helper class for testing rules
+ *
+ */
+public class RuleTester {
+
+ private Rule rule;
+ private AttributeValues attributeValues;
+
+ /**
+ * @param trinityRule
+ * @param attributeValues
+ */
+ public RuleTester(Rule trinityRule, AttributeValues attributeValues) {
+ this.rule = trinityRule;
+ this.attributeValues = attributeValues;
+ }
+
+ /**
+ * @param expectedResult
+ */
+ public void test(boolean expectedResult) {
+ RuleHelper.assertRuleResult(rule, attributeValues, expectedResult);
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/ruledriven/rule/TestConfigurationLoader.java b/src/test/java/org/onap/aai/validation/ruledriven/rule/TestConfigurationLoader.java
new file mode 100644
index 0000000..f226252
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/ruledriven/rule/TestConfigurationLoader.java
@@ -0,0 +1,190 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.ruledriven.rule;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import javax.inject.Inject;
+import org.junit.Test;
+import org.onap.aai.validation.reader.OxmReader;
+import org.onap.aai.validation.reader.data.AttributeValues;
+import org.onap.aai.validation.ruledriven.RuleDrivenValidator;
+import org.onap.aai.validation.ruledriven.rule.Rule;
+
+public class TestConfigurationLoader {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ private enum AAIRelation {
+ RELATED_TO("related-to"),
+ PROPERTY_KEY("property-key"),
+ PROPERTY_VALUE("property-value");
+
+ private final String text;
+
+ /**
+ * @param text
+ */
+ private AAIRelation(final String text) {
+ this.text = text;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Enum#toString()
+ */
+ @Override
+ public String toString() {
+ return text;
+ }
+ }
+
+ @Inject
+ private OxmReader oxmReader;
+
+ /**
+ * If vserver is related to an image with image-name = 'TRINITY' then generic-vnf.vnf-name must match xxxxnnnnv
+ */
+ @Test
+ public void testTrinityRule() throws Exception {
+ Path configurationPath = Paths.get("bundleconfig/etc/rules");
+
+ RuleDrivenValidator validator = new RuleDrivenValidator(configurationPath, oxmReader, null, null);
+ validator.initialise();
+
+ // Find the trinity rule
+ Rule trinityRule = null;
+ for (Rule rule : validator.getRulesForEntity("vserver", "aai-event")) {
+ if (rule.getName().contains("TRINITY") && rule.getName().contains("generic-vnf")) {
+ trinityRule = rule;
+ }
+ }
+
+ // Create a set of relationship objects to be passed to the rule
+ Set<JsonObject> relationships = new LinkedHashSet<>();
+ AttributeValues attributeValues = new AttributeValues();
+ attributeValues.put("relationship-list.relationship[*]", relationships);
+
+ // Test the rule against the relationships
+ RuleTester ruleTester = new RuleTester(trinityRule, attributeValues);
+ ruleTester.test(true);
+
+ JsonObject genericVnfData = createRelationshipData(relationships, "generic-vnf");
+ ruleTester.test(true);
+
+ // Add a new object for the image relationship
+ JsonObject imageData = createRelationshipData(relationships, "image");
+ ruleTester.test(true);
+
+ createRelationshipData(relationships, "pserver");
+ ruleTester.test(true);
+
+ // Add a new JSON object for the image name
+ JsonObject imageNameProperty = createRelatedToProperty(imageData);
+ ruleTester.test(true);
+
+ setPropertyKey(imageNameProperty, "image.image-name");
+ ruleTester.test(true);
+
+ setPropertyValue(imageNameProperty, "not TRINITY");
+ ruleTester.test(true);
+
+ setPropertyValue(imageNameProperty, "TRINITY");
+ ruleTester.test(false);
+
+ JsonObject vnfNameProperty = createRelatedToProperty(genericVnfData);
+ ruleTester.test(false);
+
+ setPropertyKey(vnfNameProperty, "generic-vnf.vnf-name");
+ ruleTester.test(false);
+
+ setPropertyValue(vnfNameProperty, "invalid");
+ ruleTester.test(false);
+
+ setPropertyValue(vnfNameProperty, "");
+ ruleTester.test(false);
+
+ setPropertyValue(vnfNameProperty, "bmsx0001v");
+ ruleTester.test(true);
+
+ // Add another new object for a different image relationship
+ JsonObject image2Data = createRelationshipData(relationships, "image");
+ ruleTester.test(true);
+
+ JsonObject image2NameProperty = createRelatedToProperty(image2Data);
+ ruleTester.test(true);
+
+ setPropertyKey(image2NameProperty, "image.image-name");
+ ruleTester.test(true);
+
+ setPropertyValue(image2NameProperty, "not TRINITY");
+ ruleTester.test(true);
+
+ setPropertyValue(vnfNameProperty, "invalid");
+ ruleTester.test(false);
+
+ setPropertyValue(imageNameProperty, "not TRINITY");
+ ruleTester.test(true);
+
+ setPropertyValue(image2NameProperty, "TRINITY");
+ ruleTester.test(false);
+
+ setPropertyValue(image2NameProperty, "also not TRINITY");
+ ruleTester.test(true);
+ }
+
+ /**
+ * @param relationshipData
+ * @return
+ */
+ private JsonObject createRelatedToProperty(JsonObject relationshipData) {
+ JsonObject imageNameProperty = new JsonObject();
+ JsonElement jsonArray = new JsonArray();
+ jsonArray.getAsJsonArray().add(imageNameProperty);
+ relationshipData.add("related-to-property", jsonArray);
+ return imageNameProperty;
+ }
+
+ /**
+ * @param relationships
+ * @param relatedObject
+ * @return
+ */
+ private JsonObject createRelationshipData(Set<JsonObject> relationships, String relatedObject) {
+ JsonObject relationData = new JsonObject();
+ relationData.addProperty(AAIRelation.RELATED_TO.toString(), relatedObject);
+ relationships.add(relationData);
+ return relationData;
+ }
+
+ private void setPropertyKey(JsonObject objectMap, String propertyKeyName) {
+ objectMap.addProperty(AAIRelation.PROPERTY_KEY.toString(), propertyKeyName);
+ }
+
+ private void setPropertyValue(JsonObject objectMap, String propertyValue) {
+ objectMap.addProperty(AAIRelation.PROPERTY_VALUE.toString(), propertyValue);
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/ruledriven/rule/TestRuleExecution.java b/src/test/java/org/onap/aai/validation/ruledriven/rule/TestRuleExecution.java
new file mode 100644
index 0000000..15e958d
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/ruledriven/rule/TestRuleExecution.java
@@ -0,0 +1,494 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.ruledriven.rule;
+
+import static org.hamcrest.CoreMatchers.containsString;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.onap.aai.validation.reader.data.AttributeValues;
+import org.onap.aai.validation.ruledriven.configuration.GroovyConfigurationException;
+import org.onap.aai.validation.ruledriven.configuration.RuleSection;
+import org.onap.aai.validation.ruledriven.rule.GroovyRule;
+
+/**
+ * Tests for creating an AuditRule object and then executing the rule expression against fixed attribute values
+ *
+ * @see GroovyRule
+ *
+ */
+public class TestRuleExecution {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ @Rule
+ public final ExpectedException exception = ExpectedException.none();
+
+ /**
+ * Simple example of a rule using a boolean expression, acting on a single attribute
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testRuleCreation() throws Exception {
+ // This object represents a rule
+ GroovyRule rule = buildRule("i", "i == 44");
+
+ // Success
+ assertRuleResult(rule, 44, true);
+
+ // Failure
+ assertRuleResult(rule, 5, false);
+ }
+
+ @Test
+ public void testRuleWithMultipleAttributes() throws Exception {
+ GroovyRule rule = buildRule(Arrays.asList("i", "j"), "i == 22 && j == 44");
+
+ // Success
+ assertRuleResult(rule, Arrays.asList(22, 44), true);
+
+ // Failure
+ assertRuleResult(rule, Arrays.asList(5, 5), false);
+ assertRuleResult(rule, Arrays.asList(22, 5), false);
+ assertRuleResult(rule, Arrays.asList(5, 44), false);
+ }
+
+ /**
+ * vserver is related to vpe and vserver-name contains me6
+ */
+ @Test
+ public void testConditionalRegExp() throws Exception {
+ // !related-to.contains("vpe") || vserver-name =~ "me6"
+ String expression = "!related-to.contains(\"vpe\") || vserver-name =~ \"me6\"";
+ List<String> attributes = Arrays.asList("related-to", "vserver-name");
+ GroovyRule rule = buildRule(attributes, expression);
+
+ // Create some tests, varying the values for each attribute
+ Collection<Collection<String>> relatedToTests = new ArrayList<>();
+ Collection<Collection<String>> vserverNameTests = new ArrayList<>();
+
+ // These are the related-to values to test
+ relatedToTests.add(Collections.<String>emptyList());
+ relatedToTests.add(Arrays.asList("vpe"));
+ relatedToTests.add(Arrays.asList("vpe", "vces"));
+ relatedToTests.add(Arrays.asList("vces"));
+ relatedToTests.add(Arrays.asList("other", "vces"));
+
+ // These are the vserver-name values to test
+ Collection<String> testNames = new ArrayList<>();
+ testNames.add("fred");
+ testNames.add("me");
+ testNames.add("me7");
+ testNames.add("me6");
+ testNames.add("123me6");
+ testNames.add("me6789");
+ testNames.add("123me6789");
+
+ // Additional test for no vserver-name values present
+ vserverNameTests.add(Collections.<String>emptyList());
+
+ for (String name : testNames) {
+ // Build single element lists containing the test vserver names
+ vserverNameTests.add(Arrays.asList(name));
+
+ // Also build multi-element lists containing the test vserver names
+ vserverNameTests.add(Arrays.asList(name, "6dummy"));
+ }
+
+ // Now run the tests, computing the expected Boolean result each time
+ for (Collection<String> relatedToList : relatedToTests) {
+ // If no vpe is related, then the result will always be true
+ boolean expectedResult = !relatedToList.contains("vpe");
+
+ Map<String, Object> map = new HashMap<>();
+ map.put("related-to", relatedToList);
+
+ for (Collection<String> vserverNames : vserverNameTests) {
+ // Assign the strings to the attribute vserver-name
+ map.put("vserver-name", vserverNames);
+
+ if (expectedResult == false) {
+ for (String name : vserverNames) {
+ if (name.contains("me6")) {
+ expectedResult = true;
+ break;
+ }
+ }
+ }
+
+ testWithAttributeValue(rule, map, expectedResult);
+ }
+ }
+ }
+
+ /**
+ * generic-vnf.vnf-type should be "BW NFM" and not "bnfm"
+ */
+ @Test
+ public void testStringComparison() throws Exception {
+ String attribute = "generic-vnf.vnf-type";
+ String expression = "vnf-type == 'BW NFM'";
+ GroovyRule rule = buildRule(attribute, expression);
+ assertRuleResult(rule, "BW NFM", true);
+ assertRuleResult(rule, "bnfm", false);
+ assertRuleResult(rule, null, false);
+ assertRuleResult(rule, "", false);
+ assertRuleResult(rule, "fred", false);
+ assertRuleResult(rule, "bob", false);
+ assertRuleResult(rule, 5, false);
+ assertRuleResult(rule, 1000L, false);
+ }
+
+ @Test
+ public void testNotEquals() throws Exception {
+ GroovyRule rule = buildRule("x", "x != 'foo'");
+ assertRuleResult(rule, "", true);
+ assertRuleResult(rule, "bar", true);
+ assertRuleResult(rule, "foo", false);
+ assertRuleResult(rule, "foo\n", true);
+ assertRuleResult(rule, 5, true);
+ assertRuleResult(rule, 1000L, true);
+ assertRuleResult(rule, null, true);
+ }
+
+ @Test
+ public void testGreaterThan() throws Exception {
+ Map<Object, Boolean> tests = new HashMap<>();
+ tests.put(-1, false);
+ tests.put(0, false);
+ tests.put(1, false);
+ tests.put(4, false);
+ tests.put(5, true);
+ tests.put(55, true);
+ tests.put(null, false);
+ testRuleExpression("i", "i > 4", tests);
+ }
+
+ @Test
+ public void testValidStringLength() throws Exception {
+ String attribute = "clli";
+ String expression = "clli.size() == 8 || clli.size() == 11";
+ Map<Object, Boolean> tests = new HashMap<>();
+ tests.put("", false);
+ tests.put("X", false);
+ tests.put("1", false);
+ tests.put("1234", false);
+ tests.put("123456", false);
+ tests.put("1234567", false);
+ tests.put("12345678", true);
+ tests.put("123456789", false);
+ tests.put("1234567890", false);
+ tests.put("12345678901", true);
+ tests.put("1234567890ABC", false);
+ tests.put("1234567890123456789012345678901234567890", false);
+ testRuleExpression(attribute, expression, tests);
+ }
+
+ /**
+ * location_clli is 8 or 11 characters and must be characters only
+ */
+ @Test
+ public void testStringLengthAndChars() throws Exception {
+ String attribute = "location_clli";
+ String expression = "location_clli != null && location_clli.matches('[a-zA-Z]{8,11}')";
+ Map<Object, Boolean> tests = new HashMap<>();
+ tests.put(null, false);
+ tests.put("", false);
+ tests.put("X", false);
+ tests.put("1234567", false);
+ tests.put("12345678", false); // 8 digits
+ tests.put("ABCDEFGH", true); // 8 chars
+ tests.put("1234567890A", false); // 11 mixed
+ tests.put("abcdefghijk", true); // 11 chars
+ tests.put("AbCdEfGhIjK", true); // 11 chars
+ tests.put("AbCdEfGhIj?", false); // special char
+ testRuleExpression(attribute, expression, tests);
+ }
+
+ /**
+ * incorrect naming, e.g. expecting ae0.x (where x is unit/subinterface number), but receiving ae0.353.3303
+ */
+ @Test
+ public void testRegularExpression() throws Exception {
+ String attribute = "unit";
+ String expression = "unit.matches('^ae0\\\\.(\\\\d)+')";
+ Map<Object, Boolean> tests = new HashMap<>();
+ tests.put("", false);
+ tests.put("X", false);
+ tests.put("ae0", false);
+ tests.put("ae0.", false);
+ tests.put("ae01", false);
+ tests.put("ae012", false);
+ tests.put("ae0.1", true);
+ tests.put("ae0.354", true);
+ tests.put("ae0.354.", false);
+ tests.put("ae0.353.3303", false);
+ tests.put("ae0.353.3303.1", false);
+ testRuleExpression(attribute, expression, tests);
+ }
+
+ @Test
+ public void testNullStringLength() throws Exception {
+ String attribute = "clli";
+ String expression = "clli.size() == 8 || clli.size() == 11";
+ exception.expect(IllegalArgumentException.class);
+ exception.expectMessage(containsString("Argument"));
+ exception.expectMessage(containsString("null"));
+ GroovyRule rule = buildRule(attribute, expression);
+ rule.execute((Object[]) null);
+ }
+
+ @Test
+ public void testStringLengthWithNull() throws Exception {
+ String attribute = "a";
+ String expression = "a == null || a.size() > 4";
+ Map<Object, Boolean> tests = new HashMap<>();
+ tests.put("", false);
+ tests.put("X", false);
+ tests.put("1", false);
+ tests.put("1234", false);
+ tests.put("123456", true);
+ tests.put("1234567", true);
+ tests.put("12345678", true);
+ tests.put("123456789", true);
+ tests.put("1234567890", true);
+ tests.put("12345678901", true);
+ tests.put("1234567890ABC", true);
+ tests.put("1234567890123456789012345678901234567890", true);
+ testRuleExpression(attribute, expression, tests);
+ }
+
+ /**
+ * Prov-status cannot be ACTIVE or NULL (empty)
+ */
+ @Test
+ public void testStringTextWithNull() throws Exception {
+ String attribute = "prov-status";
+ String expression = "prov-status != null && prov-status != 'ACTIVE'";
+ Map<Object, Boolean> tests = new HashMap<>();
+ tests.put(null, false);
+ tests.put("ACTIVE", false);
+ tests.put("", true);
+ tests.put("X", true);
+ tests.put("1", true);
+ tests.put("1234", true);
+ tests.put("123456", true);
+ tests.put("1234567", true);
+ tests.put("12345678", true);
+ tests.put("123456789", true);
+ tests.put("1234567890", true);
+ tests.put("12345678901", true);
+ tests.put("1234567890ABC", true);
+ tests.put("1234567890123456789012345678901234567890", true);
+ testRuleExpression(attribute, expression, tests);
+ }
+
+ /**
+ * Prov-status cannot be ACTIVE/active or NULL/null or empty or missing
+ */
+ @Test
+ public void testCaseInsensitveStringMatch() throws Exception {
+ String attribute = "prov-status";
+ String expression =
+ "prov-status != null && prov-status.size() > 0 && !prov-status.equalsIgnoreCase('NULL') && !prov-status.equalsIgnoreCase('ACTIVE')";
+ Map<Object, Boolean> tests = new HashMap<>();
+ tests.put(null, false);
+ tests.put("", false);
+ tests.put("active", false);
+ tests.put("ACTIVE", false);
+ tests.put("null", false);
+ tests.put("NULL", false);
+ tests.put("NVTPROV", true);
+ tests.put("1", true);
+ tests.put("1234", true);
+ testRuleExpression(attribute, expression, tests);
+ }
+
+ @Test
+ public void testUsingAttributeValuesObject() throws Exception {
+ List<String> attributes = Arrays.asList("attr1", "attr2");
+ String expression = "attr1.size() == 8 || attr2.size() == 11";
+ GroovyRule rule = buildRule(attributes, expression);
+ AttributeValues attributeValues = new AttributeValues("attr1", "other");
+ attributeValues.put("attr2", "other");
+ rule.execute(attributeValues);
+ }
+
+ @Test
+ public void testMissingMethod() throws Exception {
+ String attribute = "clli";
+ String expression = "clli.size() == 8 || clli.size() == 11";
+ exception.expect(IllegalArgumentException.class);
+ exception.expectMessage(containsString("Integer"));
+ exception.expectMessage(containsString("size()"));
+ GroovyRule rule = buildRule(attribute, expression);
+ rule.execute(1);
+ }
+
+ @Test
+ public void testMultipleAttributes() throws Exception {
+ List<String> attributes = Arrays.asList("clli", "other");
+ String expression = "clli.size() == 8 || other.size() == 11";
+ exception.expect(IllegalArgumentException.class);
+ exception.expectMessage(containsString("Integer"));
+ exception.expectMessage(containsString("size()"));
+ GroovyRule rule = buildRule(attributes, expression);
+ rule.execute(new Integer(1), new Integer(2));
+ }
+
+ /**
+ * Compare two attributes (using a sub-string match)
+ */
+ @Test
+ public void testAttributeComparison() throws Exception {
+ String attribute1 = "heat-stack-id";
+ String attribute2 = "vnf-name";
+
+ // Alternative forms of the expression
+ Collection<String> expressionsToTest = new ArrayList<>();
+ expressionsToTest.add("heat-stack-id?.size() > 10 && heat-stack-id[0..10] == vnf-name");
+ expressionsToTest.add("heat-stack-id?.size() > 10 && heat-stack-id.substring(0,11) == vnf-name");
+ expressionsToTest.add("heat-stack-id?.size() > 10 && heat-stack-id.take(11) == vnf-name");
+
+ // Create some tests, varying the values for each attribute
+ Collection<String> heatStackIds = new ArrayList<>();
+ Collection<String> vnfNames = new ArrayList<>();
+
+ heatStackIds.add("123me67890abcdef");
+ heatStackIds.add("123me67890a");
+ heatStackIds.add("fred");
+ heatStackIds.add("");
+ heatStackIds.add(null);
+
+ vnfNames.add("123me67890abcdef");
+ vnfNames.add("123me67890a");
+ vnfNames.add("123me6789");
+ vnfNames.add("fred");
+ vnfNames.add("bob");
+ vnfNames.add("");
+ vnfNames.add(null);
+
+ // Build a rule per expression
+ for (String expression : expressionsToTest) {
+ GroovyRule rule = buildRule(Arrays.asList(attribute1, attribute2), expression);
+
+ // Now run the tests, computing the expected Boolean result each time
+ for (String heatStackId : heatStackIds) {
+ Map<String, Object> map = new HashMap<>();
+ map.put(attribute1, heatStackId);
+ for (String vnfName : vnfNames) {
+ map.put(attribute2, vnfName);
+ boolean expectedExpressionResult = // Java equivalent of the expression
+ heatStackId != null && heatStackId.length() > 10
+ && heatStackId.substring(0, 11).equals(vnfName);
+ testWithAttributeValue(rule, map, expectedExpressionResult);
+ }
+ }
+ }
+ }
+
+ /**
+ * @param rule
+ * @param tests
+ */
+ public void assertTestResults(GroovyRule rule, Map<Object, Boolean> tests) {
+ for (Entry<?, ?> e : tests.entrySet()) {
+ Object attributeValue = e.getKey();
+ Boolean expectedResult = (Boolean) e.getValue();
+ RuleHelper.assertRuleResult(rule, attributeValue, expectedResult);
+ }
+ }
+
+ private void testWithAttributeValue(GroovyRule rule, Map<String, Object> map, boolean expectedResult) {
+ AttributeValues attributeValues = new AttributeValues(map);
+ RuleHelper.assertRuleResult(rule, attributeValues, expectedResult);
+ }
+
+ private void testRuleExpression(String attributes, String expression, Map<Object, Boolean> tests)
+ throws InstantiationException, IllegalAccessException, IOException, GroovyConfigurationException {
+ GroovyRule rule = buildRule("testRule", attributes, expression);
+ assertTestResults(rule, tests);
+ }
+
+ /**
+ * Build a simple rule using a RuleConfiguration object
+ *
+ * @param name the rule name
+ * @param attribute a named variable, referenced in the expression
+ * @param expression the expression to evaluate (returns a Boolean value)
+ * @return
+ * @throws IOException
+ * @throws InstantiationException
+ * @throws IllegalAccessException
+ * @throws GroovyConfigurationException
+ */
+ private GroovyRule buildRule(String name, String attribute, String expression)
+ throws IOException, InstantiationException, IllegalAccessException, GroovyConfigurationException {
+ RuleSection ruleConfig = new RuleSection();
+ ruleConfig.setName(name);
+ ruleConfig.setAttributes(Collections.singletonList(attribute));
+ ruleConfig.setExpression(expression);
+ return new GroovyRule(ruleConfig);
+ }
+
+ private GroovyRule buildRule(String name, List<String> attributes, String expression)
+ throws InstantiationException, IllegalAccessException, IOException, GroovyConfigurationException {
+ RuleSection ruleConfig = new RuleSection();
+ ruleConfig.setName(name);
+ ruleConfig.setAttributes(attributes);
+ ruleConfig.setExpression(expression);
+ return new GroovyRule(ruleConfig);
+ }
+
+ /**
+ * Build a simple rule (with a default name) using a RuleConfiguration object
+ *
+ * @see TestRuleExecution#buildRule(String, String, String)
+ *
+ * @param attribute a named variable, referenced in the expression
+ * @param expression the expression to evaluate (returns a Boolean value)
+ * @throws GroovyConfigurationException
+ */
+ private GroovyRule buildRule(String attribute, String expression)
+ throws InstantiationException, IllegalAccessException, IOException, GroovyConfigurationException {
+ return buildRule("testRule", attribute, expression);
+ }
+
+ private GroovyRule buildRule(List<String> attributes, String expression)
+ throws InstantiationException, IllegalAccessException, IOException, GroovyConfigurationException {
+ return buildRule("testRule", attributes, expression);
+ }
+
+ private void assertRuleResult(GroovyRule rule, Object value, boolean expectedResult) {
+ RuleHelper.assertRuleResult(rule, value, expectedResult);
+ }
+
+}
diff --git a/src/test/java/org/onap/aai/validation/ruledriven/rule/TestRuleValidation.java b/src/test/java/org/onap/aai/validation/ruledriven/rule/TestRuleValidation.java
new file mode 100644
index 0000000..0650743
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/ruledriven/rule/TestRuleValidation.java
@@ -0,0 +1,229 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.ruledriven.rule;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.onap.aai.validation.ruledriven.configuration.GroovyConfigurationException;
+import org.onap.aai.validation.ruledriven.configuration.RuleSection;
+import org.onap.aai.validation.ruledriven.rule.GroovyRule;
+
+/**
+ * Tests for creating an AuditRule object and then executing the rule expression against fixed attribute values
+ *
+ * @see GroovyRule
+ *
+ */
+public class TestRuleValidation {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ @Rule
+ public final ExpectedException exception = ExpectedException.none();
+
+ /**
+ * Test multiple sample expressions each with various different attribute names. Each of the attribute names used in
+ * this test is valid for use within a rule.
+ *
+ * @throws GroovyConfigurationException
+ * @throws IOException
+ * @throws IllegalAccessException
+ * @throws InstantiationException
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testValidAttributeNames()
+ throws InstantiationException, IllegalAccessException, IOException, GroovyConfigurationException {
+ testValidExpressions("clli"); // Sample name
+ testValidExpressions("c");
+ testValidExpressions("i"); // Short attribute name, part of the size() text
+ testValidExpressions("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+ testValidExpressions("size"); // Does not interfere with .size() method call
+ testValidExpressions("s12"); // Digits allowed in the attribute name
+ testValidExpressions("s12s");
+ testValidExpressions("12s");
+ testValidExpressions("12-s"); // Hyphens supported
+ testValidExpressions("12_s"); // Underscores supported
+ testValidExpressions("if"); // Keyword
+ testValidExpressions("return");
+ testValidExpressions("A.B.C"); // Dots indicate a JSON Path
+ }
+
+ /**
+ * Test that the attribute name is sanitised. Each of the following attribute names is invalid for use in the rules
+ * configuration.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testInvalidAttributeNames() throws Exception {
+ testInvalidAttributeName(""); // Zero-length
+ testInvalidAttributeName("null"); // Reserved keyword
+ testInvalidAttributeName("8"); // This would cause replacement of the value 8 in the expression
+ testInvalidAttributeName("size()"); // This would replace the call to size()
+ testInvalidAttributeName("s?"); // Special character not supported by the implementation
+ testInvalidAttributeName("\"");
+ testInvalidAttributeName("s\\");
+ testInvalidAttributeName("s/");
+ testInvalidAttributeName("s\"");
+ testInvalidAttributeName("s'");
+ testInvalidAttributeName("==");
+ }
+
+ /**
+ * A rule cannot support an attribute that is zero-length. This test ensures that this is detected even when the
+ * expression itself is valid.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testZeroLengthAttribute() throws Exception {
+ String attribute = "";
+ String expression = "clli.size() == 8 || clli.size() == 11";
+ GroovyRule rule = buildRule("testRule", attribute, expression);
+ assertThat(rule.toString(), rule.isValid(), is(equalTo(false)));
+ }
+
+ @Test
+ public void testInvalidRuleSyntax() throws Exception {
+ String attribute = "fred";
+ String expression = "fred. = 8 || fred.size() == 11";
+ exception.expect(GroovyConfigurationException.class);
+ exception.expectMessage(containsString("unexpected"));
+ buildRule("testRule", attribute, expression);
+ }
+
+ @Test
+ public void testInvalidAttribute() throws Exception {
+ String attribute = "fred";
+ String expression = "size.size() == 8 || size.size() == 11";
+ GroovyRule rule = buildRule("testRule", attribute, expression);
+
+ assertThat(rule.toString(), rule.isValid(), is(equalTo(false)));
+ }
+
+ /**
+ * Utility to build and test different expressions using the supplied attribute name
+ *
+ * @param attribute attribute (field) identifier
+ * @throws InstantiationException
+ * @throws IllegalAccessException
+ * @throws IOException
+ * @throws GroovyConfigurationException
+ */
+ private void testValidExpressions(String attribute)
+ throws InstantiationException, IllegalAccessException, IOException, GroovyConfigurationException {
+ testValidLengthRule(attribute);
+ }
+
+ /**
+ * Utility to build and test an expression asserting that the size() of the attribute is 8 or 11
+ *
+ * @param attribute attribute (field) identifier
+ * @throws InstantiationException
+ * @throws IllegalAccessException
+ * @throws IOException
+ * @throws GroovyConfigurationException
+ */
+ private void testValidLengthRule(String attribute)
+ throws InstantiationException, IllegalAccessException, IOException, GroovyConfigurationException {
+ String fieldName = attribute.substring(attribute.lastIndexOf(".") + 1);
+ String expression = fieldName + ".size() == 8 || " + fieldName + ".size() == 11";
+ GroovyRule rule = buildRule("testRule", attribute, expression);
+
+ // Test that the rule is valid
+ assertThat(rule.toString(), rule.isValid(), is(equalTo(true)));
+
+ // Now test that the rule actually executes successfully
+ Map<Object, Boolean> tests = new HashMap<>();
+ tests.put("", false);
+ tests.put("X", false);
+ tests.put("1234567", false);
+ tests.put("12345678", true); // 8 digits
+ tests.put("ABCDEFGH", true); // 8 chars
+ tests.put("12E4567890A", true); // 11 mixed digits/chars
+ tests.put("abcdefghijk", true); // 11 chars
+ tests.put("AbCdEfGhIjK", true); // 11 chars mixed case
+ tests.put("AbCdEfGhIj?", true); // special char
+ testRuleExpression(attribute, expression, tests);
+ }
+
+ private void testRuleExpression(String attributes, String expression, Map<Object, Boolean> tests)
+ throws InstantiationException, IllegalAccessException, IOException, GroovyConfigurationException {
+ GroovyRule rule = buildRule("testRule", attributes, expression);
+ assertThat("The rule should be valid", rule.isValid(), is(equalTo(true)));
+ for (Entry<?, ?> e : tests.entrySet()) {
+ Object attributeValue = e.getKey();
+ Boolean expectedResult = (Boolean) e.getValue();
+ RuleHelper.assertRuleResult(rule, attributeValue, expectedResult);
+ }
+ }
+
+ /**
+ * Build a simple rule using a RuleConfiguration object
+ *
+ * @param name the rule name
+ * @param attribute a named variable, referenced in the expression
+ * @param expression the expression to evaluate (returns a Boolean value)
+ * @return
+ * @throws IOException
+ * @throws InstantiationException
+ * @throws IllegalAccessException
+ * @throws GroovyConfigurationException
+ */
+ private GroovyRule buildRule(String name, String attribute, String expression)
+ throws InstantiationException, IllegalAccessException, IOException, GroovyConfigurationException {
+ RuleSection ruleConfig = new RuleSection();
+ ruleConfig.setName(name);
+ ruleConfig.setAttributes(Collections.singletonList(attribute));
+ ruleConfig.setExpression(expression);
+ return new GroovyRule(ruleConfig);
+ }
+
+ /**
+ * Utility to build a rule and test that the attribute is valid
+ *
+ * @param attribute attribute (field) identifier
+ * @throws InstantiationException
+ * @throws IllegalAccessException
+ * @throws IOException
+ * @throws GroovyConfigurationException
+ */
+ private void testInvalidAttributeName(String attribute)
+ throws InstantiationException, IllegalAccessException, IOException, GroovyConfigurationException {
+ String expression = attribute + ".size() == 8 || " + attribute + ".size() == 11";
+ GroovyRule rule = buildRule("testRule", attribute, expression);
+
+ // Test that the rule is invalid
+ assertThat(rule.toString(), rule.isValid(), is(equalTo(false)));
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/ruledriven/validator/TestRuleDrivenValidator.java b/src/test/java/org/onap/aai/validation/ruledriven/validator/TestRuleDrivenValidator.java
new file mode 100644
index 0000000..cf1e874
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/ruledriven/validator/TestRuleDrivenValidator.java
@@ -0,0 +1,125 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.ruledriven.validator;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.google.gson.JsonSyntaxException;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.BiPredicate;
+import java.util.stream.Stream;
+import javax.inject.Inject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.aai.validation.exception.ValidationServiceException;
+import org.onap.aai.validation.result.ValidationResult;
+import org.onap.aai.validation.ruledriven.RuleDrivenValidator;
+import org.onap.aai.validation.test.util.TestEntity;
+import org.onap.aai.validation.test.util.ValidationResultIsEqual;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@TestPropertySource(properties = {"schemaIngestPropLoc = src/test/resources/oxm-reader/schemaIngest.properties"})
+@ContextConfiguration(
+ locations = {"classpath:" + TestRuleDrivenValidator.UNIT_TEST_FOLDER + "/test-rule-driven-validator-beans.xml"})
+public class TestRuleDrivenValidator {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ public static final String UNIT_TEST_FOLDER = "rule-driven-validator";
+ private static final String TEST_EVENTS_PATH = "/test_events";
+
+ @Inject
+ private RuleDrivenValidator validator;
+
+ /**
+ * @param testEntitiesPath
+ * @param testEventsPath
+ * @param resultsPath
+ * @return all test entities
+ * @throws URISyntaxException
+ */
+ public static List<TestEntity> getEntities(String testEntitiesPath, String testEventsPath, String resultsPath)
+ throws URISyntaxException {
+ Path testEvents = Paths.get(ClassLoader.getSystemResource(testEntitiesPath + testEventsPath).toURI());
+
+ BiPredicate<Path, BasicFileAttributes> jsonMatcher =
+ (path, basicFileAttributes) -> path.toFile().getName().matches(".*\\.json");
+
+ List<TestEntity> entitiesList = new ArrayList<>();
+ try (Stream<Path> paths = Files.find(testEvents, 2, jsonMatcher)) {
+ paths.forEach((path) -> entitiesList.add(new TestEntity(testEvents, path, testEventsPath, resultsPath)));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ return entitiesList;
+ }
+
+ /**
+ * @throws ValidationServiceException
+ * @throws JsonSyntaxException
+ * @throws URISyntaxException
+ * @throws IOException
+ */
+ @Test
+ public void testValidateUnitTestInstances()
+ throws ValidationServiceException, JsonSyntaxException, URISyntaxException, IOException {
+ validateEntities(UNIT_TEST_FOLDER, TEST_EVENTS_PATH, "/results/expected");
+ }
+
+ /**
+ * @param inputEventsFolder
+ * @param testEventsPath
+ * @param resultsPath
+ * @throws URISyntaxException
+ * @throws ValidationServiceException
+ * @throws IOException
+ */
+ private void validateEntities(String inputEventsFolder, String testEventsPath, String resultsPath)
+ throws URISyntaxException, ValidationServiceException, IOException {
+ for (TestEntity entity : getEntities(inputEventsFolder, testEventsPath, resultsPath)) {
+ List<ValidationResult> results = validator.validate(entity.getJson());
+ assertThat(results.size(), is(1));
+ ValidationResult expectedResult = entity.getExpectedValidationResult();
+ if (expectedResult == null) {
+ Path testEvents = Paths.get(ClassLoader.getSystemResource(inputEventsFolder + resultsPath).toURI());
+ StringBuilder sb = new StringBuilder();
+ Files.walk(testEvents).forEach((path) -> sb.append(path).append("\n"));
+ assertThat("Expected results missing (" + entity.expectedResultsFile + ")\n" + sb.toString(),
+ expectedResult, is(notNullValue()));
+ }
+ assertThat(entity.inputFile.getAbsolutePath(), results.get(0),
+ is(ValidationResultIsEqual.equalTo(expectedResult)));
+ }
+ }
+
+}
diff --git a/src/test/java/org/onap/aai/validation/services/TestInfoService.java b/src/test/java/org/onap/aai/validation/services/TestInfoService.java
new file mode 100644
index 0000000..0bfa8ba
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/services/TestInfoService.java
@@ -0,0 +1,140 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.services;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.CoreMatchers.startsWith;
+import static org.junit.Assert.assertThat;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import javax.inject.Inject;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.aai.validation.controller.ValidationController;
+import org.onap.aai.validation.exception.ValidationServiceException;
+import org.onap.aai.validation.publisher.MockEventPublisher;
+import org.onap.aai.validation.services.InfoService;
+import org.onap.aai.validation.test.util.TestEntity;
+import org.onap.aai.validation.test.util.TestUtil;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@TestPropertySource(properties = {"schemaIngestPropLoc = src/test/resources/oxm-reader/schemaIngest.properties"})
+@ContextConfiguration(locations = {"classpath:/info-service/test-validation-service-beans.xml"})
+public class TestInfoService {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ enum TestData {
+ // @formatter:off
+ VSERVER ("rule-driven-validator/test_events/vserver-create-event.json");
+
+ private String filename;
+ TestData(String filename) {this.filename = filename;}
+ public String getFilename() {return this.filename;}
+ // @formatter:on
+ }
+
+ private InfoService infoService;
+
+ @Inject
+ private ValidationController validationController;
+
+ @Inject
+ MockEventPublisher messagePublisher;
+
+ @Before
+ public void setUp() throws ValidationServiceException {
+ infoService = new InfoService();
+ infoService.setValidationController(validationController);
+ }
+
+ /**
+ * @throws ValidationServiceException
+ */
+ @Test
+ public void testInitialisedInfoService() throws ValidationServiceException {
+ assertThat(infoService.getValidationController(), is(validationController));
+ String info = infoService.getInfo();
+ assertResultsStringFormatted(info);
+ }
+
+ /**
+ * @throws ValidationServiceException
+ */
+ @Test
+ public void testThrowableRecorded() throws ValidationServiceException {
+ validationController.recordThrowable(new Exception());
+ String info = infoService.getInfo();
+ assertResultsStringFormatted(info);
+ assertThat(info, containsString("Exception reported"));
+ }
+
+ /**
+ * @throws ValidationServiceException
+ */
+ @Test
+ public void testInvalidEventRecorded() throws ValidationServiceException {
+ validationController.execute("", "http");
+ String info = infoService.getInfo();
+ assertResultsStringFormatted(info);
+ assertThat(info, containsString("errored=1"));
+ }
+
+ /**
+ * @throws ValidationServiceException
+ * @throws IOException
+ * @throws URISyntaxException
+ */
+ @Test
+ public void testVserverEventRecorded() throws ValidationServiceException, URISyntaxException, IOException {
+ Path vserverTestFile = Paths.get(ClassLoader.getSystemResource(TestData.VSERVER.getFilename()).toURI());
+ Path root = vserverTestFile.getParent();
+ assertThat(root, is(not(nullValue())));
+ TestEntity entity = new TestEntity(root, vserverTestFile, "test_events", "results/expected");
+ messagePublisher.setTestEntity(entity);
+ messagePublisher.setTestDescription(entity.inputFile.getAbsolutePath());
+ validationController.execute(TestUtil.getFileAsString(TestData.VSERVER.getFilename()), "http");
+ String info = infoService.getInfo();
+ assertResultsStringFormatted(info);
+ assertThat(info, containsString("total=1"));
+ }
+
+ /**
+ * Assert that the info service status string contains the expected standard results and formatting.
+ *
+ * @param info
+ */
+ private void assertResultsStringFormatted(String info) {
+ assertThat(info, startsWith("Status: Up\n"));
+ assertThat(info, containsString("Started at"));
+ assertThat(info, containsString("total=0"));
+ }
+
+}
diff --git a/src/test/java/org/onap/aai/validation/services/TestValidateServiceImpl.java b/src/test/java/org/onap/aai/validation/services/TestValidateServiceImpl.java
new file mode 100644
index 0000000..e23f7a2
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/services/TestValidateServiceImpl.java
@@ -0,0 +1,115 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.services;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+
+import java.net.URISyntaxException;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map.Entry;
+import javax.security.auth.x500.X500Principal;
+import javax.ws.rs.core.MultivaluedHashMap;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onap.aai.auth.AAIMicroServiceAuth;
+import org.onap.aai.validation.controller.ValidationController;
+import org.onap.aai.validation.services.ValidateServiceImpl;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.mock.web.MockHttpServletRequest;
+
+public class TestValidateServiceImpl {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ private ValidationController mockValidationController;
+ private AAIMicroServiceAuth mockAaiMicroServiceAuth;
+
+ @Before
+ public void setUp() {
+ mockValidationController = Mockito.mock(ValidationController.class);
+ mockAaiMicroServiceAuth = Mockito.mock(AAIMicroServiceAuth.class);
+ }
+
+ @Test
+ public void validateConstructor() {
+ ValidateServiceImpl validateServiceImpl =
+ new ValidateServiceImpl(mockValidationController, mockAaiMicroServiceAuth);
+ assertNotNull(validateServiceImpl);
+ assertThat(validateServiceImpl.toString(), is(notNullValue()));
+ }
+
+ @Test
+ public void testValidateEventWithoutHeaderFailure() {
+ ValidateServiceImpl validateServiceImpl =
+ new ValidateServiceImpl(mockValidationController, mockAaiMicroServiceAuth);
+ ResponseEntity<String> response = validateServiceImpl.validate("testEvent");
+ assertThat(response.getStatusCode(), is(HttpStatus.INTERNAL_SERVER_ERROR));
+ }
+
+ /**
+ * Create a (mocked) HTTPS request and invoke the Babel generate artifacts API
+ *
+ * @param request for the Babel Service
+ * @return the Response from the HTTP API
+ * @throws URISyntaxException
+ */
+ @Test
+ public void testRequestWithHeaders() throws URISyntaxException {
+ // Create mocked request headers map
+ MultivaluedHashMap<String, String> headersMap = new MultivaluedHashMap<>();
+ headersMap.put("X-TransactionId", createSingletonList("transaction-id"));
+ headersMap.put("X-FromAppId", createSingletonList("app-id"));
+ headersMap.put("Host", createSingletonList("hostname"));
+
+ HttpHeaders headers = Mockito.mock(HttpHeaders.class);
+ for (Entry<String, List<String>> entry : headersMap.entrySet()) {
+ Mockito.when(headers.get(entry.getKey())).thenReturn(entry.getValue());
+ }
+
+ MockHttpServletRequest servletRequest = new MockHttpServletRequest();
+ servletRequest.setSecure(true);
+ servletRequest.setScheme("https");
+ servletRequest.setServerPort(9501);
+ servletRequest.setServerName("localhost");
+ servletRequest.setRequestURI("/services/validation-service/v1/app/validate");
+
+ X509Certificate mockCertificate = Mockito.mock(X509Certificate.class);
+ Mockito.when(mockCertificate.getSubjectX500Principal())
+ .thenReturn(new X500Principal("CN=test, OU=qa, O=Test Ltd, L=London, ST=London, C=GB"));
+
+ servletRequest.setAttribute("javax.servlet.request.X509Certificate", new X509Certificate[] {mockCertificate});
+ servletRequest.setAttribute("javax.servlet.request.cipher_suite", "");
+
+ ValidateServiceImpl service = new ValidateServiceImpl(mockValidationController, mockAaiMicroServiceAuth);
+ service.validate(headers, servletRequest, "testEvent");
+ }
+
+ private List<String> createSingletonList(String listItem) {
+ return Collections.<String>singletonList(listItem);
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/test/util/RandomString.java b/src/test/java/org/onap/aai/validation/test/util/RandomString.java
new file mode 100644
index 0000000..ba2d85e
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/test/util/RandomString.java
@@ -0,0 +1,40 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.test.util;
+
+import java.util.Random;
+
+public class RandomString {
+
+ private static final String VALID_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+ private static final int MAX_STRING_LENGTH = 50;
+ private static Random rng = new Random();
+
+ public static String generate() {
+ return generateString(rng, VALID_CHARS, rng.nextInt(MAX_STRING_LENGTH) + 1);
+ }
+
+ public static String generateString(Random rng, String characters, int length) {
+ char[] text = new char[length];
+ for (int i = 0; i < length; i++) {
+ text[i] = characters.charAt(rng.nextInt(characters.length()));
+ }
+ return new String(text);
+ }
+
+}
diff --git a/src/test/java/org/onap/aai/validation/test/util/TestEntity.java b/src/test/java/org/onap/aai/validation/test/util/TestEntity.java
new file mode 100644
index 0000000..e42873a
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/test/util/TestEntity.java
@@ -0,0 +1,88 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.test.util;
+
+import com.google.gson.JsonSyntaxException;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.NoSuchFileException;
+import java.nio.file.Path;
+import org.onap.aai.validation.result.ValidationResult;
+
+public class TestEntity {
+
+ public File inputFile;
+ public String expectedResultsFile;
+
+ public TestEntity(Path root, Path inputFilePath, String inputEventsPath, String outputEventsPath) {
+ String rootUri = root.toUri().toString();
+ String resultsRoot = rootUri.replaceAll(inputEventsPath + "/$", outputEventsPath + "/");
+ String inputFileUri = inputFilePath.toUri().toString();
+ this.inputFile = inputFilePath.toFile();
+ this.expectedResultsFile = inputFileUri.replace(rootUri, resultsRoot).replaceAll("\\.json$", ".exp.json");
+ }
+
+ public String getJson() throws URISyntaxException, IOException {
+ return TestUtil.getFileAsString(inputFile.getPath());
+ }
+
+ /**
+ * @return the contents of the file that stores the expected JSON, or an empty string if there is no expected JSON
+ * @throws URISyntaxException
+ * @throws IOException
+ */
+ public String getExpectedJson() throws URISyntaxException, IOException {
+ try {
+ return TestUtil.getFileAsString(new URI(expectedResultsFile).getPath());
+ } catch (NoSuchFileException e) {
+ return "";
+ }
+ }
+
+ public ValidationResult getExpectedValidationResult() throws JsonSyntaxException, URISyntaxException, IOException {
+ return ValidationResult.fromJson(getExpectedJson());
+ }
+
+ @Override
+ public String toString() {
+ return "TestEntity [inputFile=" + inputFile + ", expectedResultsFile=" + expectedResultsFile + "]";
+ }
+
+ public boolean expectsError() throws URISyntaxException, IOException {
+ try {
+ getErrorFileContents();
+ } catch (NoSuchFileException e) {
+ return false;
+ }
+ return true;
+ }
+
+ public String getExpectedErrorMessage() throws URISyntaxException, IOException {
+ return getErrorFileContents().trim();
+ }
+
+ private String getErrorFileContents() throws URISyntaxException, IOException {
+ return TestUtil.getFileAsString(new URI(getErrorFileURI()).getPath());
+ }
+
+ private String getErrorFileURI() {
+ return expectedResultsFile.replaceAll("\\.exp\\.json$", ".error");
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/test/util/TestUtil.java b/src/test/java/org/onap/aai/validation/test/util/TestUtil.java
new file mode 100644
index 0000000..39d1246
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/test/util/TestUtil.java
@@ -0,0 +1,52 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.test.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+/**
+ * Test helper methods.
+ */
+public class TestUtil {
+
+ /**
+ * Gets files, such as test data from the classpath.
+ *
+ * @param filename the name of the file
+ * @return a String with the file contents.
+ * @throws URISyntaxException
+ * @throws IOException
+ */
+ public static String getFileAsString(String filename) throws URISyntaxException, IOException {
+ // Try loading the named file directly
+ URI uri = new File(filename).toURI();
+ URL systemResource = ClassLoader.getSystemResource(filename);
+ if (systemResource != null) {
+ uri = systemResource.toURI();
+ }
+ byte[] encoded = Files.readAllBytes(Paths.get(uri));
+ return new String(encoded, StandardCharsets.UTF_8);
+ }
+}
diff --git a/src/test/java/org/onap/aai/validation/test/util/ValidationResultIsEqual.java b/src/test/java/org/onap/aai/validation/test/util/ValidationResultIsEqual.java
new file mode 100644
index 0000000..aa6471f
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/test/util/ValidationResultIsEqual.java
@@ -0,0 +1,58 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.test.util;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.onap.aai.validation.result.ValidationResult;
+
+/**
+ * Matcher for comparing actual and expected ValidationResults
+ *
+ */
+public class ValidationResultIsEqual extends BaseMatcher<ValidationResult> {
+ private final ValidationResult expected;
+
+ public static Matcher<? super ValidationResult> equalTo(ValidationResult validationResult) {
+ return new ValidationResultIsEqual(validationResult);
+ }
+
+ private ValidationResultIsEqual(ValidationResult expected) {
+ this.expected = expected;
+ }
+
+ @Override
+ public boolean matches(Object o) {
+ if (expected == null) {
+ return false;
+ }
+ ValidationResult actual = (ValidationResult) o;
+ return actual.getEntityId().equals(expected.getEntityId()) && //
+ actual.getEntityType().equals(expected.getEntityType()) && //
+ (actual.getEntityLink() == null ? "" : actual.getEntityLink()).equals(expected.getEntityLink()) && //
+ actual.getResourceVersion().equals(expected.getResourceVersion()) && //
+ actual.getViolations().equals(expected.getViolations());
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText(expected == null ? "<not defined>" : expected.toString());
+ }
+
+}
diff --git a/src/test/java/org/onap/aai/validation/util/TestStringUtils.java b/src/test/java/org/onap/aai/validation/util/TestStringUtils.java
new file mode 100644
index 0000000..038e10d
--- /dev/null
+++ b/src/test/java/org/onap/aai/validation/util/TestStringUtils.java
@@ -0,0 +1,170 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * 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.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.aai.validation.util;
+
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import java.util.Arrays;
+import java.util.List;
+import org.junit.Test;
+import org.onap.aai.validation.exception.ValidationServiceException;
+import org.onap.aai.validation.util.StringUtils;
+
+public class TestStringUtils {
+
+ static {
+ System.setProperty("APP_HOME", ".");
+ }
+
+ @Test
+ public void testStripSinglePrefix() throws Exception {
+ String prefixDelimiter = ".";
+ String prefix = "prefix";
+ String suffix = "suffix";
+ String testString = prefix + prefixDelimiter + suffix;
+
+ String result = StringUtils.stripPrefix(testString, prefixDelimiter);
+
+ assertEquals("Prefix incorrectly stripped.", suffix, result);
+ }
+
+ @Test
+ public void testStripMultiplePrefix() throws Exception {
+ String prefixDelimiter = "***";
+ String prefix = "prefix";
+ String suffix = "suffix";
+ String testString = prefix + prefixDelimiter + prefix + prefixDelimiter + suffix;
+
+ String result = StringUtils.stripPrefix(testString, prefixDelimiter);
+
+ assertEquals("Prefix incorrectly stripped.", suffix, result);
+ }
+
+ @Test
+ public void testStripSubstr() {
+ List<String> stringList = Arrays.asList("/text()one", "tw/text()o", "three/text()");
+ List<String> stripSubstr = StringUtils.stripSuffix(stringList, "/text()");
+ assertThat(stripSubstr, containsInAnyOrder("/text()one", "tw/text()o", "three"));
+ }
+
+ @Test
+ public void testStripStringRegex() throws Exception {
+ String prefixDelimiter = "/aai/v8/";
+ String prefix = "prefix";
+ String suffix = "suffix";
+ String testString = prefix + prefixDelimiter + suffix;
+ String regex = "\\/aai\\/v[0-9]*\\/";
+
+ String stripString = StringUtils.stripPrefixRegex(testString, regex);
+
+ assertThat(stripString, is(suffix));
+ }
+
+ @Test
+ public void testStripStringRegexNotFound() throws Exception {
+ String prefixDelimiter = "delimiter";
+ String prefix = "prefix";
+ String suffix = "suffix";
+ String testString = prefix + prefixDelimiter + suffix;
+ String regex = "\\/aai\\/v[0-9]*\\/";
+
+ String stripString = StringUtils.stripPrefixRegex(testString, regex);
+
+ assertThat(stripString, is(testString));
+ }
+
+ @Test
+ public void testStripStringRegexMultiplePrefix() throws Exception {
+ String prefixDelimiter = "/aai/v8/";
+ String prefix = "prefix";
+ String suffix = "text" + prefixDelimiter + "text";
+ String testString = prefix + prefixDelimiter + suffix;
+ String regex = "\\/aai\\/v[0-9]*\\/";
+
+ String stripString = StringUtils.stripPrefixRegex(testString, regex);
+
+ assertThat(stripString, is(suffix));
+ }
+
+ @Test
+ public void testStripStringRegexNullString() throws Exception {
+ String testString = null;
+ String regex = "\\/aai\\/v[0-9]*\\/";
+
+ String stripString = StringUtils.stripPrefixRegex(testString, regex);
+
+ assertThat(stripString, nullValue());
+ }
+
+ @Test
+ public void testStripStringRegexEmptyString() throws Exception {
+ String testString = "";
+ String regex = "\\/aai\\/v[0-9]*\\/";
+
+ String stripString = StringUtils.stripPrefixRegex(testString, regex);
+
+ assertThat(stripString, is(testString));
+ }
+
+ @Test
+ public void testStripStringRegexNullRegex() throws Exception {
+ String testString = "test";
+ String regex = null;
+
+ String stripString = StringUtils.stripPrefixRegex(testString, regex);
+
+ assertThat(stripString, is(testString));
+ }
+
+ @Test
+ public void testStripStringRegexEmptyRegex() throws Exception {
+ String testString = "test";
+ String regex = "";
+
+ String stripString = StringUtils.stripPrefixRegex(testString, regex);
+
+ assertThat(stripString, is(testString));
+ }
+
+ @Test(expected = ValidationServiceException.class)
+ public void testStripStringRegexInvalidRegex() throws Exception {
+ String prefixDelimiter = "/aai/v8/";
+ String prefix = "prefix";
+ String suffix = "suffix";
+ String testString = prefix + prefixDelimiter + suffix;
+ String regex = "***";
+
+ StringUtils.stripPrefixRegex(testString, regex);
+ }
+
+ @Test
+ public void testStripStringRegexLimitedPrefix() throws Exception {
+ String prefixDelimiter = "/aai/v8/";
+ String suffix = "suffix";
+ String testString = prefixDelimiter + suffix;
+ String regex = "\\/aai\\/v[0-9]*\\/";
+
+ String stripString = StringUtils.stripPrefixRegex(testString, regex);
+
+ assertThat(stripString, is(suffix));
+ }
+}