Cm Subscription: PENDING logic handling in NCMP 22/135722/5
authormpriyank <priyank.maheshwari@est.tech>
Thu, 10 Aug 2023 22:09:38 +0000 (23:09 +0100)
committermpriyank <priyank.maheshwari@est.tech>
Thu, 17 Aug 2023 09:40:29 +0000 (10:40 +0100)
- Remove PENDING state from dmi schema
- Modify ncmp out event mapper to categorize
  response per details
- Rename class and method names as well as
  in unit tests
- resolved the merge conflicts

Issue-ID: CPS-1830
Change-Id: I5b7f523f546ec9940c246bd286586fdeba2f892e
Signed-off-by: halil.cakal <halil.cakal@est.tech>
Signed-off-by: mpriyank <priyank.maheshwari@est.tech>
16 files changed:
cps-ncmp-events/src/main/resources/schemas/cmsubscription/cm-subscription-dmi-out-event-schema-1.0.0.json
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionDmiOutEventConsumer.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionEventToCmSubscriptionNcmpOutEventMapper.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionDmiOutEventToCmSubscriptionNcmpOutEventMapper.java with 64% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpInEventForwarder.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpOutEventPublisher.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/ResponseTimeoutTask.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmSubscriptionEvent.java [new file with mode: 0644]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmSubscriptionStatus.java [new file with mode: 0644]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionDmiOutEventConsumerSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionDmiOutEventToYangModelSubscriptionEventMapperSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionEventToCmSubscriptionNcmpOutEventMapperSpec.groovy [moved from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionDmiOutEventToCmSubscriptionNcmpOutEventMapperSpec.groovy with 52% similarity]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpInEventForwarderSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpOutEventPublisherSpec.groovy
cps-ncmp-service/src/test/resources/cmSubscriptionDmiOutEvent.json
cps-ncmp-service/src/test/resources/cmSubscriptionEvent.json [new file with mode: 0644]
cps-ncmp-service/src/test/resources/cmSubscriptionNcmpOutEvent.json

index c08a4ea..ebbdde9 100644 (file)
@@ -14,8 +14,7 @@
           "type": "string",
           "enum": [
             "ACCEPTED",
-            "REJECTED",
-            "PENDING"
+            "REJECTED"
           ]
         },
         "details" : {
index 1ac4044..9459778 100644 (file)
@@ -36,6 +36,7 @@ import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionPersistence;
 import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus;
 import org.onap.cps.ncmp.api.impl.utils.DataNodeHelper;
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelSubscriptionEvent;
+import org.onap.cps.ncmp.api.models.CmSubscriptionEvent;
 import org.onap.cps.ncmp.events.cmsubscription1_0_0.dmi_to_ncmp.CmSubscriptionDmiOutEvent;
 import org.onap.cps.spi.model.DataNode;
 import org.springframework.beans.factory.annotation.Value;
@@ -66,7 +67,7 @@ public class CmSubscriptionDmiOutEventConsumer {
      */
     @KafkaListener(topics = "${app.ncmp.avc.subscription-response-topic}",
             containerFactory = "cloudEventConcurrentKafkaListenerContainerFactory")
-    public void consumeSubscriptionEventResponse(
+    public void consumeDmiOutEvent(
             final ConsumerRecord<String, CloudEvent> cmSubscriptionDmiOutConsumerRecord) {
         final CloudEvent cloudEvent = cmSubscriptionDmiOutConsumerRecord.value();
         final String eventType = cmSubscriptionDmiOutConsumerRecord.value().getType();
@@ -90,7 +91,12 @@ public class CmSubscriptionDmiOutEventConsumer {
         if (createOutcomeResponse
                 && notificationFeatureEnabled
                 && hasNoPendingCmHandles(clientId, subscriptionName)) {
-            cmSubscriptionNcmpOutEventPublisher.sendResponse(cmSubscriptionDmiOutEvent, eventType);
+
+            final CmSubscriptionEvent cmSubscriptionEvent = new CmSubscriptionEvent();
+            cmSubscriptionEvent.setClientId(cmSubscriptionDmiOutEvent.getData().getClientId());
+            cmSubscriptionEvent.setSubscriptionName(cmSubscriptionDmiOutEvent.getData().getSubscriptionName());
+
+            cmSubscriptionNcmpOutEventPublisher.sendResponse(cmSubscriptionEvent, eventType);
             forwardedSubscriptionEventCache.remove(subscriptionEventId);
         }
     }
@@ -26,43 +26,43 @@ import java.util.stream.Collectors;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
 import org.mapstruct.Named;
-import org.onap.cps.ncmp.events.cmsubscription1_0_0.dmi_to_ncmp.CmSubscriptionDmiOutEvent;
-import org.onap.cps.ncmp.events.cmsubscription1_0_0.dmi_to_ncmp.SubscriptionStatus;
+import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus;
+import org.onap.cps.ncmp.api.models.CmSubscriptionEvent;
+import org.onap.cps.ncmp.api.models.CmSubscriptionStatus;
 import org.onap.cps.ncmp.events.cmsubscription1_0_0.ncmp_to_client.AdditionalInfo;
 import org.onap.cps.ncmp.events.cmsubscription1_0_0.ncmp_to_client.AdditionalInfoDetail;
 import org.onap.cps.ncmp.events.cmsubscription1_0_0.ncmp_to_client.CmSubscriptionNcmpOutEvent;
 import org.onap.cps.spi.exceptions.DataValidationException;
 
 @Mapper(componentModel = "spring")
-public interface CmSubscriptionDmiOutEventToCmSubscriptionNcmpOutEventMapper {
+public interface CmSubscriptionEventToCmSubscriptionNcmpOutEventMapper {
 
-    @Mapping(source = "data.subscriptionStatus", target = "data.additionalInfo",
-            qualifiedByName = "mapListOfSubscriptionStatusToAdditionalInfo")
-    CmSubscriptionNcmpOutEvent toCmSubscriptionNcmpOutEvent(CmSubscriptionDmiOutEvent cmSubscriptionDmiOutEvent);
+    @Mapping(source = "cmSubscriptionStatus", target = "data.additionalInfo",
+            qualifiedByName = "mapCmSubscriptionStatusToAdditionalInfo")
+    CmSubscriptionNcmpOutEvent toCmSubscriptionNcmpOutEvent(CmSubscriptionEvent cmSubscriptionEvent);
 
     /**
      * Maps list of SubscriptionStatus to an AdditionalInfo.
      *
-     * @param subscriptionStatusList containing details
+     * @param cmSubscriptionStatusList containing details
      * @return an AdditionalInfo
      */
-    @Named("mapListOfSubscriptionStatusToAdditionalInfo")
-    default AdditionalInfo mapListOfSubscriptionStatusToAdditionalInfo(
-            final List<SubscriptionStatus> subscriptionStatusList) {
-        if (subscriptionStatusList == null || subscriptionStatusList.isEmpty()) {
-            throw new DataValidationException("Invalid subscriptionStatusList",
-                    "SubscriptionStatus list cannot be null or empty");
+    @Named("mapCmSubscriptionStatusToAdditionalInfo")
+    default AdditionalInfo mapCmSubscriptionStatusToAdditionalInfo(
+            final List<CmSubscriptionStatus> cmSubscriptionStatusList) {
+        if (cmSubscriptionStatusList == null || cmSubscriptionStatusList.isEmpty()) {
+            throw new DataValidationException("Invalid cmSubscriptionStatusList",
+                    "CmSubscriptionStatus list cannot be null or empty");
         }
 
-        final Map<String, List<SubscriptionStatus>> rejectedSubscriptionsPerDetails = getSubscriptionsPerDetails(
-                subscriptionStatusList, SubscriptionStatus.Status.REJECTED);
+        final Map<String, List<CmSubscriptionStatus>> rejectedSubscriptionsPerDetails =
+                getSubscriptionsPerDetails(cmSubscriptionStatusList, SubscriptionStatus.REJECTED);
         final Map<String, List<String>> rejectedCmHandlesPerDetails =
                 getCmHandlesPerDetails(rejectedSubscriptionsPerDetails);
         final List<AdditionalInfoDetail> rejectedCmHandles = getAdditionalInfoDetailList(rejectedCmHandlesPerDetails);
 
-
-        final Map<String, List<SubscriptionStatus>> pendingSubscriptionsPerDetails = getSubscriptionsPerDetails(
-                subscriptionStatusList, SubscriptionStatus.Status.PENDING);
+        final Map<String, List<CmSubscriptionStatus>> pendingSubscriptionsPerDetails =
+                getSubscriptionsPerDetails(cmSubscriptionStatusList, SubscriptionStatus.PENDING);
         final Map<String, List<String>> pendingCmHandlesPerDetails =
                 getCmHandlesPerDetails(pendingSubscriptionsPerDetails);
         final List<AdditionalInfoDetail> pendingCmHandles = getAdditionalInfoDetailList(pendingCmHandlesPerDetails);
@@ -74,20 +74,20 @@ public interface CmSubscriptionDmiOutEventToCmSubscriptionNcmpOutEventMapper {
         return additionalInfo;
     }
 
-    private static Map<String, List<SubscriptionStatus>> getSubscriptionsPerDetails(
-            final List<SubscriptionStatus> subscriptionStatusList, final SubscriptionStatus.Status status) {
-        return subscriptionStatusList.stream()
+    private static Map<String, List<CmSubscriptionStatus>> getSubscriptionsPerDetails(
+            final List<CmSubscriptionStatus> cmSubscriptionStatusList, final SubscriptionStatus status) {
+        return cmSubscriptionStatusList.stream()
                 .filter(subscriptionStatus -> subscriptionStatus.getStatus() == status)
-                .collect(Collectors.groupingBy(SubscriptionStatus::getDetails));
+                .collect(Collectors.groupingBy(CmSubscriptionStatus::getDetails));
     }
 
     private static Map<String, List<String>> getCmHandlesPerDetails(
-            final Map<String, List<SubscriptionStatus>> subscriptionsPerDetails) {
-        return subscriptionsPerDetails.entrySet().stream()
+            final Map<String, List<CmSubscriptionStatus>> cmSubscriptionsPerDetails) {
+        return cmSubscriptionsPerDetails.entrySet().stream()
                 .collect(Collectors.toMap(
                         Map.Entry::getKey,
                         entry -> entry.getValue().stream()
-                                .map(SubscriptionStatus::getId)
+                                .map(CmSubscriptionStatus::getId)
                                 .collect(Collectors.toList())
                 ));
     }
index 4a17495..ea2d17d 100644 (file)
@@ -43,9 +43,8 @@ import org.onap.cps.ncmp.api.impl.utils.DmiServiceNameOrganizer;
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelSubscriptionEvent;
 import org.onap.cps.ncmp.api.inventory.InventoryPersistence;
+import org.onap.cps.ncmp.api.models.CmSubscriptionEvent;
 import org.onap.cps.ncmp.events.cmsubscription1_0_0.client_to_ncmp.CmSubscriptionNcmpInEvent;
-import org.onap.cps.ncmp.events.cmsubscription1_0_0.dmi_to_ncmp.CmSubscriptionDmiOutEvent;
-import org.onap.cps.ncmp.events.cmsubscription1_0_0.dmi_to_ncmp.Data;
 import org.onap.cps.ncmp.events.cmsubscription1_0_0.ncmp_to_dmi.CmHandle;
 import org.onap.cps.ncmp.events.cmsubscription1_0_0.ncmp_to_dmi.CmSubscriptionDmiInEvent;
 import org.springframework.beans.factory.annotation.Value;
@@ -97,12 +96,11 @@ public class CmSubscriptionNcmpInEventForwarder {
     private void findDmisAndRespond(final CmSubscriptionNcmpInEvent cmSubscriptionNcmpInEvent, final String eventType,
             final List<String> cmHandleTargetsAsStrings,
             final Map<String, Map<String, Map<String, String>>> dmiPropertiesPerCmHandleIdPerServiceName) {
-        final CmSubscriptionDmiOutEvent emptyCmSubscriptionDmiOutEvent =
-                new CmSubscriptionDmiOutEvent().withData(new Data());
-        emptyCmSubscriptionDmiOutEvent.getData()
-                .setSubscriptionName(cmSubscriptionNcmpInEvent.getData().getSubscription().getName());
-        emptyCmSubscriptionDmiOutEvent.getData()
-                .setClientId(cmSubscriptionNcmpInEvent.getData().getSubscription().getClientID());
+
+        final CmSubscriptionEvent cmSubscriptionEvent = new CmSubscriptionEvent();
+        cmSubscriptionEvent.setSubscriptionName(cmSubscriptionNcmpInEvent.getData().getSubscription().getName());
+        cmSubscriptionEvent.setClientId(cmSubscriptionNcmpInEvent.getData().getSubscription().getClientID());
+
         final List<String> cmHandlesThatExistsInDb =
                 dmiPropertiesPerCmHandleIdPerServiceName.entrySet().stream().map(Map.Entry::getValue).map(Map::keySet)
                         .flatMap(Set::stream).collect(Collectors.toList());
@@ -117,10 +115,10 @@ public class CmSubscriptionNcmpInEventForwarder {
                     targetCmHandlesDoesNotExistInDb);
         }
         if (dmisToRespond.isEmpty()) {
-            cmSubscriptionNcmpOutEventPublisher.sendResponse(emptyCmSubscriptionDmiOutEvent,
+            cmSubscriptionNcmpOutEventPublisher.sendResponse(cmSubscriptionEvent,
                     "subscriptionCreatedStatus");
         } else {
-            startResponseTimeout(emptyCmSubscriptionDmiOutEvent, dmisToRespond);
+            startResponseTimeout(cmSubscriptionEvent, dmisToRespond);
             final CmSubscriptionDmiInEvent cmSubscriptionDmiInEvent =
                     cmSubscriptionNcmpInEventToCmSubscriptionDmiInEventMapper.toCmSubscriptionDmiInEvent(
                             cmSubscriptionNcmpInEvent);
@@ -128,17 +126,17 @@ public class CmSubscriptionNcmpInEventForwarder {
         }
     }
 
-    private void startResponseTimeout(final CmSubscriptionDmiOutEvent emptyCmSubscriptionDmiOutEvent,
+    private void startResponseTimeout(final CmSubscriptionEvent cmSubscriptionEvent,
                                       final Set<String> dmisToRespond) {
-        final String subscriptionClientId = emptyCmSubscriptionDmiOutEvent.getData().getClientId();
-        final String subscriptionName = emptyCmSubscriptionDmiOutEvent.getData().getSubscriptionName();
+        final String subscriptionClientId = cmSubscriptionEvent.getClientId();
+        final String subscriptionName = cmSubscriptionEvent.getSubscriptionName();
         final String subscriptionEventId = subscriptionClientId + subscriptionName;
 
         forwardedSubscriptionEventCache.put(subscriptionEventId, dmisToRespond,
                 ForwardedSubscriptionEventCacheConfig.SUBSCRIPTION_FORWARD_STARTED_TTL_SECS, TimeUnit.SECONDS);
         final ResponseTimeoutTask responseTimeoutTask =
             new ResponseTimeoutTask(forwardedSubscriptionEventCache, cmSubscriptionNcmpOutEventPublisher,
-                    emptyCmSubscriptionDmiOutEvent);
+                    cmSubscriptionEvent);
 
         executorService.schedule(responseTimeoutTask, dmiResponseTimeoutInMs, TimeUnit.MILLISECONDS);
     }
index 38cc724..473538c 100644 (file)
@@ -32,7 +32,8 @@ import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionPersistence;
 import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus;
 import org.onap.cps.ncmp.api.impl.utils.DataNodeHelper;
 import org.onap.cps.ncmp.api.impl.utils.SubscriptionOutcomeCloudMapper;
-import org.onap.cps.ncmp.events.cmsubscription1_0_0.dmi_to_ncmp.CmSubscriptionDmiOutEvent;
+import org.onap.cps.ncmp.api.models.CmSubscriptionEvent;
+import org.onap.cps.ncmp.api.models.CmSubscriptionStatus;
 import org.onap.cps.ncmp.events.cmsubscription1_0_0.ncmp_to_client.CmSubscriptionNcmpOutEvent;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
@@ -46,8 +47,8 @@ public class CmSubscriptionNcmpOutEventPublisher {
 
     private final EventsPublisher<CloudEvent> outcomeEventsPublisher;
 
-    private final CmSubscriptionDmiOutEventToCmSubscriptionNcmpOutEventMapper
-            cmSubscriptionDmiOutEventToCmSubscriptionNcmpOutEventMapper;
+    private final CmSubscriptionEventToCmSubscriptionNcmpOutEventMapper
+            cmSubscriptionEventToCmSubscriptionNcmpOutEventMapper;
 
     private final SubscriptionOutcomeCloudMapper subscriptionOutcomeCloudMapper;
 
@@ -57,54 +58,48 @@ public class CmSubscriptionNcmpOutEventPublisher {
     /**
      * This is for construction of outcome message to be published for client apps.
      *
-     * @param cmSubscriptionDmiOutEvent event produced by Dmi Plugin
+     * @param cmSubscriptionEvent event produced by Dmi Plugin
      */
-    public void sendResponse(final CmSubscriptionDmiOutEvent cmSubscriptionDmiOutEvent, final String eventKey) {
+    public void sendResponse(final CmSubscriptionEvent cmSubscriptionEvent, final String eventType) {
         final CmSubscriptionNcmpOutEvent cmSubscriptionNcmpOutEvent =
-                formCmSubscriptionNcmpOutEvent(cmSubscriptionDmiOutEvent);
-        final String subscriptionClientId = cmSubscriptionDmiOutEvent.getData().getClientId();
-        final String subscriptionName = cmSubscriptionDmiOutEvent.getData().getSubscriptionName();
+                formCmSubscriptionNcmpOutEvent(cmSubscriptionEvent);
+        final String subscriptionClientId = cmSubscriptionEvent.getClientId();
+        final String subscriptionName = cmSubscriptionEvent.getSubscriptionName();
         final String subscriptionEventId = subscriptionClientId + subscriptionName;
         final CloudEvent subscriptionOutcomeCloudEvent =
                 subscriptionOutcomeCloudMapper.toCloudEvent(cmSubscriptionNcmpOutEvent,
-                subscriptionEventId, eventKey);
+                subscriptionEventId, eventType);
         outcomeEventsPublisher.publishCloudEvent(subscriptionOutcomeEventTopic,
                 subscriptionEventId, subscriptionOutcomeCloudEvent);
     }
 
     private CmSubscriptionNcmpOutEvent formCmSubscriptionNcmpOutEvent(
-            final CmSubscriptionDmiOutEvent cmSubscriptionDmiOutEvent) {
+            final CmSubscriptionEvent cmSubscriptionEvent) {
         final Map<String, Map<String, String>> cmHandleIdToStatusAndDetailsAsMap =
                 DataNodeHelper.cmHandleIdToStatusAndDetailsAsMapFromDataNode(
                         subscriptionPersistence.getCmHandlesForSubscriptionEvent(
-                                cmSubscriptionDmiOutEvent.getData().getClientId(),
-                                cmSubscriptionDmiOutEvent.getData().getSubscriptionName()));
-        final List<org.onap.cps.ncmp.events.cmsubscription1_0_0.dmi_to_ncmp.SubscriptionStatus>
-                subscriptionStatusList =
+                                cmSubscriptionEvent.getClientId(),
+                                cmSubscriptionEvent.getSubscriptionName()));
+        final List<CmSubscriptionStatus> cmSubscriptionStatusList =
                 mapCmHandleIdStatusDetailsMapToSubscriptionStatusList(cmHandleIdToStatusAndDetailsAsMap);
-        cmSubscriptionDmiOutEvent.getData().setSubscriptionStatus(subscriptionStatusList);
-        return fromDmiOutEvent(cmSubscriptionDmiOutEvent,
+        cmSubscriptionEvent.setCmSubscriptionStatus(cmSubscriptionStatusList);
+        return fromCmSubscriptionEvent(cmSubscriptionEvent,
                 decideOnNcmpEventResponseCodeForSubscription(cmHandleIdToStatusAndDetailsAsMap));
     }
 
-    private static List<org.onap.cps.ncmp.events.cmsubscription1_0_0.dmi_to_ncmp.SubscriptionStatus>
-        mapCmHandleIdStatusDetailsMapToSubscriptionStatusList(
+    private static List<CmSubscriptionStatus> mapCmHandleIdStatusDetailsMapToSubscriptionStatusList(
             final Map<String, Map<String, String>> cmHandleIdToStatusAndDetailsAsMap) {
         return cmHandleIdToStatusAndDetailsAsMap.entrySet()
                 .stream().map(entryset -> {
-                    final org.onap.cps.ncmp.events.cmsubscription1_0_0.dmi_to_ncmp.SubscriptionStatus
-                            subscriptionStatus = new org.onap.cps.ncmp.events.cmsubscription1_0_0
-                            .dmi_to_ncmp.SubscriptionStatus();
+                    final CmSubscriptionStatus cmSubscriptionStatus = new CmSubscriptionStatus();
                     final String cmHandleId = entryset.getKey();
                     final Map<String, String> statusAndDetailsMap = entryset.getValue();
                     final String status = statusAndDetailsMap.get("status");
                     final String details = statusAndDetailsMap.get("details");
-                    subscriptionStatus.setId(cmHandleId);
-                    subscriptionStatus.setStatus(
-                            org.onap.cps.ncmp.events.cmsubscription1_0_0.dmi_to_ncmp
-                                    .SubscriptionStatus.Status.fromValue(status));
-                    subscriptionStatus.setDetails(details);
-                    return subscriptionStatus;
+                    cmSubscriptionStatus.setId(cmHandleId);
+                    cmSubscriptionStatus.setStatus(SubscriptionStatus.fromString(status));
+                    cmSubscriptionStatus.setDetails(details);
+                    return cmSubscriptionStatus;
                 }).collect(Collectors.toList());
     }
 
@@ -138,13 +133,13 @@ public class CmSubscriptionNcmpOutEventPublisher {
                 .allMatch(entryset -> entryset.containsValue(subscriptionStatus.toString()));
     }
 
-    private CmSubscriptionNcmpOutEvent fromDmiOutEvent(
-            final CmSubscriptionDmiOutEvent cmSubscriptionDmiOutEvent,
+    private CmSubscriptionNcmpOutEvent fromCmSubscriptionEvent(
+            final CmSubscriptionEvent cmSubscriptionEvent,
             final NcmpEventResponseCode ncmpEventResponseCode) {
 
         final CmSubscriptionNcmpOutEvent cmSubscriptionNcmpOutEvent =
-                cmSubscriptionDmiOutEventToCmSubscriptionNcmpOutEventMapper.toCmSubscriptionNcmpOutEvent(
-                        cmSubscriptionDmiOutEvent);
+                cmSubscriptionEventToCmSubscriptionNcmpOutEventMapper.toCmSubscriptionNcmpOutEvent(
+                        cmSubscriptionEvent);
         cmSubscriptionNcmpOutEvent.getData().setStatusCode(Integer.parseInt(ncmpEventResponseCode.getStatusCode()));
         cmSubscriptionNcmpOutEvent.getData().setStatusMessage(ncmpEventResponseCode.getStatusMessage());
 
index 7f8cbf6..78b000d 100644 (file)
@@ -24,7 +24,7 @@ import com.hazelcast.map.IMap;
 import java.util.Set;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.onap.cps.ncmp.events.cmsubscription1_0_0.dmi_to_ncmp.CmSubscriptionDmiOutEvent;
+import org.onap.cps.ncmp.api.models.CmSubscriptionEvent;
 
 @Slf4j
 @RequiredArgsConstructor
@@ -32,7 +32,7 @@ public class ResponseTimeoutTask implements Runnable {
 
     private final IMap<String, Set<String>> forwardedSubscriptionEventCache;
     private final CmSubscriptionNcmpOutEventPublisher cmSubscriptionNcmpOutEventPublisher;
-    private final CmSubscriptionDmiOutEvent cmSubscriptionDmiOutEvent;
+    private final CmSubscriptionEvent cmSubscriptionEvent;
 
     @Override
     public void run() {
@@ -40,11 +40,11 @@ public class ResponseTimeoutTask implements Runnable {
     }
 
     private void generateTimeoutResponse() {
-        final String subscriptionClientId = cmSubscriptionDmiOutEvent.getData().getClientId();
-        final String subscriptionName = cmSubscriptionDmiOutEvent.getData().getSubscriptionName();
+        final String subscriptionClientId = cmSubscriptionEvent.getClientId();
+        final String subscriptionName = cmSubscriptionEvent.getSubscriptionName();
         final String subscriptionEventId = subscriptionClientId + subscriptionName;
         if (forwardedSubscriptionEventCache.containsKey(subscriptionEventId)) {
-            cmSubscriptionNcmpOutEventPublisher.sendResponse(cmSubscriptionDmiOutEvent,
+            cmSubscriptionNcmpOutEventPublisher.sendResponse(cmSubscriptionEvent,
                     "subscriptionCreatedStatus");
             forwardedSubscriptionEventCache.remove(subscriptionEventId);
         }
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmSubscriptionEvent.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmSubscriptionEvent.java
new file mode 100644 (file)
index 0000000..2a60b2a
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ *  ============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.models;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.List;
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import lombok.Getter;
+import lombok.Setter;
+
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@Getter
+@Setter
+public class CmSubscriptionEvent {
+
+    @JsonProperty("clientId")
+    @NotNull
+    private String clientId;
+
+    @JsonProperty("subscriptionName")
+    @NotNull
+    private String subscriptionName;
+
+    @JsonProperty("cmSubscriptionStatus")
+    @Valid
+    @NotNull
+    private List<CmSubscriptionStatus> cmSubscriptionStatus = new ArrayList<>();
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmSubscriptionStatus.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmSubscriptionStatus.java
new file mode 100644 (file)
index 0000000..bba5607
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ *  ============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.models;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import javax.validation.constraints.NotNull;
+import lombok.Getter;
+import lombok.Setter;
+import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@Getter
+@Setter
+public class CmSubscriptionStatus {
+
+    @JsonProperty("id")
+    @NotNull
+    private String id;
+
+    @JsonProperty("status")
+    @NotNull
+    private SubscriptionStatus status;
+
+    @JsonProperty("details")
+    private String details;
+}
index a8a21b2..175ead8 100644 (file)
@@ -46,24 +46,22 @@ class CmSubscriptionDmiOutEventConsumerSpec extends MessagingBaseSpec {
     IMap<String, Set<String>> mockForwardedSubscriptionEventCache = Mock(IMap<String, Set<String>>)
     def mockSubscriptionPersistence = Mock(SubscriptionPersistenceImpl)
     def mockSubscriptionEventResponseMapper  = Mock(CmSubscriptionDmiOutEventToYangModelSubscriptionEventMapper)
-    def mockSubscriptionEventResponseOutcome = Mock(CmSubscriptionNcmpOutEventPublisher)
+    def mockCmSubscriptionNcmpOutEventPublisher = Mock(CmSubscriptionNcmpOutEventPublisher)
 
     def objectUnderTest = new CmSubscriptionDmiOutEventConsumer(mockForwardedSubscriptionEventCache,
-        mockSubscriptionPersistence, mockSubscriptionEventResponseMapper, mockSubscriptionEventResponseOutcome)
+        mockSubscriptionPersistence, mockSubscriptionEventResponseMapper, mockCmSubscriptionNcmpOutEventPublisher)
 
-    def 'Consume Subscription Event Response where all DMIs have responded'() {
-        given: 'a consumer record including cloud event having subscription response'
-            def consumerRecordWithCloudEventAndSubscriptionResponse = getConsumerRecord()
-        and: 'a subscription response event'
-            def subscriptionResponseEvent = getSubscriptionResponseEvent()
-        and: 'a subscription event response and notifications are enabled'
+    def 'Consume dmi out event where all DMIs have responded'() {
+        given: 'a consumer record including cloud event having dmi out event'
+            def dmiOutConsumerRecord = getDmiOutConsumerRecord()
+        and: 'notifications are enabled'
             objectUnderTest.notificationFeatureEnabled = notificationEnabled
         and: 'subscription model loader is enabled'
             objectUnderTest.subscriptionModelLoaderEnabled = modelLoaderEnabled
         and: 'subscription persistence service returns data node includes no pending cm handle'
             mockSubscriptionPersistence.getCmHandlesForSubscriptionEvent(*_) >> [getDataNode()]
         when: 'the valid event is consumed'
-            objectUnderTest.consumeSubscriptionEventResponse(consumerRecordWithCloudEventAndSubscriptionResponse)
+            objectUnderTest.consumeDmiOutEvent(dmiOutConsumerRecord)
         then: 'the forwarded subscription event cache returns only the received dmiName existing for the subscription create event'
             1 * mockForwardedSubscriptionEventCache.containsKey('SCO-9989752cm-subscription-001') >> true
             1 * mockForwardedSubscriptionEventCache.get('SCO-9989752cm-subscription-001') >> (['some-dmi-name'] as Set)
@@ -76,7 +74,7 @@ class CmSubscriptionDmiOutEventConsumerSpec extends MessagingBaseSpec {
         and: 'the subscription event is removed from the map'
             numberOfTimeToRemove * mockForwardedSubscriptionEventCache.remove('SCO-9989752cm-subscription-001')
         and: 'a response outcome has been created'
-            numberOfTimeToResponse * mockSubscriptionEventResponseOutcome.sendResponse(subscriptionResponseEvent, 'subscriptionCreated')
+            numberOfTimeToResponse * mockCmSubscriptionNcmpOutEventPublisher.sendResponse(_, 'subscriptionCreated')
         where: 'the following values are used'
             scenario                                              | modelLoaderEnabled  |   notificationEnabled  ||  numberOfTimeToPersist  ||  numberOfTimeToRemove  || numberOfTimeToResponse
             'Both model loader and notification are enabled'      |    true             |     true               ||   1                     ||      1                 ||       1
@@ -85,13 +83,13 @@ class CmSubscriptionDmiOutEventConsumerSpec extends MessagingBaseSpec {
             'Model loader disabled and notification enabled'      |    false            |     true               ||   0                     ||      1                 ||       1
     }
 
-    def 'Consume Subscription Event Response where another DMI has not yet responded'() {
+    def 'Consume dmi out event where another DMI has not yet responded'() {
         given: 'a subscription event response and notifications are enabled'
             objectUnderTest.notificationFeatureEnabled = notificationEnabled
         and: 'subscription model loader is enabled'
             objectUnderTest.subscriptionModelLoaderEnabled = modelLoaderEnabled
         when: 'the valid event is consumed'
-            objectUnderTest.consumeSubscriptionEventResponse(getConsumerRecord())
+            objectUnderTest.consumeDmiOutEvent(getDmiOutConsumerRecord())
         then: 'the forwarded subscription event cache returns only the received dmiName existing for the subscription create event'
             1 * mockForwardedSubscriptionEventCache.containsKey('SCO-9989752cm-subscription-001') >> true
             1 * mockForwardedSubscriptionEventCache.get('SCO-9989752cm-subscription-001') >> (['responded-dmi', 'non-responded-dmi'] as Set)
@@ -105,7 +103,7 @@ class CmSubscriptionDmiOutEventConsumerSpec extends MessagingBaseSpec {
         and: 'the subscription event is not removed from the map'
             0 * mockForwardedSubscriptionEventCache.remove(_)
         and: 'a response outcome has not been created'
-            0 * mockSubscriptionEventResponseOutcome.sendResponse(*_)
+            0 * mockCmSubscriptionNcmpOutEventPublisher.sendResponse(*_)
         where: 'the following values are used'
             scenario                                              | modelLoaderEnabled  |   notificationEnabled  ||  numberOfTimeToPersist
             'Both model loader and notification are enabled'      |    true             |     true               ||   1
@@ -114,21 +112,21 @@ class CmSubscriptionDmiOutEventConsumerSpec extends MessagingBaseSpec {
             'Model loader disabled and notification enabled'      |    false            |     true               ||   0
     }
 
-    def getSubscriptionResponseEvent() {
-        def subscriptionResponseJsonData = TestUtils.getResourceFileContent('cmSubscriptionDmiOutEvent.json')
-        return jsonObjectMapper.convertJsonString(subscriptionResponseJsonData, CmSubscriptionDmiOutEvent.class)
+    def getDmiOutEvent() {
+        def cmSubscriptionDmiOutEventJsonData = TestUtils.getResourceFileContent('cmSubscriptionDmiOutEvent.json')
+        return jsonObjectMapper.convertJsonString(cmSubscriptionDmiOutEventJsonData, CmSubscriptionDmiOutEvent.class)
     }
 
-    def getCloudEventHavingSubscriptionResponseEvent() {
+    def getCloudEvent() {
         return CloudEventBuilder.v1()
-            .withData(objectMapper.writeValueAsBytes(getSubscriptionResponseEvent()))
+            .withData(objectMapper.writeValueAsBytes(getDmiOutEvent()))
             .withId('some-id')
             .withType('subscriptionCreated')
             .withSource(URI.create('NCMP')).build()
     }
 
-    def getConsumerRecord() {
-        return new ConsumerRecord<String, CloudEvent>('topic-name', 0, 0, 'event-key', getCloudEventHavingSubscriptionResponseEvent())
+    def getDmiOutConsumerRecord() {
+        return new ConsumerRecord<String, CloudEvent>('topic-name', 0, 0, 'event-key', getCloudEvent())
     }
 
     def getDataNode() {
index 036bedb..b13a2ce 100644 (file)
@@ -39,8 +39,8 @@ class CmSubscriptionDmiOutEventToYangModelSubscriptionEventMapperSpec extends Sp
     @Autowired
     JsonObjectMapper jsonObjectMapper
 
-    def 'Map subscription response event to yang model subscription event'() {
-        given: 'a Subscription Response Event'
+    def 'Map dmi out event to yang model subscription event'() {
+        given: 'a dmi out event'
             def jsonData = TestUtils.getResourceFileContent('cmSubscriptionDmiOutEvent.json')
             def testEventToMap = jsonObjectMapper.convertJsonString(jsonData, CmSubscriptionDmiOutEvent.class)
         when: 'the event is mapped to a yang model subscription'
@@ -50,11 +50,11 @@ class CmSubscriptionDmiOutEventToYangModelSubscriptionEventMapperSpec extends Sp
         and: 'subscription name'
             assert result.subscriptionName == "cm-subscription-001"
         and: 'predicate targets cm handle size as expected'
-            assert result.predicates.targetCmHandles.size() == 4
+            assert result.predicates.targetCmHandles.size() == 2
         and: 'predicate targets cm handle ids as expected'
-            assert result.predicates.targetCmHandles.cmHandleId == ["CMHandle1", "CMHandle2", "CMHandle3", "CMHandle4"]
+            assert result.predicates.targetCmHandles.cmHandleId == ["CMHandle1", "CMHandle2"]
         and: 'the status for these targets is set to expected values'
-            assert result.predicates.targetCmHandles.status == [SubscriptionStatus.REJECTED, SubscriptionStatus.REJECTED, SubscriptionStatus.PENDING, SubscriptionStatus.PENDING]
+            assert result.predicates.targetCmHandles.status == [SubscriptionStatus.REJECTED, SubscriptionStatus.REJECTED]
     }
 
 }
\ No newline at end of file
@@ -22,8 +22,8 @@ package org.onap.cps.ncmp.api.impl.events.cmsubscription
 
 import com.fasterxml.jackson.databind.ObjectMapper
 import org.mapstruct.factory.Mappers
-import org.onap.cps.ncmp.events.cmsubscription1_0_0.dmi_to_ncmp.CmSubscriptionDmiOutEvent
-import org.onap.cps.ncmp.events.cmsubscription1_0_0.dmi_to_ncmp.SubscriptionStatus
+import org.onap.cps.ncmp.api.models.CmSubscriptionEvent
+import org.onap.cps.ncmp.api.models.CmSubscriptionStatus
 import org.onap.cps.ncmp.utils.TestUtils
 import org.onap.cps.spi.exceptions.DataValidationException
 import org.onap.cps.utils.JsonObjectMapper
@@ -33,24 +33,26 @@ import spock.lang.Specification
 
 
 @SpringBootTest(classes = [JsonObjectMapper, ObjectMapper])
-class CmSubscriptionDmiOutEventToCmSubscriptionNcmpOutEventMapperSpec extends Specification {
+class CmSubscriptionEventToCmSubscriptionNcmpOutEventMapperSpec extends Specification {
 
-    CmSubscriptionDmiOutEventToCmSubscriptionNcmpOutEventMapper objectUnderTest = Mappers.getMapper(CmSubscriptionDmiOutEventToCmSubscriptionNcmpOutEventMapper)
+    CmSubscriptionEventToCmSubscriptionNcmpOutEventMapper objectUnderTest = Mappers.getMapper(CmSubscriptionEventToCmSubscriptionNcmpOutEventMapper)
 
     @Autowired
     JsonObjectMapper jsonObjectMapper
 
-    def 'Map subscription event response to subscription event outcome'() {
-        given: 'a Subscription Response Event'
-            def subscriptionResponseJsonData = TestUtils.getResourceFileContent('cmSubscriptionDmiOutEvent.json')
-            def subscriptionResponseEvent = jsonObjectMapper.convertJsonString(subscriptionResponseJsonData, CmSubscriptionDmiOutEvent.class)
-        when: 'the subscription response event is mapped to a subscription event outcome'
-            def result = objectUnderTest.toCmSubscriptionNcmpOutEvent(subscriptionResponseEvent)
-        then: 'the resulting subscription event outcome contains expected pending targets per details grouping'
+    def 'Map cm subscription event to ncmp out event'() {
+        given: 'a cm subscription event'
+            def cmSubscriptionEventJsonData = TestUtils.getResourceFileContent('cmSubscriptionEvent.json')
+            def cmSubscriptionEvent = jsonObjectMapper.convertJsonString(cmSubscriptionEventJsonData, CmSubscriptionEvent.class)
+        when: 'cm subscription event is mapped to ncmp out event'
+            def result = objectUnderTest.toCmSubscriptionNcmpOutEvent(cmSubscriptionEvent)
+        then: 'the resulting ncmp out event contains expected pending targets per details grouping'
             def pendingCmHandleTargetsPerDetails = result.getData().getAdditionalInfo().getPending()
-            assert pendingCmHandleTargetsPerDetails.get(0).getDetails() == 'No reply from DMI yet'
-            assert pendingCmHandleTargetsPerDetails.get(0).getTargets() == ['CMHandle3', 'CMHandle4']
-        and: 'the resulting subscription event outcome contains expected rejected targets per details grouping'
+            assert pendingCmHandleTargetsPerDetails.get(0).getDetails() == 'Some other error happened'
+            assert pendingCmHandleTargetsPerDetails.get(0).getTargets() == ['CMHandle4','CMHandle5']
+            assert pendingCmHandleTargetsPerDetails.get(1).getDetails() == 'Some error causes pending'
+            assert pendingCmHandleTargetsPerDetails.get(1).getTargets() == ['CMHandle3']
+        and: 'the resulting ncmp out event contains expected rejected targets per details grouping'
             def rejectedCmHandleTargetsPerDetails = result.getData().getAdditionalInfo().getRejected()
             assert rejectedCmHandleTargetsPerDetails.get(0).getDetails() == 'Some other error message from the DMI'
             assert rejectedCmHandleTargetsPerDetails.get(0).getTargets() == ['CMHandle2']
@@ -58,28 +60,28 @@ class CmSubscriptionDmiOutEventToCmSubscriptionNcmpOutEventMapperSpec extends Sp
             assert rejectedCmHandleTargetsPerDetails.get(1).getTargets() == ['CMHandle1']
     }
 
-    def 'Map subscription event response with null of subscription status list to subscription event outcome causes an exception'() {
-        given: 'a Subscription Response Event'
-            def subscriptionResponseJsonData = TestUtils.getResourceFileContent('cmSubscriptionDmiOutEvent.json')
-            def subscriptionResponseEvent = jsonObjectMapper.convertJsonString(subscriptionResponseJsonData, CmSubscriptionDmiOutEvent.class)
-        and: 'set subscription status list to null'
-            subscriptionResponseEvent.getData().setSubscriptionStatus(subscriptionStatusList)
-        when: 'the subscription response event is mapped to a subscription event outcome'
-            objectUnderTest.toCmSubscriptionNcmpOutEvent(subscriptionResponseEvent)
+    def 'Map cm subscription event to ncmp out event with the given scenarios causes an exception'() {
+        given: 'a cm subscription event'
+            def cmSubscriptionEventJsonData = TestUtils.getResourceFileContent('cmSubscriptionEvent.json')
+            def cmSubscriptionEvent = jsonObjectMapper.convertJsonString(cmSubscriptionEventJsonData, CmSubscriptionEvent.class)
+        and: 'set cm subscription status with given scenarios'
+            cmSubscriptionEvent.setCmSubscriptionStatus(subscriptionStatusList)
+        when: 'cm subscription event is mapped to ncmp out event'
+            objectUnderTest.toCmSubscriptionNcmpOutEvent(cmSubscriptionEvent)
         then: 'a DataValidationException is thrown with an expected exception details'
             def exception = thrown(DataValidationException)
-            exception.details == 'SubscriptionStatus list cannot be null or empty'
+            exception.details == 'CmSubscriptionStatus list cannot be null or empty'
         where: 'the following values are used'
             scenario                            ||     subscriptionStatusList
-            'A null subscription status list'   ||      null
-            'An empty subscription status list' ||      new ArrayList<SubscriptionStatus>()
+            'A null subscription status list'   ||     null
+            'An empty subscription status list' ||     new ArrayList<CmSubscriptionStatus>()
     }
 
-    def 'Map subscription event response with subscription status list to subscription event outcome without any exception'() {
-        given: 'a Subscription Response Event'
-            def subscriptionResponseJsonData = TestUtils.getResourceFileContent('cmSubscriptionDmiOutEvent.json')
-            def subscriptionResponseEvent = jsonObjectMapper.convertJsonString(subscriptionResponseJsonData, CmSubscriptionDmiOutEvent.class)
-        when: 'the subscription response event is mapped to a subscription event outcome'
+    def 'Map cm subscription event to ncmp out event without any exception'() {
+        given: 'a cm subscription Event'
+            def subscriptionResponseJsonData = TestUtils.getResourceFileContent('cmSubscriptionEvent.json')
+            def subscriptionResponseEvent = jsonObjectMapper.convertJsonString(subscriptionResponseJsonData, CmSubscriptionEvent.class)
+        when: 'cm subscription event is mapped to ncmp out event'
             objectUnderTest.toCmSubscriptionNcmpOutEvent(subscriptionResponseEvent)
         then: 'no exception thrown'
             noExceptionThrown()
index a13fe53..fd1a83e 100644 (file)
@@ -32,6 +32,7 @@ import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelSubscriptionEvent.TargetCmHandle
 import org.onap.cps.ncmp.api.inventory.InventoryPersistence
 import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec
+import org.onap.cps.ncmp.api.models.CmSubscriptionEvent
 import org.onap.cps.ncmp.events.cmsubscription1_0_0.client_to_ncmp.CmSubscriptionNcmpInEvent
 import org.onap.cps.ncmp.events.cmsubscription1_0_0.dmi_to_ncmp.CmSubscriptionDmiOutEvent
 import org.onap.cps.ncmp.events.cmsubscription1_0_0.dmi_to_ncmp.Data
@@ -74,24 +75,25 @@ class CmSubscriptionNcmpInEventForwarderSpec extends MessagingBaseSpec {
     ObjectMapper objectMapper
 
     def 'Forward valid CM create subscription and simulate timeout'() {
-        given: 'an event'
-            def jsonData = TestUtils.getResourceFileContent('cmSubscriptionNcmpInEvent.json')
-            def testEventSent = jsonObjectMapper.convertJsonString(jsonData, CmSubscriptionNcmpInEvent.class)
+        given: 'a ncmp in event'
+            def ncmpInEventJsonData = TestUtils.getResourceFileContent('cmSubscriptionNcmpInEvent.json')
+            def ncmpInEventJson = jsonObjectMapper.convertJsonString(ncmpInEventJsonData, CmSubscriptionNcmpInEvent.class)
         and: 'the InventoryPersistence returns private properties for the supplied CM Handles'
             1 * mockInventoryPersistence.getYangModelCmHandles(["CMHandle1", "CMHandle2", "CMHandle3"]) >> [
-                createYangModelCmHandleWithDmiProperty(1, 1, "shape", "circle"),
-                createYangModelCmHandleWithDmiProperty(2, 1, "shape", "square")
+                createYangModelCmHandleWithDmiProperty(1, 1,"shape","circle"),
+                createYangModelCmHandleWithDmiProperty(2, 1,"shape","square"),
+                createYangModelCmHandleWithDmiProperty(3, 2,"shape","triangle")
             ]
         and: 'the thread creation delay is reduced to 2 seconds for testing'
             objectUnderTest.dmiResponseTimeoutInMs = 2000
         and: 'a Blocking Variable is used for the Asynchronous call with a timeout of 5 seconds'
             def block = new BlockingVariable<Object>(5)
         when: 'the valid event is forwarded'
-            objectUnderTest.forwardCreateSubscriptionEvent(testEventSent, 'subscriptionCreated')
+            objectUnderTest.forwardCreateSubscriptionEvent(ncmpInEventJson, 'subscriptionCreated')
         then: 'An asynchronous call is made to the blocking variable'
             block.get()
         then: 'the event is added to the forwarded subscription event cache'
-            1 * mockForwardedSubscriptionEventCache.put("SCO-9989752cm-subscription-001", ["DMIName1"] as Set, 600, TimeUnit.SECONDS)
+            1 * mockForwardedSubscriptionEventCache.put("SCO-9989752cm-subscription-001", ["DMIName1","DMIName2"] as Set, 600, TimeUnit.SECONDS)
         and: 'the event is forwarded twice with the CMHandle private properties and provides a valid listenable future'
             1 * mockSubscriptionEventPublisher.publishCloudEvent("ncmp-dmi-cm-avc-subscription-DMIName1", "SCO-9989752-cm-subscription-001-DMIName1",
                 cloudEvent -> {
@@ -101,6 +103,13 @@ class CmSubscriptionNcmpInEventForwarderSpec extends MessagingBaseSpec {
                     targets == [cmHandle2, cmHandle1]
                 }
             )
+            1 * mockSubscriptionEventPublisher.publishCloudEvent("ncmp-dmi-cm-avc-subscription-DMIName2", "SCO-9989752-cm-subscription-001-DMIName2",
+                cloudEvent -> {
+                    def targets = toTargetEvent(cloudEvent, CmSubscriptionDmiInEvent.class).getData().getPredicates().getTargets()
+                    def cmHandle3 = createCmHandle('CMHandle3', ['shape':'triangle'] as Map)
+                    targets == [cmHandle3]
+                }
+            )
         and: 'a separate thread has been created where the map is polled'
             1 * mockForwardedSubscriptionEventCache.containsKey("SCO-9989752cm-subscription-001") >> true
             1 * mockCmSubscriptionNcmpOutEventPublisher.sendResponse(*_)
@@ -109,13 +118,13 @@ class CmSubscriptionNcmpInEventForwarderSpec extends MessagingBaseSpec {
     }
 
     def 'Forward CM create subscription where target CM Handles are #scenario'() {
-        given: 'an event'
-            def jsonData = TestUtils.getResourceFileContent('cmSubscriptionNcmpInEvent.json')
-            def testEventSent = jsonObjectMapper.convertJsonString(jsonData, CmSubscriptionNcmpInEvent.class)
+        given: 'a ncmp in event'
+            def ncmpInEventJsonData = TestUtils.getResourceFileContent('cmSubscriptionNcmpInEvent.json')
+            def ncmpInEventJson = jsonObjectMapper.convertJsonString(ncmpInEventJsonData, CmSubscriptionNcmpInEvent.class)
         and: 'the target CMHandles are set to #scenario'
-            testEventSent.getData().getPredicates().setTargets(invalidTargets)
+            ncmpInEventJson.getData().getPredicates().setTargets(invalidTargets)
         when: 'the event is forwarded'
-            objectUnderTest.forwardCreateSubscriptionEvent(testEventSent, 'some-event-type')
+            objectUnderTest.forwardCreateSubscriptionEvent(ncmpInEventJson, 'some-event-type')
         then: 'an operation not supported exception is thrown'
             thrown(UnsupportedOperationException)
         where:
@@ -126,28 +135,24 @@ class CmSubscriptionNcmpInEventForwarderSpec extends MessagingBaseSpec {
     }
 
     def 'Forward valid CM create subscription where targets are not associated to any existing CMHandles'() {
-        given: 'an event'
-            def jsonData = TestUtils.getResourceFileContent('cmSubscriptionNcmpInEvent.json')
-            def testEventSent = jsonObjectMapper.convertJsonString(jsonData, CmSubscriptionNcmpInEvent.class)
-        and: 'a subscription event response'
-            def emptySubscriptionEventResponse = new CmSubscriptionDmiOutEvent().withData(new Data());
-            emptySubscriptionEventResponse.getData().setSubscriptionName('cm-subscription-001');
-            emptySubscriptionEventResponse.getData().setClientId('SCO-9989752');
-        and: 'the cm handles will be rejected'
+        given: 'a ncmp in event'
+            def ncmpInEventJsonData = TestUtils.getResourceFileContent('cmSubscriptionNcmpInEvent.json')
+            def ncmpInEventJson = jsonObjectMapper.convertJsonString(ncmpInEventJsonData, CmSubscriptionNcmpInEvent.class)
+        and: 'the InventoryPersistence returns no private properties for the supplied CM Handles'
+            1 * mockInventoryPersistence.getYangModelCmHandles(["CMHandle1", "CMHandle2", "CMHandle3"]) >> []
+        and: 'some rejected cm handles'
             def rejectedCmHandles = [new TargetCmHandle('CMHandle1', SubscriptionStatus.REJECTED, 'Cm handle does not exist'),
                                      new TargetCmHandle('CMHandle2', SubscriptionStatus.REJECTED, 'Cm handle does not exist'),
                                      new TargetCmHandle('CMHandle3', SubscriptionStatus.REJECTED, 'Cm handle does not exist')]
         and: 'a yang model subscription event will be saved into the db with rejected cm handles'
-            def yangModelSubscriptionEvent = cmSubscriptionNcmpInEventMapper.toYangModelSubscriptionEvent(testEventSent)
+            def yangModelSubscriptionEvent = cmSubscriptionNcmpInEventMapper.toYangModelSubscriptionEvent(ncmpInEventJson)
             yangModelSubscriptionEvent.getPredicates().setTargetCmHandles(rejectedCmHandles)
-        and: 'the InventoryPersistence returns no private properties for the supplied CM Handles'
-            1 * mockInventoryPersistence.getYangModelCmHandles(["CMHandle1", "CMHandle2", "CMHandle3"]) >> []
         and: 'the thread creation delay is reduced to 2 seconds for testing'
             objectUnderTest.dmiResponseTimeoutInMs = 2000
         and: 'a Blocking Variable is used for the Asynchronous call with a timeout of 5 seconds'
             def block = new BlockingVariable<Object>(5)
         when: 'the valid event is forwarded'
-            objectUnderTest.forwardCreateSubscriptionEvent(testEventSent, 'subscriptionCreatedStatus')
+            objectUnderTest.forwardCreateSubscriptionEvent(ncmpInEventJson, 'subscriptionCreatedStatus')
         then: 'the event is not added to the forwarded subscription event cache'
             0 * mockForwardedSubscriptionEventCache.put("SCO-9989752cm-subscription-001", ["DMIName1", "DMIName2"] as Set)
         and: 'the event is not being forwarded with the CMHandle private properties and does not provides a valid listenable future'
@@ -170,11 +175,11 @@ class CmSubscriptionNcmpInEventForwarderSpec extends MessagingBaseSpec {
             0 * mockForwardedSubscriptionEventCache.containsKey("SCO-9989752cm-subscription-001") >> true
             0 * mockForwardedSubscriptionEventCache.get(_)
         and: 'the subscription id is removed from the event cache map returning the asynchronous blocking variable'
-            0 * mockForwardedSubscriptionEventCache.remove("SCO-9989752cm-subscription-001") >> { block.set(_) }
-        and: 'the persistence service save target cm handles of the yang model subscription event as rejected '
+            0 * mockForwardedSubscriptionEventCache.remove("SCO-9989752cm-subscription-001") >> {block.set(_)}
+        and: 'the persistence service save target cm handles of the yang model subscription event as rejected'
             1 * mockSubscriptionPersistence.saveSubscriptionEvent(yangModelSubscriptionEvent)
         and: 'subscription outcome has been sent'
-            1 * mockCmSubscriptionNcmpOutEventPublisher.sendResponse(emptySubscriptionEventResponse, 'subscriptionCreatedStatus')
+            1 * mockCmSubscriptionNcmpOutEventPublisher.sendResponse(_, 'subscriptionCreatedStatus')
     }
 
     static def createYangModelCmHandleWithDmiProperty(id, dmiId, propertyName, propertyValue) {
index 07e2e3f..cc14195 100644 (file)
@@ -29,7 +29,7 @@ import org.onap.cps.ncmp.api.impl.events.EventsPublisher
 import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionPersistence
 import org.onap.cps.ncmp.api.impl.utils.DataNodeBaseSpec
 import org.onap.cps.ncmp.api.impl.utils.SubscriptionOutcomeCloudMapper
-import org.onap.cps.ncmp.events.cmsubscription1_0_0.dmi_to_ncmp.CmSubscriptionDmiOutEvent
+import org.onap.cps.ncmp.api.models.CmSubscriptionEvent
 import org.onap.cps.ncmp.events.cmsubscription1_0_0.ncmp_to_client.CmSubscriptionNcmpOutEvent
 import org.onap.cps.ncmp.utils.TestUtils
 import org.onap.cps.utils.JsonObjectMapper
@@ -37,7 +37,7 @@ import org.spockframework.spring.SpringBean
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.boot.test.context.SpringBootTest
 
-@SpringBootTest(classes = [ObjectMapper, JsonObjectMapper, CmSubscriptionDmiOutEventToCmSubscriptionNcmpOutEventMapper, CmSubscriptionNcmpOutEventPublisher])
+@SpringBootTest(classes = [ObjectMapper, JsonObjectMapper, CmSubscriptionEventToCmSubscriptionNcmpOutEventMapper, CmSubscriptionNcmpOutEventPublisher])
 class CmSubscriptionNcmpOutEventPublisherSpec extends DataNodeBaseSpec {
 
     @Autowired
@@ -48,7 +48,7 @@ class CmSubscriptionNcmpOutEventPublisherSpec extends DataNodeBaseSpec {
     @SpringBean
     EventsPublisher<CloudEvent> mockCmSubscriptionNcmpOutEventPublisher = Mock(EventsPublisher<CloudEvent>)
     @SpringBean
-    CmSubscriptionDmiOutEventToCmSubscriptionNcmpOutEventMapper cmSubscriptionDmiOutEventToCmSubscriptionNcmpOutEventMapper = Mappers.getMapper(CmSubscriptionDmiOutEventToCmSubscriptionNcmpOutEventMapper)
+    CmSubscriptionEventToCmSubscriptionNcmpOutEventMapper cmSubscriptionEventToCmSubscriptionNcmpOutEventMapper = Mappers.getMapper(CmSubscriptionEventToCmSubscriptionNcmpOutEventMapper)
     @SpringBean
     SubscriptionOutcomeCloudMapper subscriptionOutcomeCloudMapper = new SubscriptionOutcomeCloudMapper(new ObjectMapper())
 
@@ -59,17 +59,17 @@ class CmSubscriptionNcmpOutEventPublisherSpec extends DataNodeBaseSpec {
     ObjectMapper objectMapper
 
     def 'Send response to the client apps successfully'() {
-        given: 'a subscription response event'
-            def subscriptionResponseJsonData = TestUtils.getResourceFileContent('cmSubscriptionDmiOutEvent.json')
-            def subscriptionResponseEvent = jsonObjectMapper.convertJsonString(subscriptionResponseJsonData, CmSubscriptionDmiOutEvent.class)
-        and: 'a subscription outcome event'
-            def subscriptionOutcomeJsonData = TestUtils.getResourceFileContent('cmSubscriptionNcmpOutEvent2.json')
-            def subscriptionOutcomeEvent = jsonObjectMapper.convertJsonString(subscriptionOutcomeJsonData, CmSubscriptionNcmpOutEvent.class)
+        given: 'a cm subscription event'
+            def cmSubscriptionEventJsonData = TestUtils.getResourceFileContent('cmSubscriptionEvent.json')
+            def cmSubscriptionEvent = jsonObjectMapper.convertJsonString(cmSubscriptionEventJsonData, CmSubscriptionEvent.class)
+        and: 'a ncmp out event'
+            def ncmpOutEventJsonData = TestUtils.getResourceFileContent('cmSubscriptionNcmpOutEvent2.json')
+            def ncmpOutEvent = jsonObjectMapper.convertJsonString(ncmpOutEventJsonData, CmSubscriptionNcmpOutEvent.class)
         and: 'a random id for the cloud event'
             SubscriptionOutcomeCloudMapper.randomId = 'some-id'
         and: 'a cloud event containing the outcome event'
             def testCloudEventSent = CloudEventBuilder.v1()
-                .withData(objectMapper.writeValueAsBytes(subscriptionOutcomeEvent))
+                .withData(objectMapper.writeValueAsBytes(ncmpOutEvent))
                 .withId('some-id')
                 .withType('subscriptionCreatedStatus')
                 .withDataSchema(URI.create('urn:cps:' + 'org.onap.cps.ncmp.events.cmsubscription1_0_0.ncmp_to_client.CmSubscriptionNcmpOutEvent' + ':1.0.0'))
@@ -78,25 +78,25 @@ class CmSubscriptionNcmpOutEventPublisherSpec extends DataNodeBaseSpec {
         and: 'the persistence service return a data node that includes pending cm handles that makes it partial success'
             mockSubscriptionPersistence.getCmHandlesForSubscriptionEvent(*_) >> [dataNode4]
         when: 'the response is being sent'
-            objectUnderTest.sendResponse(subscriptionResponseEvent, 'subscriptionCreatedStatus')
+            objectUnderTest.sendResponse(cmSubscriptionEvent, 'subscriptionCreatedStatus')
         then: 'the publisher publish the cloud event with itself and expected parameters'
             1 * mockCmSubscriptionNcmpOutEventPublisher.publishCloudEvent('subscription-response', 'SCO-9989752cm-subscription-001', testCloudEventSent)
     }
 
-    def 'Create subscription outcome message as expected'() {
-        given: 'a subscription response event'
-            def subscriptionResponseJsonData = TestUtils.getResourceFileContent('cmSubscriptionDmiOutEvent.json')
-            def subscriptionResponseEvent = jsonObjectMapper.convertJsonString(subscriptionResponseJsonData, CmSubscriptionDmiOutEvent.class)
-        and: 'a subscription outcome event'
-            def subscriptionOutcomeJsonData = TestUtils.getResourceFileContent('cmSubscriptionNcmpOutEvent.json')
-            def subscriptionOutcomeEvent = jsonObjectMapper.convertJsonString(subscriptionOutcomeJsonData, CmSubscriptionNcmpOutEvent.class)
+    def 'Create ncmp out message as expected'() {
+        given: 'a cm subscription event'
+            def cmSubscriptionEventJsonData = TestUtils.getResourceFileContent('cmSubscriptionEvent.json')
+            def cmSubscriptionEvent = jsonObjectMapper.convertJsonString(cmSubscriptionEventJsonData, CmSubscriptionEvent.class)
+        and: 'a ncmp out event'
+            def ncmpOutEventJsonData = TestUtils.getResourceFileContent('cmSubscriptionNcmpOutEvent.json')
+            def ncmpOutEvent = jsonObjectMapper.convertJsonString(ncmpOutEventJsonData, CmSubscriptionNcmpOutEvent.class)
         and: 'a status code and status message a per #scenarios'
-            subscriptionOutcomeEvent.getData().setStatusCode(statusCode)
-            subscriptionOutcomeEvent.getData().setStatusMessage(statusMessage)
-        when: 'a subscription event outcome message is being formed'
-            def result = objectUnderTest.fromDmiOutEvent(subscriptionResponseEvent, ncmpEventResponseCode)
-        then: 'the result will be equal to event outcome'
-            result == subscriptionOutcomeEvent
+            ncmpOutEvent.getData().setStatusCode(statusCode)
+            ncmpOutEvent.getData().setStatusMessage(statusMessage)
+        when: 'a cm subscription event is being formed'
+            def expectedResult = objectUnderTest.fromCmSubscriptionEvent(cmSubscriptionEvent, ncmpEventResponseCode)
+        then: 'the result will be equal to ncmp out event'
+            expectedResult == ncmpOutEvent
         where: 'the following values are used'
             scenario             | ncmpEventResponseCode                                        || statusMessage                          ||  statusCode
             'is full outcome'    | NcmpEventResponseCode.SUCCESSFULLY_APPLIED_SUBSCRIPTION      || 'successfully applied subscription'    ||  1
index dfe8f50..ae14b5c 100644 (file)
         "id": "CMHandle2",
         "status": "REJECTED",
         "details": "Some other error message from the DMI"
-      },
-      {
-        "id": "CMHandle3",
-        "status": "PENDING",
-        "details": "No reply from DMI yet"
-      },
-      {
-        "id": "CMHandle4",
-        "status": "PENDING",
-        "details": "No reply from DMI yet"
       }
     ]
   }
diff --git a/cps-ncmp-service/src/test/resources/cmSubscriptionEvent.json b/cps-ncmp-service/src/test/resources/cmSubscriptionEvent.json
new file mode 100644 (file)
index 0000000..c38cb79
--- /dev/null
@@ -0,0 +1,31 @@
+{
+  "clientId": "SCO-9989752",
+  "subscriptionName": "cm-subscription-001",
+  "cmSubscriptionStatus": [
+    {
+      "id": "CMHandle1",
+      "status": "REJECTED",
+      "details": "Some error message from the DMI"
+    },
+    {
+      "id": "CMHandle2",
+      "status": "REJECTED",
+      "details": "Some other error message from the DMI"
+    },
+    {
+      "id": "CMHandle3",
+      "status": "PENDING",
+      "details": "Some error causes pending"
+    },
+    {
+      "id": "CMHandle4",
+      "status": "PENDING",
+      "details": "Some other error happened"
+    },
+    {
+      "id": "CMHandle5",
+      "status": "PENDING",
+      "details": "Some other error happened"
+    }
+  ]
+}
\ No newline at end of file
index 14e8cbb..856f238 100644 (file)
       ],
       "pending": [
         {
-          "details": "No reply from DMI yet",
-          "targets": ["CMHandle3", "CMHandle4"]
+          "details": "Some other error happened",
+          "targets": ["CMHandle4", "CMHandle5"]
+        },
+        {
+          "details": "Some error causes pending",
+          "targets": ["CMHandle3"]
         }
       ]
     }