summaryrefslogtreecommitdiffstats
path: root/aai-core
diff options
context:
space:
mode:
Diffstat (limited to 'aai-core')
-rw-r--r--aai-core/src/main/java/org/onap/aai/prevalidation/ValidationConfiguration.java3
-rw-r--r--aai-core/src/main/java/org/onap/aai/rest/notification/NotificationService.java18
-rw-r--r--aai-core/src/main/java/org/onap/aai/web/KafkaConfig.java3
-rw-r--r--aai-core/src/test/java/org/onap/aai/rest/db/HttpEntryNotificationIntegrationTest.java212
-rw-r--r--aai-core/src/test/java/org/onap/aai/rest/db/HttpEntryTest.java91
-rw-r--r--aai-core/src/test/java/org/onap/aai/rest/notification/NotificationServiceTest.java128
-rw-r--r--aai-core/src/test/java/org/onap/aai/rest/notification/UEBNotificationTest.java (renamed from aai-core/src/test/java/org/onap/aai/rest/ueb/UEBNotificationTest.java)3
7 files changed, 375 insertions, 83 deletions
diff --git a/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationConfiguration.java b/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationConfiguration.java
index 7030cf7d..c1a4f2a7 100644
--- a/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationConfiguration.java
+++ b/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationConfiguration.java
@@ -26,10 +26,9 @@ import org.onap.aai.restclient.RestClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Profile;
-@Profile("pre-validation")
@Configuration
+@ConditionalOnProperty(name = "aai.notification.validation.enabled", havingValue = "true")
public class ValidationConfiguration {
@Bean(name = "validationRestClient")
diff --git a/aai-core/src/main/java/org/onap/aai/rest/notification/NotificationService.java b/aai-core/src/main/java/org/onap/aai/rest/notification/NotificationService.java
index d6a3f897..9c3dde15 100644
--- a/aai-core/src/main/java/org/onap/aai/rest/notification/NotificationService.java
+++ b/aai-core/src/main/java/org/onap/aai/rest/notification/NotificationService.java
@@ -35,7 +35,6 @@ import org.onap.aai.exceptions.AAIException;
import org.onap.aai.introspection.Introspector;
import org.onap.aai.introspection.LoaderFactory;
import org.onap.aai.prevalidation.ValidationService;
-import org.onap.aai.rest.db.HttpEntry;
import org.onap.aai.serialization.db.DBSerializer;
import org.onap.aai.serialization.engines.query.QueryEngine;
import org.onap.aai.setup.SchemaVersion;
@@ -43,8 +42,8 @@ import org.onap.aai.util.AAIConfig;
import org.onap.aai.util.delta.DeltaEvents;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
@Service
@@ -52,28 +51,23 @@ public class NotificationService {
public static final Logger LOGGER = LoggerFactory.getLogger(NotificationService.class);
+ private final ValidationService validationService;
private final LoaderFactory loaderFactory;
private final boolean isDeltaEventsEnabled;
private final String basePath;
public NotificationService(
+ @Nullable ValidationService validationService,
LoaderFactory loaderFactory,
@Value("${schema.uri.base.path}") String basePath,
@Value("${delta.events.enabled:false}") boolean isDeltaEventsEnabled) {
+ this.validationService = validationService;
this.loaderFactory = loaderFactory;
this.basePath = basePath;
this.isDeltaEventsEnabled = isDeltaEventsEnabled;
}
/**
- * Inject the validation service if the profile pre-valiation is enabled,
- * Otherwise this variable will be set to null and thats why required=false
- * so that it can continue even if pre validation isn't enabled
- */
- @Autowired(required = false)
- private ValidationService validationService;
-
- /**
* Generate notification events for the resulting db requests.
*/
public void generateEvents(UEBNotification notification, int notificationDepth, String sourceOfTruth, DBSerializer serializer,
@@ -100,9 +94,7 @@ public class NotificationService {
LOGGER.warn("Encountered exception generating events", e);
}
- // Since @Autowired required is set to false, we need to do a null check
- // for the existence of the validationService since its only enabled if profile
- // is enabled
+ // validation is configurable via aai.notification.validation.enabled
if (validationService != null) {
validationService.validate(notification.getEvents());
}
diff --git a/aai-core/src/main/java/org/onap/aai/web/KafkaConfig.java b/aai-core/src/main/java/org/onap/aai/web/KafkaConfig.java
index 05e4768d..c1e8357d 100644
--- a/aai-core/src/main/java/org/onap/aai/web/KafkaConfig.java
+++ b/aai-core/src/main/java/org/onap/aai/web/KafkaConfig.java
@@ -176,9 +176,10 @@ public class KafkaConfig {
}
@Bean
+ @ConditionalOnMissingBean
public NotificationService notificationService(LoaderFactory loaderFactory,
@Value("${schema.uri.base.path}") String basePath,
@Value("${delta.events.enabled:false}") boolean isDeltaEventsEnabled) {
- return new NotificationService(loaderFactory, basePath, isDeltaEventsEnabled);
+ return new NotificationService(null, loaderFactory, basePath, isDeltaEventsEnabled);
}
}
diff --git a/aai-core/src/test/java/org/onap/aai/rest/db/HttpEntryNotificationIntegrationTest.java b/aai-core/src/test/java/org/onap/aai/rest/db/HttpEntryNotificationIntegrationTest.java
new file mode 100644
index 00000000..e8e3d691
--- /dev/null
+++ b/aai-core/src/test/java/org/onap/aai/rest/db/HttpEntryNotificationIntegrationTest.java
@@ -0,0 +1,212 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2024 Deutsche Telekom. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aai.rest.db;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.when;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.javatuples.Pair;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onap.aai.AAISetup;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.introspection.Introspector;
+import org.onap.aai.introspection.Loader;
+import org.onap.aai.introspection.ModelType;
+import org.onap.aai.parsers.query.QueryParser;
+import org.onap.aai.query.builder.QueryOptions;
+import org.onap.aai.rest.notification.UEBNotification;
+import org.onap.aai.restcore.HttpMethod;
+import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+import org.springframework.test.annotation.DirtiesContext;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
+public class HttpEntryNotificationIntegrationTest extends AAISetup {
+
+ private static final MediaType APPLICATION_JSON = MediaType.valueOf("application/json");
+ private Loader loader;
+ private TransactionalGraphEngine dbEngine;
+ private GraphTraversalSource traversal;
+ private HttpHeaders httpHeaders;
+ private UriInfo uriInfo;
+ private MultivaluedMap<String, String> headersMultiMap;
+ private MultivaluedMap<String, String> queryParameters;
+ private List<String> aaiRequestContextList;
+ private List<MediaType> outputMediaTypes;
+
+ ObjectMapper mapper = new ObjectMapper();
+
+ @Before
+ public void setup() {
+
+ httpHeaders = Mockito.mock(HttpHeaders.class);
+ uriInfo = Mockito.mock(UriInfo.class);
+
+ headersMultiMap = new MultivaluedHashMap<>();
+ queryParameters = Mockito.spy(new MultivaluedHashMap<>());
+
+ headersMultiMap.add("X-FromAppId", "JUNIT");
+ headersMultiMap.add("X-TransactionId", UUID.randomUUID().toString());
+ headersMultiMap.add("Real-Time", "true");
+ headersMultiMap.add("Accept", "application/json");
+ headersMultiMap.add("aai-request-context", "");
+
+ outputMediaTypes = new ArrayList<>();
+ outputMediaTypes.add(APPLICATION_JSON);
+
+ aaiRequestContextList = new ArrayList<>();
+ aaiRequestContextList.add("");
+
+ traversalHttpEntry.setHttpEntryProperties(schemaVersions.getDefaultVersion());
+ loader = traversalHttpEntry.getLoader();
+ dbEngine = traversalHttpEntry.getDbEngine();
+ traversal = dbEngine.tx().traversal();
+
+ when(httpHeaders.getAcceptableMediaTypes()).thenReturn(outputMediaTypes);
+ when(httpHeaders.getRequestHeaders()).thenReturn(headersMultiMap);
+
+ when(httpHeaders.getRequestHeader("aai-request-context")).thenReturn(aaiRequestContextList);
+
+ when(uriInfo.getQueryParameters()).thenReturn(queryParameters);
+ when(uriInfo.getQueryParameters(false)).thenReturn(queryParameters);
+
+ // TODO - Check if this is valid since RemoveDME2QueryParameters seems to be
+ // very unreasonable
+ Mockito.doReturn(null).when(queryParameters).remove(any());
+
+ when(httpHeaders.getMediaType()).thenReturn(APPLICATION_JSON);
+ }
+
+ @After
+ public void rollback() {
+ dbEngine.rollback();
+ }
+
+ @Test
+ public void notificationOnRelatedToTest() throws UnsupportedEncodingException, AAIException {
+
+ Loader ld = loaderFactory.createLoaderForVersion(ModelType.MOXY, schemaVersions.getDefaultVersion());
+ UEBNotification uebNotification = Mockito.spy(new UEBNotification(ld, loaderFactory, schemaVersions));
+ traversalHttpEntry.setHttpEntryProperties(schemaVersions.getDefaultVersion(), uebNotification);
+
+ Loader loader = traversalHttpEntry.getLoader();
+ TransactionalGraphEngine dbEngine = traversalHttpEntry.getDbEngine();
+ // Put pserver
+ String uri = "/cloud-infrastructure/pservers/pserver/junit-edge-test-pserver";
+ String content = "{\"hostname\":\"junit-edge-test-pserver\"}";
+ doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, content);
+ // Put complex
+ uri = "/cloud-infrastructure/complexes/complex/junit-edge-test-complex";
+ content = "{\"physical-location-id\":\"junit-edge-test-complex\",\"physical-location-type\":\"AAIDefault\",\"street1\":\"AAIDefault\",\"city\":\"AAIDefault\",\"state\":\"NJ\",\"postal-code\":\"07748\",\"country\":\"USA\",\"region\":\"US\"}";
+ doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, content);
+
+ // PutEdge
+ uri = "/cloud-infrastructure/complexes/complex/junit-edge-test-complex/relationship-list/relationship";
+ content = "{\"related-to\":\"pserver\",\"related-link\":\"/aai/" + schemaVersions.getDefaultVersion().toString()
+ + "/cloud-infrastructure/pservers/pserver/junit-edge-test-pserver\",\"relationship-label\":\"org.onap.relationships.inventory.LocatedIn\"}";
+
+ doNothing().when(uebNotification).triggerEvents();
+ Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT_EDGE, uri,
+ content);
+
+ assertEquals("Expected the pserver relationship to be deleted", 200, response.getStatus());
+ assertEquals("Two notifications", 2, uebNotification.getEvents().size());
+ assertEquals("Notification generated for PUT edge", "UPDATE",
+ uebNotification.getEvents().get(0).getEventHeader().getValue("action").toString());
+ assertThat("Event body for the edge create has the related to",
+ uebNotification.getEvents().get(0).getObj().marshal(false),
+ containsString("cloud-infrastructure/pservers/pserver/junit-edge-test-pserver"));
+
+ response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.DELETE_EDGE, uri, content);
+ assertEquals("Expected the pserver relationship to be deleted", 204, response.getStatus());
+ assertEquals("Two notifications", 2, uebNotification.getEvents().size());
+ assertEquals("Notification generated for DELETE edge", "UPDATE",
+ uebNotification.getEvents().get(0).getEventHeader().getValue("action").toString());
+ assertThat("Event body for the edge delete does not have the related to",
+ uebNotification.getEvents().get(0).getObj().marshal(false),
+ not(containsString("cloud-infrastructure/pservers/pserver/junit-edge-test-pserver")));
+ dbEngine.rollback();
+
+ }
+
+ private Response doRequest(HttpEntry httpEntry, Loader loader, TransactionalGraphEngine dbEngine, HttpMethod method,
+ String uri, String requestBody) throws UnsupportedEncodingException, AAIException {
+ return doRequest(httpEntry, loader, dbEngine, method, uri, requestBody, null);
+ }
+
+ private Response doRequest(HttpEntry httpEntry, Loader loader, TransactionalGraphEngine dbEngine, HttpMethod method,
+ String uri, String requestBody, QueryOptions queryOptions) throws UnsupportedEncodingException, AAIException {
+ URI uriObject = UriBuilder.fromPath(uri).build();
+ QueryParser uriQuery = dbEngine.getQueryBuilder().createQueryFromURI(uriObject);
+ String objType;
+ if (!uriQuery.getContainerType().equals("")) {
+ objType = uriQuery.getContainerType();
+ } else {
+ objType = uriQuery.getResultType();
+ }
+ if (uri.endsWith("relationship")) {
+ objType = "relationship";
+ }
+ Introspector obj;
+ if (method.equals(HttpMethod.GET) || method.equals(HttpMethod.GET_RELATIONSHIP)) {
+ obj = loader.introspectorFromName(objType);
+ } else {
+ obj = loader.unmarshal(objType, requestBody, org.onap.aai.restcore.MediaType.getEnum("application/json"));
+ }
+
+ DBRequest.Builder builder = new DBRequest.Builder(method, uriObject, uriQuery, obj, httpHeaders, uriInfo,
+ "JUNIT-TRANSACTION");
+ DBRequest dbRequest = requestBody != null
+ ? builder.rawRequestContent(requestBody).build()
+ : builder.build();
+
+ List<DBRequest> dbRequestList = Collections.singletonList(dbRequest);
+
+ Pair<Boolean, List<Pair<URI, Response>>> responsesTuple = httpEntry.process(dbRequestList, "JUNIT",
+ Collections.emptySet(), true, queryOptions);
+ return responsesTuple.getValue1().get(0).getValue1();
+ }
+}
diff --git a/aai-core/src/test/java/org/onap/aai/rest/db/HttpEntryTest.java b/aai-core/src/test/java/org/onap/aai/rest/db/HttpEntryTest.java
index ccc2c74c..5ecffbc0 100644
--- a/aai-core/src/test/java/org/onap/aai/rest/db/HttpEntryTest.java
+++ b/aai-core/src/test/java/org/onap/aai/rest/db/HttpEntryTest.java
@@ -31,8 +31,10 @@
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
- import static org.mockito.Mockito.doNothing;
- import static org.mockito.Mockito.times;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -95,6 +97,7 @@
import org.onap.aai.rest.db.responses.Relationship;
import org.onap.aai.rest.db.responses.RelationshipWrapper;
import org.onap.aai.rest.db.responses.ServiceException;
+import org.onap.aai.rest.notification.NotificationService;
import org.onap.aai.rest.notification.UEBNotification;
import org.onap.aai.restcore.HttpMethod;
import org.onap.aai.serialization.engines.QueryStyle;
@@ -110,6 +113,7 @@ import org.onap.aai.restcore.HttpMethod;
public class HttpEntryTest extends AAISetup {
@MockBean ValidationService validationService;
+ @MockBean NotificationService notificationService;
protected static final MediaType APPLICATION_JSON = MediaType.valueOf("application/json");
@@ -213,7 +217,7 @@ import org.onap.aai.restcore.HttpMethod;
JSONAssert.assertEquals(expectedResponseBody, actualResponseBody, JSONCompareMode.NON_EXTENSIBLE);
assertEquals("Expected the pserver to be returned", 200, response.getStatus());
- verify(validationService, times(1)).validate(any());
+ verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
}
@Test
@@ -249,7 +253,7 @@ import org.onap.aai.restcore.HttpMethod;
JSONAssert.assertEquals(expectedResponseBody, actualResponseBody, JSONCompareMode.NON_EXTENSIBLE);
assertEquals("Expected the pservers to be returned", 200, response.getStatus());
- verify(validationService, times(1)).validate(any());
+ verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
}
@Test
@@ -283,7 +287,7 @@ import org.onap.aai.restcore.HttpMethod;
assertNull(response.getHeaderString("total-results"));
assertEquals(1, actualResponseBody.getJSONArray("pserver").length());
assertEquals("Expected the pservers to be returned", 200, response.getStatus());
- verify(validationService, times(1)).validate(any());
+ verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
queryOptions = QueryOptions.builder().pageable(new Pageable(0,5).includeTotalCount()).build();
response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri, queryOptions);
@@ -307,6 +311,7 @@ import org.onap.aai.restcore.HttpMethod;
assertTrue( response.getEntity().toString().contains("Node Not Found:No Node of type pserver found at: /cloud-infrastructure/pservers"));
assertEquals(HttpStatus.NOT_FOUND.value(), response.getStatus());
+ verify(notificationService, never()).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
}
@@ -344,7 +349,7 @@ import org.onap.aai.restcore.HttpMethod;
assertEquals(2, Integer.parseInt(totalPages));
assertEquals(1, actualResponseBody.getJSONArray("pserver").length());
assertEquals("Expected the pservers to be returned", 200, response.getStatus());
- verify(validationService, times(1)).validate(any());
+ verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
queryOptions = QueryOptions.builder().pageable(new Pageable(0, 2)).build();
response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri, queryOptions);
@@ -392,7 +397,6 @@ import org.onap.aai.restcore.HttpMethod;
actualResponseBody = new JSONObject(response.getEntity().toString());
assertEquals("theEquipType2", actualResponseBody.getJSONArray("pserver").getJSONObject(0).getString("equip-type"));
assertEquals("theEquipType", actualResponseBody.getJSONArray("pserver").getJSONObject(1).getString("equip-type"));
-
}
@Test
@@ -401,6 +405,7 @@ import org.onap.aai.restcore.HttpMethod;
Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri);
assertEquals("The pserver is not found", 404, response.getStatus());
+ verify(notificationService, never()).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
}
@Test
@@ -410,7 +415,7 @@ import org.onap.aai.restcore.HttpMethod;
Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, requestBody);
assertEquals("Expecting the pserver to be created", 201, response.getStatus());
- verify(validationService, times(1)).validate(any());
+ verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
}
@Test
@@ -428,6 +433,7 @@ import org.onap.aai.restcore.HttpMethod;
assertEquals(
"Resource version specified on create:resource-version passed for create of /cloud-infrastructure/pservers/pserver/theHostname",
errorResponseEntity.getRequestError().getServiceException().getVariables().get(2));
+ verify(notificationService, never()).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
}
@Test
@@ -449,7 +455,7 @@ import org.onap.aai.restcore.HttpMethod;
assertEquals("Expecting the pserver to be updated", 200, response.getStatus());
assertTrue("That old properties are removed",
traversal.V().has("hostname", "updatedHostname").hasNot("number-of-cpus").hasNext());
- verify(validationService, times(1)).validate(any());
+ verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
}
@Test
@@ -473,6 +479,7 @@ import org.onap.aai.restcore.HttpMethod;
assertEquals(
"Precondition Failed:resource-version MISMATCH for update of /cloud-infrastructure/pservers/pserver/updatedHostname",
errorResponseEntity.getRequestError().getServiceException().getVariables().get(2));
+ verify(notificationService, never()).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
}
@Test
@@ -518,7 +525,7 @@ import org.onap.aai.restcore.HttpMethod;
traversal.V().has("aai-node-type", "p-interface").has("aai-uri", uri).has("interface-name", "p1")
.out("tosca.relationships.network.BindsTo").has("aai-node-type", "pserver")
.has("hostname", "hostname").hasNext());
- verify(validationService, times(1)).validate(any());
+ verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
}
@Test
@@ -538,7 +545,7 @@ import org.onap.aai.restcore.HttpMethod;
assertTrue("object should be updated while keeping old properties",
traversal.V().has("aai-node-type", "pserver").has("hostname", "new-hostname")
.has("equip-type", "the-equip-type").hasNext());
- verify(validationService, times(1)).validate(any());
+ verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
}
@Test
@@ -555,7 +562,7 @@ import org.onap.aai.restcore.HttpMethod;
doDelete(resourceVersion, uri, "pserver").getStatus());
assertTrue("Expecting the pserver to be deleted",
!traversal.V().has("aai-node-type", "pserver").has("hostname", "the-hostname").hasNext());
- verify(validationService, times(1)).validate(any());
+ verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
}
@Test
@@ -605,7 +612,7 @@ import org.onap.aai.restcore.HttpMethod;
.has(EdgeProperty.PREVENT_DELETE.toString(), "IN");
assertTrue("p-server has incoming edge from complex", vertexQuery.hasNext());
assertTrue("Created Edge has expected properties", edgeQuery.hasNext());
- verify(validationService, times(1)).validate(any());
+ verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
}
@Test
@@ -724,7 +731,7 @@ import org.onap.aai.restcore.HttpMethod;
assertEquals("Expected get to succeed", 200, response.getStatus());
assertThat(responseEntity, containsString("/cloud-infrastructure/pservers/pserver/pserver-1"));
assertThat(responseEntity, containsString("/cloud-infrastructure/pservers/pserver/pserver-2"));
- verify(validationService, times(1)).validate(any());
+ verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
}
@Test
@@ -759,7 +766,7 @@ import org.onap.aai.restcore.HttpMethod;
assertEquals("Expected the response to be successful", 200, response.getStatus());
assertThat("Related pserver is returned", response.getEntity().toString(),
containsString("\"hostname\":\"related-to-pserver\""));
- verify(validationService, times(1)).validate(any());
+ verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
}
@@ -788,7 +795,7 @@ import org.onap.aai.restcore.HttpMethod;
Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri);
assertThat("Related to pserver is returned.", response.getEntity().toString(),
containsString("\"hostname\":\"abstract-pserver\""));
- verify(validationService, times(1)).validate(any());
+ verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
}
@Test
@@ -833,7 +840,7 @@ import org.onap.aai.restcore.HttpMethod;
relationships[0].getRelatedLink());
assertEquals("complex.physical-location-id", relationships[0].getRelationshipData()[0].getRelationshipKey());
assertEquals("related-to-complex", relationships[0].getRelationshipData()[0].getRelationshipValue());
- verify(validationService, times(1)).validate(any());
+ verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
}
@Test
@@ -891,53 +898,7 @@ import org.onap.aai.restcore.HttpMethod;
JSONAssert.assertEquals(expectedResponseBody, actualResponseBody, JSONCompareMode.NON_EXTENSIBLE);
queryParameters.remove("format");
- verify(validationService, times(1)).validate(any());
- }
-
- @Test
- public void notificationOnRelatedToTest() throws UnsupportedEncodingException, AAIException {
-
- Loader ld = loaderFactory.createLoaderForVersion(ModelType.MOXY, schemaVersions.getDefaultVersion());
- UEBNotification uebNotification = Mockito.spy(new UEBNotification(ld, loaderFactory, schemaVersions));
- traversalHttpEntry.setHttpEntryProperties(schemaVersions.getDefaultVersion(), uebNotification);
-
- Loader loader = traversalHttpEntry.getLoader();
- TransactionalGraphEngine dbEngine = traversalHttpEntry.getDbEngine();
- // Put pserver
- String uri = "/cloud-infrastructure/pservers/pserver/junit-edge-test-pserver";
- String content = "{\"hostname\":\"junit-edge-test-pserver\"}";
- doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, content);
- // Put complex
- uri = "/cloud-infrastructure/complexes/complex/junit-edge-test-complex";
- content = "{\"physical-location-id\":\"junit-edge-test-complex\",\"physical-location-type\":\"AAIDefault\",\"street1\":\"AAIDefault\",\"city\":\"AAIDefault\",\"state\":\"NJ\",\"postal-code\":\"07748\",\"country\":\"USA\",\"region\":\"US\"}";
- doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, content);
-
- // PutEdge
- uri = "/cloud-infrastructure/complexes/complex/junit-edge-test-complex/relationship-list/relationship";
- content = "{\"related-to\":\"pserver\",\"related-link\":\"/aai/" + schemaVersions.getDefaultVersion().toString()
- + "/cloud-infrastructure/pservers/pserver/junit-edge-test-pserver\",\"relationship-label\":\"org.onap.relationships.inventory.LocatedIn\"}";
-
- doNothing().when(uebNotification).triggerEvents();
- Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT_EDGE, uri, content);
-
- assertEquals("Expected the pserver relationship to be deleted", 200, response.getStatus());
- assertEquals("Two notifications", 2, uebNotification.getEvents().size());
- assertEquals("Notification generated for PUT edge", "UPDATE",
- uebNotification.getEvents().get(0).getEventHeader().getValue("action").toString());
- assertThat("Event body for the edge create has the related to",
- uebNotification.getEvents().get(0).getObj().marshal(false),
- containsString("cloud-infrastructure/pservers/pserver/junit-edge-test-pserver"));
-
- response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.DELETE_EDGE, uri, content);
- assertEquals("Expected the pserver relationship to be deleted", 204, response.getStatus());
- assertEquals("Two notifications", 2, uebNotification.getEvents().size());
- assertEquals("Notification generated for DELETE edge", "UPDATE",
- uebNotification.getEvents().get(0).getEventHeader().getValue("action").toString());
- assertThat("Event body for the edge delete does not have the related to",
- uebNotification.getEvents().get(0).getObj().marshal(false),
- not(containsString("cloud-infrastructure/pservers/pserver/junit-edge-test-pserver")));
- dbEngine.rollback();
-
+ verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
}
private Response doRequest(HttpEntry httpEntry, Loader loader, TransactionalGraphEngine dbEngine, HttpMethod method,
@@ -1035,6 +996,6 @@ import org.onap.aai.restcore.HttpMethod;
JSONAssert.assertEquals(expectedResponseBody, actualResponseBody, JSONCompareMode.NON_EXTENSIBLE);
assertEquals("Expected the pserver to be returned", 200, response.getStatus());
- verify(validationService, times(1)).validate(any());
+ verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
}
}
diff --git a/aai-core/src/test/java/org/onap/aai/rest/notification/NotificationServiceTest.java b/aai-core/src/test/java/org/onap/aai/rest/notification/NotificationServiceTest.java
new file mode 100644
index 00000000..b3556bbe
--- /dev/null
+++ b/aai-core/src/test/java/org/onap/aai/rest/notification/NotificationServiceTest.java
@@ -0,0 +1,128 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2024 Deutsche Telekom. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.rest.notification;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyList;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ws.rs.core.Response.Status;
+
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex;
+import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertexProperty;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.onap.aai.AAISetup;
+import org.onap.aai.db.props.AAIProperties;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.introspection.Introspector;
+import org.onap.aai.introspection.LoaderFactory;
+import org.onap.aai.prevalidation.ValidationService;
+import org.onap.aai.serialization.db.DBSerializer;
+import org.onap.aai.serialization.engines.query.QueryEngine;
+import org.onap.aai.setup.SchemaVersion;
+import org.onap.aai.setup.SchemaVersions;
+
+public class NotificationServiceTest extends AAISetup {
+
+ @Mock LoaderFactory loaderFactory;
+ @Mock SchemaVersions schemaVersions;
+ @Mock UEBNotification uebNotification;
+ @Mock ValidationService validationService;
+ @Mock DBSerializer dbSerializer;
+ @Mock QueryEngine queryEngine;
+ @Mock Introspector introspector;
+
+ boolean isDeltaEventsEnabled = false;
+ String basePath = "/aai";
+ NotificationService notificationService;
+
+ @Before
+ public void setup() throws UnsupportedEncodingException, AAIException {
+ MockitoAnnotations.openMocks(this);
+
+ when(dbSerializer.touchStandardVertexPropertiesForEdges()).thenReturn(Collections.emptySet());
+ when(dbSerializer.getLatestVersionView(any(),anyInt())).thenReturn(introspector);
+
+ notificationService = new NotificationService(validationService, loaderFactory, basePath, isDeltaEventsEnabled);
+ when(schemaVersions.getDefaultVersion()).thenReturn(new SchemaVersion("v29"));
+ doNothing().when(uebNotification).createNotificationEvent(any(),any(),any(),any(),any(),any(),any());
+ }
+
+ @Test
+ public void thatNotificationsCanBeCreatedWithoutEdges() throws AAIException, UnsupportedEncodingException {
+
+ Map<String, Object> properties = new HashMap<>();
+ properties.put(AAIProperties.NODE_TYPE, Collections.singletonList(new DetachedVertexProperty<String>("1", null, "pserver", new HashMap<>())));
+ properties.put(AAIProperties.AAI_URI, Collections.singletonList(new DetachedVertexProperty<String>("1", null, "/pservers/pserver/hostname", new HashMap<>())));
+ properties.put(AAIProperties.CREATED_TS, Collections.singletonList(new DetachedVertexProperty<String>("1", null, "12", new HashMap<>())));
+ properties.put(AAIProperties.LAST_MOD_TS, Collections.singletonList(new DetachedVertexProperty<String>("1", null, "34", new HashMap<>())));
+
+ Vertex vertex = new DetachedVertex("1","label", properties);
+ Set<Vertex> mainVertexesToNotifyOn = new HashSet<>();
+ mainVertexesToNotifyOn.add(vertex);
+ SchemaVersion schemaVersion = new SchemaVersion("v29");
+ when(dbSerializer.getUpdatedVertexes()).thenReturn(Collections.emptyMap());
+
+ notificationService.generateEvents(uebNotification, AAIProperties.MINIMUM_DEPTH, "sourceOfTruth", dbSerializer, "transactionId", queryEngine, mainVertexesToNotifyOn, schemaVersion);
+
+ verify(uebNotification, times(1)).createNotificationEvent(eq("transactionId"), eq("sourceOfTruth"), eq(Status.OK), eq(URI.create("/aai/v29/pservers/pserver/hostname")), eq(introspector), any(), eq("/aai"));
+ verify(validationService, times(1)).validate(anyList());
+ verify(uebNotification, times(1)).triggerEvents();
+ }
+
+ @Test
+ public void thatValidationCanBeDisabled() throws AAIException, UnsupportedEncodingException {
+
+ Map<String, Object> properties = new HashMap<>();
+ properties.put(AAIProperties.NODE_TYPE, Collections.singletonList(new DetachedVertexProperty<String>("1", null, "pserver", new HashMap<>())));
+ properties.put(AAIProperties.AAI_URI, Collections.singletonList(new DetachedVertexProperty<String>("1", null, "/pservers/pserver/hostname", new HashMap<>())));
+ properties.put(AAIProperties.CREATED_TS, Collections.singletonList(new DetachedVertexProperty<String>("1", null, "12", new HashMap<>())));
+ properties.put(AAIProperties.LAST_MOD_TS, Collections.singletonList(new DetachedVertexProperty<String>("1", null, "34", new HashMap<>())));
+
+ Vertex vertex = new DetachedVertex("1","label", properties);
+ Set<Vertex> mainVertexesToNotifyOn = new HashSet<>();
+ mainVertexesToNotifyOn.add(vertex);
+ SchemaVersion schemaVersion = new SchemaVersion("v29");
+ when(dbSerializer.getUpdatedVertexes()).thenReturn(Collections.emptyMap());
+
+ notificationService = new NotificationService(null, loaderFactory, basePath, isDeltaEventsEnabled);
+ notificationService.generateEvents(uebNotification, AAIProperties.MINIMUM_DEPTH, "sourceOfTruth", dbSerializer, "transactionId", queryEngine, mainVertexesToNotifyOn, schemaVersion);
+
+ verify(uebNotification, times(1)).triggerEvents();
+ }
+}
diff --git a/aai-core/src/test/java/org/onap/aai/rest/ueb/UEBNotificationTest.java b/aai-core/src/test/java/org/onap/aai/rest/notification/UEBNotificationTest.java
index 57422587..229abae4 100644
--- a/aai-core/src/test/java/org/onap/aai/rest/ueb/UEBNotificationTest.java
+++ b/aai-core/src/test/java/org/onap/aai/rest/notification/UEBNotificationTest.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.aai.rest.ueb;
+package org.onap.aai.rest.notification;
import static org.junit.Assert.assertEquals;
@@ -38,7 +38,6 @@ import org.onap.aai.exceptions.AAIException;
import org.onap.aai.introspection.Introspector;
import org.onap.aai.introspection.Loader;
import org.onap.aai.introspection.ModelType;
-import org.onap.aai.rest.notification.UEBNotification;
import org.onap.aai.serialization.db.EdgeSerializer;
import org.onap.aai.serialization.engines.QueryStyle;
import org.onap.aai.setup.SchemaVersion;