From: danielhanrahan Date: Tue, 7 Mar 2023 20:53:04 +0000 (+0000) Subject: Reduce dataspace/anchor lookups in CpsDataService X-Git-Tag: 3.2.6~14 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=530d4d41f3e3deb2b6bf36e0345bdc9153c0611b;p=cps.git Reduce dataspace/anchor lookups in CpsDataService - Use Anchor object instead of names in processDataUpdatedEventAsync - Use Anchor object instead of names in buildDataNodes - Avoid unnecessary ArrayList copy in updateDataNodesAndDescendants Issue-ID: CPS-1536 Signed-off-by: danielhanrahan Change-Id: I46936a655a3d151357e55b68e1c4161e07100e84 --- 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 82e6388d8..475699113 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 @@ -486,7 +486,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService @Override public void updateDataNodesAndDescendants(final String dataspaceName, final String anchorName, - final List updatedDataNodes) { + final Collection updatedDataNodes) { final AnchorEntity anchorEntity = getAnchorEntity(dataspaceName, anchorName); final Map xpathToUpdatedDataNode = updatedDataNodes.stream() diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java index 721d4a9fb..cd14795ad 100755 --- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java +++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java @@ -30,9 +30,7 @@ import static org.onap.cps.notification.Operation.UPDATE; import io.micrometer.core.annotation.Timed; import java.time.OffsetDateTime; -import java.util.ArrayList; import java.util.Collection; -import java.util.List; import java.util.Map; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; @@ -81,10 +79,10 @@ public class CpsDataServiceImpl implements CpsDataService { public void saveData(final String dataspaceName, final String anchorName, final String nodeData, final OffsetDateTime observedTimestamp, final ContentType contentType) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); - final Collection dataNodes = - buildDataNodes(dataspaceName, anchorName, ROOT_NODE_XPATH, nodeData, contentType); + final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName); + final Collection dataNodes = buildDataNodes(anchor, ROOT_NODE_XPATH, nodeData, contentType); cpsDataPersistenceService.storeDataNodes(dataspaceName, anchorName, dataNodes); - processDataUpdatedEventAsync(dataspaceName, anchorName, ROOT_NODE_XPATH, CREATE, observedTimestamp); + processDataUpdatedEventAsync(anchor, ROOT_NODE_XPATH, CREATE, observedTimestamp); } @Override @@ -100,10 +98,10 @@ public class CpsDataServiceImpl implements CpsDataService { final String nodeData, final OffsetDateTime observedTimestamp, final ContentType contentType) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); - final Collection dataNodes = - buildDataNodes(dataspaceName, anchorName, parentNodeXpath, nodeData, contentType); + final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName); + final Collection dataNodes = buildDataNodes(anchor, parentNodeXpath, nodeData, contentType); cpsDataPersistenceService.addChildDataNodes(dataspaceName, anchorName, parentNodeXpath, dataNodes); - processDataUpdatedEventAsync(dataspaceName, anchorName, parentNodeXpath, CREATE, observedTimestamp); + processDataUpdatedEventAsync(anchor, parentNodeXpath, CREATE, observedTimestamp); } @Override @@ -112,11 +110,12 @@ public class CpsDataServiceImpl implements CpsDataService { public void saveListElements(final String dataspaceName, final String anchorName, final String parentNodeXpath, final String jsonData, final OffsetDateTime observedTimestamp) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); + final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName); final Collection listElementDataNodeCollection = - buildDataNodes(dataspaceName, anchorName, parentNodeXpath, jsonData, ContentType.JSON); + buildDataNodes(anchor, parentNodeXpath, jsonData, ContentType.JSON); cpsDataPersistenceService.addListElements(dataspaceName, anchorName, parentNodeXpath, listElementDataNodeCollection); - processDataUpdatedEventAsync(dataspaceName, anchorName, parentNodeXpath, UPDATE, observedTimestamp); + processDataUpdatedEventAsync(anchor, parentNodeXpath, UPDATE, observedTimestamp); } @Override @@ -125,11 +124,12 @@ public class CpsDataServiceImpl implements CpsDataService { public void saveListElementsBatch(final String dataspaceName, final String anchorName, final String parentNodeXpath, final Collection jsonDataList, final OffsetDateTime observedTimestamp) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); + final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName); final Collection> listElementDataNodeCollections = - buildDataNodes(dataspaceName, anchorName, parentNodeXpath, jsonDataList, ContentType.JSON); + buildDataNodes(anchor, parentNodeXpath, jsonDataList, ContentType.JSON); cpsDataPersistenceService.addMultipleLists(dataspaceName, anchorName, parentNodeXpath, listElementDataNodeCollections); - processDataUpdatedEventAsync(dataspaceName, anchorName, parentNodeXpath, UPDATE, observedTimestamp); + processDataUpdatedEventAsync(anchor, parentNodeXpath, UPDATE, observedTimestamp); } @Override @@ -159,10 +159,11 @@ public class CpsDataServiceImpl implements CpsDataService { public void updateNodeLeaves(final String dataspaceName, final String anchorName, final String parentNodeXpath, final String jsonData, final OffsetDateTime observedTimestamp) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); - final DataNode dataNode = buildDataNode(dataspaceName, anchorName, parentNodeXpath, jsonData, ContentType.JSON); - cpsDataPersistenceService - .updateDataLeaves(dataspaceName, anchorName, dataNode.getXpath(), dataNode.getLeaves()); - processDataUpdatedEventAsync(dataspaceName, anchorName, parentNodeXpath, UPDATE, observedTimestamp); + final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName); + final DataNode dataNode = buildDataNode(anchor, parentNodeXpath, jsonData, ContentType.JSON); + cpsDataPersistenceService.updateDataLeaves(dataspaceName, anchorName, dataNode.getXpath(), + dataNode.getLeaves()); + processDataUpdatedEventAsync(anchor, parentNodeXpath, UPDATE, observedTimestamp); } @Override @@ -173,13 +174,13 @@ public class CpsDataServiceImpl implements CpsDataService { final String dataNodeUpdatesAsJson, final OffsetDateTime observedTimestamp) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); + final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName); final Collection dataNodeUpdates = - buildDataNodes(dataspaceName, anchorName, - parentNodeXpath, dataNodeUpdatesAsJson, ContentType.JSON); + buildDataNodes(anchor, parentNodeXpath, dataNodeUpdatesAsJson, ContentType.JSON); for (final DataNode dataNodeUpdate : dataNodeUpdates) { - processDataNodeUpdate(dataspaceName, anchorName, dataNodeUpdate); + processDataNodeUpdate(anchor, dataNodeUpdate); } - processDataUpdatedEventAsync(dataspaceName, anchorName, parentNodeXpath, UPDATE, observedTimestamp); + processDataUpdatedEventAsync(anchor, parentNodeXpath, UPDATE, observedTimestamp); } @Override @@ -210,11 +211,10 @@ public class CpsDataServiceImpl implements CpsDataService { final String parentNodeXpath, final String jsonData, final OffsetDateTime observedTimestamp) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); - final Collection dataNodes = - buildDataNodes(dataspaceName, anchorName, parentNodeXpath, jsonData, ContentType.JSON); - final ArrayList nodes = new ArrayList<>(dataNodes); - cpsDataPersistenceService.updateDataNodesAndDescendants(dataspaceName, anchorName, nodes); - processDataUpdatedEventAsync(dataspaceName, anchorName, parentNodeXpath, UPDATE, observedTimestamp); + final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName); + final Collection dataNodes = buildDataNodes(anchor, parentNodeXpath, jsonData, ContentType.JSON); + cpsDataPersistenceService.updateDataNodesAndDescendants(dataspaceName, anchorName, dataNodes); + processDataUpdatedEventAsync(anchor, parentNodeXpath, UPDATE, observedTimestamp); } @Override @@ -224,11 +224,11 @@ public class CpsDataServiceImpl implements CpsDataService { final Map nodesJsonData, final OffsetDateTime observedTimestamp) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); - final List dataNodes = buildDataNodes(dataspaceName, anchorName, nodesJsonData); + final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName); + final Collection dataNodes = buildDataNodes(anchor, nodesJsonData); cpsDataPersistenceService.updateDataNodesAndDescendants(dataspaceName, anchorName, dataNodes); nodesJsonData.keySet().forEach(nodeXpath -> - processDataUpdatedEventAsync(dataspaceName, anchorName, nodeXpath, - UPDATE, observedTimestamp)); + processDataUpdatedEventAsync(anchor, nodeXpath, UPDATE, observedTimestamp)); } @Override @@ -237,8 +237,9 @@ public class CpsDataServiceImpl implements CpsDataService { public void replaceListContent(final String dataspaceName, final String anchorName, final String parentNodeXpath, final String jsonData, final OffsetDateTime observedTimestamp) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); + final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName); final Collection newListElements = - buildDataNodes(dataspaceName, anchorName, parentNodeXpath, jsonData, ContentType.JSON); + buildDataNodes(anchor, parentNodeXpath, jsonData, ContentType.JSON); replaceListContent(dataspaceName, anchorName, parentNodeXpath, newListElements, observedTimestamp); } @@ -248,8 +249,9 @@ public class CpsDataServiceImpl implements CpsDataService { public void replaceListContent(final String dataspaceName, final String anchorName, final String parentNodeXpath, final Collection dataNodes, final OffsetDateTime observedTimestamp) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); + final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName); cpsDataPersistenceService.replaceListContent(dataspaceName, anchorName, parentNodeXpath, dataNodes); - processDataUpdatedEventAsync(dataspaceName, anchorName, parentNodeXpath, UPDATE, observedTimestamp); + processDataUpdatedEventAsync(anchor, parentNodeXpath, UPDATE, observedTimestamp); } @Override @@ -258,8 +260,9 @@ public class CpsDataServiceImpl implements CpsDataService { public void deleteDataNode(final String dataspaceName, final String anchorName, final String dataNodeXpath, final OffsetDateTime observedTimestamp) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); + final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName); cpsDataPersistenceService.deleteDataNode(dataspaceName, anchorName, dataNodeXpath); - processDataUpdatedEventAsync(dataspaceName, anchorName, dataNodeXpath, DELETE, observedTimestamp); + processDataUpdatedEventAsync(anchor, dataNodeXpath, DELETE, observedTimestamp); } @Override @@ -269,8 +272,9 @@ public class CpsDataServiceImpl implements CpsDataService { final Collection dataNodeXpaths, final OffsetDateTime observedTimestamp) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); cpsDataPersistenceService.deleteDataNodes(dataspaceName, anchorName, dataNodeXpaths); + final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName); dataNodeXpaths.forEach(dataNodeXpath -> - processDataUpdatedEventAsync(dataspaceName, anchorName, dataNodeXpath, DELETE, observedTimestamp)); + processDataUpdatedEventAsync(anchor, dataNodeXpath, DELETE, observedTimestamp)); } @Override @@ -279,7 +283,8 @@ public class CpsDataServiceImpl implements CpsDataService { public void deleteDataNodes(final String dataspaceName, final String anchorName, final OffsetDateTime observedTimestamp) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); - processDataUpdatedEventAsync(dataspaceName, anchorName, ROOT_NODE_XPATH, DELETE, observedTimestamp); + final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName); + processDataUpdatedEventAsync(anchor, ROOT_NODE_XPATH, DELETE, observedTimestamp); cpsDataPersistenceService.deleteDataNodes(dataspaceName, anchorName); } @@ -290,8 +295,8 @@ public class CpsDataServiceImpl implements CpsDataService { final OffsetDateTime observedTimestamp) { cpsValidator.validateNameCharacters(dataspaceName); cpsValidator.validateNameCharacters(anchorNames); - for (final String anchorName : anchorNames) { - processDataUpdatedEventAsync(dataspaceName, anchorName, ROOT_NODE_XPATH, DELETE, observedTimestamp); + for (final Anchor anchor : cpsAdminService.getAnchors(dataspaceName, anchorNames)) { + processDataUpdatedEventAsync(anchor, ROOT_NODE_XPATH, DELETE, observedTimestamp); } cpsDataPersistenceService.deleteDataNodes(dataspaceName, anchorNames); } @@ -302,16 +307,14 @@ public class CpsDataServiceImpl implements CpsDataService { public void deleteListOrListElement(final String dataspaceName, final String anchorName, final String listNodeXpath, final OffsetDateTime observedTimestamp) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); + final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName); cpsDataPersistenceService.deleteListDataNode(dataspaceName, anchorName, listNodeXpath); - processDataUpdatedEventAsync(dataspaceName, anchorName, listNodeXpath, DELETE, observedTimestamp); + processDataUpdatedEventAsync(anchor, listNodeXpath, DELETE, observedTimestamp); } - private DataNode buildDataNode(final String dataspaceName, final String anchorName, - final String parentNodeXpath, final String nodeData, + private DataNode buildDataNode(final Anchor anchor, final String parentNodeXpath, final String nodeData, final ContentType contentType) { - - final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName); - final SchemaContext schemaContext = getSchemaContext(dataspaceName, anchor.getSchemaSetName()); + final SchemaContext schemaContext = getSchemaContext(anchor); if (ROOT_NODE_XPATH.equals(parentNodeXpath)) { final ContainerNode containerNode = timedYangParser.parseData(contentType, nodeData, schemaContext); @@ -327,21 +330,15 @@ public class CpsDataServiceImpl implements CpsDataService { .build(); } - private List buildDataNodes(final String dataspaceName, final String anchorName, - final Map nodesJsonData) { + private Collection buildDataNodes(final Anchor anchor, final Map nodesJsonData) { return nodesJsonData.entrySet().stream().map(nodeJsonData -> - buildDataNode(dataspaceName, anchorName, nodeJsonData.getKey(), + buildDataNode(anchor, nodeJsonData.getKey(), nodeJsonData.getValue(), ContentType.JSON)).collect(Collectors.toList()); } - private Collection buildDataNodes(final String dataspaceName, - final String anchorName, - final String parentNodeXpath, - final String nodeData, - final ContentType contentType) { - - final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName); - final SchemaContext schemaContext = getSchemaContext(dataspaceName, anchor.getSchemaSetName()); + private Collection buildDataNodes(final Anchor anchor, final String parentNodeXpath, + final String nodeData, final ContentType contentType) { + final SchemaContext schemaContext = getSchemaContext(anchor); if (ROOT_NODE_XPATH.equals(parentNodeXpath)) { final ContainerNode containerNode = timedYangParser.parseData(contentType, nodeData, schemaContext); @@ -365,37 +362,38 @@ public class CpsDataServiceImpl implements CpsDataService { return dataNodes; } - private Collection> buildDataNodes(final String dataspaceName, final String anchorName, - final String parentNodeXpath, final Collection nodeDataList, final ContentType contentType) { + private Collection> buildDataNodes(final Anchor anchor, final String parentNodeXpath, + final Collection nodeDataList, + final ContentType contentType) { return nodeDataList.stream() - .map(nodeData -> buildDataNodes(dataspaceName, anchorName, parentNodeXpath, nodeData, contentType)) - .collect(Collectors.toList()); + .map(nodeData -> buildDataNodes(anchor, parentNodeXpath, nodeData, contentType)) + .collect(Collectors.toList()); } - private void processDataUpdatedEventAsync(final String dataspaceName, final String anchorName, final String xpath, - final Operation operation, final OffsetDateTime observedTimestamp) { + private void processDataUpdatedEventAsync(final Anchor anchor, final String xpath, + final Operation operation, final OffsetDateTime observedTimestamp) { try { - notificationService.processDataUpdatedEvent(dataspaceName, anchorName, xpath, operation, observedTimestamp); + notificationService.processDataUpdatedEvent(anchor, xpath, operation, observedTimestamp); } catch (final Exception exception) { //If async message can't be queued for notification service, the initial request should not failed. log.error("Failed to send message to notification service", exception); } } - private SchemaContext getSchemaContext(final String dataspaceName, final String schemaSetName) { - return yangTextSchemaSourceSetCache.get(dataspaceName, schemaSetName).getSchemaContext(); + private SchemaContext getSchemaContext(final Anchor anchor) { + return yangTextSchemaSourceSetCache + .get(anchor.getDataspaceName(), anchor.getSchemaSetName()).getSchemaContext(); } - private void processDataNodeUpdate(final String dataspaceName, final String anchorName, - final DataNode dataNodeUpdate) { + private void processDataNodeUpdate(final Anchor anchor, final DataNode dataNodeUpdate) { if (dataNodeUpdate == null) { return; } - cpsDataPersistenceService.updateDataLeaves(dataspaceName, anchorName, dataNodeUpdate.getXpath(), - dataNodeUpdate.getLeaves()); + cpsDataPersistenceService.updateDataLeaves(anchor.getDataspaceName(), anchor.getName(), + dataNodeUpdate.getXpath(), dataNodeUpdate.getLeaves()); final Collection childDataNodeUpdates = dataNodeUpdate.getChildDataNodes(); for (final DataNode childDataNodeUpdate : childDataNodeUpdates) { - processDataNodeUpdate(dataspaceName, anchorName, childDataNodeUpdate); + processDataNodeUpdate(anchor, childDataNodeUpdate); } } 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 7da3a6123..b9d40740e 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 @@ -1,7 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (c) 2021-2022 Bell Canada. - * Modifications Copyright (C) 2022 Nordix Foundation + * Modifications Copyright (C) 2022-2023 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -70,21 +70,19 @@ public class NotificationService { /** * Process Data Updated Event and publishes the notification. * - * @param dataspaceName dataspaceName - * @param anchorName anchorName + * @param anchor anchor * @param xpath xpath of changed data node * @param operation operation * @param observedTimestamp observedTimestamp * @return future */ @Async("notificationExecutor") - public Future processDataUpdatedEvent(final String dataspaceName, final String anchorName, - final String xpath, final Operation operation, final OffsetDateTime observedTimestamp) { + public Future processDataUpdatedEvent(final Anchor anchor, final String xpath, final Operation operation, + final OffsetDateTime observedTimestamp) { - final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName); log.debug("process data updated event for anchor '{}'", anchor); try { - if (shouldSendNotification(dataspaceName)) { + if (shouldSendNotification(anchor.getDataspaceName())) { final var cpsDataUpdatedEvent = cpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(anchor, observedTimestamp, getRootNodeOperation(xpath, operation)); diff --git a/cps-service/src/main/java/org/onap/cps/spi/CpsDataPersistenceService.java b/cps-service/src/main/java/org/onap/cps/spi/CpsDataPersistenceService.java index 90e6ec761..f10443fda 100644 --- a/cps-service/src/main/java/org/onap/cps/spi/CpsDataPersistenceService.java +++ b/cps-service/src/main/java/org/onap/cps/spi/CpsDataPersistenceService.java @@ -153,7 +153,7 @@ public interface CpsDataPersistenceService { * @param anchorName anchor name * @param dataNodes data nodes */ - void updateDataNodesAndDescendants(String dataspaceName, String anchorName, final List dataNodes); + void updateDataNodesAndDescendants(String dataspaceName, String anchorName, final Collection dataNodes); /** * Replaces list content by removing all existing elements and inserting the given new elements diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy index e304d28d8..faa5d2edb 100644 --- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy +++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy @@ -61,7 +61,7 @@ class CpsDataServiceImplSpec extends Specification { def dataspaceName = 'some-dataspace' def anchorName = 'some-anchor' def schemaSetName = 'some-schema-set' - def anchor = Anchor.builder().name(anchorName).schemaSetName(schemaSetName).build() + def anchor = Anchor.builder().name(anchorName).dataspaceName(dataspaceName).schemaSetName(schemaSetName).build() def observedTimestamp = OffsetDateTime.now() def 'Saving multicontainer json data.'() { @@ -76,7 +76,7 @@ class CpsDataServiceImplSpec extends Specification { and: 'the CpsValidator is called on the dataspaceName and AnchorName' 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) and: 'data updated event is sent to notification service' - 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, '/', Operation.CREATE, observedTimestamp) + 1 * mockNotificationService.processDataUpdatedEvent(anchor, '/', Operation.CREATE, observedTimestamp) where: index | xpath 0 | '/first-container' @@ -96,7 +96,7 @@ class CpsDataServiceImplSpec extends Specification { and: 'the CpsValidator is called on the dataspaceName and AnchorName' 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) and: 'data updated event is sent to notification service' - 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, '/', Operation.CREATE, observedTimestamp) + 1 * mockNotificationService.processDataUpdatedEvent(anchor, '/', Operation.CREATE, observedTimestamp) where: 'given parameters' scenario | dataFile | contentType 'json' | 'test-tree.json' | ContentType.JSON @@ -129,7 +129,7 @@ class CpsDataServiceImplSpec extends Specification { and: 'the CpsValidator is called on the dataspaceName and AnchorName' 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) and: 'data updated event is sent to notification service' - 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, '/test-tree', Operation.CREATE, observedTimestamp) + 1 * mockNotificationService.processDataUpdatedEvent(anchor, '/test-tree', Operation.CREATE, observedTimestamp) } def 'Saving list element data fragment under existing node.'() { @@ -151,7 +151,7 @@ class CpsDataServiceImplSpec extends Specification { and: 'the CpsValidator is called on the dataspaceName and AnchorName' 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) and: 'data updated event is sent to notification service' - 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, '/test-tree', Operation.UPDATE, observedTimestamp) + 1 * mockNotificationService.processDataUpdatedEvent(anchor, '/test-tree', Operation.UPDATE, observedTimestamp) } def 'Saving collection of a batch with data fragment under existing node.'() { @@ -171,7 +171,7 @@ class CpsDataServiceImplSpec extends Specification { } } and: 'data updated event is sent to notification service' - 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, '/test-tree', Operation.UPDATE, observedTimestamp) + 1 * mockNotificationService.processDataUpdatedEvent(anchor, '/test-tree', Operation.UPDATE, observedTimestamp) } def 'Saving empty list element data fragment.'() { @@ -219,7 +219,7 @@ class CpsDataServiceImplSpec extends Specification { and: 'the CpsValidator is called on the dataspaceName and AnchorName' 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) and: 'data updated event is sent to notification service' - 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, parentNodeXpath, Operation.UPDATE, observedTimestamp) + 1 * mockNotificationService.processDataUpdatedEvent(anchor, parentNodeXpath, Operation.UPDATE, observedTimestamp) where: 'following parameters were used' scenario | parentNodeXpath | jsonData || expectedNodeXpath | leaves 'top level node' | '/' | '{"test-tree": {"branch": []}}' || '/test-tree' | Collections.emptyMap() @@ -254,7 +254,7 @@ class CpsDataServiceImplSpec extends Specification { and: 'the CpsValidator is called on the dataspaceName and AnchorName' 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) and: 'the data updated event is sent to the notification service' - 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, '/bookstore', Operation.UPDATE, observedTimestamp) + 1 * mockNotificationService.processDataUpdatedEvent(anchor, '/bookstore', Operation.UPDATE, observedTimestamp) } def 'Replace data node using singular data node: #scenario.'() { @@ -266,7 +266,7 @@ class CpsDataServiceImplSpec extends Specification { 1 * mockCpsDataPersistenceService.updateDataNodesAndDescendants(dataspaceName, anchorName, { dataNode -> dataNode.xpath[0] == expectedNodeXpath }) and: 'data updated event is sent to notification service' - 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, parentNodeXpath, Operation.UPDATE, observedTimestamp) + 1 * mockNotificationService.processDataUpdatedEvent(anchor, parentNodeXpath, Operation.UPDATE, observedTimestamp) and: 'the CpsValidator is called on the dataspaceName and AnchorName' 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) where: 'following parameters were used' @@ -284,8 +284,8 @@ class CpsDataServiceImplSpec extends Specification { 1 * mockCpsDataPersistenceService.updateDataNodesAndDescendants(dataspaceName, anchorName, { dataNode -> dataNode.xpath == expectedNodeXpath}) and: 'data updated event is sent to notification service' - 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, nodesJsonData.keySet()[0], Operation.UPDATE, observedTimestamp) - 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, nodesJsonData.keySet()[1], Operation.UPDATE, observedTimestamp) + 1 * mockNotificationService.processDataUpdatedEvent(anchor, nodesJsonData.keySet()[0], Operation.UPDATE, observedTimestamp) + 1 * mockNotificationService.processDataUpdatedEvent(anchor, nodesJsonData.keySet()[1], Operation.UPDATE, observedTimestamp) and: 'the CpsValidator is called on the dataspaceName and AnchorName' 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) where: 'following parameters were used' @@ -313,7 +313,7 @@ class CpsDataServiceImplSpec extends Specification { and: 'the CpsValidator is called on the dataspaceName and AnchorName twice' 2 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) and: 'data updated event is sent to notification service' - 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, '/test-tree', Operation.UPDATE, observedTimestamp) + 1 * mockNotificationService.processDataUpdatedEvent(anchor, '/test-tree', Operation.UPDATE, observedTimestamp) } def 'Replace whole list content with empty list element.'() { @@ -336,7 +336,7 @@ class CpsDataServiceImplSpec extends Specification { and: 'the CpsValidator is called on the dataspaceName and AnchorName' 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) and: 'data updated event is sent to notification service' - 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, '/test-tree/branch', Operation.DELETE, observedTimestamp) + 1 * mockNotificationService.processDataUpdatedEvent(anchor, '/test-tree/branch', Operation.DELETE, observedTimestamp) } def 'Delete multiple list elements under existing node.'() { @@ -349,7 +349,7 @@ class CpsDataServiceImplSpec extends Specification { and: 'the CpsValidator is called on the dataspaceName and AnchorName' 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) and: 'two data updated events are sent to notification service' - 2 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, _, Operation.DELETE, observedTimestamp) + 2 * mockNotificationService.processDataUpdatedEvent(anchor, _, Operation.DELETE, observedTimestamp) } def 'Delete data node under anchor and dataspace.'() { @@ -362,7 +362,7 @@ class CpsDataServiceImplSpec extends Specification { and: 'the CpsValidator is called on the dataspaceName and AnchorName' 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) and: 'data updated event is sent to notification service' - 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, '/data-node', Operation.DELETE, observedTimestamp) + 1 * mockNotificationService.processDataUpdatedEvent(anchor, '/data-node', Operation.DELETE, observedTimestamp) } def 'Delete all data nodes for a given anchor and dataspace.'() { @@ -371,7 +371,7 @@ class CpsDataServiceImplSpec extends Specification { when: 'delete data node method is invoked with correct parameters' objectUnderTest.deleteDataNodes(dataspaceName, anchorName, observedTimestamp) then: 'data updated event is sent to notification service before the delete' - 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, '/', Operation.DELETE, observedTimestamp) + 1 * mockNotificationService.processDataUpdatedEvent(anchor, '/', Operation.DELETE, observedTimestamp) and: 'the CpsValidator is called on the dataspaceName and AnchorName' 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) and: 'the persistence service method is invoked with the correct parameters' @@ -381,10 +381,13 @@ class CpsDataServiceImplSpec extends Specification { def 'Delete all data nodes for given dataspace and multiple anchors.'() { given: 'schema set for given anchors and dataspace references test tree model' setupSchemaSetMocks('test-tree.yang') + mockCpsAdminService.getAnchors(dataspaceName, ['anchor1', 'anchor2']) >> + [new Anchor(name: 'anchor1', dataspaceName: dataspaceName), + new Anchor(name: 'anchor2', dataspaceName: dataspaceName)] when: 'delete data node method is invoked with correct parameters' objectUnderTest.deleteDataNodes(dataspaceName, ['anchor1', 'anchor2'], observedTimestamp) then: 'data updated events are sent to notification service before the delete' - 2 * mockNotificationService.processDataUpdatedEvent(dataspaceName, _, '/', Operation.DELETE, observedTimestamp) + 2 * mockNotificationService.processDataUpdatedEvent(_, '/', Operation.DELETE, observedTimestamp) and: 'the CpsValidator is called on the dataspace name and the anchor names' 2 * mockCpsValidator.validateNameCharacters(_) and: 'the persistence service method is invoked with the correct parameters' @@ -431,4 +434,4 @@ class CpsDataServiceImplSpec extends Specification { 1 * mockCpsDataPersistenceService.lockAnchor('some-sessionId', 'some-dataspaceName', 'some-anchorName', 250L) } -} \ No newline at end of file +} diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/E2ENetworkSliceSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/E2ENetworkSliceSpec.groovy index 8ed7aede6..75f29746d 100755 --- a/cps-service/src/test/groovy/org/onap/cps/api/impl/E2ENetworkSliceSpec.groovy +++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/E2ENetworkSliceSpec.groovy @@ -90,7 +90,7 @@ class E2ENetworkSliceSpec extends Specification { def jsonData = TestUtils.getResourceFileContent('e2e/basic/cps-Cavsta-Data.txt') and : 'all the further dependencies are mocked ' mockCpsAdminService.getAnchor(dataspaceName, anchorName) >> - new Anchor().builder().name(anchorName).schemaSetName(schemaSetName).build() + new Anchor().builder().name(anchorName).schemaSetName(schemaSetName).dataspaceName(dataspaceName).build() mockYangTextSchemaSourceSetCache.get(dataspaceName, schemaSetName) >> YangTextSchemaSourceSetBuilder.of(yangResourcesNameToContentMap) mockModuleStoreService.getYangSchemaResources(dataspaceName, schemaSetName) >> schemaContext @@ -123,7 +123,7 @@ class E2ENetworkSliceSpec extends Specification { def jsonData = TestUtils.getResourceFileContent('e2e/basic/cps-ran-inventory-data.json') and : 'all the further dependencies are mocked ' mockCpsAdminService.getAnchor('someDataspace', 'someAnchor') >> - new Anchor().builder().name('someAnchor').schemaSetName('someSchemaSet').build() + new Anchor().builder().name('someAnchor').schemaSetName('someSchemaSet').dataspaceName(dataspaceName).build() mockYangTextSchemaSourceSetCache.get('someDataspace', 'someSchemaSet') >> YangTextSchemaSourceSetBuilder.of(yangResourcesNameToContentMap) mockModuleStoreService.getYangSchemaResources('someDataspace', 'someSchemaSet') >> schemaContext when: 'saveData method is invoked' 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 a996195c0..2ef468bb5 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 @@ -1,7 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (c) 2021-2022 Bell Canada. - * Modifications Copyright (C) 2022 Nordix Foundation + * Modifications Copyright (C) 2022-2023 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -72,7 +72,7 @@ class NotificationServiceSpec extends Specification { given: 'notification is disabled' spyNotificationProperties.isEnabled() >> false when: 'dataUpdatedEvent is received' - objectUnderTest.processDataUpdatedEvent(dataspaceName, anchorName, '/', Operation.CREATE, myObservedTimestamp) + objectUnderTest.processDataUpdatedEvent(anchor, '/', Operation.CREATE, myObservedTimestamp) then: 'the notification is not sent' 0 * mockNotificationPublisher.sendNotification(_) } @@ -84,11 +84,9 @@ class NotificationServiceSpec extends Specification { def anchor = new Anchor('my-anchorname', dataspaceName, 'my-schemaset-name') and: 'event factory can create event successfully' def cpsDataUpdatedEvent = new CpsDataUpdatedEvent() - mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(anchor, myObservedTimestamp, Operation.CREATE) >> - cpsDataUpdatedEvent + mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(anchor, myObservedTimestamp, Operation.CREATE) >> cpsDataUpdatedEvent when: 'dataUpdatedEvent is received' - def future = objectUnderTest.processDataUpdatedEvent(dataspaceName, anchorName, - '/', Operation.CREATE, myObservedTimestamp) + def future = objectUnderTest.processDataUpdatedEvent(anchor, '/', Operation.CREATE, myObservedTimestamp) and: 'wait for async processing to complete' future.get(10, TimeUnit.SECONDS) then: 'async process completed successfully' @@ -109,7 +107,7 @@ class NotificationServiceSpec extends Specification { mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(anchor, myObservedTimestamp, expectedOperationInEvent) >> cpsDataUpdatedEvent when: 'dataUpdatedEvent is received for #xpath' - def future = objectUnderTest.processDataUpdatedEvent(dataspaceName, anchorName, xpath, operation, myObservedTimestamp) + def future = objectUnderTest.processDataUpdatedEvent(anchor, xpath, operation, myObservedTimestamp) and: 'wait for async processing to complete' future.get(10, TimeUnit.SECONDS) then: 'async process completed successfully' @@ -139,7 +137,7 @@ class NotificationServiceSpec extends Specification { mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(anchor, myObservedTimestamp, Operation.CREATE) >> { throw new Exception("Could not create event") } when: 'event is sent for processing' - def future = objectUnderTest.processDataUpdatedEvent(dataspaceName, anchorName, '/', Operation.CREATE, myObservedTimestamp) + def future = objectUnderTest.processDataUpdatedEvent(anchor, '/', Operation.CREATE, myObservedTimestamp) and: 'wait for async processing to complete' future.get(10, TimeUnit.SECONDS) then: 'async process completed successfully'