aboutsummaryrefslogtreecommitdiffstats
path: root/cps-ncmp-service/src
diff options
context:
space:
mode:
authorsourabh_sourabh <sourabh.sourabh@est.tech>2023-03-27 14:36:20 +0100
committersourabh_sourabh <sourabh.sourabh@est.tech>2023-04-27 12:36:02 +0100
commit4031d43f06cb6ceb2e5bc39feb3e4a19ed3c6307 (patch)
tree04c8dad982804ec7d36a7814e91d730dfb7173c8 /cps-ncmp-service/src
parent8c32ab510d9554ef6713f34d9895e2909e17200e (diff)
CPS-1553 :REST endpoint to accept collection of cm handles for GET operation
-Introduced an interface having all un-implemented or default defination of any method that is further extended or implemented by abstract or stubbed controller. -Exposed an endpoint to accept bulk request -Modified an existing methods for more readability. (Parameterized datasource for ... methods) -Code impl. for getResourceDataFromDmi method to send bulk request to new proposed dmi-plugin endpoint that would accept bulk request. -We need to investigate a groovy test that fails only into onap CICD pipeline. For now it's commented out by added TODO tag. (org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy:205) Issue-ID: CPS-1553 Signed-off-by: sourabh_sourabh <sourabh.sourabh@est.tech> Change-Id: Ieac39690956e3a0eab41068db57c5d93a16d04f0 Signed-off-by: sourabh_sourabh <sourabh.sourabh@est.tech>
Diffstat (limited to 'cps-ncmp-service/src')
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java55
-rwxr-xr-xcps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java42
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/client/DmiRestClient.java12
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventForwarder.java47
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/executor/TaskExecutor.java47
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DataStoreEnum.java34
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java186
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java9
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java16
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiRequestBody.java19
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/OperationEnum.java43
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceNameOrganizer.java64
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilder.java68
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/SyncUtils.java8
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy78
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy9
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy41
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiModelOperationsSpec.groovy18
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiOperationsBaseSpec.groovy11
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilderSpec.groovy13
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/SyncUtilsSpec.groovy8
21 files changed, 570 insertions, 258 deletions
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java
index 128eed3f2c..03737bc51b 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java
@@ -23,10 +23,10 @@
package org.onap.cps.ncmp.api;
-import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum;
-
import java.util.Collection;
+import java.util.List;
import java.util.Map;
+import org.onap.cps.ncmp.api.impl.operations.OperationEnum;
import org.onap.cps.ncmp.api.inventory.CompositeState;
import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters;
import org.onap.cps.ncmp.api.models.CmHandleQueryServiceParameters;
@@ -51,50 +51,55 @@ public interface NetworkCmProxyDataService {
DmiPluginRegistrationResponse updateDmiRegistrationAndSyncModule(DmiPluginRegistration dmiPluginRegistration);
/**
- * Get resource data for data store pass-through operational
- * using dmi.
+ * Get resource data for given data store using dmi.
*
- * @param cmHandleId cm handle identifier
- * @param resourceIdentifier resource identifier
+ * @param dataStoreName data store name
+ * @param cmHandleId cm handle identifier
+ * @param resourceIdentifier resource identifier
* @param optionsParamInQuery options query
- * @param topicParamInQuery topic name for (triggering) async responses
- * @param requestId unique requestId for async request
+ * @param topicParamInQuery topic name for (triggering) async responses
+ * @param requestId unique requestId for async request
* @return {@code Object} resource data
*/
- Object getResourceDataOperationalForCmHandle(String cmHandleId,
- String resourceIdentifier,
- String optionsParamInQuery,
- String topicParamInQuery,
- String requestId);
+ Object getResourceDataForCmHandle(String dataStoreName,
+ String cmHandleId,
+ String resourceIdentifier,
+ String optionsParamInQuery,
+ String topicParamInQuery,
+ String requestId);
/**
* Get resource data for operational.
*
+ * @param dataStoreName data store name
* @param cmHandleId cm handle identifier
* @param resourceIdentifier resource identifier
* @Link FetchDescendantsOption fetch descendants option
* @return {@code Object} resource data
*/
- Object getResourceDataOperational(String cmHandleId,
+ Object getResourceDataForCmHandle(String dataStoreName,
+ String cmHandleId,
String resourceIdentifier,
FetchDescendantsOption fetchDescendantsOption);
/**
- * Get resource data for data store pass-through running
- * using dmi.
+ * Get resource data for given batch of cm handles using dmi.
*
- * @param cmHandleId cm handle identifier
- * @param resourceIdentifier resource identifier
+ * @param dataStoreName data store name
+ * @param cmHandleIds cm handle identifiers
+ * @param resourceIdentifier resource identifier
* @param optionsParamInQuery options query
- * @param topicParamInQuery topic name for (triggering) async responses
- * @param requestId unique requestId for async request
+ * @param topicParamInQuery topic name for (triggering) async responses
+ * @param requestId unique requestId for async request
* @return {@code Object} resource data
*/
- Object getResourceDataPassThroughRunningForCmHandle(String cmHandleId,
- String resourceIdentifier,
- String optionsParamInQuery,
- String topicParamInQuery,
- String requestId);
+ Object getResourceDataForCmHandleBatch(String dataStoreName,
+ List<String> cmHandleIds,
+ String resourceIdentifier,
+ String optionsParamInQuery,
+ String topicParamInQuery,
+ String requestId);
+
/**
* Write resource data for data store pass-through running
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 b3904bd0bb..1b1997f23a 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
@@ -25,7 +25,6 @@
package org.onap.cps.ncmp.api.impl;
import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME;
-import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum;
import static org.onap.cps.ncmp.api.impl.utils.RestQueryParametersValidator.validateCmHandleQueryParameters;
import com.google.common.collect.Lists;
@@ -46,7 +45,7 @@ import org.onap.cps.ncmp.api.NetworkCmProxyCmHandleQueryService;
import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
import org.onap.cps.ncmp.api.impl.events.lcm.LcmEventsCmHandleStateHandler;
import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations;
-import org.onap.cps.ncmp.api.impl.operations.DmiOperations;
+import org.onap.cps.ncmp.api.impl.operations.OperationEnum;
import org.onap.cps.ncmp.api.impl.utils.CmHandleQueryConditions;
import org.onap.cps.ncmp.api.impl.utils.InventoryQueryConditions;
import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
@@ -115,38 +114,41 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
}
@Override
- public Object getResourceDataOperationalForCmHandle(final String cmHandleId,
- final String resourceIdentifier,
- final String optionsParamInQuery,
- final String topicParamInQuery,
- final String requestId) {
- final ResponseEntity<?> responseEntity = dmiDataOperations.getResourceDataFromDmi(cmHandleId,
+ public Object getResourceDataForCmHandle(final String dataStoreName,
+ final String cmHandleId,
+ final String resourceIdentifier,
+ final String optionsParamInQuery,
+ final String topicParamInQuery,
+ final String requestId) {
+ final ResponseEntity<?> responseEntity = dmiDataOperations.getResourceDataFromDmi(dataStoreName, cmHandleId,
resourceIdentifier,
optionsParamInQuery,
- DmiOperations.DataStoreEnum.PASSTHROUGH_OPERATIONAL,
- requestId, topicParamInQuery);
+ topicParamInQuery,
+ requestId);
return responseEntity.getBody();
}
@Override
- public Object getResourceDataOperational(final String cmHandleId,
+ public Object getResourceDataForCmHandle(final String dataStoreName,
+ final String cmHandleId,
final String resourceIdentifier,
final FetchDescendantsOption fetchDescendantsOption) {
- return cpsDataService.getDataNodes(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId, resourceIdentifier,
+ return cpsDataService.getDataNodes(dataStoreName, cmHandleId, resourceIdentifier,
fetchDescendantsOption).iterator().next();
}
@Override
- public Object getResourceDataPassThroughRunningForCmHandle(final String cmHandleId,
- final String resourceIdentifier,
- final String optionsParamInQuery,
- final String topicParamInQuery,
- final String requestId) {
- final ResponseEntity<?> responseEntity = dmiDataOperations.getResourceDataFromDmi(cmHandleId,
+ public Object getResourceDataForCmHandleBatch(final String dataStoreName,
+ final List<String> cmHandleIds,
+ final String resourceIdentifier,
+ final String optionsParamInQuery,
+ final String topicParamInQuery,
+ final String requestId) {
+ final ResponseEntity<?> responseEntity = dmiDataOperations.getResourceDataFromDmi(dataStoreName, cmHandleIds,
resourceIdentifier,
optionsParamInQuery,
- DmiOperations.DataStoreEnum.PASSTHROUGH_RUNNING,
- requestId, topicParamInQuery);
+ topicParamInQuery,
+ requestId);
return responseEntity.getBody();
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/client/DmiRestClient.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/client/DmiRestClient.java
index d5b459b025..9d087806c0 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/client/DmiRestClient.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/client/DmiRestClient.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2022 Nordix Foundation
+ * Copyright (C) 2021-2023 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,7 +24,7 @@ package org.onap.cps.ncmp.api.impl.client;
import lombok.AllArgsConstructor;
import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration.DmiProperties;
import org.onap.cps.ncmp.api.impl.exception.HttpClientRequestException;
-import org.onap.cps.ncmp.api.impl.operations.DmiRequestBody;
+import org.onap.cps.ncmp.api.impl.operations.OperationEnum;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
@@ -43,14 +43,14 @@ public class DmiRestClient {
/**
* Sends POST operation to DMI with json body containing module references.
* @param dmiResourceUrl dmi resource url
- * @param jsonData json data body
+ * @param requestBodyAsJsonString json data body
* @param operation the type of operation being executed (for error reporting only)
* @return response entity of type String
*/
public ResponseEntity<Object> postOperationWithJsonData(final String dmiResourceUrl,
- final String jsonData,
- final DmiRequestBody.OperationEnum operation) {
- final var httpEntity = new HttpEntity<>(jsonData, configureHttpHeaders(new HttpHeaders()));
+ final String requestBodyAsJsonString,
+ final OperationEnum operation) {
+ final var httpEntity = new HttpEntity<>(requestBodyAsJsonString, configureHttpHeaders(new HttpHeaders()));
try {
return restTemplate.postForEntity(dmiResourceUrl, httpEntity, Object.class);
} catch (final HttpStatusCodeException httpStatusCodeException) {
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventForwarder.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventForwarder.java
index c3624b8005..1fb72a59d3 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventForwarder.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventForwarder.java
@@ -22,7 +22,6 @@ package org.onap.cps.ncmp.api.impl.events.avcsubscription;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -30,7 +29,7 @@ import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.ncmp.api.impl.events.EventsPublisher;
-import org.onap.cps.ncmp.api.impl.operations.RequiredDmiService;
+import org.onap.cps.ncmp.api.impl.utils.DmiServiceNameOrganizer;
import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
import org.onap.cps.ncmp.api.inventory.InventoryPersistence;
import org.onap.cps.ncmp.event.model.SubscriptionEvent;
@@ -45,7 +44,6 @@ public class SubscriptionEventForwarder {
private final InventoryPersistence inventoryPersistence;
private final EventsPublisher<SubscriptionEvent> eventsPublisher;
-
private static final String DMI_AVC_SUBSCRIPTION_TOPIC_PREFIX = "ncmp-dmi-cm-avc-subscription-";
/**
@@ -56,38 +54,24 @@ public class SubscriptionEventForwarder {
public void forwardCreateSubscriptionEvent(final SubscriptionEvent subscriptionEvent) {
final List<Object> cmHandleTargets = subscriptionEvent.getEvent().getPredicates().getTargets();
if (cmHandleTargets == null || cmHandleTargets.isEmpty()
- || cmHandleTargets.stream().anyMatch(id -> ((String) id).contains("*"))) {
+ || cmHandleTargets.stream().anyMatch(id -> ((String) id).contains("*"))) {
throw new OperationNotYetSupportedException(
- "CMHandle targets are required. \"Wildcard\" operations are not yet supported");
+ "CMHandle targets are required. \"Wildcard\" operations are not yet supported");
}
final List<String> cmHandleTargetsAsStrings = cmHandleTargets.stream().map(
- Objects::toString).collect(Collectors.toList());
+ Objects::toString).collect(Collectors.toList());
final Collection<YangModelCmHandle> yangModelCmHandles =
- inventoryPersistence.getYangModelCmHandles(cmHandleTargetsAsStrings);
- final Map<String, Map<String, Map<String, String>>> dmiNameCmHandleMap =
- organizeByDmiName(yangModelCmHandles);
- dmiNameCmHandleMap.forEach((dmiName, cmHandlePropertiesMap) -> {
- subscriptionEvent.getEvent().getPredicates().setTargets(Collections.singletonList(cmHandlePropertiesMap));
- final String eventKey = createEventKey(subscriptionEvent, dmiName);
- eventsPublisher.publishEvent(DMI_AVC_SUBSCRIPTION_TOPIC_PREFIX + dmiName, eventKey, subscriptionEvent);
- });
- }
+ inventoryPersistence.getYangModelCmHandles(cmHandleTargetsAsStrings);
- private Map<String, Map<String, Map<String, String>>> organizeByDmiName(
- final Collection<YangModelCmHandle> yangModelCmHandles) {
- final Map<String, Map<String, Map<String, String>>> dmiNameCmHandlePropertiesMap = new HashMap<>();
- yangModelCmHandles.forEach(cmHandle -> {
- final String dmiName = cmHandle.resolveDmiServiceName(RequiredDmiService.DATA);
- if (!dmiNameCmHandlePropertiesMap.containsKey(dmiName)) {
- final Map<String, Map<String, String>> cmHandleDmiPropertiesMap = new HashMap<>();
- cmHandleDmiPropertiesMap.put(cmHandle.getId(), dmiPropertiesAsMap(cmHandle));
- dmiNameCmHandlePropertiesMap.put(cmHandle.getDmiDataServiceName(), cmHandleDmiPropertiesMap);
- } else {
- dmiNameCmHandlePropertiesMap.get(cmHandle.getDmiDataServiceName())
- .put(cmHandle.getId(), dmiPropertiesAsMap(cmHandle));
- }
+ final Map<String, Map<String, Map<String, String>>> dmiPropertiesPerCmHandleIdPerServiceName
+ = DmiServiceNameOrganizer.getDmiPropertiesPerCmHandleIdPerServiceName(yangModelCmHandles);
+ dmiPropertiesPerCmHandleIdPerServiceName.forEach((dmiServiceName, cmHandlePropertiesMap) -> {
+ subscriptionEvent.getEvent().getPredicates().setTargets(Collections
+ .singletonList(cmHandlePropertiesMap));
+ final String eventKey = createEventKey(subscriptionEvent, dmiServiceName);
+ eventsPublisher.publishEvent(DMI_AVC_SUBSCRIPTION_TOPIC_PREFIX + dmiServiceName, eventKey,
+ subscriptionEvent);
});
- return dmiNameCmHandlePropertiesMap;
}
private String createEventKey(final SubscriptionEvent subscriptionEvent, final String dmiName) {
@@ -98,9 +82,4 @@ public class SubscriptionEventForwarder {
+ dmiName;
}
- public Map<String, String> dmiPropertiesAsMap(final YangModelCmHandle yangModelCmHandle) {
- return yangModelCmHandle.getDmiProperties().stream().collect(
- Collectors.toMap(YangModelCmHandle.Property::getName, YangModelCmHandle.Property::getValue));
- }
-
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/executor/TaskExecutor.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/executor/TaskExecutor.java
new file mode 100644
index 0000000000..192062fde5
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/executor/TaskExecutor.java
@@ -0,0 +1,47 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 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.
+ * 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.executor;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Supplier;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class TaskExecutor {
+
+ /**
+ * Execute task asynchronously.
+ *
+ * @param taskSupplier functional method is get() task need to executed asynchronously
+ * @param timeOutInMillis the timeout value in milliseconds
+ */
+ public static CompletableFuture<Object> executeTask(final Supplier<Object> taskSupplier,
+ final long timeOutInMillis) {
+ return CompletableFuture.supplyAsync(taskSupplier::get)
+ .orTimeout(timeOutInMillis, MILLISECONDS);
+ }
+}
+
+
+
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DataStoreEnum.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DataStoreEnum.java
new file mode 100644
index 0000000000..24edc73f3c
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DataStoreEnum.java
@@ -0,0 +1,34 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 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.
+ * 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.operations;
+
+import lombok.Getter;
+
+@Getter
+public enum DataStoreEnum {
+ PASSTHROUGH_OPERATIONAL("ncmp-datastore:passthrough-operational"),
+ PASSTHROUGH_RUNNING("ncmp-datastore:passthrough-running");
+ private final String value;
+
+ DataStoreEnum(final String value) {
+ this.value = value;
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java
index 83faa005f0..d648352f15 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2022 Nordix Foundation
+ * Copyright (C) 2021-2023 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,19 +21,24 @@
package org.onap.cps.ncmp.api.impl.operations;
-import static org.onap.cps.ncmp.api.impl.operations.DmiOperations.DataStoreEnum.PASSTHROUGH_RUNNING;
-import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum;
-import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.READ;
+import static org.onap.cps.ncmp.api.impl.operations.DataStoreEnum.PASSTHROUGH_RUNNING;
+import static org.onap.cps.ncmp.api.impl.operations.OperationEnum.READ;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.ncmp.api.impl.client.DmiRestClient;
import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration;
+import org.onap.cps.ncmp.api.impl.executor.TaskExecutor;
+import org.onap.cps.ncmp.api.impl.utils.DmiServiceNameOrganizer;
import org.onap.cps.ncmp.api.impl.utils.DmiServiceUrlBuilder;
import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
import org.onap.cps.ncmp.api.inventory.CmHandleState;
import org.onap.cps.ncmp.api.inventory.InventoryPersistence;
import org.onap.cps.spi.exceptions.CpsException;
import org.onap.cps.utils.JsonObjectMapper;
+import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
@@ -44,15 +49,14 @@ import org.springframework.stereotype.Component;
@Slf4j
public class DmiDataOperations extends DmiOperations {
- /**
- * Constructor for {@code DmiOperations}. This method also manipulates url properties.
- *
- * @param dmiRestClient {@code DmiRestClient}
- */
+ private static final long DEFAULT_ASYNC_TASK_EXECUTOR_TIMEOUT_IN_MILLISECONDS = 30000L;
+ private static final String NO_CM_HANDLE_ID = "";
+
public DmiDataOperations(final InventoryPersistence inventoryPersistence,
final JsonObjectMapper jsonObjectMapper,
final NcmpConfiguration.DmiProperties dmiProperties,
- final DmiRestClient dmiRestClient, final DmiServiceUrlBuilder dmiServiceUrlBuilder) {
+ final DmiRestClient dmiRestClient,
+ final DmiServiceUrlBuilder dmiServiceUrlBuilder) {
super(inventoryPersistence, jsonObjectMapper, dmiProperties, dmiRestClient, dmiServiceUrlBuilder);
}
@@ -60,48 +64,78 @@ public class DmiDataOperations extends DmiOperations {
* This method fetches the resource data from operational data store for given cm handle
* identifier on given resource using dmi client.
*
- * @param cmHandleId network resource identifier
- * @param resourceId resource identifier
+ * @param dataStoreName name of data store
+ * @param cmHandleId network resource identifier
+ * @param resourceId resource identifier
* @param optionsParamInQuery options query
- * @param dataStore data store enum
- * @param requestId requestId for async responses
* @param topicParamInQuery topic name for (triggering) async responses
+ * @param requestId requestId for async responses
* @return {@code ResponseEntity} response entity
*/
- public ResponseEntity<Object> getResourceDataFromDmi(final String cmHandleId,
+ public ResponseEntity<Object> getResourceDataFromDmi(final String dataStoreName,
+ final String cmHandleId,
final String resourceId,
final String optionsParamInQuery,
- final DataStoreEnum dataStore,
- final String requestId,
- final String topicParamInQuery) {
+ final String topicParamInQuery,
+ final String requestId) {
final YangModelCmHandle yangModelCmHandle = getYangModelCmHandle(cmHandleId);
- final String jsonBody = getDmiRequestBody(READ, requestId, null, null, yangModelCmHandle);
- final String dmiResourceDataUrl = getDmiRequestUrl(cmHandleId, resourceId, optionsParamInQuery, dataStore,
- topicParamInQuery, yangModelCmHandle);
final CmHandleState cmHandleState = yangModelCmHandle.getCompositeState().getCmHandleState();
- isCmHandleStateReady(yangModelCmHandle, cmHandleState);
- return dmiRestClient.postOperationWithJsonData(dmiResourceDataUrl, jsonBody, READ);
+ validateIfCmHandleStateReady(yangModelCmHandle, cmHandleState);
+ final String jsonRequestBody = getDmiRequestBody(READ, requestId, null, null,
+ yangModelCmHandle);
+ final String dmiResourceDataUrl = getDmiRequestUrl(dataStoreName, cmHandleId, resourceId, optionsParamInQuery,
+ topicParamInQuery, yangModelCmHandle.resolveDmiServiceName(RequiredDmiService.DATA));
+ return dmiRestClient.postOperationWithJsonData(dmiResourceDataUrl, jsonRequestBody, READ);
+ }
+
+ /**
+ * This method fetches the resource data by data store for given list of cm handles using dmi client.
+ *
+ * @param dataStoreName data store name
+ * @param cmHandleIds list of cm handles
+ * @param resourceId resource identifier
+ * @param optionsParamInQuery options query
+ * @param topicParamInQuery topic name for (triggering) async responses
+ * @param requestId requestId for async responses
+ * @return {@code ResponseEntity} response entity
+ */
+ public ResponseEntity<Object> getResourceDataFromDmi(final String dataStoreName,
+ final List<String> cmHandleIds,
+ final String resourceId,
+ final String optionsParamInQuery,
+ final String topicParamInQuery,
+ final String requestId) {
+ final Collection<YangModelCmHandle> yangModelCmHandles
+ = inventoryPersistence.getYangModelCmHandles(cmHandleIds);
+ final Map<String, Map<String, Map<String, String>>> dmiServiceNameCmHandlePropertiesMap =
+ DmiServiceNameOrganizer.getDmiPropertiesPerCmHandleIdPerServiceName(yangModelCmHandles);
+
+ buildBulkResourceDataRequestAndSend(dataStoreName, resourceId, optionsParamInQuery,
+ topicParamInQuery, requestId, dmiServiceNameCmHandlePropertiesMap);
+ return new ResponseEntity<>(HttpStatus.ACCEPTED);
}
/**
* This method fetches all the resource data from operational data store for given cm handle
* identifier using dmi client.
*
+ * @param dataStoreName data store name
* @param cmHandleId network resource identifier
- * @param dataStore data store enum
* @param requestId requestId for async responses
* @return {@code ResponseEntity} response entity
*/
- public ResponseEntity<Object> getResourceDataFromDmi(final String cmHandleId,
- final DataStoreEnum dataStore,
+ public ResponseEntity<Object> getResourceDataFromDmi(final String dataStoreName,
+ final String cmHandleId,
final String requestId) {
final YangModelCmHandle yangModelCmHandle = getYangModelCmHandle(cmHandleId);
- final String jsonBody = getDmiRequestBody(READ, requestId, null, null, yangModelCmHandle);
- final String dmiResourceDataUrl = getDmiRequestUrl(cmHandleId, "/", null, dataStore,
- null, yangModelCmHandle);
+ final String jsonRequestBody = getDmiRequestBody(READ, requestId, null, null,
+ yangModelCmHandle);
+ final String dmiResourceDataUrl = getDmiRequestUrl(dataStoreName, cmHandleId, "/", null,
+ null, yangModelCmHandle.resolveDmiServiceName(RequiredDmiService.DATA));
final CmHandleState cmHandleState = yangModelCmHandle.getCompositeState().getCmHandleState();
- isCmHandleStateReady(yangModelCmHandle, cmHandleState);
- return dmiRestClient.postOperationWithJsonData(dmiResourceDataUrl, jsonBody, READ);
+ validateIfCmHandleStateReady(yangModelCmHandle, cmHandleState);
+ return dmiRestClient.postOperationWithJsonData(dmiResourceDataUrl, jsonRequestBody,
+ READ);
}
/**
@@ -121,12 +155,14 @@ public class DmiDataOperations extends DmiOperations {
final String requestData,
final String dataType) {
final YangModelCmHandle yangModelCmHandle = getYangModelCmHandle(cmHandleId);
- final String jsonBody = getDmiRequestBody(operation, null, requestData, dataType, yangModelCmHandle);
- final String dmiUrl = getDmiRequestUrl(cmHandleId, resourceId, null, PASSTHROUGH_RUNNING,
- null, yangModelCmHandle);
+ final String jsonRequestBody = getDmiRequestBody(operation, null, requestData, dataType,
+ yangModelCmHandle);
+ final String dmiUrl = getDmiRequestUrl(PASSTHROUGH_RUNNING.getValue(), cmHandleId, resourceId,
+ null, null,
+ yangModelCmHandle.resolveDmiServiceName(RequiredDmiService.DATA));
final CmHandleState cmHandleState = yangModelCmHandle.getCompositeState().getCmHandleState();
- isCmHandleStateReady(yangModelCmHandle, cmHandleState);
- return dmiRestClient.postOperationWithJsonData(dmiUrl, jsonBody, operation);
+ validateIfCmHandleStateReady(yangModelCmHandle, cmHandleState);
+ return dmiRestClient.postOperationWithJsonData(dmiUrl, jsonRequestBody, operation);
}
private YangModelCmHandle getYangModelCmHandle(final String cmHandleId) {
@@ -145,24 +181,80 @@ public class DmiDataOperations extends DmiOperations {
return jsonObjectMapper.asJsonString(dmiRequestBody);
}
- private String getDmiRequestUrl(final String cmHandleId,
- final String resourceId,
- final String optionsParamInQuery,
- final DataStoreEnum dataStore,
- final String topicParamInQuery,
- final YangModelCmHandle yangModelCmHandle) {
+ private String getDmiBulkRequestBody(final OperationEnum operation,
+ final String requestId,
+ final String requestData) {
+ final DmiRequestBody dmiBulkRequestBody = DmiRequestBody.builder()
+ .operation(operation)
+ .requestId(requestId)
+ .data(requestData)
+ .build();
+ return jsonObjectMapper.asJsonString(dmiBulkRequestBody);
+ }
+
+ private String getDmiRequestUrl(final String dataStoreName,
+ final String cmHandleId,
+ final String resourceId,
+ final String optionsParamInQuery,
+ final String topicParamInQuery,
+ final String dmiServiceName) {
return dmiServiceUrlBuilder.getDmiDatastoreUrl(
dmiServiceUrlBuilder.populateQueryParams(resourceId, optionsParamInQuery,
- topicParamInQuery), dmiServiceUrlBuilder.populateUriVariables(
- yangModelCmHandle, cmHandleId, dataStore));
+ topicParamInQuery), dmiServiceUrlBuilder.populateUriVariables(dataStoreName, dmiServiceName,
+ cmHandleId));
}
- private void isCmHandleStateReady(final YangModelCmHandle yangModelCmHandle, final CmHandleState cmHandleState) {
+ private String getDmiServiceBulkRequestUrl(final String dataStoreName,
+ final String resourceId,
+ final String optionsParamInQuery,
+ final String topicParamInQuery,
+ final String dmiServiceName) {
+ return dmiServiceUrlBuilder.getBulkRequestUrl(
+ dmiServiceUrlBuilder.populateQueryParams(resourceId, optionsParamInQuery,
+ topicParamInQuery), dmiServiceUrlBuilder.populateUriVariables(dataStoreName, dmiServiceName,
+ NO_CM_HANDLE_ID));
+ }
+
+ private void validateIfCmHandleStateReady(final YangModelCmHandle yangModelCmHandle,
+ final CmHandleState cmHandleState) {
if (cmHandleState != CmHandleState.READY) {
throw new CpsException("State mismatch exception.", "Cm-Handle not in READY state. "
- + "cm handle state is "
- + yangModelCmHandle.getCompositeState().getCmHandleState());
+ + "cm handle state is "
+ + yangModelCmHandle.getCompositeState().getCmHandleState());
}
}
+ private void buildBulkResourceDataRequestAndSend(final String dataStoreName,
+ final String resourceId,
+ final String optionsParamInQuery,
+ final String topicParamInQuery,
+ final String requestId,
+ final Map<String, Map<String, Map<String, String>>>
+ dmiServiceNameCmHandlePropertiesMap) {
+ dmiServiceNameCmHandlePropertiesMap.entrySet().parallelStream().forEach(
+ dmiServiceNameCmHandlePropertiesEntry -> {
+ final String dmiBulkResourceDataUrl = getDmiServiceBulkRequestUrl(dataStoreName, resourceId,
+ optionsParamInQuery, topicParamInQuery, dmiServiceNameCmHandlePropertiesEntry.getKey());
+ final String jsonRequestBodyAsJsonString =
+ jsonObjectMapper.asJsonString(dmiServiceNameCmHandlePropertiesEntry.getValue());
+ final String jsonRequestBody
+ = getDmiBulkRequestBody(READ, requestId, jsonRequestBodyAsJsonString);
+ sendDmiResourceDataRequestToDmiService(dmiBulkResourceDataUrl, jsonRequestBody);
+ });
+ }
+
+ private void sendDmiResourceDataRequestToDmiService(final String dmiBulkResourceDataUrl,
+ final String dmiResourceDataRequestAsJsonString) {
+ TaskExecutor.executeTask(() ->
+ dmiRestClient.postOperationWithJsonData(dmiBulkResourceDataUrl,
+ dmiResourceDataRequestAsJsonString, READ),
+ DEFAULT_ASYNC_TASK_EXECUTOR_TIMEOUT_IN_MILLISECONDS)
+ .whenCompleteAsync(this::handleTaskCompletion);
+ }
+
+ private void handleTaskCompletion(final Object response, final Throwable throwable) {
+ // TODO Need to publish an error response to client given topic.
+ // Code should be implemented into https://jira.onap.org/browse/CPS-1558 (
+ // NCMP : Handle non responding DMI-Plugin)
+ }
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java
index d8d03041fb..392e9c1a24 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2022 Nordix Foundation
+ * Copyright (C) 2021-2023 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -98,17 +98,18 @@ public class DmiModelOperations extends DmiOperations {
* Get resources from DMI for modules.
*
* @param dmiServiceName dmi service name
- * @param jsonData module names and revisions as JSON
+ * @param jsonRequestBody module names and revisions as JSON
* @param cmHandle cmHandle
* @param resourceName name of the resource(s)
* @return {@code ResponseEntity} response entity
*/
private ResponseEntity<Object> getResourceFromDmiWithJsonData(final String dmiServiceName,
- final String jsonData,
+ final String jsonRequestBody,
final String cmHandle,
final String resourceName) {
final String dmiResourceDataUrl = getDmiResourceUrl(dmiServiceName, cmHandle, resourceName);
- return dmiRestClient.postOperationWithJsonData(dmiResourceDataUrl, jsonData, DmiRequestBody.OperationEnum.READ);
+ return dmiRestClient.postOperationWithJsonData(dmiResourceDataUrl, jsonRequestBody,
+ OperationEnum.READ);
}
private static String getRequestBodyToFetchYangResources(final Collection<ModuleReference> newModuleReferences,
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java
index e26ffef870..7e9079ec94 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2022 Nordix Foundation
+ * Copyright (C) 2021-2023 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,7 +21,6 @@
package org.onap.cps.ncmp.api.impl.operations;
-import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.onap.cps.ncmp.api.impl.client.DmiRestClient;
import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration;
@@ -34,17 +33,6 @@ import org.springframework.stereotype.Service;
@Service
public class DmiOperations {
- @Getter
- public enum DataStoreEnum {
- PASSTHROUGH_OPERATIONAL("ncmp-datastore:passthrough-operational"),
- PASSTHROUGH_RUNNING("ncmp-datastore:passthrough-running");
- private final String value;
-
- DataStoreEnum(final String value) {
- this.value = value;
- }
- }
-
protected final InventoryPersistence inventoryPersistence;
protected final JsonObjectMapper jsonObjectMapper;
protected final NcmpConfiguration.DmiProperties dmiProperties;
@@ -52,7 +40,7 @@ public class DmiOperations {
protected final DmiServiceUrlBuilder dmiServiceUrlBuilder;
String getDmiResourceUrl(final String dmiServiceName, final String cmHandle, final String resourceName) {
- return dmiServiceUrlBuilder.getCmHandleUrl()
+ return dmiServiceUrlBuilder.getResourceDataBasePathUriBuilder()
.pathSegment("{resourceName}")
.buildAndExpand(dmiServiceName, dmiProperties.getDmiBasePath(), cmHandle, resourceName).toUriString();
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiRequestBody.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiRequestBody.java
index c84e4cb870..3aa6366155 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiRequestBody.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiRequestBody.java
@@ -22,7 +22,6 @@ package org.onap.cps.ncmp.api.impl.operations;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonValue;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -34,24 +33,6 @@ import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
@Getter
@Builder
public class DmiRequestBody {
- public enum OperationEnum {
- READ("read"),
- CREATE("create"),
- UPDATE("update"),
- PATCH("patch"),
- DELETE("delete");
- private final String value;
-
- OperationEnum(final String value) {
- this.value = value;
- }
-
- @Override
- @JsonValue
- public String toString() {
- return String.valueOf(value);
- }
- }
private OperationEnum operation;
private String dataType;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/OperationEnum.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/OperationEnum.java
new file mode 100644
index 0000000000..796cef23d0
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/OperationEnum.java
@@ -0,0 +1,43 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 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.
+ * 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.operations;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+
+public enum OperationEnum {
+
+ READ("read"),
+ CREATE("create"),
+ UPDATE("update"),
+ PATCH("patch"),
+ DELETE("delete");
+ private final String value;
+
+ OperationEnum(final String value) {
+ this.value = value;
+ }
+
+ @Override
+ @JsonValue
+ public String toString() {
+ return String.valueOf(value);
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceNameOrganizer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceNameOrganizer.java
new file mode 100644
index 0000000000..26e94866a1
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceNameOrganizer.java
@@ -0,0 +1,64 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 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.
+ * 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.utils;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.onap.cps.ncmp.api.impl.operations.RequiredDmiService;
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class DmiServiceNameOrganizer {
+
+ /**
+ * organizes a map with dmi service name as key for cm handle with its properties.
+ *
+ * @param yangModelCmHandles list of cm handle model
+ */
+ public static Map<String, Map<String, Map<String, String>>> getDmiPropertiesPerCmHandleIdPerServiceName(
+ final Collection<YangModelCmHandle> yangModelCmHandles) {
+ final Map<String, Map<String, Map<String, String>>> dmiPropertiesPerCmHandleIdPerServiceName
+ = new HashMap<>();
+ yangModelCmHandles.forEach(yangModelCmHandle -> {
+ final String dmiServiceName = yangModelCmHandle.resolveDmiServiceName(RequiredDmiService.DATA);
+ if (!dmiPropertiesPerCmHandleIdPerServiceName.containsKey(dmiServiceName)) {
+ final Map<String, Map<String, String>> cmHandleDmiPropertiesMap = new HashMap<>();
+ cmHandleDmiPropertiesMap.put(yangModelCmHandle.getId(),
+ dmiPropertiesAsMap(yangModelCmHandle.getDmiProperties()));
+ dmiPropertiesPerCmHandleIdPerServiceName.put(dmiServiceName, cmHandleDmiPropertiesMap);
+ } else {
+ dmiPropertiesPerCmHandleIdPerServiceName.get(dmiServiceName)
+ .put(yangModelCmHandle.getId(), dmiPropertiesAsMap(yangModelCmHandle.getDmiProperties()));
+ }
+ });
+ return dmiPropertiesPerCmHandleIdPerServiceName;
+ }
+
+ private static Map<String, String> dmiPropertiesAsMap(final List<YangModelCmHandle.Property> dmiProperties) {
+ return dmiProperties.stream().collect(
+ Collectors.toMap(YangModelCmHandle.Property::getName, YangModelCmHandle.Property::getValue));
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilder.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilder.java
index 5f4a6540c2..bba8f48fbd 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilder.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilder.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2022 Nordix Foundation
+ * 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.
@@ -20,16 +20,12 @@
package org.onap.cps.ncmp.api.impl.utils;
-import static org.onap.cps.ncmp.api.impl.operations.RequiredDmiService.DATA;
-
import java.util.HashMap;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.apache.logging.log4j.util.Strings;
import org.apache.logging.log4j.util.TriConsumer;
import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration;
-import org.onap.cps.ncmp.api.impl.operations.DmiOperations;
-import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
import org.onap.cps.spi.utils.CpsValidator;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
@@ -52,13 +48,21 @@ public class DmiServiceUrlBuilder {
*/
public String getDmiDatastoreUrl(final MultiValueMap<String, String> queryParams,
final Map<String, Object> uriVariables) {
- final UriComponentsBuilder uriComponentsBuilder = getCmHandleUrl()
- .pathSegment("data")
- .pathSegment("ds")
- .pathSegment("{dataStore}")
- .queryParams(queryParams)
- .uriVariables(uriVariables);
- return uriComponentsBuilder.buildAndExpand().toUriString();
+ return getUriComponentsBuilder(getResourceDataBasePathUriBuilder(), queryParams, uriVariables)
+ .buildAndExpand().toUriString();
+ }
+
+ /**
+ * This method creates the dmi service url for bulk request.
+ *
+ * @param queryParams query param map as key,value pair
+ * @param uriVariables uri param map as key (placeholder),value pair
+ * @return {@code String} dmi service url as string
+ */
+ public String getBulkRequestUrl(final MultiValueMap<String, String> queryParams,
+ final Map<String, Object> uriVariables) {
+ return getUriComponentsBuilder(getBulkResourceDataBasePathUriBuilder(), queryParams, uriVariables)
+ .buildAndExpand().toUriString();
}
/**
@@ -66,7 +70,7 @@ public class DmiServiceUrlBuilder {
*
* @return {@code UriComponentsBuilder} dmi service url builder object
*/
- public UriComponentsBuilder getCmHandleUrl() {
+ public UriComponentsBuilder getResourceDataBasePathUriBuilder() {
return UriComponentsBuilder.newInstance()
.path("{dmiServiceName}")
.pathSegment("{dmiBasePath}")
@@ -76,23 +80,36 @@ public class DmiServiceUrlBuilder {
}
/**
+ * This method creates the dmi service url builder object with path variables for batch of cm handles.
+ *
+ * @return {@code UriComponentsBuilder} dmi service url builder object
+ */
+ public UriComponentsBuilder getBulkResourceDataBasePathUriBuilder() {
+ return UriComponentsBuilder.newInstance()
+ .path("{dmiServiceName}")
+ .pathSegment("{dmiBasePath}")
+ .pathSegment("v1")
+ .pathSegment("batch");
+ }
+
+ /**
* This method populates uri variables.
*
- * @param yangModelCmHandle get dmi service name
+ * @param dataStoreName data store name
+ * @param dmiServiceName dmi service name
* @param cmHandleId cm handle id for dmi registration
* @return {@code String} dmi service url as string
*/
- public Map<String, Object> populateUriVariables(final YangModelCmHandle yangModelCmHandle,
- final String cmHandleId,
- final DmiOperations.DataStoreEnum dataStore) {
+ public Map<String, Object> populateUriVariables(final String dataStoreName,
+ final String dmiServiceName,
+ final String cmHandleId) {
cpsValidator.validateNameCharacters(cmHandleId);
final Map<String, Object> uriVariables = new HashMap<>();
final String dmiBasePath = dmiProperties.getDmiBasePath();
- uriVariables.put("dmiServiceName",
- yangModelCmHandle.resolveDmiServiceName(DATA));
+ uriVariables.put("dmiServiceName", dmiServiceName);
uriVariables.put("dmiBasePath", dmiBasePath);
uriVariables.put("cmHandleId", cmHandleId);
- uriVariables.put("dataStore", dataStore.getValue());
+ uriVariables.put("dataStore", dataStoreName);
return uriVariables;
}
@@ -124,4 +141,15 @@ public class DmiServiceUrlBuilder {
}
};
}
+
+ private UriComponentsBuilder getUriComponentsBuilder(final UriComponentsBuilder uriComponentsBuilder,
+ final MultiValueMap<String, String> queryParams,
+ final Map<String, Object> uriVariables) {
+ return uriComponentsBuilder
+ .pathSegment("data")
+ .pathSegment("ds")
+ .pathSegment("{dataStore}")
+ .queryParams(queryParams)
+ .uriVariables(uriVariables);
+ }
}
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 537f50122c..b9cecfb3d0 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,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2022 Nordix Foundation
+ * Copyright (C) 2022-2023 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,6 +21,8 @@
package org.onap.cps.ncmp.api.inventory.sync;
+import static org.onap.cps.ncmp.api.impl.operations.DataStoreEnum.PASSTHROUGH_OPERATIONAL;
+
import com.fasterxml.jackson.databind.JsonNode;
import java.time.Duration;
import java.time.OffsetDateTime;
@@ -37,7 +39,6 @@ import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations;
-import org.onap.cps.ncmp.api.impl.operations.DmiOperations;
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.CmHandleQueries;
@@ -167,7 +168,8 @@ public class SyncUtils {
*/
public String getResourceData(final String cmHandleId) {
final ResponseEntity<Object> resourceDataResponseEntity = dmiDataOperations.getResourceDataFromDmi(
- cmHandleId, DmiOperations.DataStoreEnum.PASSTHROUGH_OPERATIONAL,
+ PASSTHROUGH_OPERATIONAL.getValue(),
+ cmHandleId,
UUID.randomUUID().toString());
if (resourceDataResponseEntity.getStatusCode().is2xxSuccessful()) {
return getFirstResource(resourceDataResponseEntity.getBody());
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 871af842ea..5b49e04635 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
@@ -52,10 +52,10 @@ import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import spock.lang.Specification
-import static org.onap.cps.ncmp.api.impl.operations.DmiOperations.DataStoreEnum.PASSTHROUGH_OPERATIONAL
-import static org.onap.cps.ncmp.api.impl.operations.DmiOperations.DataStoreEnum.PASSTHROUGH_RUNNING
-import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.CREATE
-import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.UPDATE
+import static org.onap.cps.ncmp.api.impl.operations.DataStoreEnum.PASSTHROUGH_OPERATIONAL
+import static org.onap.cps.ncmp.api.impl.operations.DataStoreEnum.PASSTHROUGH_RUNNING
+import static org.onap.cps.ncmp.api.impl.operations.OperationEnum.CREATE
+import static org.onap.cps.ncmp.api.impl.operations.OperationEnum.UPDATE
class NetworkCmProxyDataServiceImplSpec extends Specification {
@@ -94,61 +94,64 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
def 'Write resource data for pass-through running from DMI using POST.'() {
given: 'cpsDataService returns valid datanode'
- mockCpsDataService.getDataNodes('NCMP-Admin', 'ncmp-dmi-registry',
- cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
+ mockDataNode()
when: 'write resource data is called'
objectUnderTest.writeResourceDataPassThroughRunningForCmHandle('testCmHandle',
'testResourceId', CREATE,
'{some-json}', 'application/json')
then: 'DMI called with correct data'
1 * mockDmiDataOperations.writeResourceDataPassThroughRunningFromDmi('testCmHandle', 'testResourceId',
- CREATE, '{some-json}', 'application/json')
+ CREATE, '{some-json}', 'application/json')
>> { new ResponseEntity<>(HttpStatus.CREATED) }
}
def 'Get resource data for pass-through operational from DMI.'() {
given: 'get data node is called'
- mockCpsDataService.getDataNodes('NCMP-Admin', 'ncmp-dmi-registry',
- cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
+ mockDataNode()
and: 'get resource data from DMI is called'
- mockDmiDataOperations.getResourceDataFromDmi(
- 'testCmHandle',
- 'testResourceId',
- OPTIONS_PARAM,
- PASSTHROUGH_OPERATIONAL,
- NO_REQUEST_ID,
- NO_TOPIC) >> new ResponseEntity<>('dmi-response', HttpStatus.OK)
+ mockDmiDataOperations.getResourceDataFromDmi(PASSTHROUGH_OPERATIONAL.value,'testCmHandle',
+ 'testResourceId', OPTIONS_PARAM, NO_TOPIC, NO_REQUEST_ID) >>
+ new ResponseEntity<>('dmi-response', HttpStatus.OK)
when: 'get resource data operational for cm-handle is called'
- def response = objectUnderTest.getResourceDataOperationalForCmHandle('testCmHandle',
- 'testResourceId',
- OPTIONS_PARAM,
- NO_TOPIC,
- NO_REQUEST_ID)
+ def response = objectUnderTest.getResourceDataForCmHandle(PASSTHROUGH_OPERATIONAL.value, 'testCmHandle',
+ 'testResourceId', OPTIONS_PARAM, NO_TOPIC, NO_REQUEST_ID)
then: 'DMI returns a json response'
response == 'dmi-response'
}
def 'Get resource data for pass-through running from DMI.'() {
given: 'cpsDataService returns valid data node'
- mockCpsDataService.getDataNodes('NCMP-Admin', 'ncmp-dmi-registry',
- cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
+ mockDataNode()
and: 'DMI returns valid response and data'
- mockDmiDataOperations.getResourceDataFromDmi('testCmHandle',
- 'testResourceId',
- OPTIONS_PARAM,
- PASSTHROUGH_RUNNING,
- NO_REQUEST_ID,
- NO_TOPIC) >> new ResponseEntity<>('{dmi-response}', HttpStatus.OK)
+ mockDmiDataOperations.getResourceDataFromDmi(PASSTHROUGH_RUNNING.value, 'testCmHandle',
+ 'testResourceId', OPTIONS_PARAM, NO_TOPIC, NO_REQUEST_ID) >>
+ new ResponseEntity<>('{dmi-response}', HttpStatus.OK)
when: 'get resource data is called'
- def response = objectUnderTest.getResourceDataPassThroughRunningForCmHandle('testCmHandle',
- 'testResourceId',
- OPTIONS_PARAM,
- NO_TOPIC,
- NO_REQUEST_ID)
+ def response = objectUnderTest.getResourceDataForCmHandle(PASSTHROUGH_RUNNING.value, 'testCmHandle',
+ 'testResourceId', OPTIONS_PARAM, NO_TOPIC, NO_REQUEST_ID)
then: 'get resource data returns expected response'
response == '{dmi-response}'
}
+ def 'Get bulk resource data for #datastoreName from DMI.'() {
+ given: 'cpsDataService returns valid data node'
+ mockDataNode()
+ and: 'DMI returns valid response and data'
+ mockDmiDataOperations.getResourceDataFromDmi(datastoreName, ['testCmHandle'],
+ 'testResourceId', OPTIONS_PARAM,'some topic','requestId') >>
+ new ResponseEntity<>('{dmi-bulk-response}', HttpStatus.OK)
+ when: 'get batch resource data is called'
+ def response = objectUnderTest.getResourceDataForCmHandleBatch(datastoreName, ['testCmHandle'],
+ 'testResourceId',
+ OPTIONS_PARAM,
+ 'some topic',
+ 'requestId')
+ then: 'get bulk resource data returns expected response'
+ response == '{dmi-bulk-response}'
+ where: 'the following data stores are used'
+ datastoreName << [PASSTHROUGH_RUNNING.value, PASSTHROUGH_OPERATIONAL.value]
+ }
+
def 'Getting Yang Resources.'() {
when: 'yang resources is called'
objectUnderTest.getYangResourcesModuleReferences('some-cm-handle')
@@ -242,7 +245,7 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
'{some-json}', 'application/json')
then: 'DMI called with correct data'
1 * mockDmiDataOperations.writeResourceDataPassThroughRunningFromDmi('testCmHandle', 'testResourceId',
- UPDATE, '{some-json}', 'application/json')
+ UPDATE, '{some-json}', 'application/json')
>> { new ResponseEntity<>(HttpStatus.OK) }
}
@@ -365,4 +368,9 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
.dataStoreSyncState(DataStoreSyncState.NONE_REQUESTED)
.lastSyncTime('some-timestamp').build()).build()
}
+
+ def mockDataNode() {
+ mockCpsDataService.getDataNodes('NCMP-Admin', 'ncmp-dmi-registry',
+ cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
+ }
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy
index 90839f8ac0..b38ca10f7b 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2022 Nordix Foundation
+ * Copyright (C) 2021-2023 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -34,10 +34,9 @@ import org.springframework.web.client.HttpServerErrorException
import org.springframework.web.client.RestTemplate
import spock.lang.Specification
-import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.READ
-import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.PATCH
-import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.CREATE
-
+import static org.onap.cps.ncmp.api.impl.operations.OperationEnum.READ
+import static org.onap.cps.ncmp.api.impl.operations.OperationEnum.PATCH
+import static org.onap.cps.ncmp.api.impl.operations.OperationEnum.CREATE
@SpringBootTest
@ContextConfiguration(classes = [NcmpConfiguration.DmiProperties, DmiRestClient])
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy
index 03825c2bbf..89b3a2ff26 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2022 Nordix Foundation
+ * Copyright (C) 2021-2023 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -30,14 +30,14 @@ import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.ResponseEntity
import org.springframework.test.context.ContextConfiguration
+import org.springframework.http.HttpStatus
import spock.lang.Shared
-import static org.onap.cps.ncmp.api.impl.operations.DmiOperations.DataStoreEnum.PASSTHROUGH_OPERATIONAL
-import static org.onap.cps.ncmp.api.impl.operations.DmiOperations.DataStoreEnum.PASSTHROUGH_RUNNING
-import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.CREATE
-import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.READ
-import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.UPDATE
-import org.springframework.http.HttpStatus
+import static org.onap.cps.ncmp.api.impl.operations.DataStoreEnum.PASSTHROUGH_OPERATIONAL
+import static org.onap.cps.ncmp.api.impl.operations.DataStoreEnum.PASSTHROUGH_RUNNING
+import static org.onap.cps.ncmp.api.impl.operations.OperationEnum.CREATE
+import static org.onap.cps.ncmp.api.impl.operations.OperationEnum.READ
+import static org.onap.cps.ncmp.api.impl.operations.OperationEnum.UPDATE
@SpringBootTest
@ContextConfiguration(classes = [NcmpConfiguration.DmiProperties, DmiDataOperations])
@@ -50,6 +50,8 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec {
def NO_REQUEST_ID = null
@Shared
def OPTIONS_PARAM = '(a=1,b=2)'
+ @Shared
+ def expectedBulkRequestAsJson = '{"operation": "read","data": {"fe1c1f1a070c4ce5bbfda7198592a0d3": {"neType": "RadioNode"},"b8e42eed0d9541ed8d8839e8eb86b3e0": {"neType": "RadioNode"}},"requestId": "bbb67474-f705-410a-93d1-b2844e7f45fd"}'
@SpringBean
JsonObjectMapper spiedJsonObjectMapper = Spy(new JsonObjectMapper(new ObjectMapper()))
@@ -66,8 +68,8 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec {
mockDmiRestClient.postOperationWithJsonData(expectedUrl, expectedJson, READ) >> responseFromDmi
dmiServiceUrlBuilder.getDmiDatastoreUrl(_, _) >> expectedUrl
when: 'get resource data is invoked'
- def result = objectUnderTest.getResourceDataFromDmi(cmHandleId, resourceIdentifier,
- options, dataStore, NO_REQUEST_ID, NO_TOPIC)
+ def result = objectUnderTest.getResourceDataFromDmi(dataStore.value, cmHandleId, resourceIdentifier,
+ options, NO_TOPIC, NO_REQUEST_ID)
then: 'the result is the response from the DMI service'
assert result == responseFromDmi
where: 'the following parameters are used'
@@ -80,6 +82,25 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec {
'datastore running with properties' | [yangModelCmHandleProperty] | PASSTHROUGH_RUNNING | OPTIONS_PARAM || '{"operation":"read","cmHandleProperties":{"prop1":"val1"}}' | 'passthrough-running' | '&options=(a=1,b=2)'
}
+ def 'call get bulk resource data for #dataStore from DMI service with topic #scenario.'() {
+ given: 'collection of yang model cm Handles'
+ mockYangModelCmHandleCollectionRetrieval([yangModelCmHandleProperty])
+ and: 'a positive response from DMI service when it is called with the expected parameters'
+ def responseFromDmi = new ResponseEntity<Object>(HttpStatus.ACCEPTED)
+ def expectedDmiBulkResourceDataUrl = "ncmp/v1/batch/data/ds/${dataStore}?resourceIdentifier=parent/child%26options=(a=1,b=2)&topic=my-topic-name&options=(fields=schemas/schema)"
+ mockDmiRestClient.postOperationWithJsonData(expectedDmiBulkResourceDataUrl, expectedBulkRequestAsJson, READ) >> responseFromDmi
+ dmiServiceUrlBuilder.getBulkRequestUrl(_, _) >> expectedDmiBulkResourceDataUrl
+ when: 'get resource data for bulk cm handle is invoked'
+ def result = objectUnderTest.getResourceDataFromDmi( dataStore.value, [cmHandleId], resourceIdentifier,
+ OPTIONS_PARAM, 'some-topic','requestId')
+ then: 'the result is the response from the DMI service'
+ assert result == responseFromDmi
+ where: 'the following parameters are used'
+ scenario | dataStore
+ 'datastore operational' | PASSTHROUGH_OPERATIONAL
+ 'datastore running' | PASSTHROUGH_RUNNING
+ }
+
def 'call get all resource data.'() {
given: 'the system returns a cm handle with a sample property'
mockYangModelCmHandleRetrieval([yangModelCmHandleProperty])
@@ -89,7 +110,7 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec {
mockDmiRestClient.postOperationWithJsonData(expectedUrl, '{"operation":"read","cmHandleProperties":{"prop1":"val1"}}', READ) >> responseFromDmi
dmiServiceUrlBuilder.getDmiDatastoreUrl(_, _) >> expectedUrl
when: 'get resource data is invoked'
- def result = objectUnderTest.getResourceDataFromDmi(cmHandleId, PASSTHROUGH_OPERATIONAL, NO_REQUEST_ID)
+ def result = objectUnderTest.getResourceDataFromDmi( PASSTHROUGH_OPERATIONAL.value, cmHandleId, NO_REQUEST_ID)
then: 'the result is the response from the DMI service'
assert result == responseFromDmi
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiModelOperationsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiModelOperationsSpec.groovy
index ed8f08698d..ed74ad3342 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiModelOperationsSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiModelOperationsSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2022 Nordix Foundation
+ * Copyright (C) 2021-2023 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,6 +24,8 @@ package org.onap.cps.ncmp.api.impl.operations
import com.fasterxml.jackson.core.JsonProcessingException
import com.fasterxml.jackson.databind.ObjectMapper
import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration
+import org.onap.cps.ncmp.api.impl.executor.TaskExecutor
+import org.onap.cps.ncmp.api.impl.utils.DmiServiceNameOrganizer
import org.onap.cps.spi.model.ModuleReference
import org.onap.cps.utils.JsonObjectMapper
import org.spockframework.spring.SpringBean
@@ -34,7 +36,7 @@ import org.springframework.http.ResponseEntity
import org.springframework.test.context.ContextConfiguration
import spock.lang.Shared
-import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.READ
+import static org.onap.cps.ncmp.api.impl.operations.OperationEnum.READ
@SpringBootTest
@ContextConfiguration(classes = [NcmpConfiguration.DmiProperties, DmiModelOperations])
@@ -49,6 +51,12 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
@SpringBean
JsonObjectMapper spiedJsonObjectMapper = Spy(new JsonObjectMapper(new ObjectMapper()))
+ @SpringBean
+ TaskExecutor stubbedTaskExecutor = Stub()
+
+ @SpringBean
+ DmiServiceNameOrganizer stubbedDmiServiceNameOrganizer = Stub()
+
def 'Retrieving module references.'() {
given: 'a cm handle'
mockYangModelCmHandleRetrieval([])
@@ -89,7 +97,7 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
and: 'a positive response from DMI service when it is called with tha expected parameters'
def responseFromDmi = new ResponseEntity<String>(HttpStatus.OK)
mockDmiRestClient.postOperationWithJsonData("${dmiServiceName}/dmi/v1/ch/${cmHandleId}/modules",
- '{"cmHandleProperties":' + expectedAdditionalPropertiesInRequest + '}', READ) >> responseFromDmi
+ '{"cmHandleProperties":' + expectedAdditionalPropertiesInRequest + '}', READ) >> responseFromDmi
when: 'a get module references is called'
def result = objectUnderTest.getModuleReferences(yangModelCmHandle)
then: 'the result is the response from DMI service'
@@ -108,7 +116,7 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
[moduleName: 'mod2', revision: 'C', yangSource: 'other yang source']], HttpStatus.OK)
def expectedModuleReferencesInRequest = '{"name":"mod1","revision":"A"},{"name":"mod2","revision":"X"}'
mockDmiRestClient.postOperationWithJsonData("${dmiServiceName}/dmi/v1/ch/${cmHandleId}/moduleResources",
- '{"data":{"modules":[' + expectedModuleReferencesInRequest + ']},"cmHandleProperties":{}}', READ) >> responseFromDmi
+ '{"data":{"modules":[' + expectedModuleReferencesInRequest + ']},"cmHandleProperties":{}}', READ) >> responseFromDmi
when: 'get new yang resources from DMI service'
def result = objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, newModuleReferences)
then: 'the result has the 2 expected yang (re)sources (order is not guaranteed)'
@@ -140,7 +148,7 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
and: 'a positive response from DMI service when it is called with the expected parameters'
def responseFromDmi = new ResponseEntity<>([[moduleName: 'mod1', revision: 'A', yangSource: 'some yang source']], HttpStatus.OK)
mockDmiRestClient.postOperationWithJsonData("${dmiServiceName}/dmi/v1/ch/${cmHandleId}/moduleResources",
- '{"data":{"modules":[' + expectedModuleReferencesInRequest + ']},"cmHandleProperties":' + expectedAdditionalPropertiesInRequest + '}', READ) >> responseFromDmi
+ '{"data":{"modules":[' + expectedModuleReferencesInRequest + ']},"cmHandleProperties":' + expectedAdditionalPropertiesInRequest + '}', READ) >> responseFromDmi
when: 'get new yang resources from DMI service'
def result = objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, unknownModuleReferences)
then: 'the result is the response from DMI service'
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiOperationsBaseSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiOperationsBaseSpec.groovy
index c4d0020a6c..1b2c50ae76 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiOperationsBaseSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiOperationsBaseSpec.groovy
@@ -58,12 +58,21 @@ abstract class DmiOperationsBaseSpec extends Specification {
def static resourceIdentifier = 'parent/child'
def mockYangModelCmHandleRetrieval(dmiProperties) {
+ populateYangModelCmHandle(dmiProperties)
+ mockInventoryPersistence.getYangModelCmHandle(cmHandleId) >> yangModelCmHandle
+ }
+
+ def mockYangModelCmHandleCollectionRetrieval(dmiProperties) {
+ populateYangModelCmHandle(dmiProperties)
+ mockInventoryPersistence.getYangModelCmHandles(_) >> [yangModelCmHandle]
+ }
+
+ def populateYangModelCmHandle(dmiProperties) {
yangModelCmHandle.dmiDataServiceName = dmiServiceName
yangModelCmHandle.dmiServiceName = dmiServiceName
yangModelCmHandle.dmiProperties = dmiProperties
yangModelCmHandle.id = cmHandleId
yangModelCmHandle.compositeState = new CompositeState()
yangModelCmHandle.compositeState.cmHandleState = CmHandleState.READY
- mockInventoryPersistence.getYangModelCmHandle(cmHandleId) >> yangModelCmHandle
}
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilderSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilderSpec.groovy
index 01569887ce..6ca3105500 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilderSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilderSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2022 Nordix Foundation
+ * 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.
@@ -20,9 +20,10 @@
package org.onap.cps.ncmp.api.impl.utils
+import org.onap.cps.ncmp.api.impl.operations.RequiredDmiService
import org.onap.cps.spi.utils.CpsValidator
-import static org.onap.cps.ncmp.api.impl.operations.DmiOperations.DataStoreEnum.PASSTHROUGH_RUNNING
+import static org.onap.cps.ncmp.api.impl.operations.DataStoreEnum.PASSTHROUGH_RUNNING
import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration
@@ -45,8 +46,8 @@ class DmiServiceUrlBuilderSpec extends Specification {
def 'Create the dmi service url with #scenario.'() {
given: 'uri variables'
dmiProperties.dmiBasePath = 'dmi'
- def uriVars = objectUnderTest.populateUriVariables(yangModelCmHandle,
- "cmHandle", PASSTHROUGH_RUNNING)
+ def uriVars = objectUnderTest.populateUriVariables(PASSTHROUGH_RUNNING.value, yangModelCmHandle.resolveDmiServiceName(RequiredDmiService.DATA),
+ "cmHandle")
and: 'query params'
def uriQueries = objectUnderTest.populateQueryParams(resourceId,
'optionsParamInQuery', topic)
@@ -65,8 +66,8 @@ class DmiServiceUrlBuilderSpec extends Specification {
def 'Populate dmi data store url #scenario.'() {
given: 'uri variables are created'
dmiProperties.dmiBasePath = dmiBasePath
- def uriVars = objectUnderTest.populateUriVariables(yangModelCmHandle,
- "cmHandle", PASSTHROUGH_RUNNING)
+ def uriVars = objectUnderTest.populateUriVariables(PASSTHROUGH_RUNNING.value, yangModelCmHandle.resolveDmiServiceName(RequiredDmiService.DATA),
+ "cmHandle")
and: 'null query params'
def uriQueries = objectUnderTest.populateQueryParams(null,
null, null)
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 f4176d6212..8164dcf9ca 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,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2022 Nordix Foundation
+ * Copyright (C) 2022-2023 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,10 +21,11 @@
package org.onap.cps.ncmp.api.inventory.sync
+import static org.onap.cps.ncmp.api.impl.operations.DataStoreEnum.PASSTHROUGH_OPERATIONAL
+
import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.ObjectMapper
import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations
-import org.onap.cps.ncmp.api.impl.operations.DmiOperations
import org.onap.cps.ncmp.api.inventory.CmHandleQueries
import org.onap.cps.ncmp.api.inventory.CmHandleState
import org.onap.cps.ncmp.api.inventory.CompositeState
@@ -38,7 +39,6 @@ import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import spock.lang.Shared
import spock.lang.Specification
-
import java.time.OffsetDateTime
import java.time.format.DateTimeFormatter
import java.util.stream.Collectors
@@ -137,7 +137,7 @@ class SyncUtilsSpec extends Specification{
def jsonString = '{"stores:bookstore":{"categories":[{"code":"01"}]}}'
JsonNode jsonNode = jsonObjectMapper.convertToJsonNode(jsonString);
def responseEntity = new ResponseEntity<>(jsonNode, HttpStatus.OK)
- mockDmiDataOperations.getResourceDataFromDmi('cm-handle-123', DmiOperations.DataStoreEnum.PASSTHROUGH_OPERATIONAL, _) >> responseEntity
+ mockDmiDataOperations.getResourceDataFromDmi(PASSTHROUGH_OPERATIONAL.value, 'cm-handle-123', _) >> responseEntity
when: 'get resource data is called'
def result = objectUnderTest.getResourceData('cm-handle-123')
then: 'the returned data is correct'