summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cps-application/src/main/resources/application.yml7
-rw-r--r--cps-ncmp-events/src/main/resources/schemas/ncmp-event-schema-v1.json6
-rwxr-xr-xcps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java1
-rw-r--r--cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/DeprecationHelper.java4
-rw-r--r--cps-ncmp-service/pom.xml5
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyCmHandlerQueryService.java6
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceImpl.java22
-rwxr-xr-xcps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java10
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsCreator.java90
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsService.java65
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistence.java12
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java23
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/SyncUtils.java18
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceSpec.groovy10
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy4
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/NcmpEventsCreatorSpec.groovy57
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/NcmpEventsServiceSpec.groovy64
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/InventoryPersistenceSpec.groovy28
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncSpec.groovy14
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/SyncUtilsSpec.groovy18
-rw-r--r--cps-service/src/main/java/org/onap/cps/spi/model/CmHandleQueryServiceParameters.java (renamed from cps-service/src/main/java/org/onap/cps/spi/model/CmHandleQueryParameters.java)2
-rw-r--r--cps-service/src/main/java/org/onap/cps/utils/CmHandleQueryRestParametersValidator.java43
-rwxr-xr-xcps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminServiceImplSpec.groovy1
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/utils/CmHandleQueryRestParametersValidatorSpec.groovy8
-rwxr-xr-xdocs/release-notes.rst46
25 files changed, 480 insertions, 84 deletions
diff --git a/cps-application/src/main/resources/application.yml b/cps-application/src/main/resources/application.yml
index 3f005c9f78..2b4dc4b7c7 100644
--- a/cps-application/src/main/resources/application.yml
+++ b/cps-application/src/main/resources/application.yml
@@ -1,6 +1,6 @@
# ============LICENSE_START=======================================================
# Copyright (C) 2021 Pantheon.tech
-# Modifications Copyright (C) 2021 Bell Canada
+# Modifications Copyright (C) 2021-2022 Bell Canada
# Modifications Copyright (C) 2021-2022 Nordix Foundation
# ================================================================================
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -157,4 +157,7 @@ dmi:
timers:
advised-modules-sync:
- sleep-time-ms: 30000 \ No newline at end of file
+ sleep-time-ms: 30000
+
+ locked-modules-sync:
+ sleep-time-ms: 300000 \ No newline at end of file
diff --git a/cps-ncmp-events/src/main/resources/schemas/ncmp-event-schema-v1.json b/cps-ncmp-events/src/main/resources/schemas/ncmp-event-schema-v1.json
index 84fc12edbd..4ddffea56a 100644
--- a/cps-ncmp-events/src/main/resources/schemas/ncmp-event-schema-v1.json
+++ b/cps-ncmp-events/src/main/resources/schemas/ncmp-event-schema-v1.json
@@ -26,8 +26,7 @@
},
"eventSource": {
"description": "The source of the event.",
- "type": "string",
- "format": "uri"
+ "type": "string"
},
"eventType": {
"description": "The type of the event.",
@@ -35,8 +34,7 @@
},
"eventSchema": {
"description": "The schema, including its version, that this event adheres to.",
- "type": "string",
- "format": "uri"
+ "type": "string"
},
"event": {
"$ref": "#/definitions/Event"
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java
index ccb1e9bbb8..fb234ef71a 100755
--- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java
@@ -211,6 +211,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
* @return collection of cm handles
*/
@Override
+ @SuppressWarnings("deprecation") // mapOldConditionProperties method will be removed in Release 12
public ResponseEntity<List<RestOutputCmHandle>> searchCmHandles(
final CmHandleQueryParameters cmHandleQueryParameters) {
final CmHandleQueryApiParameters cmHandleQueryApiParameters =
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/DeprecationHelper.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/DeprecationHelper.java
index fc992da41a..573491ca3f 100644
--- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/DeprecationHelper.java
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/DeprecationHelper.java
@@ -40,9 +40,11 @@ public class DeprecationHelper {
* !!! remove it after the old condition removed !!!
* it only works for module names
*
+ * @deprecated this method will be removed in Release 12 (No Name know yet)
+ *
* @param cmHandleQueryParameters the original input parameter
*/
- @Deprecated //this method wil be removed in Release 12 (No Name know yet)
+ @Deprecated
public CmHandleQueryApiParameters mapOldConditionProperties(
final CmHandleQueryParameters cmHandleQueryParameters) {
final CmHandleQueryApiParameters cmHandleQueryApiParameters =
diff --git a/cps-ncmp-service/pom.xml b/cps-ncmp-service/pom.xml
index 99a024e65d..502e9824d7 100644
--- a/cps-ncmp-service/pom.xml
+++ b/cps-ncmp-service/pom.xml
@@ -3,6 +3,7 @@
============LICENSE_START=======================================================
Copyright (C) 2021-2022 Nordix Foundation
Modifications Copyright (C) 2021 Pantheon.tech
+ Modifications Copyright (C) 2022 Bell Canada
================================================================================
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -31,10 +32,10 @@
</parent>
<artifactId>cps-ncmp-service</artifactId>
+
<properties>
- <minimum-coverage>0.93</minimum-coverage>
+ <minimum-coverage>0.96</minimum-coverage>
</properties>
-
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyCmHandlerQueryService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyCmHandlerQueryService.java
index f8d51feba8..92b1e82c3e 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyCmHandlerQueryService.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyCmHandlerQueryService.java
@@ -21,15 +21,15 @@
package org.onap.cps.ncmp.api;
import java.util.Collection;
-import org.onap.cps.spi.model.CmHandleQueryParameters;
+import org.onap.cps.spi.model.CmHandleQueryServiceParameters;
import org.onap.cps.spi.model.DataNode;
public interface NetworkCmProxyCmHandlerQueryService {
/**
* Query and return cm handles that match the given query parameters.
*
- * @param cmHandleQueryParameters the cm handle query parameters
+ * @param cmHandleQueryServiceParameters the cm handle query parameters
* @return collection of cm handles
*/
- Collection<DataNode> queryCmHandles(CmHandleQueryParameters cmHandleQueryParameters);
+ Collection<DataNode> queryCmHandles(CmHandleQueryServiceParameters cmHandleQueryServiceParameters);
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceImpl.java
index ef6e953e2f..00cbe69f54 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceImpl.java
@@ -37,7 +37,7 @@ import org.onap.cps.ncmp.api.NetworkCmProxyCmHandlerQueryService;
import org.onap.cps.spi.CpsAdminPersistenceService;
import org.onap.cps.spi.CpsDataPersistenceService;
import org.onap.cps.spi.model.Anchor;
-import org.onap.cps.spi.model.CmHandleQueryParameters;
+import org.onap.cps.spi.model.CmHandleQueryServiceParameters;
import org.onap.cps.spi.model.ConditionProperties;
import org.onap.cps.spi.model.DataNode;
import org.onap.cps.spi.model.DataNodeIdentifier;
@@ -58,23 +58,23 @@ public class NetworkCmProxyCmHandlerQueryServiceImpl implements NetworkCmProxyCm
/**
* Query and return cm handles that match the given query parameters.
*
- * @param cmHandleQueryParameters the cm handle query parameters
+ * @param cmHandleQueryServiceParameters the cm handle query parameters
* @return collection of cm handles
*/
@Override
- public Collection<DataNode> queryCmHandles(final CmHandleQueryParameters cmHandleQueryParameters) {
+ public Collection<DataNode> queryCmHandles(final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
- if (cmHandleQueryParameters.getCmHandleQueryParameters().isEmpty()) {
+ if (cmHandleQueryServiceParameters.getCmHandleQueryParameters().isEmpty()) {
return getAllCmHandles();
}
final Collection<DataNodeIdentifier> amalgamatedQueryResultIdentifiers = new ArrayList<>();
final Map<DataNodeIdentifier, DataNode> amalgamatedQueryResults = new HashMap<>();
- final boolean firstQuery = moduleNameQuery(cmHandleQueryParameters,
+ final boolean firstQuery = moduleNameQuery(cmHandleQueryServiceParameters,
amalgamatedQueryResultIdentifiers, amalgamatedQueryResults);
- publicPropertyQuery(cmHandleQueryParameters, amalgamatedQueryResultIdentifiers,
+ publicPropertyQuery(cmHandleQueryServiceParameters, amalgamatedQueryResultIdentifiers,
amalgamatedQueryResults, firstQuery);
final Collection<DataNode> filteredDataNodes = new ArrayList<>();
@@ -85,12 +85,12 @@ public class NetworkCmProxyCmHandlerQueryServiceImpl implements NetworkCmProxyCm
return filteredDataNodes;
}
- private void publicPropertyQuery(final CmHandleQueryParameters cmHandleQueryParameters,
+ private void publicPropertyQuery(final CmHandleQueryServiceParameters cmHandleQueryServiceParameters,
final Collection<DataNodeIdentifier> amalgamatedQueryResultIdentifiers,
final Map<DataNodeIdentifier, DataNode> amalgamatedQueryResults,
boolean firstQuery) {
for (final Map.Entry<String, String> entry :
- getPublicPropertyPairs(cmHandleQueryParameters.getCmHandleQueryParameters()).entrySet()) {
+ getPublicPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters()).entrySet()) {
final String cmHandlePath = "//public-properties[@name='" + entry.getKey() + "' " + "and @value='"
+ entry.getValue() + "']" + "/ancestor::cm-handles";
@@ -121,13 +121,13 @@ public class NetworkCmProxyCmHandlerQueryServiceImpl implements NetworkCmProxyCm
}
}
- private boolean moduleNameQuery(final CmHandleQueryParameters cmHandleQueryParameters,
+ private boolean moduleNameQuery(final CmHandleQueryServiceParameters cmHandleQueryServiceParameters,
final Collection<DataNodeIdentifier> amalgamatedQueryResultIdentifiers,
final Map<DataNodeIdentifier, DataNode> amalgamatedQueryResults) {
boolean firstQuery = true;
- if (!getModuleNames(cmHandleQueryParameters.getCmHandleQueryParameters()).isEmpty()) {
+ if (!getModuleNames(cmHandleQueryServiceParameters.getCmHandleQueryParameters()).isEmpty()) {
final Collection<Anchor> anchors = cpsAdminPersistenceService.queryAnchors("NFP-Operational",
- getModuleNames(cmHandleQueryParameters.getCmHandleQueryParameters()));
+ getModuleNames(cmHandleQueryServiceParameters.getCmHandleQueryParameters()));
anchors.forEach(anchor -> {
final List<DataNode> dataNodes = getDataNodes("//cm-handles[@id='" + anchor.getName() + "']");
dataNodes.parallelStream().forEach(dataNode -> {
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
index d1f72a5ef4..f8cab4f1ca 100755
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
@@ -63,7 +63,7 @@ import org.onap.cps.spi.exceptions.AlreadyDefinedException;
import org.onap.cps.spi.exceptions.DataNodeNotFoundException;
import org.onap.cps.spi.exceptions.DataValidationException;
import org.onap.cps.spi.exceptions.SchemaSetNotFoundException;
-import org.onap.cps.spi.model.CmHandleQueryParameters;
+import org.onap.cps.spi.model.CmHandleQueryServiceParameters;
import org.onap.cps.spi.model.ModuleReference;
import org.onap.cps.utils.CpsValidator;
import org.onap.cps.utils.JsonObjectMapper;
@@ -167,12 +167,12 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
@Override
public Set<NcmpServiceCmHandle> executeCmHandleSearch(final CmHandleQueryApiParameters cmHandleQueryApiParameters) {
- final CmHandleQueryParameters cmHandleQueryParameters = jsonObjectMapper.convertToValueType(
- cmHandleQueryApiParameters, CmHandleQueryParameters.class);
+ final CmHandleQueryServiceParameters cmHandleQueryServiceParameters = jsonObjectMapper.convertToValueType(
+ cmHandleQueryApiParameters, CmHandleQueryServiceParameters.class);
- validateCmHandleQueryParameters(cmHandleQueryParameters);
+ validateCmHandleQueryParameters(cmHandleQueryServiceParameters);
- return networkCmProxyCmHandlerQueryService.queryCmHandles(cmHandleQueryParameters).stream()
+ return networkCmProxyCmHandlerQueryService.queryCmHandles(cmHandleQueryServiceParameters).stream()
.map(dataNode -> YangDataConverter
.convertCmHandleToYangModel(dataNode, dataNode.getLeaves().get("id").toString()))
.map(YangDataConverter::convertYangModelCmHandleToNcmpServiceCmHandle).collect(Collectors.toSet());
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsCreator.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsCreator.java
new file mode 100644
index 0000000000..609306f08e
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsCreator.java
@@ -0,0 +1,90 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.api.impl.event;
+
+import static org.onap.ncmp.cmhandle.lcm.event.Event.CmhandleState.READY;
+import static org.onap.ncmp.cmhandle.lcm.event.Event.Operation.DELETE;
+
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+import java.util.UUID;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
+import org.onap.ncmp.cmhandle.lcm.event.Event;
+import org.onap.ncmp.cmhandle.lcm.event.Event.Operation;
+import org.onap.ncmp.cmhandle.lcm.event.NcmpEvent;
+import org.springframework.stereotype.Component;
+
+
+/**
+ * NcmpEventsCreator to create NcmpEvent based on relevant operation.
+ */
+@Slf4j
+@Component
+public class NcmpEventsCreator {
+
+
+ /**
+ * Populate NcmpEvent.
+ *
+ * @param cmHandleId Cm Handle Identifier
+ * @param operation Relevant Operation
+ * @param ncmpServiceCmHandle Ncmp CmHandle Data
+ * @return Populated NcmpEvent
+ */
+ public NcmpEvent populateNcmpEvent(final String cmHandleId, final Operation operation,
+ final NcmpServiceCmHandle ncmpServiceCmHandle) {
+ return createNcmpEvent(cmHandleId, operation, ncmpServiceCmHandle);
+ }
+
+ private NcmpEvent createNcmpEvent(final String cmHandleId, final Operation operation,
+ final NcmpServiceCmHandle ncmpServiceCmHandle) {
+ final NcmpEvent ncmpEvent = ncmpEventHeader(cmHandleId);
+ ncmpEvent.setEvent(ncmpEventPayload(cmHandleId, operation, ncmpServiceCmHandle));
+ return ncmpEvent;
+ }
+
+ private Event ncmpEventPayload(final String eventCorrelationId, final Operation operation,
+ final NcmpServiceCmHandle ncmpServiceCmHandle) {
+ final Event event = new Event();
+ event.setOperation(operation);
+ event.setCmHandleId(eventCorrelationId);
+
+ if (!DELETE.equals(operation)) {
+ event.setCmhandleState(READY);
+ event.setCmhandleProperties(List.of(ncmpServiceCmHandle.getPublicProperties()));
+ }
+ return event;
+ }
+
+ private NcmpEvent ncmpEventHeader(final String eventCorrelationId) {
+ final NcmpEvent ncmpEvent = new NcmpEvent();
+ ncmpEvent.setEventId(UUID.randomUUID().toString());
+ ncmpEvent.setEventCorrelationId(eventCorrelationId);
+ ncmpEvent.setEventTime(ZonedDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ")));
+ ncmpEvent.setEventSource("org.onap.ncmp");
+ ncmpEvent.setEventType("org.onap.ncmp.cmhandle-lcm-event");
+ ncmpEvent.setEventSchema("org.onap.ncmp:cmhandle-lcm-event:v1");
+ return ncmpEvent;
+ }
+
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsService.java
new file mode 100644
index 0000000000..045a67a104
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsService.java
@@ -0,0 +1,65 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.api.impl.event;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
+import org.onap.cps.ncmp.api.inventory.InventoryPersistence;
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
+import org.onap.ncmp.cmhandle.lcm.event.Event.Operation;
+import org.onap.ncmp.cmhandle.lcm.event.NcmpEvent;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+/**
+ * NcmpEventService to map the event correctly and publish to the public topic.
+ */
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class NcmpEventsService {
+
+ private final InventoryPersistence inventoryPersistence;
+
+ private final NcmpEventsPublisher ncmpEventsPublisher;
+
+ private final NcmpEventsCreator ncmpEventsCreator;
+
+ @Value("${app.ncmp.events.topic:ncmp-events}")
+ private String topicName;
+
+ /**
+ * Publish the NcmpEvent to the public topic.
+ *
+ * @param cmHandleId Cm Handle Id
+ * @param operation Relevant operation(CREATE,UPDATE or DELETE)
+ */
+ public void publishNcmpEvent(final String cmHandleId, final Operation operation) {
+
+ final NcmpServiceCmHandle ncmpServiceCmHandle = YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle(
+ inventoryPersistence.getYangModelCmHandle(cmHandleId));
+ final NcmpEvent ncmpEvent = ncmpEventsCreator.populateNcmpEvent(cmHandleId, operation, ncmpServiceCmHandle);
+ ncmpEventsPublisher.publishEvent(topicName, cmHandleId, ncmpEvent);
+
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistence.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistence.java
index 2fc2dc5c1a..ce34154b9b 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistence.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistence.java
@@ -1,6 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2022 Nordix Foundation
+ * Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -92,6 +93,17 @@ public class InventoryPersistence {
}
/**
+ * Method to return cm handles from the cps path.
+ *
+ * @param cpsPath cps path for which the cmHandle is requested
+ * @return a list of cm handles
+ */
+ public List<DataNode> getCmHandlesByCpsPath(final String cpsPath) {
+ return cpsDataPersistenceService.queryDataNodes(
+ NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, cpsPath, FetchDescendantsOption.OMIT_DESCENDANTS);
+ }
+
+ /**
* This method retrieves DMI service name, DMI properties and the state for a given cm handle.
* @param cmHandleId the id of the cm handle
* @return yang model cm handle
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java
index bcc7daa39d..dbc7dd4f2c 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java
@@ -1,6 +1,7 @@
/*
- * ============LICENSE_START=======================================================
+ * ============LICENSE_START=======================================================
* Copyright (C) 2022 Nordix Foundation
+ * Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,11 +21,13 @@
package org.onap.cps.ncmp.api.inventory.sync;
+import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
import org.onap.cps.ncmp.api.inventory.CmHandleState;
import org.onap.cps.ncmp.api.inventory.CompositeState;
+import org.onap.cps.ncmp.api.inventory.CompositeState.LockReason;
import org.onap.cps.ncmp.api.inventory.InventoryPersistence;
import org.onap.cps.ncmp.api.inventory.LockReasonCategory;
import org.springframework.scheduling.annotation.Scheduled;
@@ -44,7 +47,7 @@ public class ModuleSyncWatchdog {
/**
* Execute Cm Handle poll which changes the cm handle state from 'ADVISED' to 'READY'.
*/
- @Scheduled(fixedDelayString = "${timers.advised-modules-sync.sleep-time-ms}")
+ @Scheduled(fixedDelayString = "${timers.advised-modules-sync.sleep-time-ms:30000}")
public void executeAdvisedCmHandlePoll() {
YangModelCmHandle advisedCmHandle = syncUtils.getAnAdvisedCmHandle();
while (advisedCmHandle != null) {
@@ -68,4 +71,20 @@ public class ModuleSyncWatchdog {
log.debug("No Cm-Handles currently found in an ADVISED state");
}
+ /**
+ * Execute Cm Handle poll which changes the cm handle state from 'LOCKED' to 'ADVISED'.
+ */
+ @Scheduled(fixedDelayString = "${timers.locked-modules-sync.sleep-time-ms:300000}")
+ public void executeLockedMisbehavingCmHandlePoll() {
+ final List<YangModelCmHandle> lockedMisbehavingCmHandles = syncUtils.getLockedMisbehavingCmHandles();
+ for (final YangModelCmHandle lockedMisbehavingModelCmHandle: lockedMisbehavingCmHandles) {
+ final CompositeState updatedCompositeState = lockedMisbehavingModelCmHandle.getCompositeState();
+ updatedCompositeState.setCmHandleState(CmHandleState.ADVISED);
+ updatedCompositeState.setLastUpdateTimeNow();
+ updatedCompositeState.setLockReason(LockReason.builder()
+ .details(updatedCompositeState.getLockReason().getDetails()).build());
+ log.debug("Locked misbehaving cm handle {} is being recycled", lockedMisbehavingModelCmHandle.getId());
+ inventoryPersistence.saveCmHandleState(lockedMisbehavingModelCmHandle.getId(), updatedCompositeState);
+ }
+ }
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/SyncUtils.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/SyncUtils.java
index a4f29de3e8..22eeabb0df 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/SyncUtils.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/SyncUtils.java
@@ -1,6 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2022 Nordix Foundation
+ * Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,8 +25,10 @@ import java.security.SecureRandom;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
import org.onap.cps.ncmp.api.inventory.CmHandleState;
import org.onap.cps.ncmp.api.inventory.CompositeState;
@@ -41,7 +44,6 @@ public class SyncUtils {
private static final SecureRandom secureRandom = new SecureRandom();
-
private final InventoryPersistence inventoryPersistence;
private static final Pattern retryAttemptPattern = Pattern.compile("^Attempt #(\\d+) failed:");
@@ -64,6 +66,19 @@ public class SyncUtils {
/**
+ * Query data nodes for cm handles with an "LOCKED" cm handle state with reason LOCKED_MISBEHAVING".
+ *
+ * @return a random yang model cm handle with an ADVISED state, return null if not found
+ */
+ public List<YangModelCmHandle> getLockedMisbehavingCmHandles() {
+ final List<DataNode> lockedCmHandleAsDataNodeList = inventoryPersistence.getCmHandlesByCpsPath(
+ "//lock-reason[@reason=\"LOCKED_MISBEHAVING\"]/ancestor::cm-handles");
+ return lockedCmHandleAsDataNodeList.stream()
+ .map(cmHandle -> YangDataConverter.convertCmHandleToYangModel(cmHandle,
+ cmHandle.getLeaves().get("id").toString())).collect(Collectors.toList());
+ }
+
+ /**
* Update Composite State attempts counter and set new lock reason and details.
*
* @param lockReasonCategory lock reason category
@@ -84,5 +99,4 @@ public class SyncUtils {
.lockReasonCategory(lockReasonCategory).build());
}
-
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceSpec.groovy
index a1ad9af191..b689097cc4 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceSpec.groovy
@@ -25,7 +25,7 @@ import org.onap.cps.ncmp.api.NetworkCmProxyCmHandlerQueryService
import org.onap.cps.spi.CpsAdminPersistenceService
import org.onap.cps.spi.CpsDataPersistenceService
import org.onap.cps.spi.model.Anchor
-import org.onap.cps.spi.model.CmHandleQueryParameters
+import org.onap.cps.spi.model.CmHandleQueryServiceParameters
import org.onap.cps.spi.model.ConditionProperties
import org.onap.cps.spi.model.DataNode
import org.onap.cps.utils.JsonObjectMapper
@@ -44,7 +44,7 @@ class NetworkCmProxyCmHandlerQueryServiceSpec extends Specification {
def 'Retrieve cm handles with public properties when #scenario.'() {
given: 'a condition property'
- def cmHandleQueryParameters = new CmHandleQueryParameters()
+ def cmHandleQueryParameters = new CmHandleQueryServiceParameters()
def conditionProperties = new ConditionProperties()
conditionProperties.conditionName = 'hasAllProperties'
conditionProperties.conditionParameters = publicProperties
@@ -65,7 +65,7 @@ class NetworkCmProxyCmHandlerQueryServiceSpec extends Specification {
def 'Retrieve cm handles with module names when #scenario.'() {
given: 'a condition property'
- def cmHandleQueryParameters = new CmHandleQueryParameters()
+ def cmHandleQueryParameters = new CmHandleQueryServiceParameters()
def conditionProperties = new ConditionProperties()
conditionProperties.conditionName = 'hasAllModules'
conditionProperties.conditionParameters = moduleNames
@@ -86,7 +86,7 @@ class NetworkCmProxyCmHandlerQueryServiceSpec extends Specification {
def 'Retrieve cm handles with combined queries when #scenario.'() {
given: 'condition properties'
- def cmHandleQueryParameters = new CmHandleQueryParameters()
+ def cmHandleQueryParameters = new CmHandleQueryServiceParameters()
def conditionProperties1 = new ConditionProperties()
conditionProperties1.conditionName = 'hasAllProperties'
conditionProperties1.conditionParameters = publicProperties
@@ -111,7 +111,7 @@ class NetworkCmProxyCmHandlerQueryServiceSpec extends Specification {
given: 'mock services'
mockResponses()
when: 'the service is invoked'
- def cmHandleQueryParameters = new CmHandleQueryParameters()
+ def cmHandleQueryParameters = new CmHandleQueryServiceParameters()
def returnedCmHandles = objectUnderTest.queryCmHandles(cmHandleQueryParameters)
then: 'the correct expected cm handles are returned'
returnedCmHandles.stream().map(d -> d.leaves.get('id').toString()).collect(Collectors.toList()) == ['PNFDemo', 'PNFDemo2', 'PNFDemo3', 'PNFDemo4']
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy
index 6ba2a2c276..d58fe6a7cd 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy
@@ -33,7 +33,7 @@ import org.onap.cps.ncmp.api.models.DmiPluginRegistration
import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
import org.onap.cps.spi.exceptions.DataValidationException
import org.onap.cps.ncmp.api.inventory.sync.ModuleSyncService
-import org.onap.cps.spi.model.CmHandleQueryParameters
+import org.onap.cps.spi.model.CmHandleQueryServiceParameters
import org.onap.cps.spi.model.ConditionProperties
import spock.lang.Shared
@@ -252,7 +252,7 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
conditionApiProperties.conditionParameters = [[moduleName: 'module-name-1']]
cmHandleQueryApiParameters.cmHandleQueryParameters = [conditionApiProperties]
and: 'valid CmHandleQueryParameters input'
- def cmHandleQueryParameters = new CmHandleQueryParameters()
+ def cmHandleQueryParameters = new CmHandleQueryServiceParameters()
def conditionProperties = new ConditionProperties()
conditionProperties.conditionName = 'hasAllModules'
conditionProperties.conditionParameters = [[moduleName: 'module-name-1']]
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/NcmpEventsCreatorSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/NcmpEventsCreatorSpec.groovy
new file mode 100644
index 0000000000..04eb0bf2bb
--- /dev/null
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/NcmpEventsCreatorSpec.groovy
@@ -0,0 +1,57 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.api.impl.event
+
+import org.onap.cps.ncmp.api.inventory.CmHandleState
+import org.onap.cps.ncmp.api.inventory.CompositeStateBuilder
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
+import spock.lang.Specification
+
+import static org.onap.ncmp.cmhandle.lcm.event.Event.Operation.CREATE
+import static org.onap.ncmp.cmhandle.lcm.event.Event.Operation.DELETE
+import static org.onap.ncmp.cmhandle.lcm.event.Event.Operation.UPDATE
+
+class NcmpEventsCreatorSpec extends Specification {
+
+ def objectUnderTest = new NcmpEventsCreator()
+ def cmHandleId = 'test-cm-handle'
+
+ def 'Map the NcmpEvent for operation #operation'() {
+ given: 'NCMP cm handle details'
+ def ncmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: cmHandleId, compositeState: new CompositeStateBuilder().withCmHandleState(CmHandleState.READY).build(),
+ publicProperties: ['publicProperty1': 'value1', 'publicProperty2': 'value2'])
+ when: 'the event is populated'
+ def result = objectUnderTest.populateNcmpEvent(cmHandleId, operation, ncmpServiceCmHandle)
+ then: 'event header is mapped correctly'
+ assert result.eventSource == 'org.onap.ncmp'
+ assert result.eventCorrelationId == cmHandleId
+ and: 'event payload is mapped correctly'
+ assert result.event.operation == operation
+ assert result.event.cmhandleProperties.size() == cmHandlePropertiesListSize
+ assert result.event.cmhandleProperties[0] == cmHandleProperties
+ where: 'the following operations are used'
+ operation | cmHandlePropertiesListSize | cmHandleProperties
+ CREATE | 1 | ['publicProperty1': 'value1', 'publicProperty2': 'value2']
+ UPDATE | 1 | ['publicProperty1': 'value1', 'publicProperty2': 'value2']
+ DELETE | 0 | null
+
+ }
+}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/NcmpEventsServiceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/NcmpEventsServiceSpec.groovy
new file mode 100644
index 0000000000..9774235561
--- /dev/null
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/NcmpEventsServiceSpec.groovy
@@ -0,0 +1,64 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.api.impl.event
+
+import org.onap.cps.ncmp.api.impl.utils.YangDataConverter
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
+import org.onap.cps.ncmp.api.inventory.InventoryPersistence
+import org.onap.ncmp.cmhandle.lcm.event.NcmpEvent
+import spock.lang.Specification
+
+import static org.onap.ncmp.cmhandle.lcm.event.Event.Operation.CREATE
+import static org.onap.ncmp.cmhandle.lcm.event.Event.Operation.DELETE
+import static org.onap.ncmp.cmhandle.lcm.event.Event.Operation.UPDATE
+
+class NcmpEventsServiceSpec extends Specification {
+
+ def mockInventoryPersistence = Mock(InventoryPersistence)
+ def mockNcmpEventsPublisher = Mock(NcmpEventsPublisher)
+ def mockNcmpEventsMapper = Mock(NcmpEventsCreator)
+
+ def objectUnderTest = new NcmpEventsService(mockInventoryPersistence, mockNcmpEventsPublisher, mockNcmpEventsMapper)
+
+ def 'Create and Publish event for #operation'() {
+ given: 'a cm handle id and operation and responses are mocked'
+ mockResponses('test-cm-handle-id', operation, 'test-topic')
+ when: 'service is called to publish ncmp event'
+ objectUnderTest.publishNcmpEvent('test-cm-handle-id', operation)
+ then: 'no exception is thrown'
+ noExceptionThrown()
+ where: 'for following operations'
+ operation << [CREATE, UPDATE, DELETE]
+ }
+
+ def mockResponses(cmHandleId, operation, topicName) {
+
+ def yangModelCmHandle = new YangModelCmHandle(id: cmHandleId, publicProperties: [new YangModelCmHandle.Property('publicProperty1', 'value1')], dmiProperties: [])
+ def ncmpEvent = new NcmpEvent(eventId: UUID.randomUUID().toString(), eventCorrelationId: cmHandleId)
+ def ncmpServiceCmhandle = YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle(yangModelCmHandle)
+
+ mockInventoryPersistence.getYangModelCmHandle(cmHandleId) >> yangModelCmHandle
+ mockNcmpEventsMapper.populateNcmpEvent(cmHandleId, operation, ncmpServiceCmhandle) >> ncmpEvent
+ mockNcmpEventsPublisher.publishEvent(topicName, cmHandleId, ncmpEvent) >> {}
+ }
+
+
+}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/InventoryPersistenceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/InventoryPersistenceSpec.groovy
index a2ebcb5d81..e6346cb024 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/InventoryPersistenceSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/InventoryPersistenceSpec.groovy
@@ -1,6 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2022 Nordix Foundation
+ * Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,6 +28,7 @@ import org.onap.cps.spi.CpsDataPersistenceService
import org.onap.cps.spi.FetchDescendantsOption
import org.onap.cps.spi.exceptions.DataValidationException
import org.onap.cps.spi.model.DataNode
+import org.onap.cps.spi.model.DataNodeBuilder
import org.onap.cps.utils.JsonObjectMapper
import spock.lang.Shared
import spock.lang.Specification
@@ -50,7 +52,7 @@ class InventoryPersistenceSpec extends Specification {
def objectUnderTest = new InventoryPersistence(spiedJsonObjectMapper, mockCpsDataService, mockCpsDataPersistenceService)
def formattedDateAndTime = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
- .format(OffsetDateTime.of(2022, 12, 31, 20, 30, 40, 1, ZoneOffset.UTC))
+ .format(OffsetDateTime.of(2022, 12, 31, 20, 30, 40, 1, ZoneOffset.UTC))
def cmHandleId = 'some-cm-handle'
def leaves = ["dmi-service-name":"common service name","dmi-data-service-name":"data service name","dmi-model-service-name":"model service name"]
@@ -88,7 +90,7 @@ class InventoryPersistenceSpec extends Specification {
where: 'the following parameters are used'
scenario | childDataNodes || expectedDmiProperties || expectedPublicProperties || expectedCompositeState
'no properties' | [] || [] || [] || null
- 'DMI and public properties' | childDataNodesForCmHandleWithAllProperties || [new YangModelCmHandle.Property("name1", "value1")] || [new YangModelCmHandle.Property("name2", "value2")] || null
+ 'DMI and public properties' | childDataNodesForCmHandleWithAllProperties || [new YangModelCmHandle.Property("name1", "value1")] || [new YangModelCmHandle.Property("name2", "value2")] || null
'just DMI properties' | childDataNodesForCmHandleWithDMIProperties || [new YangModelCmHandle.Property("name1", "value1")] || [] || null
'just public properties' | childDataNodesForCmHandleWithPublicProperties || [] || [new YangModelCmHandle.Property("name2", "value2")] || null
'with state details' | childDataNodesForCmHandleWithState || [] || [] || CmHandleState.ADVISED
@@ -105,7 +107,7 @@ class InventoryPersistenceSpec extends Specification {
def "Handling missing service names as null CPS-1043."() {
given: 'the cps data service returns a data node from the DMI registry with empty child and leaf attributes'
- def dataNode = new DataNode(childDataNodes:[], leaves: ["cm-handle-state":"ADVISED"])
+ def dataNode = new DataNode(childDataNodes:[], leaves: [:])
mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', xpath, INCLUDE_ALL_DESCENDANTS) >> dataNode
when: 'retrieving the yang modelled cm handle'
def result = objectUnderTest.getYangModelCmHandle(cmHandleId)
@@ -121,7 +123,7 @@ class InventoryPersistenceSpec extends Specification {
def dataNode = new DataNode(leaves: ['cm-handle-state': 'ADVISED'])
and: 'cps data service returns a valid data node'
mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
- '/dmi-registry/cm-handles[@id=\'Some-Cm-Handle\']/state', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
+ '/dmi-registry/cm-handles[@id=\'Some-Cm-Handle\']/state', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
when: 'get cm handle state is invoked'
def result = objectUnderTest.getCmHandleState(cmHandleId)
then: 'result has returned the correct cm handle state'
@@ -137,7 +139,7 @@ class InventoryPersistenceSpec extends Specification {
then: 'update node leaves is invoked with the correct params'
1 * mockCpsDataService.replaceNodeTree('NCMP-Admin', 'ncmp-dmi-registry', '/dmi-registry/cm-handles[@id=\'Some-Cm-Handle\']', expectedJsonData, _ as OffsetDateTime)
where: 'the following states are used'
- scenario | cmHandleState || expectedJsonData
+ scenario | cmHandleState || expectedJsonData
'READY' | CmHandleState.READY || '{"state":{"cm-handle-state":"READY","last-update-time":"2022-12-31T20:30:40.000+0000"}}'
'LOCKED' | CmHandleState.LOCKED || '{"state":{"cm-handle-state":"LOCKED","last-update-time":"2022-12-31T20:30:40.000+0000"}}'
}
@@ -148,11 +150,25 @@ class InventoryPersistenceSpec extends Specification {
and: 'cps data service returns a list of data nodes'
def dataNodes = [new DataNode()]
mockCpsDataPersistenceService.queryDataNodes('NCMP-Admin', 'ncmp-dmi-registry',
- '//state[@cm-handle-state="ADVISED"]/ancestor::cm-handles', OMIT_DESCENDANTS) >> dataNodes
+ '//state[@cm-handle-state="ADVISED"]/ancestor::cm-handles', OMIT_DESCENDANTS) >> dataNodes
when: 'get cm handles by state is invoked'
def result = objectUnderTest.getCmHandlesByState(cmHandleState)
then: 'the returned result is a list of data nodes returned by cps data service'
assert result == dataNodes
}
+ def 'Retrieve cm handle by cps path '() {
+ given: 'a cm handle state to query based on the cps path'
+ def cmHandleDataNode = new DataNode(xpath: 'xpath', leaves: ['cm-handle-state': 'LOCKED'])
+ def cpsPath = '//cps-path'
+ and: 'cps data service returns a valid data node'
+ mockCpsDataPersistenceService.queryDataNodes('NCMP-Admin', 'ncmp-dmi-registry',
+ cpsPath, OMIT_DESCENDANTS)
+ >> Arrays.asList(cmHandleDataNode)
+ when: 'get cm handles by cps path is invoked'
+ def result = objectUnderTest.getCmHandlesByCpsPath(cpsPath)
+ then: 'the returned result is a list of data nodes returned by cps data service'
+ assert result.contains(cmHandleDataNode)
+ }
+
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncSpec.groovy
index 97bea096a3..544f739c06 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncSpec.groovy
@@ -1,6 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2022 Nordix Foundation
+ * Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +26,7 @@ import org.onap.cps.ncmp.api.inventory.CmHandleState
import org.onap.cps.ncmp.api.inventory.CompositeState
import org.onap.cps.ncmp.api.inventory.InventoryPersistence
import org.onap.cps.ncmp.api.inventory.LockReasonCategory
+import org.onap.cps.ncmp.api.inventory.CompositeStateBuilder
import spock.lang.Specification
class ModuleSyncSpec extends Specification {
@@ -88,4 +90,16 @@ class ModuleSyncSpec extends Specification {
}
+ def 'Schedule a Cm-Handle Sync for LOCKED with reason LOCKED_MISBEHAVING Cm-Handles '() {
+ given: 'cm handles in an locked state'
+ def compositeState = new CompositeStateBuilder().withCmHandleState(CmHandleState.LOCKED)
+ .withLockReason(LockReasonCategory.LOCKED_MISBEHAVING, '').build()
+ def yangModelCmHandle = new YangModelCmHandle(id: 'some-cm-handle', compositeState: compositeState)
+ and: 'sync utilities return a cm handle twice'
+ mockSyncUtils.getLockedMisbehavingCmHandles() >> [yangModelCmHandle, yangModelCmHandle]
+ when: 'module sync poll is executed'
+ objectUnderTest.executeLockedMisbehavingCmHandlePoll()
+ then: 'the first cm handle is updated to state "ADVISED" from "READY"'
+ 2 * mockInventoryPersistence.saveCmHandleState(yangModelCmHandle.id, compositeState)
+ }
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/SyncUtilsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/SyncUtilsSpec.groovy
index 7d67acccc3..15d1efe068 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/SyncUtilsSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/SyncUtilsSpec.groovy
@@ -1,6 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2022 Nordix Foundation
+ * Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,15 +25,12 @@ import org.onap.cps.ncmp.api.inventory.CmHandleState
import org.onap.cps.ncmp.api.inventory.CompositeState
import org.onap.cps.ncmp.api.inventory.InventoryPersistence
import org.onap.cps.ncmp.api.inventory.LockReasonCategory
-import org.onap.cps.spi.CpsDataPersistenceService
-import org.onap.cps.spi.FetchDescendantsOption
import org.onap.cps.spi.model.DataNode
import spock.lang.Shared
import spock.lang.Specification
class SyncUtilsSpec extends Specification{
- def mockCpsDataPersistenceService = Mock(CpsDataPersistenceService)
def mockInventoryPersistence = Mock(InventoryPersistence)
def objectUnderTest = new SyncUtils(mockInventoryPersistence)
@@ -40,8 +38,6 @@ class SyncUtilsSpec extends Specification{
@Shared
def dataNode = new DataNode(leaves: ['id': 'cm-handle-123'])
-
-
def 'Get an advised Cm-Handle where ADVISED cm handle #scenario'() {
given: 'the inventory persistence service returns a collection of data nodes'
mockInventoryPersistence.getCmHandlesByState(CmHandleState.ADVISED) >> dataNodeCollection
@@ -71,5 +67,15 @@ class SyncUtilsSpec extends Specification{
'does not exist' | null || 'Attempt #1 failed: new error message'
'exists' | CompositeState.LockReason.builder().details("Attempt #2 failed: some error message").build() || 'Attempt #3 failed: new error message'
}
-
+ def 'Get all locked Cm-Handle where Lock Reason is LOCKED_MISBEHAVING cm handle #scenario'() {
+ given: 'the cps (persistence service) returns a collection of data nodes'
+ mockInventoryPersistence.getCmHandlesByCpsPath(
+ '//lock-reason[@reason="LOCKED_MISBEHAVING"]/ancestor::cm-handles') >> [dataNode ]
+ when: 'get locked Misbehaving cm handle is called'
+ def result = objectUnderTest.getLockedMisbehavingCmHandles()
+ then: 'the returned cm handle collection is the correct size'
+ result.size() == 1
+ and: 'the correct cm handle is returned'
+ result[0].id == 'cm-handle-123'
+ }
}
diff --git a/cps-service/src/main/java/org/onap/cps/spi/model/CmHandleQueryParameters.java b/cps-service/src/main/java/org/onap/cps/spi/model/CmHandleQueryServiceParameters.java
index cf364db3a8..8dcf88b0eb 100644
--- a/cps-service/src/main/java/org/onap/cps/spi/model/CmHandleQueryParameters.java
+++ b/cps-service/src/main/java/org/onap/cps/spi/model/CmHandleQueryServiceParameters.java
@@ -34,7 +34,7 @@ import lombok.Setter;
@Getter
@EqualsAndHashCode
@JsonInclude(Include.NON_EMPTY)
-public class CmHandleQueryParameters {
+public class CmHandleQueryServiceParameters {
@JsonProperty("cmHandleQueryParameters")
@Valid
private List<ConditionProperties> cmHandleQueryParameters = Collections.emptyList();
diff --git a/cps-service/src/main/java/org/onap/cps/utils/CmHandleQueryRestParametersValidator.java b/cps-service/src/main/java/org/onap/cps/utils/CmHandleQueryRestParametersValidator.java
index c510a73af2..c3811eb485 100644
--- a/cps-service/src/main/java/org/onap/cps/utils/CmHandleQueryRestParametersValidator.java
+++ b/cps-service/src/main/java/org/onap/cps/utils/CmHandleQueryRestParametersValidator.java
@@ -27,7 +27,7 @@ import java.util.Map;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.onap.cps.spi.exceptions.DataValidationException;
-import org.onap.cps.spi.model.CmHandleQueryParameters;
+import org.onap.cps.spi.model.CmHandleQueryServiceParameters;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class CmHandleQueryRestParametersValidator {
@@ -36,10 +36,11 @@ public class CmHandleQueryRestParametersValidator {
/**
* Validate cm handle query parameters.
- * @param cmHandleQueryParameters name of data to be validated
+ * @param cmHandleQueryServiceParameters name of data to be validated
*/
- public static void validateCmHandleQueryParameters(final CmHandleQueryParameters cmHandleQueryParameters) {
- cmHandleQueryParameters.getCmHandleQueryParameters().forEach(
+ public static void validateCmHandleQueryParameters(
+ final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
+ cmHandleQueryServiceParameters.getCmHandleQueryParameters().forEach(
conditionApiProperty -> {
if (Strings.isNullOrEmpty(conditionApiProperty.getConditionName())) {
throwDataValidationException("Missing 'conditionName' - please supply a valid name.");
@@ -54,27 +55,29 @@ public class CmHandleQueryRestParametersValidator {
"Empty 'conditionsParameters' - please supply a valid condition parameter.");
}
conditionApiProperty.getConditionParameters().forEach(
- conditionParameter -> {
- if (conditionParameter.isEmpty()) {
- throwDataValidationException(
- "Empty 'conditionsParameter' - please supply a valid condition parameter.");
- }
- if (conditionParameter.size() > 1) {
- throwDataValidationException("Too many name in one 'conditionsParameter' -"
- + " please supply one name in one condition parameter.");
- }
- conditionParameter.forEach((key, value) -> {
- if (Strings.isNullOrEmpty(key)) {
- throwDataValidationException(
- "Missing 'conditionsParameterName' - please supply a valid name.");
- }
- });
- }
+ CmHandleQueryRestParametersValidator::validateConditionParameter
);
}
);
}
+ private static void validateConditionParameter(final Map<String, String> conditionParameter) {
+ if (conditionParameter.isEmpty()) {
+ throwDataValidationException(
+ "Empty 'conditionsParameter' - please supply a valid condition parameter.");
+ }
+ if (conditionParameter.size() > 1) {
+ throwDataValidationException("Too many name in one 'conditionsParameter' -"
+ + " please supply one name in one condition parameter.");
+ }
+ conditionParameter.forEach((key, value) -> {
+ if (Strings.isNullOrEmpty(key)) {
+ throwDataValidationException(
+ "Missing 'conditionsParameterName' - please supply a valid name.");
+ }
+ });
+ }
+
/**
* Validate module name condition properties.
* @param conditionProperty name of data to be validated
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminServiceImplSpec.groovy
index def99e21f4..41fcb29edd 100755
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminServiceImplSpec.groovy
@@ -26,7 +26,6 @@ import org.onap.cps.api.CpsDataService
import org.onap.cps.spi.CpsAdminPersistenceService
import org.onap.cps.spi.exceptions.DataValidationException
import org.onap.cps.spi.model.Anchor
-import org.onap.cps.spi.model.CmHandleQueryParameters
import spock.lang.Specification
import java.time.OffsetDateTime
diff --git a/cps-service/src/test/groovy/org/onap/cps/utils/CmHandleQueryRestParametersValidatorSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/utils/CmHandleQueryRestParametersValidatorSpec.groovy
index 645829b2a2..a9b04c1ced 100644
--- a/cps-service/src/test/groovy/org/onap/cps/utils/CmHandleQueryRestParametersValidatorSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/utils/CmHandleQueryRestParametersValidatorSpec.groovy
@@ -21,14 +21,14 @@
package org.onap.cps.utils
import org.onap.cps.spi.exceptions.DataValidationException
-import org.onap.cps.spi.model.CmHandleQueryParameters
+import org.onap.cps.spi.model.CmHandleQueryServiceParameters
import org.onap.cps.spi.model.ConditionProperties
import spock.lang.Specification
class CmHandleQueryRestParametersValidatorSpec extends Specification {
def 'CM Handle Query validation: empty query.'() {
given: 'a cm handle query'
- def cmHandleQueryParameters = new CmHandleQueryParameters()
+ def cmHandleQueryParameters = new CmHandleQueryServiceParameters()
when: 'validator is invoked'
CmHandleQueryRestParametersValidator.validateCmHandleQueryParameters(cmHandleQueryParameters)
then: 'data validation exception is not thrown'
@@ -37,7 +37,7 @@ class CmHandleQueryRestParametersValidatorSpec extends Specification {
def 'CM Handle Query validation: normal query.'() {
given: 'a cm handle query'
- def cmHandleQueryParameters = new CmHandleQueryParameters()
+ def cmHandleQueryParameters = new CmHandleQueryServiceParameters()
def condition = new ConditionProperties()
condition.conditionName = 'hasAllProperties'
condition.conditionParameters = [[key1:'value1'],[key2:'value2']]
@@ -50,7 +50,7 @@ class CmHandleQueryRestParametersValidatorSpec extends Specification {
def 'CM Handle Query validation: #scenario.'() {
given: 'a cm handle query'
- def cmHandleQueryParameters = new CmHandleQueryParameters()
+ def cmHandleQueryParameters = new CmHandleQueryServiceParameters()
def condition = new ConditionProperties()
condition.conditionName = conditionName
condition.conditionParameters = conditionParameters
diff --git a/docs/release-notes.rst b/docs/release-notes.rst
index a584b580a1..58dc060bbd 100755
--- a/docs/release-notes.rst
+++ b/docs/release-notes.rst
@@ -12,12 +12,16 @@ CPS Release Notes
:depth: 2
..
-.. ========================
-.. * * * JAKARTA * * *
-.. ========================
+.. ====================
+.. * * * KOHN * * *
+.. ====================
+
+Version: 3.1.0 (not released yet)
+=================================
+
+Release Data
+------------
-Version: 3.1.0
-==============
+--------------------------------------+--------------------------------------------------------+
| **CPS Project** | |
| | |
@@ -25,10 +29,10 @@ Version: 3.1.0
| **Docker images** | onap/cps-and-ncmp:3.1.0 |
| | |
+--------------------------------------+--------------------------------------------------------+
-| **Release designation** | 3.1.0 Jakarta |
+| **Release designation** | 3.1.0 Kohn |
| | |
+--------------------------------------+--------------------------------------------------------+
-| **Release date** | |
+| **Release date** | N/A |
| | |
+--------------------------------------+--------------------------------------------------------+
@@ -36,6 +40,34 @@ Features
--------
- `CPS-322 <https://jira.onap.org/browse/CPS-322>`_ Implement additional validation for names and identifiers
+.. ========================
+.. * * * JAKARTA * * *
+.. ========================
+
+Version: 3.0.1
+==============
+
+Release Data
+------------
+
++--------------------------------------+--------------------------------------------------------+
+| **CPS Project** | |
+| | |
++--------------------------------------+--------------------------------------------------------+
+| **Docker images** | onap/cps-and-ncmp:3.0.1 |
+| | |
++--------------------------------------+--------------------------------------------------------+
+| **Release designation** | 3.0.1 Jakarta |
+| | |
++--------------------------------------+--------------------------------------------------------+
+| **Release date** | 2022 April 28 |
+| | |
++--------------------------------------+--------------------------------------------------------+
+
+Bug Fixes
+---------
+ - `CPS-961 <https://jira.onap.org/browse/CPS-961>`_ Updated ANTLR compiler version to 4.9.2 to be compatible with runtime version
+
Version: 3.0.0
==============