summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xcps-dependencies/pom.xml10
-rwxr-xr-xcps-ri/src/main/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceImpl.java18
-rw-r--r--cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java4
-rwxr-xr-xcps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java4
-rw-r--r--cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepositoryImpl.java4
-rw-r--r--cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java8
-rw-r--r--cps-service/src/main/java/org/onap/cps/notification/NotificationService.java12
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/notification/NotificationServiceSpec.groovy44
8 files changed, 57 insertions, 47 deletions
diff --git a/cps-dependencies/pom.xml b/cps-dependencies/pom.xml
index 5c2ff565e..80513ba94 100755
--- a/cps-dependencies/pom.xml
+++ b/cps-dependencies/pom.xml
@@ -77,6 +77,11 @@
<scope>import</scope>
</dependency>
<dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-web</artifactId>
+ <version>5.3.13</version>
+ </dependency>
+ <dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yangtools-artifacts</artifactId>
<version>6.0.1</version>
@@ -94,6 +99,11 @@
<version>3.0.0</version>
</dependency>
<dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ <version>2.8.9</version>
+ </dependency>
+ <dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-52</artifactId>
<version>2.10.0</version>
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceImpl.java
index 5b89d9f4c..50b27207e 100755
--- a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceImpl.java
+++ b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceImpl.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2020 Nordix Foundation.
+ * Copyright (C) 2020-2022 Nordix Foundation.
* Modifications Copyright (C) 2020-2022 Bell Canada.
* Modifications Copyright (C) 2021 Pantheon.tech
* ================================================================================
@@ -147,20 +147,24 @@ public class CpsAdminPersistenceServiceImpl implements CpsAdminPersistenceServic
private void validateDataspaceAndModuleNames(final String dataspaceName,
final Collection<String> inputModuleNames) {
- final Collection<String> retrievedModuleNames =
- yangResourceRepository.findAllModuleReferences(dataspaceName, inputModuleNames)
+ final Collection<String> retrievedModuleReferences =
+ yangResourceRepository.findAllModuleReferencesByDataspaceAndModuleNames(dataspaceName, inputModuleNames)
.stream().map(YangResourceModuleReference::getModuleName)
.collect(Collectors.toList());
- if (retrievedModuleNames.isEmpty()) {
- dataspaceRepository.getByName(dataspaceName);
+ if (retrievedModuleReferences.isEmpty()) {
+ verifyDataspaceName(dataspaceName);
}
- if (inputModuleNames.size() > retrievedModuleNames.size()) {
+ if (inputModuleNames.size() > retrievedModuleReferences.size()) {
final List<String> moduleNamesNotFound = inputModuleNames.stream()
- .filter(moduleName -> !retrievedModuleNames.contains(moduleName))
+ .filter(moduleName -> !retrievedModuleReferences.contains(moduleName))
.collect(Collectors.toList());
if (!moduleNamesNotFound.isEmpty()) {
throw new ModuleNamesNotFoundException(dataspaceName, moduleNamesNotFound);
}
}
}
+
+ private void verifyDataspaceName(final String dataspaceName) {
+ dataspaceRepository.getByName(dataspaceName);
+ }
}
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java
index f22d83b98..78862d723 100644
--- a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java
+++ b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java
@@ -337,7 +337,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
deleteDataNodes(dataspaceName, anchorName);
targetDeleted = true;
} else {
- if (isContainerNodeXpath(targetXpath)) {
+ if (isRootContainerNodeXpath(targetXpath)) {
parentNodeXpath = targetXpath;
} else {
parentNodeXpath = targetXpath.substring(0, targetXpath.lastIndexOf('/'));
@@ -423,7 +423,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
return !existingListElementsByXpath.containsKey(replacementDataNode.getXpath());
}
- private static boolean isContainerNodeXpath(final String xpath) {
+ private static boolean isRootContainerNodeXpath(final String xpath) {
return 0 == xpath.lastIndexOf('/');
}
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java
index ec720b8a9..3719256fc 100755
--- a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java
+++ b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java
@@ -106,7 +106,7 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ
@Override
public Collection<ModuleReference> getYangResourceModuleReferences(final String dataspaceName) {
final Set<YangResourceModuleReference> yangResourceModuleReferenceList =
- yangResourceRepository.findAllModuleReferences(dataspaceName);
+ yangResourceRepository.findAllModuleReferencesByDataspace(dataspaceName);
return yangResourceModuleReferenceList.stream().map(CpsModulePersistenceServiceImpl::toModuleReference)
.collect(Collectors.toList());
}
@@ -116,7 +116,7 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ
final String anchorName) {
final Set<YangResourceModuleReference> yangResourceModuleReferenceList =
yangResourceRepository
- .findAllModuleReferences(dataspaceName, anchorName);
+ .findAllModuleReferencesByDataspaceAndAnchor(dataspaceName, anchorName);
return yangResourceModuleReferenceList.stream().map(CpsModulePersistenceServiceImpl::toModuleReference)
.collect(Collectors.toList());
}
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepositoryImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepositoryImpl.java
index f4078ffec..0e79deb8e 100644
--- a/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepositoryImpl.java
+++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepositoryImpl.java
@@ -45,11 +45,11 @@ public class ModuleReferenceRepositoryImpl implements ModuleReferenceQuery {
final Collection<ModuleReference> moduleReferencesToCheck) {
if (moduleReferencesToCheck == null || moduleReferencesToCheck.isEmpty()) {
- return Collections.EMPTY_LIST;
+ return Collections.emptyList();
}
final String tempTableName = "moduleReferencesToCheckTemp"
- + UUID.randomUUID().toString().replaceAll("-", "");
+ + UUID.randomUUID().toString().replace("-", "");
createTemporaryTable(tempTableName);
insertDataIntoTable(tempTableName, moduleReferencesToCheck);
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java
index 895937b60..5e9c47429 100644
--- a/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java
+++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java
@@ -49,7 +49,7 @@ public interface YangResourceRepository extends JpaRepository<YangResourceEntity
+ "JOIN yang_resource ON yang_resource.id = schema_set_yang_resources.yang_resource_id\n"
+ "WHERE\n"
+ "dataspace.name = :dataspaceName", nativeQuery = true)
- Set<YangResourceModuleReference> findAllModuleReferences(@Param("dataspaceName") String dataspaceName);
+ Set<YangResourceModuleReference> findAllModuleReferencesByDataspace(@Param("dataspaceName") String dataspaceName);
@Query(value = "SELECT DISTINCT\n"
+ "yang_resource.module_Name AS module_name,\n"
@@ -64,7 +64,7 @@ public interface YangResourceRepository extends JpaRepository<YangResourceEntity
+ "WHERE\n"
+ "dataspace.name = :dataspaceName AND\n"
+ "anchor.name =:anchorName", nativeQuery = true)
- Set<YangResourceModuleReference> findAllModuleReferences(
+ Set<YangResourceModuleReference> findAllModuleReferencesByDataspaceAndAnchor(
@Param("dataspaceName") String dataspaceName, @Param("anchorName") String anchorName);
@Query(value = "SELECT DISTINCT\n"
@@ -77,8 +77,8 @@ public interface YangResourceRepository extends JpaRepository<YangResourceEntity
+ "JOIN yang_resource ON yang_resource.id = schema_set_yang_resources.yang_resource_id\n"
+ "WHERE\n"
+ "dataspace.name = :dataspaceName and yang_resource.module_Name IN (:moduleNames)", nativeQuery = true)
- Set<YangResourceModuleReference> findAllModuleReferences(@Param("dataspaceName") String dataspaceName,
- @Param("moduleNames") Collection<String> moduleNames);
+ Set<YangResourceModuleReference> findAllModuleReferencesByDataspaceAndModuleNames(
+ @Param("dataspaceName") String dataspaceName, @Param("moduleNames") Collection<String> moduleNames);
@Query(value = "SELECT id FROM yang_resource WHERE module_name=:name and revision=:revision", nativeQuery = true)
diff --git a/cps-service/src/main/java/org/onap/cps/notification/NotificationService.java b/cps-service/src/main/java/org/onap/cps/notification/NotificationService.java
index 5ad59df2a..5e26a2204 100644
--- a/cps-service/src/main/java/org/onap/cps/notification/NotificationService.java
+++ b/cps-service/src/main/java/org/onap/cps/notification/NotificationService.java
@@ -37,8 +37,6 @@ import org.springframework.stereotype.Service;
@Slf4j
public class NotificationService {
- private static final String ROOT_NODE_XPATH = "/";
-
private NotificationProperties notificationProperties;
private NotificationPublisher notificationPublisher;
private CpsDataUpdatedEventFactory cpsDataUpdatedEventFactory;
@@ -120,7 +118,15 @@ public class NotificationService {
}
private Operation getRootNodeOperation(final String xpath, final Operation operation) {
- return ROOT_NODE_XPATH.equals(xpath) ? operation : Operation.UPDATE;
+ return isRootXpath(xpath) || isRootContainerNodeXpath(xpath) ? operation : Operation.UPDATE;
+ }
+
+ private static boolean isRootXpath(final String xpath) {
+ return "/".equals(xpath) || "".equals(xpath);
+ }
+
+ private static boolean isRootContainerNodeXpath(final String xpath) {
+ return 0 == xpath.lastIndexOf('/');
}
}
diff --git a/cps-service/src/test/groovy/org/onap/cps/notification/NotificationServiceSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/notification/NotificationServiceSpec.groovy
index c20bdeea7..6ef6874b3 100644
--- a/cps-service/src/test/groovy/org/onap/cps/notification/NotificationServiceSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/notification/NotificationServiceSpec.groovy
@@ -90,35 +90,15 @@ class NotificationServiceSpec extends Specification {
'dataspace name matches filter' | 'my-dataspace-published' || 1
}
- def 'Send UPDATE operation when non-root data nodes are changed.'() {
- given: 'notification is enabled'
- spyNotificationProperties.isEnabled() >> true
- and: 'event factory creates event if operation is UPDATE'
- def cpsDataUpdatedEvent = new CpsDataUpdatedEvent()
- mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(anchor, myObservedTimestamp,
- Operation.UPDATE) >> cpsDataUpdatedEvent
- when: 'dataUpdatedEvent is received for non-root xpath'
- def future = objectUnderTest.processDataUpdatedEvent(anchor, myObservedTimestamp, '/non-root-node',
- operation)
- and: 'wait for async processing to complete'
- future.get(10, TimeUnit.SECONDS)
- then: 'async process completed successfully'
- future.isDone()
- and: 'notification is sent'
- 1 * mockNotificationPublisher.sendNotification(cpsDataUpdatedEvent)
- where:
- operation << [Operation.CREATE, Operation.UPDATE, Operation.DELETE]
- }
-
- def 'Send same operation when root nodes are changed.'() {
+ def '#scenario are changed with xpath #xpath and operation #operation'() {
given: 'notification is enabled'
spyNotificationProperties.isEnabled() >> true
and: 'event factory creates event if operation is #operation'
def cpsDataUpdatedEvent = new CpsDataUpdatedEvent()
- mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(anchor, myObservedTimestamp, operation) >>
+ mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(anchor, myObservedTimestamp, expectedOperationInEvent) >>
cpsDataUpdatedEvent
- when: 'dataUpdatedEvent is received for root xpath'
- def future = objectUnderTest.processDataUpdatedEvent(anchor, myObservedTimestamp, '/', operation)
+ when: 'dataUpdatedEvent is received for #xpath'
+ def future = objectUnderTest.processDataUpdatedEvent(anchor, myObservedTimestamp, xpath, operation)
and: 'wait for async processing to complete'
future.get(10, TimeUnit.SECONDS)
then: 'async process completed successfully'
@@ -126,10 +106,21 @@ class NotificationServiceSpec extends Specification {
and: 'notification is sent'
1 * mockNotificationPublisher.sendNotification(cpsDataUpdatedEvent)
where:
- operation << [Operation.CREATE, Operation.UPDATE, Operation.DELETE]
+ scenario | xpath | operation || expectedOperationInEvent
+ 'Same event is sent when root nodes' | '' | Operation.CREATE || Operation.CREATE
+ 'Same event is sent when root nodes' | '' | Operation.UPDATE || Operation.UPDATE
+ 'Same event is sent when root nodes' | '' | Operation.DELETE || Operation.DELETE
+ 'Same event is sent when root nodes' | '/' | Operation.CREATE || Operation.CREATE
+ 'Same event is sent when root nodes' | '/' | Operation.UPDATE || Operation.UPDATE
+ 'Same event is sent when root nodes' | '/' | Operation.DELETE || Operation.DELETE
+ 'Same event is sent when container nodes' | '/parent' | Operation.CREATE || Operation.CREATE
+ 'Same event is sent when container nodes' | '/parent' | Operation.UPDATE || Operation.UPDATE
+ 'Same event is sent when container nodes' | '/parent' | Operation.DELETE || Operation.DELETE
+ 'UPDATE event is sent when non root nodes' | '/parent/child' | Operation.CREATE || Operation.UPDATE
+ 'UPDATE event is sent when non root nodes' | '/parent/child' | Operation.UPDATE || Operation.UPDATE
+ 'UPDATE event is sent when non root nodes' | '/parent/child' | Operation.DELETE || Operation.UPDATE
}
-
def 'Error handling in notification service.'() {
given: 'notification is enabled'
spyNotificationProperties.isEnabled() >> true
@@ -146,5 +137,4 @@ class NotificationServiceSpec extends Specification {
notThrown Exception
1 * spyNotificationErrorHandler.onException(_, _, _, '/', Operation.CREATE)
}
-
}