refactor cmsubscription code 55/138355/7
authormpriyank <priyank.maheshwari@est.tech>
Mon, 1 Jul 2024 11:32:27 +0000 (12:32 +0100)
committermpriyank <priyank.maheshwari@est.tech>
Thu, 4 Jul 2024 09:15:47 +0000 (10:15 +0100)
- Moved cmsubscription to the impl package instead of api.
- Below packages are renamed or newly created for code and tests
  - moved ..api.cmsubsription to ..impl.cmsubscription
  - renamed ..api.cmsubscription.mappers to ..impl.cmsubscription.ncmp
    or dmi as per the functionality
  - renamed ..api.cmsubscription.model to ..impl.cmsubscription.models
  - removed ..api.cmsubscription.producer/consumer and classes moved to  ..impl.cmsubscription.ncmp/dmi
  - new package ..impl.cmsubscription.cache to hold cache config and
    cache operations
  - new package ..impl.cmsubscription.avc to hold the CmAvcEventConsumer
    for the notifications emitted as a result of the subscriptions
  - Removed the prefix CmNotificationSubscription for majority of the classes , not removed for Config and model classes
  - Renamed the schemas and package structure as per the code refactoring

Note: *EventsFacade and *MappersFacade to be removed in the next
patchset

Issue-ID: CPS-2298
Change-Id: I1d788ab745d65965570e28beaefa511cbe4a8547
Signed-off-by: mpriyank <priyank.maheshwari@est.tech>
52 files changed:
cps-ncmp-events/src/main/resources/schemas/cmnotificationsubscription/dmi-in-event-schema-1.0.0.json [moved from cps-ncmp-events/src/main/resources/schemas/cmnotificationsubscription/cm-notification-subscription-dmi-in-event-schema-1.0.0.json with 91% similarity]
cps-ncmp-events/src/main/resources/schemas/cmnotificationsubscription/dmi-out-event-schema-1.0.0.json [moved from cps-ncmp-events/src/main/resources/schemas/cmnotificationsubscription/cm-notification-subscription-dmi-out-event-schema-1.0.0.json with 78% similarity]
cps-ncmp-events/src/main/resources/schemas/cmnotificationsubscription/ncmp-in-event-schema-1.0.0.json [moved from cps-ncmp-events/src/main/resources/schemas/cmnotificationsubscription/cm-notification-subscription-ncmp-in-event-schema-1.0.0.json with 90% similarity]
cps-ncmp-events/src/main/resources/schemas/cmnotificationsubscription/ncmp-out-event-schema-1.0.0.json [moved from cps-ncmp-events/src/main/resources/schemas/cmnotificationsubscription/cm-notification-subscription-ncmp-out-event-schema-1.0.0.json with 83% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionDelta.java [deleted file]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionEventsHandler.java [deleted file]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionMappersHandler.java [deleted file]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionNcmpOutEventPublishingTask.java [deleted file]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/consumer/CmNotificationSubscriptionDmiOutEventConsumer.java [deleted file]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/mapper/CmNotificationSubscriptionNcmpOutEventMapper.java [deleted file]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/producer/CmNotificationSubscriptionNcmpOutEventProducer.java [deleted file]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionHandlerServiceImpl.java [deleted file]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionPersistenceService.java [deleted file]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/EventsFacade.java [new file with mode: 0644]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/MappersFacade.java [new file with mode: 0644]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/cache/CmSubscriptionConfig.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/CmNotificationSubscriptionCacheConfig.java with 83% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/cache/DmiCacheHandler.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/DmiCmNotificationSubscriptionCacheHandler.java with 51% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/cmavc/CmAvcEventConsumer.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avc/AvcEventConsumer.java with 79% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiInEventMapper.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/mapper/CmNotificationSubscriptionDmiInEventMapper.java with 60% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiInEventProducer.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/producer/CmNotificationSubscriptionDmiInEventProducer.java with 59% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiOutEventConsumer.java [new file with mode: 0644]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/models/CmSubscriptionStatus.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/CmNotificationSubscriptionStatus.java with 85% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/models/DmiCmSubscriptionDetails.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/DmiCmNotificationSubscriptionDetails.java with 78% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/models/DmiCmSubscriptionPredicate.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/DmiCmNotificationSubscriptionPredicate.java with 91% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/CmSubscriptionComparator.java [new file with mode: 0644]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/CmSubscriptionHandler.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionHandlerService.java with 87% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/CmSubscriptionHandlerImpl.java [new file with mode: 0644]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpInEventConsumer.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/consumer/CmNotificationSubscriptionNcmpInEventConsumer.java with 59% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventMapper.java [new file with mode: 0644]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventProducer.java [new file with mode: 0644]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventPublishingTask.java [new file with mode: 0644]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/utils/CmSubscriptionPersistenceService.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionPersistenceServiceImpl.java with 64% similarity]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/OpenTelemetryCmNotificationSubscriptionConfigSpec.groovy [moved from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/OpenTelemetryConfigSpec.groovy with 100% similarity]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionDeltaSpec.groovy [deleted file]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionNcmpOutEventProducerSpec.groovy [deleted file]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/mapper/CmNotificationSubscriptionNcmpOutEventMapperSpec.groovy [deleted file]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionHandlerServiceImplSpec.groovy [deleted file]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/EventsFacadeSpec.groovy [moved from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionEventsHandlerSpec.groovy with 52% similarity]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/MappersFacadeSpec.groovy [moved from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionMappersHandlerSpec.groovy with 63% similarity]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/cache/CmSubscriptionConfigSpec.groovy [moved from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/embeddedcache/CmNotificationSubscriptionCacheConfigSpec.groovy with 63% similarity]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/cache/DmiCacheHandlerSpec.groovy [moved from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/DmiCmNotificationSubscriptionCacheHandlerSpec.groovy with 62% similarity]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/cmavc/CmAvcEventConsumerSpec.groovy [moved from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avc/AvcEventConsumerSpec.groovy with 93% similarity]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiInEventMapperSpec.groovy [moved from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/mapper/CmNotificationSubscriptionDmiInEventMapperSpec.groovy with 76% similarity]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiInEventProducerSpec.groovy [moved from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionDmiInEventProducerSpec.groovy with 53% similarity]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiOutEventConsumerSpec.groovy [moved from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionDmiOutEventConsumerSpec.groovy with 60% similarity]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/CmSubscriptionComparatorSpec.groovy [new file with mode: 0644]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/CmSubscriptionHandlerImplSpec.groovy [new file with mode: 0644]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpInEventConsumerSpec.groovy [moved from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionNcmpInEventConsumerSpec.groovy with 78% similarity]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventMapperSpec.groovy [new file with mode: 0644]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventProducerSpec.groovy [new file with mode: 0644]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/utils/CmSubscriptionPersistenceServiceSpec.groovy [moved from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionPersistenceServiceImplSpec.groovy with 70% similarity]
integration-test/src/test/groovy/org/onap/cps/integration/functional/NcmpCmNotificationSubscriptionSpec.groovy

@@ -1,12 +1,12 @@
 {
   "$schema": "https://json-schema.org/draft/2019-09/schema",
   "$id": "urn:cps:org.onap.cps.ncmp.events:cm-notification-subscription-dmi-in-event-schema:1.0.0",
-  "$ref": "#/definitions/CmNotificationSubscriptionDmiInEvent",
+  "$ref": "#/definitions/DmiInEvent",
   "definitions": {
-    "CmNotificationSubscriptionDmiInEvent": {
+    "DmiInEvent": {
       "description": "The payload for cm notification subscription event incoming message from NCMP.",
       "type": "object",
-      "javaType": "org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.ncmp_to_dmi.CmNotificationSubscriptionDmiInEvent",
+      "javaType": "org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_dmi.DmiInEvent",
       "additionalProperties": false,
       "properties": {
         "data": {
@@ -1,13 +1,13 @@
 {
   "$schema": "https://json-schema.org/draft/2019-09/schema",
   "$id": "urn:cps:org.onap.cps.ncmp.events:cm-notification-subscription-dmi-out-event-schema:1.0.0",
-  "$ref": "#/definitions/CmNotificationSubscriptionDmiOutEvent",
+  "$ref": "#/definitions/DmiOutEvent",
   "definitions": {
-    "CmNotificationSubscriptionDmiOutEvent": {
+    "DmiOutEvent": {
       "description": "The payload for cm notification subscription merge event coming out from DMI Plugin.",
       "type": "object",
       "additionalProperties": false,
-      "javaType": "org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.dmi_to_ncmp.CmNotificationSubscriptionDmiOutEvent",
+      "javaType": "org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.dmi_to_ncmp.DmiOutEvent",
       "properties": {
         "data": {
           "$ref": "#/definitions/Data"
@@ -16,7 +16,7 @@
       "required": [
         "data"
       ],
-      "title": "CmNotificationSubscriptionDmiOutEvent"
+      "title": "DmiOutEvent"
     },
     "Data": {
       "type": "object",
@@ -1,11 +1,11 @@
 {
   "$id": "urn:cps:org.onap.cps.ncmp.events:cm-notification-subscription-ncmp-in-event:1.0.0",
-  "$ref": "#/definitions/CmNotificationSubscriptionNcmpInEvent",
+  "$ref": "#/definitions/NcmpInEvent",
   "$schema": "https://json-schema.org/draft/2019-09/schema",
   "definitions": {
-    "CmNotificationSubscriptionNcmpInEvent": {
+    "NcmpInEvent": {
       "description": "The payload for subscription merge event.",
-      "javaType": "org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.client_to_ncmp.CmNotificationSubscriptionNcmpInEvent",
+      "javaType": "org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.client_to_ncmp.NcmpInEvent",
       "properties": {
         "data": {
           "properties": {
@@ -1,12 +1,12 @@
 {
   "$schema": "https://json-schema.org/draft/2019-09/schema",
   "$id": "urn:cps:org.onap.cps.ncmp.events:cm-notification-subscription-ncmp-out-event-schema:1.0.0",
-  "$ref": "#/definitions/CmNotificationSubscriptionNcmpOutEvent",
+  "$ref": "#/definitions/NcmpOutEvent",
   "definitions": {
-    "CmNotificationSubscriptionNcmpOutEvent": {
+    "NcmpOutEvent": {
       "type": "object",
       "description": "The payload applied cm subscription merge event coming out from NCMP.",
-      "javaType": "org.onap.cps.ncmp.events.cmsubscription_merge1_0_0.ncmp_to_client.CmNotificationSubscriptionNcmpOutEvent",
+      "javaType": "org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_client.NcmpOutEvent",
       "additionalProperties": false,
       "properties": {
         "data": {
@@ -16,7 +16,7 @@
       "required": [
         "data"
       ],
-      "title": "CmNotificationSubscriptionNcmpOutEvent"
+      "title": "NcmpOutEvent"
     },
     "Data": {
       "type": "object",
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionDelta.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionDelta.java
deleted file mode 100644 (file)
index ff322ee..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- *  Copyright (C) 2024 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.events.cmsubscription;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import lombok.RequiredArgsConstructor;
-import org.onap.cps.ncmp.api.data.models.DatastoreType;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionPredicate;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.service.CmNotificationSubscriptionPersistenceService;
-import org.springframework.stereotype.Component;
-
-@Component
-@RequiredArgsConstructor
-public class CmNotificationSubscriptionDelta {
-
-    private final CmNotificationSubscriptionPersistenceService cmNotificationSubscriptionPersistenceService;
-
-    /**
-     * Get the delta for a given predicates list.
-     *
-     * @param dmiCmNotificationSubscriptionPredicates list of DmiCmNotificationSubscriptionPredicates
-     * @return delta list of DmiCmNotificationSubscriptionPredicates
-     */
-    public List<DmiCmNotificationSubscriptionPredicate> getDelta(
-        final List<DmiCmNotificationSubscriptionPredicate> dmiCmNotificationSubscriptionPredicates) {
-        final List<DmiCmNotificationSubscriptionPredicate> delta = new ArrayList<>();
-
-        for (final DmiCmNotificationSubscriptionPredicate cmNotificationSubscriptionPredicate:
-            dmiCmNotificationSubscriptionPredicates) {
-
-            final Set<String> targetCmHandleIds = new HashSet<>();
-            final Set<String> xpaths = new HashSet<>();
-            final DatastoreType datastoreType = cmNotificationSubscriptionPredicate.getDatastoreType();
-
-            for (final String cmHandleId : cmNotificationSubscriptionPredicate.getTargetCmHandleIds()) {
-                for (final String xpath : cmNotificationSubscriptionPredicate.getXpaths()) {
-                    if (!cmNotificationSubscriptionPersistenceService.isOngoingCmNotificationSubscription(datastoreType,
-                            cmHandleId, xpath)) {
-                        xpaths.add(xpath);
-                        targetCmHandleIds.add(cmHandleId);
-
-                    }
-                }
-            }
-
-            populateValidDmiCmNotificationSubscriptionPredicateDelta(targetCmHandleIds, xpaths, datastoreType, delta);
-        }
-        return delta;
-    }
-
-    private void populateValidDmiCmNotificationSubscriptionPredicateDelta(final Set<String> targetCmHandleIds,
-            final Set<String> xpaths, final DatastoreType datastoreType,
-            final List<DmiCmNotificationSubscriptionPredicate> delta) {
-        if (!(targetCmHandleIds.isEmpty() || xpaths.isEmpty())) {
-            final DmiCmNotificationSubscriptionPredicate predicateDelta =
-                    new DmiCmNotificationSubscriptionPredicate(targetCmHandleIds, datastoreType, xpaths);
-            delta.add(predicateDelta);
-        }
-    }
-
-}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionEventsHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionEventsHandler.java
deleted file mode 100644 (file)
index 50a5df5..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (c) 2024 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.events.cmsubscription;
-
-import lombok.RequiredArgsConstructor;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.producer.CmNotificationSubscriptionDmiInEventProducer;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.producer.CmNotificationSubscriptionNcmpOutEventProducer;
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.ncmp_to_dmi.CmNotificationSubscriptionDmiInEvent;
-import org.onap.cps.ncmp.events.cmsubscription_merge1_0_0.ncmp_to_client.CmNotificationSubscriptionNcmpOutEvent;
-import org.springframework.stereotype.Component;
-
-@Component
-@RequiredArgsConstructor
-public class CmNotificationSubscriptionEventsHandler {
-    private final CmNotificationSubscriptionNcmpOutEventProducer cmNotificationSubscriptionNcmpOutEventProducer;
-    private final CmNotificationSubscriptionDmiInEventProducer cmNotificationSubscriptionDmiInEventProducer;
-
-    /**
-     * Publish the event to the client who requested the subscription with key as subscription id and event is Cloud
-     * Event compliant.
-     *
-     * @param subscriptionId                         Cm Subscription id
-     * @param eventType                              Type of event
-     * @param cmNotificationSubscriptionNcmpOutEvent Cm Notification Subscription Event for the
-     *                                               client
-     * @param isScheduledEvent                       Determines if the event is to be scheduled
-     *                                               or published now
-     */
-    public void publishCmNotificationSubscriptionNcmpOutEvent(final String subscriptionId, final String eventType,
-                                                              final CmNotificationSubscriptionNcmpOutEvent
-                                                                      cmNotificationSubscriptionNcmpOutEvent,
-                                                              final boolean isScheduledEvent) {
-        cmNotificationSubscriptionNcmpOutEventProducer.publishCmNotificationSubscriptionNcmpOutEvent(subscriptionId,
-                eventType, cmNotificationSubscriptionNcmpOutEvent, isScheduledEvent);
-    }
-
-    /**
-     * Publish the event to the provided dmi plugin with key as subscription id and the event is in Cloud Event format.
-     *
-     * @param subscriptionId                       Cm Subscription id
-     * @param dmiPluginName                        Dmi Plugin Name
-     * @param eventType                            Type of event
-     * @param cmNotificationSubscriptionDmiInEvent Cm Notification Subscription event for Dmi
-     */
-    public void publishCmNotificationSubscriptionDmiInEvent(final String subscriptionId, final String dmiPluginName,
-                                                            final String eventType,
-                                                            final CmNotificationSubscriptionDmiInEvent
-                                                                    cmNotificationSubscriptionDmiInEvent) {
-        cmNotificationSubscriptionDmiInEventProducer.publishCmNotificationSubscriptionDmiInEvent(subscriptionId,
-                dmiPluginName, eventType, cmNotificationSubscriptionDmiInEvent);
-    }
-}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionMappersHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionMappersHandler.java
deleted file mode 100644 (file)
index 73f9563..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- *  ============LICENSE_START=======================================================
- *  Copyright (C) 2024 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.events.cmsubscription;
-
-import java.util.List;
-import java.util.Map;
-import lombok.RequiredArgsConstructor;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.mapper.CmNotificationSubscriptionDmiInEventMapper;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.mapper.CmNotificationSubscriptionNcmpOutEventMapper;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionDetails;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionPredicate;
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.ncmp_to_dmi.CmNotificationSubscriptionDmiInEvent;
-import org.onap.cps.ncmp.events.cmsubscription_merge1_0_0.ncmp_to_client.CmNotificationSubscriptionNcmpOutEvent;
-import org.springframework.stereotype.Component;
-
-@Component
-@RequiredArgsConstructor
-public class CmNotificationSubscriptionMappersHandler {
-
-    private final CmNotificationSubscriptionDmiInEventMapper cmNotificationSubscriptionDmiInEventMapper;
-    private final CmNotificationSubscriptionNcmpOutEventMapper cmNotificationSubscriptionNcmpOutEventMapper;
-
-    /**
-     * Mapper to form a request for the DMI Plugin for the Cm Notification Subscription.
-     *
-     * @param dmiCmNotificationSubscriptionPredicates Collection of Cm Notification Subscription predicates
-     * @return cm notification subscription dmi in event
-     */
-    public CmNotificationSubscriptionDmiInEvent toCmNotificationSubscriptionDmiInEvent(
-            final List<DmiCmNotificationSubscriptionPredicate> dmiCmNotificationSubscriptionPredicates) {
-        return cmNotificationSubscriptionDmiInEventMapper.toCmNotificationSubscriptionDmiInEvent(
-                dmiCmNotificationSubscriptionPredicates);
-    }
-
-    /**
-     * Mapper to form a response for the client for the Cm Notification Subscription.
-     *
-     * @param subscriptionId                          Cm Notification Subscription id
-     * @param dmiCmNotificationSubscriptionDetailsMap contains CmNotificationSubscriptionDetails per dmi plugin
-     * @return CmNotificationSubscriptionNcmpOutEvent to sent back to the client
-     */
-    public CmNotificationSubscriptionNcmpOutEvent toCmNotificationSubscriptionNcmpOutEvent(final String subscriptionId,
-         final Map<String, DmiCmNotificationSubscriptionDetails> dmiCmNotificationSubscriptionDetailsMap) {
-        return cmNotificationSubscriptionNcmpOutEventMapper.toCmNotificationSubscriptionNcmpOutEvent(subscriptionId,
-                dmiCmNotificationSubscriptionDetailsMap);
-    }
-
-    /**
-     * Mapper to form a rejected response for the client for the Cm Notification Subscription Request.
-     *
-     * @param subscriptionId subscription id
-     * @param rejectedTargetFilters list of rejected target filters for the subscription request
-     * @return to sent back to the client
-     */
-    public CmNotificationSubscriptionNcmpOutEvent toCmNotificationSubscriptionNcmpOutEventForRejectedRequest(
-            final String subscriptionId, final List<String> rejectedTargetFilters) {
-        return cmNotificationSubscriptionNcmpOutEventMapper.toCmNotificationSubscriptionNcmpOutEventForRejectedRequest(
-                subscriptionId, rejectedTargetFilters);
-    }
-}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionNcmpOutEventPublishingTask.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionNcmpOutEventPublishingTask.java
deleted file mode 100644 (file)
index f7dd51e..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *  ============LICENSE_START=======================================================
- *  Copyright (C) 2024 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.events.cmsubscription;
-
-import static org.onap.cps.ncmp.api.impl.events.cmsubscription.producer.CmNotificationSubscriptionNcmpOutEventProducer.buildAndGetCmNotificationNcmpOutEventAsCloudEvent;
-
-import io.cloudevents.CloudEvent;
-import java.util.Map;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.onap.cps.events.EventsPublisher;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionDetails;
-import org.onap.cps.ncmp.events.cmsubscription_merge1_0_0.ncmp_to_client.CmNotificationSubscriptionNcmpOutEvent;
-import org.onap.cps.utils.JsonObjectMapper;
-
-@Slf4j
-@RequiredArgsConstructor
-public class CmNotificationSubscriptionNcmpOutEventPublishingTask implements Runnable {
-
-    private final String topicName;
-    private final String subscriptionId;
-    private final String eventType;
-    private final EventsPublisher<CloudEvent> eventsPublisher;
-    private final JsonObjectMapper jsonObjectMapper;
-    private final CmNotificationSubscriptionMappersHandler cmNotificationSubscriptionMappersHandler;
-    private final DmiCmNotificationSubscriptionCacheHandler dmiCmNotificationSubscriptionCacheHandler;
-
-    /**
-     * Delegating the responsibility of publishing CmNotificationSubscriptionNcmpOutEvent as a separate task which will
-     * be called after a specified delay.
-     */
-    @Override
-    public void run() {
-        final Map<String, DmiCmNotificationSubscriptionDetails> dmiCmNotificationSubscriptionDetailsMap =
-                dmiCmNotificationSubscriptionCacheHandler.get(subscriptionId);
-        final CmNotificationSubscriptionNcmpOutEvent cmNotificationSubscriptionNcmpOutEvent =
-                cmNotificationSubscriptionMappersHandler.toCmNotificationSubscriptionNcmpOutEvent(subscriptionId,
-                        dmiCmNotificationSubscriptionDetailsMap);
-        eventsPublisher.publishCloudEvent(topicName, subscriptionId,
-                buildAndGetCmNotificationNcmpOutEventAsCloudEvent(jsonObjectMapper, subscriptionId, eventType,
-                        cmNotificationSubscriptionNcmpOutEvent));
-        dmiCmNotificationSubscriptionCacheHandler
-                .removeAcceptedAndRejectedDmiCmNotificationSubscriptionEntries(subscriptionId);
-    }
-}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/consumer/CmNotificationSubscriptionDmiOutEventConsumer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/consumer/CmNotificationSubscriptionDmiOutEventConsumer.java
deleted file mode 100644 (file)
index 978a4cd..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- *  Copyright (C) 2024 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.events.cmsubscription.consumer;
-
-import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_DATA_SUBSCRIPTION_ACCEPTED;
-import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_DATA_SUBSCRIPTION_REJECTED;
-import static org.onap.cps.ncmp.utils.events.CloudEventMapper.toTargetEvent;
-
-import io.cloudevents.CloudEvent;
-import java.util.Map;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.kafka.clients.consumer.ConsumerRecord;
-import org.onap.cps.ncmp.api.NcmpResponseStatus;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.CmNotificationSubscriptionEventsHandler;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.CmNotificationSubscriptionMappersHandler;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.DmiCmNotificationSubscriptionCacheHandler;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.CmNotificationSubscriptionStatus;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionDetails;
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.dmi_to_ncmp.CmNotificationSubscriptionDmiOutEvent;
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.dmi_to_ncmp.Data;
-import org.onap.cps.ncmp.events.cmsubscription_merge1_0_0.ncmp_to_client.CmNotificationSubscriptionNcmpOutEvent;
-import org.springframework.kafka.annotation.KafkaListener;
-import org.springframework.stereotype.Component;
-
-@Component
-@Slf4j
-@RequiredArgsConstructor
-public class CmNotificationSubscriptionDmiOutEventConsumer {
-
-    private final DmiCmNotificationSubscriptionCacheHandler dmiCmNotificationSubscriptionCacheHandler;
-    private final CmNotificationSubscriptionEventsHandler cmNotificationSubscriptionEventsHandler;
-    private final CmNotificationSubscriptionMappersHandler cmNotificationSubscriptionMappersHandler;
-
-    private static final String CM_DATA_SUBSCRIPTION_CORRELATION_ID_SEPARATOR = "#";
-
-    /**
-     * Consume the Cm Notification Subscription event from the dmi-plugin.
-     *
-     * @param cmNotificationSubscriptionDmiOutEventConsumerRecord the event to be consumed
-     */
-    @KafkaListener(topics = "${app.ncmp.avc.cm-subscription-dmi-out}",
-            containerFactory = "cloudEventConcurrentKafkaListenerContainerFactory")
-    public void consumeCmNotificationSubscriptionDmiOutEvent(
-            final ConsumerRecord<String, CloudEvent> cmNotificationSubscriptionDmiOutEventConsumerRecord) {
-        final CloudEvent cloudEvent = cmNotificationSubscriptionDmiOutEventConsumerRecord.value();
-        final CmNotificationSubscriptionDmiOutEvent cmNotificationSubscriptionDmiOutEvent =
-                toTargetEvent(cloudEvent, CmNotificationSubscriptionDmiOutEvent.class);
-        final String correlationId = String.valueOf(cloudEvent.getExtension("correlationid"));
-        if (cmNotificationSubscriptionDmiOutEvent != null && correlationId != null) {
-            final String eventType = cloudEvent.getType();
-            handleCmSubscriptionDmiOutEvent(correlationId, eventType, cmNotificationSubscriptionDmiOutEvent);
-        }
-    }
-
-    private void handleCmSubscriptionDmiOutEvent(final String correlationId,
-                                                 final String eventType,
-                                                 final CmNotificationSubscriptionDmiOutEvent
-                                                         cmNotificationSubscriptionDmiOutEvent) {
-        final String subscriptionId = correlationId.split(CM_DATA_SUBSCRIPTION_CORRELATION_ID_SEPARATOR)[0];
-        final String dmiPluginName = correlationId.split(CM_DATA_SUBSCRIPTION_CORRELATION_ID_SEPARATOR)[1];
-
-        if (checkStatusCodeAndMessage(CM_DATA_SUBSCRIPTION_ACCEPTED, cmNotificationSubscriptionDmiOutEvent.getData())) {
-            handleCacheStatusPerDmi(subscriptionId, dmiPluginName, CmNotificationSubscriptionStatus.ACCEPTED);
-            if (eventType.equals("subscriptionCreateResponse")) {
-                dmiCmNotificationSubscriptionCacheHandler.persistIntoDatabasePerDmi(subscriptionId, dmiPluginName);
-            }
-            if (eventType.equals("subscriptionDeleteResponse")) {
-                dmiCmNotificationSubscriptionCacheHandler.removeFromDatabasePerDmi(subscriptionId, dmiPluginName);
-            }
-            handleEventsStatusPerDmi(subscriptionId, eventType);
-        }
-
-        if (checkStatusCodeAndMessage(CM_DATA_SUBSCRIPTION_REJECTED, cmNotificationSubscriptionDmiOutEvent.getData())) {
-            handleCacheStatusPerDmi(subscriptionId, dmiPluginName, CmNotificationSubscriptionStatus.REJECTED);
-            handleEventsStatusPerDmi(subscriptionId, eventType);
-        }
-
-        log.info("Cm Subscription with id : {} handled by the dmi-plugin : {} has the status : {}", subscriptionId,
-                dmiPluginName, cmNotificationSubscriptionDmiOutEvent.getData().getStatusMessage());
-    }
-
-    private void handleCacheStatusPerDmi(final String subscriptionId, final String dmiPluginName,
-                                         final CmNotificationSubscriptionStatus cmNotificationSubscriptionStatus) {
-        dmiCmNotificationSubscriptionCacheHandler.updateDmiCmNotificationSubscriptionStatusPerDmi(subscriptionId,
-                dmiPluginName, cmNotificationSubscriptionStatus);
-    }
-
-    private void handleEventsStatusPerDmi(final String subscriptionId, final String eventType) {
-        final Map<String, DmiCmNotificationSubscriptionDetails> dmiCmNotificationSubscriptionDetailsPerDmi =
-                dmiCmNotificationSubscriptionCacheHandler.get(subscriptionId);
-        final CmNotificationSubscriptionNcmpOutEvent cmNotificationSubscriptionNcmpOutEvent =
-                cmNotificationSubscriptionMappersHandler.toCmNotificationSubscriptionNcmpOutEvent(subscriptionId,
-                        dmiCmNotificationSubscriptionDetailsPerDmi);
-        cmNotificationSubscriptionEventsHandler.publishCmNotificationSubscriptionNcmpOutEvent(subscriptionId,
-                eventType, cmNotificationSubscriptionNcmpOutEvent, false);
-    }
-
-    private boolean checkStatusCodeAndMessage(final NcmpResponseStatus ncmpResponseStatus,
-                                              final Data cmNotificationSubscriptionDmiOutData) {
-        return ncmpResponseStatus.getCode().equals(cmNotificationSubscriptionDmiOutData.getStatusCode())
-                && ncmpResponseStatus.getMessage()
-                .equals(cmNotificationSubscriptionDmiOutData.getStatusMessage());
-    }
-}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/mapper/CmNotificationSubscriptionNcmpOutEventMapper.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/mapper/CmNotificationSubscriptionNcmpOutEventMapper.java
deleted file mode 100644 (file)
index ea21751..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- *  Copyright (C) 2024 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.events.cmsubscription.mapper;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import lombok.RequiredArgsConstructor;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.CmNotificationSubscriptionStatus;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionDetails;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionPredicate;
-import org.onap.cps.ncmp.events.cmsubscription_merge1_0_0.ncmp_to_client.CmNotificationSubscriptionNcmpOutEvent;
-import org.onap.cps.ncmp.events.cmsubscription_merge1_0_0.ncmp_to_client.Data;
-import org.springframework.stereotype.Component;
-
-@Component
-@RequiredArgsConstructor
-public class CmNotificationSubscriptionNcmpOutEventMapper {
-
-    /**
-     * Mapper to form a response for the client for the Cm Notification Subscription.
-     *
-     * @param subscriptionId                          Cm Notification Subscription Id
-     * @param dmiCmNotificationSubscriptionDetailsMap contains CmNotificationSubscriptionDetails per dmi plugin
-     * @return CmNotificationSubscriptionNcmpOutEvent to sent back to the client
-     */
-    public CmNotificationSubscriptionNcmpOutEvent toCmNotificationSubscriptionNcmpOutEvent(final String subscriptionId,
-            final Map<String, DmiCmNotificationSubscriptionDetails> dmiCmNotificationSubscriptionDetailsMap) {
-
-        final CmNotificationSubscriptionNcmpOutEvent cmNotificationSubscriptionNcmpOutEvent =
-                new CmNotificationSubscriptionNcmpOutEvent();
-        final Data cmSubscriptionData = new Data();
-        cmSubscriptionData.setSubscriptionId(subscriptionId);
-        populateCmNotificationSubscriptionNcmpOutEventWithCmHandleIds(dmiCmNotificationSubscriptionDetailsMap,
-                cmSubscriptionData);
-        cmNotificationSubscriptionNcmpOutEvent.setData(cmSubscriptionData);
-
-        return cmNotificationSubscriptionNcmpOutEvent;
-    }
-
-    /**
-     * Mapper to form a rejected response for the client for the Cm Notification Subscription Request.
-     *
-     * @param subscriptionId subscription id
-     * @param rejectedTargetFilters list of rejected target filters for the subscription request
-     * @return to sent back to the client
-     */
-    public CmNotificationSubscriptionNcmpOutEvent toCmNotificationSubscriptionNcmpOutEventForRejectedRequest(
-            final String subscriptionId, final List<String> rejectedTargetFilters) {
-        final CmNotificationSubscriptionNcmpOutEvent cmNotificationSubscriptionNcmpOutEvent =
-                new CmNotificationSubscriptionNcmpOutEvent();
-        final Data cmSubscriptionData = new Data();
-        cmSubscriptionData.setSubscriptionId(subscriptionId);
-        cmSubscriptionData.setRejectedTargets(rejectedTargetFilters);
-        cmNotificationSubscriptionNcmpOutEvent.setData(cmSubscriptionData);
-        return cmNotificationSubscriptionNcmpOutEvent;
-    }
-
-    private void populateCmNotificationSubscriptionNcmpOutEventWithCmHandleIds(
-            final Map<String, DmiCmNotificationSubscriptionDetails> dmiCmNotificationSubscriptionDetailsMap,
-            final Data cmSubscriptionData) {
-
-        final List<String> acceptedCmHandleIds = new ArrayList<>();
-        final List<String> pendingCmHandleIds = new ArrayList<>();
-        final List<String> rejectedCmHandleIds = new ArrayList<>();
-
-        dmiCmNotificationSubscriptionDetailsMap.forEach((dmiPluginName, dmiCmNotificationSubscriptionDetails) -> {
-            final CmNotificationSubscriptionStatus cmNotificationSubscriptionStatus =
-                    dmiCmNotificationSubscriptionDetails.getCmNotificationSubscriptionStatus();
-            final List<DmiCmNotificationSubscriptionPredicate> dmiCmNotificationSubscriptionPredicates =
-                    dmiCmNotificationSubscriptionDetails.getDmiCmNotificationSubscriptionPredicates();
-
-            switch (cmNotificationSubscriptionStatus) {
-                case ACCEPTED -> acceptedCmHandleIds.addAll(
-                        extractCmHandleIds(dmiCmNotificationSubscriptionPredicates));
-                case PENDING -> pendingCmHandleIds.addAll(extractCmHandleIds(dmiCmNotificationSubscriptionPredicates));
-                default -> rejectedCmHandleIds.addAll(extractCmHandleIds(dmiCmNotificationSubscriptionPredicates));
-            }
-        });
-
-        cmSubscriptionData.setAcceptedTargets(acceptedCmHandleIds);
-        cmSubscriptionData.setPendingTargets(pendingCmHandleIds);
-        cmSubscriptionData.setRejectedTargets(rejectedCmHandleIds);
-
-    }
-
-    private List<String> extractCmHandleIds(
-            final List<DmiCmNotificationSubscriptionPredicate> dmiCmNotificationSubscriptionPredicates) {
-        final List<String> cmHandleIds = new ArrayList<>();
-        dmiCmNotificationSubscriptionPredicates.forEach(dmiCmNotificationSubscriptionPredicate -> cmHandleIds.addAll(
-                dmiCmNotificationSubscriptionPredicate.getTargetCmHandleIds()));
-
-        return cmHandleIds;
-    }
-
-}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/producer/CmNotificationSubscriptionNcmpOutEventProducer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/producer/CmNotificationSubscriptionNcmpOutEventProducer.java
deleted file mode 100644 (file)
index ed7ed2a..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- *  Copyright (C) 2024 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.events.cmsubscription.producer;
-
-import io.cloudevents.CloudEvent;
-import io.cloudevents.core.builder.CloudEventBuilder;
-import java.net.URI;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.onap.cps.events.EventsPublisher;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.CmNotificationSubscriptionMappersHandler;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.CmNotificationSubscriptionNcmpOutEventPublishingTask;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.DmiCmNotificationSubscriptionCacheHandler;
-import org.onap.cps.ncmp.events.cmsubscription_merge1_0_0.ncmp_to_client.CmNotificationSubscriptionNcmpOutEvent;
-import org.onap.cps.utils.JsonObjectMapper;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.stereotype.Component;
-
-@Component
-@Slf4j
-@RequiredArgsConstructor
-@ConditionalOnProperty(name = "notification.enabled", havingValue = "true", matchIfMissing = true)
-public class CmNotificationSubscriptionNcmpOutEventProducer {
-
-    @Value("${app.ncmp.avc.cm-subscription-ncmp-out}")
-    private String cmNotificationSubscriptionNcmpOutEventTopic;
-
-    @Value("${ncmp.timers.subscription-forwarding.dmi-response-timeout-ms}")
-    private Integer cmNotificationSubscriptionDmiOutEventTimeoutInMs;
-
-    private final EventsPublisher<CloudEvent> eventsPublisher;
-    private final JsonObjectMapper jsonObjectMapper;
-    private final CmNotificationSubscriptionMappersHandler cmNotificationSubscriptionMappersHandler;
-    private final DmiCmNotificationSubscriptionCacheHandler dmiCmNotificationSubscriptionCacheHandler;
-    private final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
-    private static final Map<String, ScheduledFuture<?>> scheduledTasksPerSubscriptionId = new ConcurrentHashMap<>();
-
-    /**
-     * Publish the event to the client who requested the subscription with key as subscription id and event is Cloud
-     * Event compliant.
-     *
-     * @param subscriptionId                         Cm Subscription Id
-     * @param eventType                              Type of event
-     * @param cmNotificationSubscriptionNcmpOutEvent Cm Notification Subscription Event for the
-     *                                               client
-     * @param isScheduledEvent                       Determines if the event is to be scheduled
-     *                                               or published now
-     */
-    public void publishCmNotificationSubscriptionNcmpOutEvent(final String subscriptionId, final String eventType,
-                                                              final CmNotificationSubscriptionNcmpOutEvent
-                                                                      cmNotificationSubscriptionNcmpOutEvent,
-                                                              final boolean isScheduledEvent) {
-
-        if (isScheduledEvent && !scheduledTasksPerSubscriptionId.containsKey(subscriptionId)) {
-            final ScheduledFuture<?> scheduledFuture =
-                    scheduleAndPublishCmNotificationSubscriptionNcmpOutEvent(subscriptionId, eventType);
-            scheduledTasksPerSubscriptionId.putIfAbsent(subscriptionId, scheduledFuture);
-            log.debug("Scheduled the CmNotificationSubscriptionEvent for subscriptionId : {}", subscriptionId);
-        } else {
-            cancelScheduledTaskForSubscriptionId(subscriptionId);
-            publishCmNotificationSubscriptionNcmpOutEventNow(subscriptionId, eventType,
-                    cmNotificationSubscriptionNcmpOutEvent);
-            log.info("Published CmNotificationSubscriptionEvent on demand for subscriptionId : {}", subscriptionId);
-        }
-    }
-
-    private ScheduledFuture<?> scheduleAndPublishCmNotificationSubscriptionNcmpOutEvent(final String subscriptionId,
-                                                                                        final String eventType) {
-        final CmNotificationSubscriptionNcmpOutEventPublishingTask
-                cmNotificationSubscriptionNcmpOutEventPublishingTask =
-                new CmNotificationSubscriptionNcmpOutEventPublishingTask(cmNotificationSubscriptionNcmpOutEventTopic,
-                        subscriptionId, eventType, eventsPublisher, jsonObjectMapper,
-                        cmNotificationSubscriptionMappersHandler, dmiCmNotificationSubscriptionCacheHandler);
-        return scheduledExecutorService.schedule(cmNotificationSubscriptionNcmpOutEventPublishingTask,
-                cmNotificationSubscriptionDmiOutEventTimeoutInMs, TimeUnit.MILLISECONDS);
-    }
-
-    private void cancelScheduledTaskForSubscriptionId(final String subscriptionId) {
-
-        final ScheduledFuture<?> scheduledFuture = scheduledTasksPerSubscriptionId.get(subscriptionId);
-        if (scheduledFuture != null) {
-            scheduledFuture.cancel(true);
-            scheduledTasksPerSubscriptionId.remove(subscriptionId);
-        }
-
-    }
-
-
-    private void publishCmNotificationSubscriptionNcmpOutEventNow(final String subscriptionId, final String eventType,
-                                                                  final CmNotificationSubscriptionNcmpOutEvent
-                                                                          cmNotificationSubscriptionNcmpOutEvent) {
-        final CloudEvent cmNotificationSubscriptionNcmpOutEventAsCloudEvent =
-                buildAndGetCmNotificationNcmpOutEventAsCloudEvent(jsonObjectMapper, subscriptionId, eventType,
-                        cmNotificationSubscriptionNcmpOutEvent);
-        eventsPublisher.publishCloudEvent(cmNotificationSubscriptionNcmpOutEventTopic, subscriptionId,
-                cmNotificationSubscriptionNcmpOutEventAsCloudEvent);
-        dmiCmNotificationSubscriptionCacheHandler
-                .removeAcceptedAndRejectedDmiCmNotificationSubscriptionEntries(subscriptionId);
-    }
-
-    /**
-     * Get an NCMP out event as cloud event.
-     *
-     * @param jsonObjectMapper  JSON object mapper
-     * @param subscriptionId subscription id
-     * @param eventType event type
-     * @param cmNotificationSubscriptionNcmpOutEvent cm notification subscription NCMP out event
-     * @return cm notification subscription NCMP out event as cloud event
-     */
-    public static CloudEvent buildAndGetCmNotificationNcmpOutEventAsCloudEvent(
-            final JsonObjectMapper jsonObjectMapper, final String subscriptionId, final String eventType,
-            final CmNotificationSubscriptionNcmpOutEvent cmNotificationSubscriptionNcmpOutEvent) {
-
-        return CloudEventBuilder.v1().withId(UUID.randomUUID().toString()).withType(eventType)
-                .withSource(URI.create("NCMP")).withDataSchema(URI.create("org.onap.ncmp.cm.subscription:1.0.0"))
-                .withExtension("correlationid", subscriptionId)
-                .withData(jsonObjectMapper.asJsonBytes(cmNotificationSubscriptionNcmpOutEvent)).build();
-    }
-
-}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionHandlerServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionHandlerServiceImpl.java
deleted file mode 100644 (file)
index 08e3c95..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- *  Copyright (C) 2024 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.events.cmsubscription.service;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-import lombok.RequiredArgsConstructor;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.CmNotificationSubscriptionDelta;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.CmNotificationSubscriptionEventsHandler;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.CmNotificationSubscriptionMappersHandler;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.DmiCmNotificationSubscriptionCacheHandler;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.CmNotificationSubscriptionStatus;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionDetails;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionPredicate;
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.client_to_ncmp.Predicate;
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.ncmp_to_dmi.CmNotificationSubscriptionDmiInEvent;
-import org.onap.cps.ncmp.events.cmsubscription_merge1_0_0.ncmp_to_client.CmNotificationSubscriptionNcmpOutEvent;
-import org.springframework.stereotype.Service;
-
-@Service
-@RequiredArgsConstructor
-public class CmNotificationSubscriptionHandlerServiceImpl implements CmNotificationSubscriptionHandlerService {
-
-    private final CmNotificationSubscriptionPersistenceService cmNotificationSubscriptionPersistenceService;
-    private final CmNotificationSubscriptionDelta cmNotificationSubscriptionDelta;
-    private final CmNotificationSubscriptionMappersHandler cmNotificationSubscriptionMappersHandler;
-    private final CmNotificationSubscriptionEventsHandler cmNotificationSubscriptionEventsHandler;
-    private final DmiCmNotificationSubscriptionCacheHandler dmiCmNotificationSubscriptionCacheHandler;
-
-    @Override
-    public void processSubscriptionCreateRequest(final String subscriptionId, final List<Predicate> predicates) {
-        if (cmNotificationSubscriptionPersistenceService.isUniqueSubscriptionId(subscriptionId)) {
-            dmiCmNotificationSubscriptionCacheHandler.add(subscriptionId, predicates);
-            handleCmNotificationSubscriptionDelta(subscriptionId);
-            scheduleCmNotificationSubscriptionNcmpOutEventResponse(subscriptionId,
-                    "subscriptionCreateResponse");
-        } else {
-            rejectAndPublishCmNotificationSubscriptionCreateRequest(subscriptionId, predicates);
-        }
-    }
-
-    @Override
-    public void processSubscriptionDeleteRequest(final String subscriptionId, final List<Predicate> predicates) {
-        dmiCmNotificationSubscriptionCacheHandler.add(subscriptionId, predicates);
-        sendSubscriptionDeleteRequestToDmi(subscriptionId);
-        scheduleCmNotificationSubscriptionNcmpOutEventResponse(subscriptionId, "subscriptionDeleteResponse");
-    }
-
-    private void scheduleCmNotificationSubscriptionNcmpOutEventResponse(final String subscriptionId,
-                                                                        final String eventType) {
-        cmNotificationSubscriptionEventsHandler.publishCmNotificationSubscriptionNcmpOutEvent(subscriptionId,
-                eventType, null, true);
-    }
-
-    private void rejectAndPublishCmNotificationSubscriptionCreateRequest(final String subscriptionId,
-                                                                         final List<Predicate> predicates) {
-        final Set<String> subscriptionTargetFilters =
-                predicates.stream().flatMap(predicate -> predicate.getTargetFilter().stream())
-                        .collect(Collectors.toSet());
-        final CmNotificationSubscriptionNcmpOutEvent cmNotificationSubscriptionNcmpOutEvent =
-                cmNotificationSubscriptionMappersHandler.toCmNotificationSubscriptionNcmpOutEventForRejectedRequest(
-                        subscriptionId, new ArrayList<>(subscriptionTargetFilters));
-        cmNotificationSubscriptionEventsHandler.publishCmNotificationSubscriptionNcmpOutEvent(subscriptionId,
-                "subscriptionCreateResponse", cmNotificationSubscriptionNcmpOutEvent, false);
-    }
-
-    private void handleCmNotificationSubscriptionDelta(final String subscriptionId) {
-        final Map<String, DmiCmNotificationSubscriptionDetails> dmiCmNotificationSubscriptionDetailsMap =
-                dmiCmNotificationSubscriptionCacheHandler.get(subscriptionId);
-        dmiCmNotificationSubscriptionDetailsMap.forEach((dmiPluginName, dmiCmNotificationSubscriptionDetails) -> {
-            final List<DmiCmNotificationSubscriptionPredicate> dmiCmNotificationSubscriptionPredicates =
-                    cmNotificationSubscriptionDelta.getDelta(
-                            dmiCmNotificationSubscriptionDetails.getDmiCmNotificationSubscriptionPredicates());
-
-            if (dmiCmNotificationSubscriptionPredicates.isEmpty()) {
-                acceptAndPublishCmNotificationSubscriptionNcmpOutEventPerDmi(subscriptionId, dmiPluginName);
-            } else {
-                publishCmNotificationSubscriptionDmiInEventPerDmi(subscriptionId, dmiPluginName,
-                        dmiCmNotificationSubscriptionPredicates);
-            }
-        });
-    }
-
-    private void publishCmNotificationSubscriptionDmiInEventPerDmi(final String subscriptionId,
-                                                                   final String dmiPluginName,
-                                                                   final List<DmiCmNotificationSubscriptionPredicate>
-                                                                           dmiCmNotificationSubscriptionPredicates) {
-        final CmNotificationSubscriptionDmiInEvent cmNotificationSubscriptionDmiInEvent =
-                cmNotificationSubscriptionMappersHandler.toCmNotificationSubscriptionDmiInEvent(
-                        dmiCmNotificationSubscriptionPredicates);
-        cmNotificationSubscriptionEventsHandler.publishCmNotificationSubscriptionDmiInEvent(subscriptionId,
-                dmiPluginName, "subscriptionCreateRequest", cmNotificationSubscriptionDmiInEvent);
-    }
-
-    private void acceptAndPublishCmNotificationSubscriptionNcmpOutEventPerDmi(final String subscriptionId,
-                                                                              final String dmiPluginName) {
-        dmiCmNotificationSubscriptionCacheHandler.updateDmiCmNotificationSubscriptionStatusPerDmi(subscriptionId,
-                dmiPluginName, CmNotificationSubscriptionStatus.ACCEPTED);
-        dmiCmNotificationSubscriptionCacheHandler.persistIntoDatabasePerDmi(subscriptionId, dmiPluginName);
-    }
-
-    private void sendSubscriptionDeleteRequestToDmi(final String subscriptionId) {
-        final Map<String, DmiCmNotificationSubscriptionDetails> dmiCmNotificationSubscriptionDetailsMap =
-                dmiCmNotificationSubscriptionCacheHandler.get(subscriptionId);
-        dmiCmNotificationSubscriptionDetailsMap.forEach((dmiPluginName, dmiCmNotificationSubscriptionDetails) -> {
-            final CmNotificationSubscriptionDmiInEvent cmNotificationSubscriptionDmiInEvent =
-                    cmNotificationSubscriptionMappersHandler.toCmNotificationSubscriptionDmiInEvent(
-                            dmiCmNotificationSubscriptionDetails.getDmiCmNotificationSubscriptionPredicates());
-            cmNotificationSubscriptionEventsHandler.publishCmNotificationSubscriptionDmiInEvent(subscriptionId,
-                    dmiPluginName, "subscriptionDeleteRequest", cmNotificationSubscriptionDmiInEvent);
-        });
-    }
-}
\ No newline at end of file
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionPersistenceService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionPersistenceService.java
deleted file mode 100644 (file)
index d87624c..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- *  Copyright (C) 2024 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.events.cmsubscription.service;
-
-import java.util.Collection;
-import org.onap.cps.ncmp.api.data.models.DatastoreType;
-
-public interface CmNotificationSubscriptionPersistenceService {
-
-    String NCMP_DATASPACE_NAME = "NCMP-Admin";
-    String CM_SUBSCRIPTIONS_ANCHOR_NAME = "cm-data-subscriptions";
-
-    /**
-     * Check if we have an ongoing cm subscription based on the parameters.
-     *
-     * @param datastoreType the susbcription target datastore type
-     * @param cmHandleId the id of the cm handle for the susbcription
-     * @param xpath the target xpath
-     * @return true for ongoing cmsubscription , otherwise false
-     */
-    boolean isOngoingCmNotificationSubscription(final DatastoreType datastoreType, final String cmHandleId,
-            final String xpath);
-
-    /**
-     * Check if the subscription ID is unique against ongoing subscriptions.
-     *
-     * @param subscriptionId subscription ID
-     * @return true if subscriptionId is not used in active subscriptions, otherwise false
-     */
-    boolean isUniqueSubscriptionId(final String subscriptionId);
-
-    /**
-     * Get all ongoing cm notification subscription based on the parameters.
-     *
-     * @param datastoreType the susbcription target datastore type
-     * @param cmHandleId the id of the cm handle for the susbcription
-     * @param xpath the target xpath
-     * @return collection of subscription ids of ongoing cm notification subscription
-     */
-    Collection<String> getOngoingCmNotificationSubscriptionIds(final DatastoreType datastoreType,
-            final String cmHandleId, final String xpath);
-
-    /**
-     * Add cm notification subscription.
-     *
-     * @param datastoreType the susbcription target datastore type
-     * @param cmHandleId the id of the cm handle for the susbcription
-     * @param xpath the target xpath
-     * @param newSubscriptionId subscription id to be added
-     */
-    void addCmNotificationSubscription(final DatastoreType datastoreType, final String cmHandleId,
-                                       final String xpath, final String newSubscriptionId);
-
-    /**
-     * Remove cm notification Subscription.
-     *
-     * @param datastoreType the susbcription target datastore type
-     * @param cmHandleId the id of the cm handle for the susbcription
-     * @param xpath the target xpath
-     * @param subscriptionId subscription id to remove
-     */
-    void removeCmNotificationSubscription(final DatastoreType datastoreType, final String cmHandleId,
-                                          final String xpath, final String subscriptionId);
-
-}
-
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/EventsFacade.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/EventsFacade.java
new file mode 100644 (file)
index 0000000..fbe2126
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (c) 2024 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.impl.cmnotificationsubscription;
+
+import lombok.RequiredArgsConstructor;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.dmi.DmiInEventProducer;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.ncmp.NcmpOutEventProducer;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_client.NcmpOutEvent;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_dmi.DmiInEvent;
+import org.springframework.stereotype.Component;
+
+@Component
+@RequiredArgsConstructor
+public class EventsFacade {
+    private final NcmpOutEventProducer ncmpOutEventProducer;
+    private final DmiInEventProducer dmiInEventProducer;
+
+    /**
+     * Publish the event to the client who requested the subscription with key as subscription id and event is Cloud
+     * Event compliant.
+     *
+     * @param subscriptionId                         Cm Subscription id
+     * @param eventType                              Type of event
+     * @param ncmpOutEvent Cm Notification Subscription Event for the
+     *                                               client
+     * @param isScheduledEvent                       Determines if the event is to be scheduled
+     *                                               or published now
+     */
+    public void publishNcmpOutEvent(final String subscriptionId, final String eventType,
+            final NcmpOutEvent ncmpOutEvent, final boolean isScheduledEvent) {
+        ncmpOutEventProducer.publishNcmpOutEvent(subscriptionId, eventType, ncmpOutEvent, isScheduledEvent);
+    }
+
+    /**
+     * Publish the event to the provided dmi plugin with key as subscription id and the event is in Cloud Event format.
+     *
+     * @param subscriptionId                       Cm Subscription id
+     * @param dmiPluginName                        Dmi Plugin Name
+     * @param eventType                            Type of event
+     * @param dmiInEvent Cm Notification Subscription event for Dmi
+     */
+    public void publishDmiInEvent(final String subscriptionId, final String dmiPluginName,
+            final String eventType, final DmiInEvent dmiInEvent) {
+        dmiInEventProducer.publishDmiInEvent(subscriptionId,
+                dmiPluginName, eventType, dmiInEvent);
+    }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/MappersFacade.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/MappersFacade.java
new file mode 100644 (file)
index 0000000..e79b4e6
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2024 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.impl.cmnotificationsubscription;
+
+import java.util.List;
+import java.util.Map;
+import lombok.RequiredArgsConstructor;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.dmi.DmiInEventMapper;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionDetails;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionPredicate;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.ncmp.NcmpOutEventMapper;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_client.NcmpOutEvent;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_dmi.DmiInEvent;
+import org.springframework.stereotype.Component;
+
+@Component
+@RequiredArgsConstructor
+public class MappersFacade {
+
+    private final DmiInEventMapper dmiInEventMapper;
+    private final NcmpOutEventMapper ncmpOutEventMapper;
+
+    /**
+     * Mapper to form a request for the DMI Plugin for the Cm Notification Subscription.
+     *
+     * @param dmiCmSubscriptionPredicates Collection of Cm Notification Subscription predicates
+     * @return cm notification subscription dmi in event
+     */
+    public DmiInEvent toDmiInEvent(
+            final List<DmiCmSubscriptionPredicate> dmiCmSubscriptionPredicates) {
+        return dmiInEventMapper.toDmiInEvent(dmiCmSubscriptionPredicates);
+    }
+
+    /**
+     * Mapper to form a response for the client for the Cm Notification Subscription.
+     *
+     * @param subscriptionId                          Cm Notification Subscription id
+     * @param dmiSubscriptionsPerDmi contains CmNotificationSubscriptionDetails per dmi plugin
+     * @return CmNotificationSubscriptionNcmpOutEvent to sent back to the client
+     */
+    public NcmpOutEvent toNcmpOutEvent(final String subscriptionId,
+         final Map<String, DmiCmSubscriptionDetails> dmiSubscriptionsPerDmi) {
+        return ncmpOutEventMapper.toNcmpOutEvent(subscriptionId,
+                dmiSubscriptionsPerDmi);
+    }
+
+    /**
+     * Mapper to form a rejected response for the client for the Cm Notification Subscription Request.
+     *
+     * @param subscriptionId subscription id
+     * @param rejectedTargetFilters list of rejected target filters for the subscription request
+     * @return to sent back to the client
+     */
+    public NcmpOutEvent toNcmpOutEventForRejectedRequest(
+            final String subscriptionId, final List<String> rejectedTargetFilters) {
+        return ncmpOutEventMapper.toNcmpOutEventForRejectedRequest(
+                subscriptionId, rejectedTargetFilters);
+    }
+}
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.config.embeddedcache;
+package org.onap.cps.ncmp.impl.cmnotificationsubscription.cache;
 
 import com.hazelcast.config.MapConfig;
 import com.hazelcast.map.IMap;
 import java.util.Map;
 import org.onap.cps.cache.HazelcastCacheConfig;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionDetails;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionDetails;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
 @Configuration
-public class CmNotificationSubscriptionCacheConfig extends HazelcastCacheConfig {
+public class CmSubscriptionConfig extends HazelcastCacheConfig {
 
     private static final MapConfig cmNotificationSubscriptionCacheMapConfig =
             createMapConfig("cmNotificationSubscriptionCacheMapConfig");
@@ -42,7 +42,7 @@ public class CmNotificationSubscriptionCacheConfig extends HazelcastCacheConfig
      * @return configured map of subscription events.
      */
     @Bean
-    public IMap<String, Map<String, DmiCmNotificationSubscriptionDetails>> cmNotificationSubscriptionCache() {
+    public IMap<String, Map<String, DmiCmSubscriptionDetails>> cmNotificationSubscriptionCache() {
         return createHazelcastInstance("hazelCastInstanceCmNotificationSubscription",
                 cmNotificationSubscriptionCacheMapConfig).getMap("cmNotificationSubscriptionCache");
     }
@@ -18,9 +18,9 @@
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription;
+package org.onap.cps.ncmp.impl.cmnotificationsubscription.cache;
 
-import static org.onap.cps.ncmp.api.impl.events.cmsubscription.model.CmNotificationSubscriptionStatus.PENDING;
+import static org.onap.cps.ncmp.impl.cmnotificationsubscription.models.CmSubscriptionStatus.PENDING;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -32,21 +32,21 @@ import java.util.Set;
 import java.util.stream.Collectors;
 import lombok.RequiredArgsConstructor;
 import org.onap.cps.ncmp.api.data.models.DatastoreType;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.CmNotificationSubscriptionStatus;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionDetails;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionPredicate;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.service.CmNotificationSubscriptionPersistenceService;
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.client_to_ncmp.Predicate;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.CmSubscriptionStatus;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionDetails;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionPredicate;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.utils.CmSubscriptionPersistenceService;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.client_to_ncmp.Predicate;
 import org.onap.cps.ncmp.impl.inventory.InventoryPersistence;
 import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
 import org.springframework.stereotype.Component;
 
 @Component
 @RequiredArgsConstructor
-public class DmiCmNotificationSubscriptionCacheHandler {
+public class DmiCacheHandler {
 
-    private final CmNotificationSubscriptionPersistenceService cmNotificationSubscriptionPersistenceService;
-    private final Map<String, Map<String, DmiCmNotificationSubscriptionDetails>> cmNotificationSubscriptionCache;
+    private final CmSubscriptionPersistenceService cmSubscriptionPersistenceService;
+    private final Map<String, Map<String, DmiCmSubscriptionDetails>> cmNotificationSubscriptionCache;
     private final InventoryPersistence inventoryPersistence;
 
     /**
@@ -56,7 +56,7 @@ public class DmiCmNotificationSubscriptionCacheHandler {
      * @param predicates        subscription request predicates
      */
     public void add(final String subscriptionId, final List<Predicate> predicates) {
-        cmNotificationSubscriptionCache.put(subscriptionId, createDmiCmNotificationSubscriptionsPerDmi(predicates));
+        cmNotificationSubscriptionCache.put(subscriptionId, createDmiSubscriptionsPerDmi(predicates));
     }
 
     /**
@@ -65,7 +65,7 @@ public class DmiCmNotificationSubscriptionCacheHandler {
      * @param subscriptionId    subscription id
      * @return map of dmi cm notification subscriptions per dmi
      */
-    public Map<String, DmiCmNotificationSubscriptionDetails> get(final String subscriptionId) {
+    public Map<String, DmiCmSubscriptionDetails> get(final String subscriptionId) {
         return cmNotificationSubscriptionCache.get(subscriptionId);
     }
 
@@ -75,15 +75,15 @@ public class DmiCmNotificationSubscriptionCacheHandler {
      *
      * @param subscriptionId subscription id as key in CM notification Subscription cache.
      */
-    public void removeAcceptedAndRejectedDmiCmNotificationSubscriptionEntries(final String subscriptionId) {
-        final Map<String, DmiCmNotificationSubscriptionDetails> dmiCmNotificationSubscriptionsPerDmi =
+    public void removeAcceptedAndRejectedDmiSubscriptionEntries(final String subscriptionId) {
+        final Map<String, DmiCmSubscriptionDetails> dmiSubscriptionsPerDmi =
                 cmNotificationSubscriptionCache.get(subscriptionId);
-        final Map<String, DmiCmNotificationSubscriptionDetails> updatedDmiCmNotificationSubscriptionsPerDmi =
-                dmiCmNotificationSubscriptionsPerDmi.entrySet().stream().filter(
-                                dmiCmNotificationSubscription ->
-                                        !isAcceptedOrRejected(dmiCmNotificationSubscription.getValue()))
+        final Map<String, DmiCmSubscriptionDetails> updatedDmiSubscriptionsPerDmi =
+                dmiSubscriptionsPerDmi.entrySet().stream()
+                        .filter(dmiCmNotificationSubscription -> !isAcceptedOrRejected(
+                                dmiCmNotificationSubscription.getValue()))
                         .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
-        cmNotificationSubscriptionCache.put(subscriptionId, updatedDmiCmNotificationSubscriptionsPerDmi);
+        cmNotificationSubscriptionCache.put(subscriptionId, updatedDmiSubscriptionsPerDmi);
     }
 
     /**
@@ -92,9 +92,9 @@ public class DmiCmNotificationSubscriptionCacheHandler {
      * @param predicates    CM Subscription Create Request Predicates
      * @return              Map of DmiCmNotificationSubscription per DMI plugin
      */
-    public Map<String, DmiCmNotificationSubscriptionDetails> createDmiCmNotificationSubscriptionsPerDmi(
+    public Map<String, DmiCmSubscriptionDetails> createDmiSubscriptionsPerDmi(
             final List<Predicate> predicates) {
-        final Map<String, DmiCmNotificationSubscriptionDetails> dmiCmNotificationSubscriptionDetailsPerDmi =
+        final Map<String, DmiCmSubscriptionDetails> dmiSubscriptionsPerDmi =
                 new HashMap<>();
         for (final Predicate requestPredicate : predicates) {
             final List<String> targetFilter = requestPredicate.getTargetFilter();
@@ -103,15 +103,15 @@ public class DmiCmNotificationSubscriptionCacheHandler {
             final Set<String> xpaths = new HashSet<>(requestPredicate.getScopeFilter().getXpathFilter());
             final Map<String, Set<String>> targetCmHandlesByDmiMap = groupTargetCmHandleIdsByDmi(targetFilter);
             for (final Map.Entry<String, Set<String>> targetCmHandlesByDmi: targetCmHandlesByDmiMap.entrySet()) {
-                final DmiCmNotificationSubscriptionPredicate dmiCmNotificationSubscriptionPredicate =
-                        new DmiCmNotificationSubscriptionPredicate(targetCmHandlesByDmi.getValue(),
+                final DmiCmSubscriptionPredicate dmiCmSubscriptionPredicate =
+                        new DmiCmSubscriptionPredicate(targetCmHandlesByDmi.getValue(),
                                 datastoreType, xpaths);
-                updateDmiCmNotificationSubscriptionDetailsPerDmi(targetCmHandlesByDmi.getKey(),
-                        dmiCmNotificationSubscriptionPredicate,
-                        dmiCmNotificationSubscriptionDetailsPerDmi);
+                updateDmiSubscriptionDetailsPerDmi(targetCmHandlesByDmi.getKey(),
+                        dmiCmSubscriptionPredicate,
+                        dmiSubscriptionsPerDmi);
             }
         }
-        return dmiCmNotificationSubscriptionDetailsPerDmi;
+        return dmiSubscriptionsPerDmi;
     }
 
     /**
@@ -122,13 +122,12 @@ public class DmiCmNotificationSubscriptionCacheHandler {
      * @param status            String of status
      *
      */
-    public void updateDmiCmNotificationSubscriptionStatusPerDmi(final String subscriptionId,
-                                                                final String dmiServiceName,
-                                                                final CmNotificationSubscriptionStatus status) {
-        final Map<String, DmiCmNotificationSubscriptionDetails> dmiCmNotificationSubscriptionDetailsPerDmi =
+    public void updateDmiSubscriptionStatusPerDmi(final String subscriptionId, final String dmiServiceName,
+            final CmSubscriptionStatus status) {
+        final Map<String, DmiCmSubscriptionDetails> dmiSubscriptionsPerDmi =
                 cmNotificationSubscriptionCache.get(subscriptionId);
-        dmiCmNotificationSubscriptionDetailsPerDmi.get(dmiServiceName).setCmNotificationSubscriptionStatus(status);
-        cmNotificationSubscriptionCache.put(subscriptionId, dmiCmNotificationSubscriptionDetailsPerDmi);
+        dmiSubscriptionsPerDmi.get(dmiServiceName).setCmSubscriptionStatus(status);
+        cmNotificationSubscriptionCache.put(subscriptionId, dmiSubscriptionsPerDmi);
     }
 
     /**
@@ -139,18 +138,17 @@ public class DmiCmNotificationSubscriptionCacheHandler {
      *
      */
     public void persistIntoDatabasePerDmi(final String subscriptionId, final String dmiServiceName) {
-        final List<DmiCmNotificationSubscriptionPredicate> dmiCmNotificationSubscriptionPredicateList =
+        final List<DmiCmSubscriptionPredicate> dmiCmSubscriptionPredicates =
                 cmNotificationSubscriptionCache.get(subscriptionId).get(dmiServiceName)
-                        .getDmiCmNotificationSubscriptionPredicates();
-        for (final DmiCmNotificationSubscriptionPredicate dmiCmNotificationSubscriptionPredicate:
-                dmiCmNotificationSubscriptionPredicateList) {
-            final DatastoreType datastoreType = dmiCmNotificationSubscriptionPredicate.getDatastoreType();
-            final Set<String> cmHandles = dmiCmNotificationSubscriptionPredicate.getTargetCmHandleIds();
-            final Set<String> xpaths = dmiCmNotificationSubscriptionPredicate.getXpaths();
+                        .getDmiCmSubscriptionPredicates();
+        for (final DmiCmSubscriptionPredicate dmiCmSubscriptionPredicate : dmiCmSubscriptionPredicates) {
+            final DatastoreType datastoreType = dmiCmSubscriptionPredicate.getDatastoreType();
+            final Set<String> cmHandles = dmiCmSubscriptionPredicate.getTargetCmHandleIds();
+            final Set<String> xpaths = dmiCmSubscriptionPredicate.getXpaths();
 
             for (final String cmHandle: cmHandles) {
                 for (final String xpath: xpaths) {
-                    cmNotificationSubscriptionPersistenceService.addCmNotificationSubscription(datastoreType, cmHandle,
+                    cmSubscriptionPersistenceService.addCmSubscription(datastoreType, cmHandle,
                             xpath, subscriptionId);
                 }
             }
@@ -165,35 +163,34 @@ public class DmiCmNotificationSubscriptionCacheHandler {
      *
      */
     public void removeFromDatabasePerDmi(final String subscriptionId, final String dmiServiceName) {
-        final List<DmiCmNotificationSubscriptionPredicate> dmiCmNotificationSubscriptionPredicateList =
+        final List<DmiCmSubscriptionPredicate> dmiCmSubscriptionPredicates =
                 cmNotificationSubscriptionCache.get(subscriptionId).get(dmiServiceName)
-                        .getDmiCmNotificationSubscriptionPredicates();
-        for (final DmiCmNotificationSubscriptionPredicate dmiCmNotificationSubscriptionPredicate:
-                dmiCmNotificationSubscriptionPredicateList) {
-            final DatastoreType datastoreType = dmiCmNotificationSubscriptionPredicate.getDatastoreType();
-            final Set<String> cmHandles = dmiCmNotificationSubscriptionPredicate.getTargetCmHandleIds();
-            final Set<String> xpaths = dmiCmNotificationSubscriptionPredicate.getXpaths();
+                        .getDmiCmSubscriptionPredicates();
+        for (final DmiCmSubscriptionPredicate dmiCmSubscriptionPredicate : dmiCmSubscriptionPredicates) {
+            final DatastoreType datastoreType = dmiCmSubscriptionPredicate.getDatastoreType();
+            final Set<String> cmHandles = dmiCmSubscriptionPredicate.getTargetCmHandleIds();
+            final Set<String> xpaths = dmiCmSubscriptionPredicate.getXpaths();
 
             for (final String cmHandle: cmHandles) {
                 for (final String xpath: xpaths) {
-                    cmNotificationSubscriptionPersistenceService.removeCmNotificationSubscription(datastoreType,
+                    cmSubscriptionPersistenceService.removeCmSubscription(datastoreType,
                             cmHandle, xpath, subscriptionId);
                 }
             }
         }
     }
 
-    private void updateDmiCmNotificationSubscriptionDetailsPerDmi(
+    private void updateDmiSubscriptionDetailsPerDmi(
             final String dmiServiceName,
-            final DmiCmNotificationSubscriptionPredicate dmiCmNotificationSubscriptionPredicate,
-            final Map<String, DmiCmNotificationSubscriptionDetails> dmiCmNotificationSubscriptionDetailsPerDmi) {
-        if (dmiCmNotificationSubscriptionDetailsPerDmi.containsKey(dmiServiceName)) {
-            dmiCmNotificationSubscriptionDetailsPerDmi.get(dmiServiceName)
-                    .getDmiCmNotificationSubscriptionPredicates().add(dmiCmNotificationSubscriptionPredicate);
+            final DmiCmSubscriptionPredicate dmiCmSubscriptionPredicate,
+            final Map<String, DmiCmSubscriptionDetails> dmiSubscriptionsPerDmi) {
+        if (dmiSubscriptionsPerDmi.containsKey(dmiServiceName)) {
+            dmiSubscriptionsPerDmi.get(dmiServiceName)
+                    .getDmiCmSubscriptionPredicates().add(dmiCmSubscriptionPredicate);
         } else {
-            dmiCmNotificationSubscriptionDetailsPerDmi.put(dmiServiceName,
-                    new DmiCmNotificationSubscriptionDetails(
-                            new ArrayList<>(List.of(dmiCmNotificationSubscriptionPredicate)),
+            dmiSubscriptionsPerDmi.put(dmiServiceName,
+                    new DmiCmSubscriptionDetails(
+                            new ArrayList<>(List.of(dmiCmSubscriptionPredicate)),
                             PENDING));
         }
     }
@@ -211,9 +208,8 @@ public class DmiCmNotificationSubscriptionCacheHandler {
         return targetCmHandlesByDmiServiceNames;
     }
 
-    private boolean isAcceptedOrRejected(
-            final DmiCmNotificationSubscriptionDetails dmiCmNotificationSubscription) {
-        return dmiCmNotificationSubscription.getCmNotificationSubscriptionStatus().toString().equals("ACCEPTED")
-                || dmiCmNotificationSubscription.getCmNotificationSubscriptionStatus().toString().equals("REJECTED");
+    private boolean isAcceptedOrRejected(final DmiCmSubscriptionDetails dmiCmSubscription) {
+        return dmiCmSubscription.getCmSubscriptionStatus().toString().equals("ACCEPTED")
+                       || dmiCmSubscription.getCmSubscriptionStatus().toString().equals("REJECTED");
     }
 }
@@ -18,7 +18,7 @@
  * ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.avc;
+package org.onap.cps.ncmp.impl.cmnotificationsubscription.cmavc;
 
 import io.cloudevents.CloudEvent;
 import io.cloudevents.core.builder.CloudEventBuilder;
@@ -33,13 +33,13 @@ import org.springframework.kafka.annotation.KafkaListener;
 import org.springframework.stereotype.Component;
 
 /**
- * Listener for AVC events.
+ * Listener for AVC events based on Cm Subscriptions.
  */
 @Component
 @Slf4j
 @RequiredArgsConstructor
 @ConditionalOnProperty(name = "notification.enabled", havingValue = "true", matchIfMissing = true)
-public class AvcEventConsumer {
+public class CmAvcEventConsumer {
 
 
     @Value("${app.ncmp.avc.cm-events-topic}")
@@ -50,15 +50,17 @@ public class AvcEventConsumer {
     /**
      * Incoming AvcEvent in the form of Consumer Record.
      *
-     * @param avcEventConsumerRecord Incoming raw consumer record
+     * @param cmAvcEventAsConsumerRecord Incoming raw consumer record
      */
     @KafkaListener(topics = "${app.dmi.cm-events.topic}",
             containerFactory = "cloudEventConcurrentKafkaListenerContainerFactory")
-    public void consumeAndForward(final ConsumerRecord<String, CloudEvent> avcEventConsumerRecord) {
-        log.debug("Consuming AVC event {} ...", avcEventConsumerRecord.value());
+    public void consumeAndForward(
+            final ConsumerRecord<String, CloudEvent> cmAvcEventAsConsumerRecord) {
+        log.debug("Consuming AVC event {} ...", cmAvcEventAsConsumerRecord.value());
         final String newEventId = UUID.randomUUID().toString();
         final CloudEvent outgoingAvcEvent =
-                CloudEventBuilder.from(avcEventConsumerRecord.value()).withId(newEventId).build();
+                CloudEventBuilder.from(cmAvcEventAsConsumerRecord.value()).withId(newEventId)
+                        .build();
         eventsPublisher.publishCloudEvent(cmEventsTopicName, newEventId, outgoingAvcEvent);
     }
 }
@@ -18,7 +18,7 @@
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription.mapper;
+package org.onap.cps.ncmp.impl.cmnotificationsubscription.dmi;
 
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -27,46 +27,44 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import lombok.RequiredArgsConstructor;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionPredicate;
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.ncmp_to_dmi.CmHandle;
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.ncmp_to_dmi.CmNotificationSubscriptionDmiInEvent;
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.ncmp_to_dmi.Data;
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.ncmp_to_dmi.Predicate;
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.ncmp_to_dmi.ScopeFilter;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionPredicate;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_dmi.CmHandle;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_dmi.Data;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_dmi.DmiInEvent;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_dmi.Predicate;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_dmi.ScopeFilter;
 import org.onap.cps.ncmp.impl.inventory.InventoryPersistence;
 import org.springframework.stereotype.Component;
 
 @Component
 @RequiredArgsConstructor
-public class CmNotificationSubscriptionDmiInEventMapper {
+public class DmiInEventMapper {
 
     private final InventoryPersistence inventoryPersistence;
 
     /**
      * Mapper to form a request for the DMI Plugin for the Cm Notification Subscription.
      *
-     * @param dmiCmNotificationSubscriptionPredicates Collection of Cm Notification Subscription predicates
-     * @return CmNotificationSubscriptionDmiInEvent to be sent to DMI Plugin
+     * @param dmiCmSubscriptionPredicates Collection of Cm Notification Subscription predicates
+     * @return DmiInEvent to be sent to DMI Plugin
      */
-    public CmNotificationSubscriptionDmiInEvent toCmNotificationSubscriptionDmiInEvent(
-            final List<DmiCmNotificationSubscriptionPredicate> dmiCmNotificationSubscriptionPredicates) {
-        final CmNotificationSubscriptionDmiInEvent cmNotificationSubscriptionDmiInEvent =
-                new CmNotificationSubscriptionDmiInEvent();
+    public DmiInEvent toDmiInEvent(final List<DmiCmSubscriptionPredicate> dmiCmSubscriptionPredicates) {
+        final DmiInEvent dmiInEvent = new DmiInEvent();
         final Data cmSubscriptionData = new Data();
-        cmSubscriptionData.setPredicates(mapToDmiInEventPredicates(dmiCmNotificationSubscriptionPredicates));
-        cmSubscriptionData.setCmHandles(mapToCmSubscriptionCmhandleWithPrivateProperties(
-                extractUniqueCmHandleIds(dmiCmNotificationSubscriptionPredicates)));
-        cmNotificationSubscriptionDmiInEvent.setData(cmSubscriptionData);
-        return cmNotificationSubscriptionDmiInEvent;
+        cmSubscriptionData.setPredicates(mapToDmiInEventPredicates(dmiCmSubscriptionPredicates));
+        cmSubscriptionData.setCmHandles(mapToCmSubscriptionCmHandleWithPrivateProperties(
+                extractUniqueCmHandleIds(dmiCmSubscriptionPredicates)));
+        dmiInEvent.setData(cmSubscriptionData);
+        return dmiInEvent;
 
     }
 
     private List<Predicate> mapToDmiInEventPredicates(
-            final List<DmiCmNotificationSubscriptionPredicate> dmiCmNotificationSubscriptionPredicates) {
+            final List<DmiCmSubscriptionPredicate> dmiCmSubscriptionPredicates) {
 
         final List<Predicate> predicates = new ArrayList<>();
 
-        dmiCmNotificationSubscriptionPredicates.forEach(dmiCmNotificationSubscriptionPredicate -> {
+        dmiCmSubscriptionPredicates.forEach(dmiCmNotificationSubscriptionPredicate -> {
             final Predicate predicate = new Predicate();
             final ScopeFilter scopeFilter = new ScopeFilter();
             scopeFilter.setDatastore(ScopeFilter.Datastore.fromValue(
@@ -81,7 +79,7 @@ public class CmNotificationSubscriptionDmiInEventMapper {
 
     }
 
-    private List<CmHandle> mapToCmSubscriptionCmhandleWithPrivateProperties(final Set<String> cmHandleIds) {
+    private List<CmHandle> mapToCmSubscriptionCmHandleWithPrivateProperties(final Set<String> cmHandleIds) {
 
         final List<CmHandle> cmSubscriptionCmHandles = new ArrayList<>();
 
@@ -99,11 +97,10 @@ public class CmNotificationSubscriptionDmiInEventMapper {
 
     }
 
-    private Set<String> extractUniqueCmHandleIds(
-            final List<DmiCmNotificationSubscriptionPredicate> dmiCmNotificationSubscriptionPredicates) {
+    private Set<String> extractUniqueCmHandleIds(final List<DmiCmSubscriptionPredicate> dmiCmSubscriptionPredicates) {
 
         final Set<String> cmHandleIds = new HashSet<>();
-        dmiCmNotificationSubscriptionPredicates.forEach(dmiCmNotificationSubscriptionPredicate -> cmHandleIds.addAll(
+        dmiCmSubscriptionPredicates.forEach(dmiCmNotificationSubscriptionPredicate -> cmHandleIds.addAll(
                 dmiCmNotificationSubscriptionPredicate.getTargetCmHandleIds()));
         return cmHandleIds;
     }
@@ -18,7 +18,7 @@
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription.producer;
+package org.onap.cps.ncmp.impl.cmnotificationsubscription.dmi;
 
 import io.cloudevents.CloudEvent;
 import io.cloudevents.core.builder.CloudEventBuilder;
@@ -26,7 +26,7 @@ import java.net.URI;
 import java.util.UUID;
 import lombok.RequiredArgsConstructor;
 import org.onap.cps.events.EventsPublisher;
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.ncmp_to_dmi.CmNotificationSubscriptionDmiInEvent;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_dmi.DmiInEvent;
 import org.onap.cps.utils.JsonObjectMapper;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -35,38 +35,36 @@ import org.springframework.stereotype.Component;
 @Component
 @RequiredArgsConstructor
 @ConditionalOnProperty(name = "notification.enabled", havingValue = "true", matchIfMissing = true)
-public class CmNotificationSubscriptionDmiInEventProducer {
+public class DmiInEventProducer {
 
     private final EventsPublisher<CloudEvent> eventsPublisher;
     private final JsonObjectMapper jsonObjectMapper;
 
     @Value("${app.ncmp.avc.cm-subscription-dmi-in}")
-    private String cmNotificationSubscriptionDmiInEventTopic;
+    private String dmiInEventTopic;
 
     /**
      * Publish the event to the provided dmi plugin with key as subscription id and the event is in Cloud Event format.
      *
-     * @param subscriptionId                       Cm Subscription Id
-     * @param dmiPluginName                        Dmi Plugin Name
-     * @param eventType                            Type of event
-     * @param cmNotificationSubscriptionDmiInEvent Cm Notification Subscription event for Dmi
+     * @param subscriptionId Cm Subscription Id
+     * @param dmiPluginName  Dmi Plugin Name
+     * @param eventType      Type of event
+     * @param dmiInEvent     Cm Notification Subscription event for Dmi
      */
-    public void publishCmNotificationSubscriptionDmiInEvent(final String subscriptionId, final String dmiPluginName,
-            final String eventType, final CmNotificationSubscriptionDmiInEvent cmNotificationSubscriptionDmiInEvent) {
-        eventsPublisher.publishCloudEvent(cmNotificationSubscriptionDmiInEventTopic, subscriptionId,
-                buildAndGetCmNotificationDmiInEventAsCloudEvent(subscriptionId, dmiPluginName, eventType,
-                        cmNotificationSubscriptionDmiInEvent));
+    public void publishDmiInEvent(final String subscriptionId, final String dmiPluginName,
+            final String eventType, final DmiInEvent dmiInEvent) {
+        eventsPublisher.publishCloudEvent(dmiInEventTopic, subscriptionId,
+                buildAndGetDmiInEventAsCloudEvent(subscriptionId, dmiPluginName, eventType, dmiInEvent));
 
     }
 
-    private CloudEvent buildAndGetCmNotificationDmiInEventAsCloudEvent(final String subscriptionId,
-            final String dmiPluginName, final String eventType,
-            final CmNotificationSubscriptionDmiInEvent cmNotificationSubscriptionDmiInEvent) {
+    private CloudEvent buildAndGetDmiInEventAsCloudEvent(final String subscriptionId,
+            final String dmiPluginName, final String eventType, final DmiInEvent dmiInEvent) {
         return CloudEventBuilder.v1().withId(UUID.randomUUID().toString()).withType(eventType)
                        .withSource(URI.create("NCMP"))
                        .withDataSchema(URI.create("org.onap.ncmp.dmi.cm.subscription:1.0.0"))
                        .withExtension("correlationid", subscriptionId.concat("#").concat(dmiPluginName))
-                       .withData(jsonObjectMapper.asJsonBytes(cmNotificationSubscriptionDmiInEvent)).build();
+                       .withData(jsonObjectMapper.asJsonBytes(dmiInEvent)).build();
     }
 
 
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiOutEventConsumer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiOutEventConsumer.java
new file mode 100644 (file)
index 0000000..2a45818
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2024 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.impl.cmnotificationsubscription.dmi;
+
+import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_DATA_SUBSCRIPTION_ACCEPTED;
+import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_DATA_SUBSCRIPTION_REJECTED;
+import static org.onap.cps.ncmp.utils.events.CloudEventMapper.toTargetEvent;
+
+import io.cloudevents.CloudEvent;
+import java.util.Map;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.kafka.clients.consumer.ConsumerRecord;
+import org.onap.cps.ncmp.api.NcmpResponseStatus;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.EventsFacade;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.MappersFacade;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.cache.DmiCacheHandler;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.CmSubscriptionStatus;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionDetails;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.dmi_to_ncmp.Data;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.dmi_to_ncmp.DmiOutEvent;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_client.NcmpOutEvent;
+import org.springframework.kafka.annotation.KafkaListener;
+import org.springframework.stereotype.Component;
+
+@Component
+@Slf4j
+@RequiredArgsConstructor
+public class DmiOutEventConsumer {
+
+    private final DmiCacheHandler dmiCacheHandler;
+    private final EventsFacade eventsFacade;
+    private final MappersFacade mappersFacade;
+
+    private static final String CM_SUBSCRIPTION_CORRELATION_ID_SEPARATOR = "#";
+
+    /**
+     * Consume the Cm Notification Subscription event from the dmi-plugin.
+     *
+     * @param dmiOutEventAsConsumerRecord the event to be consumed
+     */
+    @KafkaListener(topics = "${app.ncmp.avc.cm-subscription-dmi-out}",
+            containerFactory = "cloudEventConcurrentKafkaListenerContainerFactory")
+    public void consumeDmiOutEvent(final ConsumerRecord<String, CloudEvent> dmiOutEventAsConsumerRecord) {
+        final CloudEvent cloudEvent = dmiOutEventAsConsumerRecord.value();
+        final DmiOutEvent dmiOutEvent = toTargetEvent(cloudEvent, DmiOutEvent.class);
+        final String correlationId = String.valueOf(cloudEvent.getExtension("correlationid"));
+        if (dmiOutEvent != null && correlationId != null) {
+            final String eventType = cloudEvent.getType();
+            handleDmiOutEvent(correlationId, eventType, dmiOutEvent);
+        }
+    }
+
+    private void handleDmiOutEvent(final String correlationId, final String eventType,
+            final DmiOutEvent dmiOutEvent) {
+        final String subscriptionId = correlationId.split(CM_SUBSCRIPTION_CORRELATION_ID_SEPARATOR)[0];
+        final String dmiPluginName = correlationId.split(CM_SUBSCRIPTION_CORRELATION_ID_SEPARATOR)[1];
+
+        if (checkStatusCodeAndMessage(CM_DATA_SUBSCRIPTION_ACCEPTED, dmiOutEvent.getData())) {
+            handleCacheStatusPerDmi(subscriptionId, dmiPluginName, CmSubscriptionStatus.ACCEPTED);
+            if (eventType.equals("subscriptionCreateResponse")) {
+                dmiCacheHandler.persistIntoDatabasePerDmi(subscriptionId, dmiPluginName);
+            }
+            if (eventType.equals("subscriptionDeleteResponse")) {
+                dmiCacheHandler.removeFromDatabasePerDmi(subscriptionId, dmiPluginName);
+            }
+            handleEventsStatusPerDmi(subscriptionId, eventType);
+        }
+
+        if (checkStatusCodeAndMessage(CM_DATA_SUBSCRIPTION_REJECTED, dmiOutEvent.getData())) {
+            handleCacheStatusPerDmi(subscriptionId, dmiPluginName, CmSubscriptionStatus.REJECTED);
+            handleEventsStatusPerDmi(subscriptionId, eventType);
+        }
+
+        log.info("Cm Subscription with id : {} handled by the dmi-plugin : {} has the status : {}", subscriptionId,
+                dmiPluginName, dmiOutEvent.getData().getStatusMessage());
+    }
+
+    private void handleCacheStatusPerDmi(final String subscriptionId, final String dmiPluginName,
+            final CmSubscriptionStatus cmSubscriptionStatus) {
+        dmiCacheHandler.updateDmiSubscriptionStatusPerDmi(subscriptionId, dmiPluginName,
+                cmSubscriptionStatus);
+    }
+
+    private void handleEventsStatusPerDmi(final String subscriptionId, final String eventType) {
+        final Map<String, DmiCmSubscriptionDetails> dmiSubscriptionsPerDmi =
+                dmiCacheHandler.get(subscriptionId);
+        final NcmpOutEvent ncmpOutEvent = mappersFacade.toNcmpOutEvent(subscriptionId,
+                dmiSubscriptionsPerDmi);
+        eventsFacade.publishNcmpOutEvent(subscriptionId, eventType,
+                ncmpOutEvent, false);
+    }
+
+    private boolean checkStatusCodeAndMessage(final NcmpResponseStatus ncmpResponseStatus,
+            final Data dmiOutData) {
+        return ncmpResponseStatus.getCode().equals(dmiOutData.getStatusCode())
+                       && ncmpResponseStatus.getMessage()
+                                  .equals(dmiOutData.getStatusMessage());
+    }
+}
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription.model;
+package org.onap.cps.ncmp.impl.cmnotificationsubscription.models;
 
-public enum CmNotificationSubscriptionStatus {
+public enum CmSubscriptionStatus {
 
     ACCEPTED("ACCEPTED"), REJECTED("REJECTED"), PENDING("PENDING");
 
     private final String cmNotificationSubscriptionStatusValue;
 
-    CmNotificationSubscriptionStatus(final String cmNotificationSubscriptionStatusValue) {
+    CmSubscriptionStatus(final String cmNotificationSubscriptionStatusValue) {
         this.cmNotificationSubscriptionStatusValue = cmNotificationSubscriptionStatusValue;
     }
 }
@@ -18,7 +18,7 @@
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription.model;
+package org.onap.cps.ncmp.impl.cmnotificationsubscription.models;
 
 import java.util.List;
 import lombok.AllArgsConstructor;
@@ -28,8 +28,8 @@ import lombok.Setter;
 @Getter
 @Setter
 @AllArgsConstructor
-public class DmiCmNotificationSubscriptionDetails {
+public class DmiCmSubscriptionDetails {
 
-    private List<DmiCmNotificationSubscriptionPredicate> dmiCmNotificationSubscriptionPredicates;
-    private CmNotificationSubscriptionStatus cmNotificationSubscriptionStatus;
+    private List<DmiCmSubscriptionPredicate> dmiCmSubscriptionPredicates;
+    private CmSubscriptionStatus cmSubscriptionStatus;
 }
@@ -18,7 +18,7 @@
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription.model;
+package org.onap.cps.ncmp.impl.cmnotificationsubscription.models;
 
 import java.util.Set;
 import lombok.AllArgsConstructor;
@@ -29,7 +29,7 @@ import org.onap.cps.ncmp.api.data.models.DatastoreType;
 @Getter
 @Setter
 @AllArgsConstructor
-public class DmiCmNotificationSubscriptionPredicate {
+public class DmiCmSubscriptionPredicate {
 
     private Set<String> targetCmHandleIds;
     private DatastoreType datastoreType;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/CmSubscriptionComparator.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/CmSubscriptionComparator.java
new file mode 100644 (file)
index 0000000..d7f15a2
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2024 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.impl.cmnotificationsubscription.ncmp;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import lombok.RequiredArgsConstructor;
+import org.onap.cps.ncmp.api.data.models.DatastoreType;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionPredicate;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.utils.CmSubscriptionPersistenceService;
+import org.springframework.stereotype.Component;
+
+@Component
+@RequiredArgsConstructor
+public class CmSubscriptionComparator {
+
+    private final CmSubscriptionPersistenceService cmSubscriptionPersistenceService;
+
+    /**
+     * Get the new Dmi Predicates for a given predicates list.
+     *
+     * @param existingDmiCmSubscriptionPredicates list of DmiCmNotificationSubscriptionPredicates
+     * @return new list of DmiCmNotificationSubscriptionPredicates
+     */
+    public List<DmiCmSubscriptionPredicate> getNewDmiSubscriptionPredicates(
+            final List<DmiCmSubscriptionPredicate> existingDmiCmSubscriptionPredicates) {
+        final List<DmiCmSubscriptionPredicate> newDmiCmSubscriptionPredicates =
+                new ArrayList<>();
+
+        for (final DmiCmSubscriptionPredicate dmiCmSubscriptionPredicate : existingDmiCmSubscriptionPredicates) {
+
+            final Set<String> targetCmHandleIds = new HashSet<>();
+            final Set<String> xpaths = new HashSet<>();
+            final DatastoreType datastoreType = dmiCmSubscriptionPredicate.getDatastoreType();
+
+            for (final String cmHandleId : dmiCmSubscriptionPredicate.getTargetCmHandleIds()) {
+                for (final String xpath : dmiCmSubscriptionPredicate.getXpaths()) {
+                    if (!cmSubscriptionPersistenceService.isOngoingCmSubscription(datastoreType,
+                            cmHandleId, xpath)) {
+                        xpaths.add(xpath);
+                        targetCmHandleIds.add(cmHandleId);
+
+                    }
+                }
+            }
+
+            populateValidDmiSubscriptionPredicates(targetCmHandleIds, xpaths, datastoreType,
+                    newDmiCmSubscriptionPredicates);
+        }
+        return newDmiCmSubscriptionPredicates;
+    }
+
+    private void populateValidDmiSubscriptionPredicates(final Set<String> targetCmHandleIds,
+            final Set<String> xpaths, final DatastoreType datastoreType,
+            final List<DmiCmSubscriptionPredicate> dmiCmSubscriptionPredicates) {
+        if (!(targetCmHandleIds.isEmpty() || xpaths.isEmpty())) {
+            final DmiCmSubscriptionPredicate dmiCmSubscriptionPredicate =
+                    new DmiCmSubscriptionPredicate(targetCmHandleIds, datastoreType, xpaths);
+            dmiCmSubscriptionPredicates.add(dmiCmSubscriptionPredicate);
+        }
+    }
+
+}
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription.service;
+package org.onap.cps.ncmp.impl.cmnotificationsubscription.ncmp;
 
 import java.util.List;
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.client_to_ncmp.Predicate;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.client_to_ncmp.Predicate;
 
-public interface CmNotificationSubscriptionHandlerService {
+public interface CmSubscriptionHandler {
 
     /**
      * Process cm notification subscription create request.
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/CmSubscriptionHandlerImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/CmSubscriptionHandlerImpl.java
new file mode 100644 (file)
index 0000000..e225b70
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2024 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.impl.cmnotificationsubscription.ncmp;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import lombok.RequiredArgsConstructor;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.EventsFacade;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.MappersFacade;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.cache.DmiCacheHandler;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.CmSubscriptionStatus;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionDetails;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionPredicate;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.utils.CmSubscriptionPersistenceService;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.client_to_ncmp.Predicate;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_client.NcmpOutEvent;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_dmi.DmiInEvent;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class CmSubscriptionHandlerImpl implements CmSubscriptionHandler {
+
+    private final CmSubscriptionPersistenceService cmSubscriptionPersistenceService;
+    private final CmSubscriptionComparator cmSubscriptionComparator;
+    private final MappersFacade mappersFacade;
+    private final EventsFacade eventsFacade;
+    private final DmiCacheHandler dmiCacheHandler;
+
+    @Override
+    public void processSubscriptionCreateRequest(final String subscriptionId, final List<Predicate> predicates) {
+        if (cmSubscriptionPersistenceService.isUniqueSubscriptionId(subscriptionId)) {
+            dmiCacheHandler.add(subscriptionId, predicates);
+            handleNewCmSubscription(subscriptionId);
+            scheduleNcmpOutEventResponse(subscriptionId, "subscriptionCreateResponse");
+        } else {
+            rejectAndPublishCreateRequest(subscriptionId, predicates);
+        }
+    }
+
+    @Override
+    public void processSubscriptionDeleteRequest(final String subscriptionId, final List<Predicate> predicates) {
+        dmiCacheHandler.add(subscriptionId, predicates);
+        sendSubscriptionDeleteRequestToDmi(subscriptionId);
+        scheduleNcmpOutEventResponse(subscriptionId, "subscriptionDeleteResponse");
+    }
+
+    private void scheduleNcmpOutEventResponse(final String subscriptionId, final String eventType) {
+        eventsFacade.publishNcmpOutEvent(subscriptionId, eventType, null, true);
+    }
+
+    private void rejectAndPublishCreateRequest(final String subscriptionId, final List<Predicate> predicates) {
+        final Set<String> subscriptionTargetFilters =
+                predicates.stream().flatMap(predicate -> predicate.getTargetFilter().stream())
+                        .collect(Collectors.toSet());
+        final NcmpOutEvent ncmpOutEvent = mappersFacade.toNcmpOutEventForRejectedRequest(subscriptionId,
+                new ArrayList<>(subscriptionTargetFilters));
+        eventsFacade.publishNcmpOutEvent(subscriptionId, "subscriptionCreateResponse", ncmpOutEvent, false);
+    }
+
+    private void handleNewCmSubscription(final String subscriptionId) {
+        final Map<String, DmiCmSubscriptionDetails> dmiSubscriptionsPerDmi =
+                dmiCacheHandler.get(subscriptionId);
+        dmiSubscriptionsPerDmi.forEach((dmiPluginName, dmiSubscriptionDetails) -> {
+            final List<DmiCmSubscriptionPredicate> dmiCmSubscriptionPredicates =
+                    cmSubscriptionComparator.getNewDmiSubscriptionPredicates(
+                            dmiSubscriptionDetails.getDmiCmSubscriptionPredicates());
+
+            if (dmiCmSubscriptionPredicates.isEmpty()) {
+                acceptAndPublishNcmpOutEventPerDmi(subscriptionId, dmiPluginName);
+            } else {
+                publishDmiInEventPerDmi(subscriptionId, dmiPluginName, dmiCmSubscriptionPredicates);
+            }
+        });
+    }
+
+    private void publishDmiInEventPerDmi(final String subscriptionId, final String dmiPluginName,
+            final List<DmiCmSubscriptionPredicate> dmiCmSubscriptionPredicates) {
+        final DmiInEvent dmiInEvent = mappersFacade.toDmiInEvent(dmiCmSubscriptionPredicates);
+        eventsFacade.publishDmiInEvent(subscriptionId, dmiPluginName,
+                "subscriptionCreateRequest", dmiInEvent);
+    }
+
+    private void acceptAndPublishNcmpOutEventPerDmi(final String subscriptionId, final String dmiPluginName) {
+        dmiCacheHandler.updateDmiSubscriptionStatusPerDmi(subscriptionId, dmiPluginName,
+                CmSubscriptionStatus.ACCEPTED);
+        dmiCacheHandler.persistIntoDatabasePerDmi(subscriptionId, dmiPluginName);
+    }
+
+    private void sendSubscriptionDeleteRequestToDmi(final String subscriptionId) {
+        final Map<String, DmiCmSubscriptionDetails> dmiSubscriptionsPerDmi =
+                dmiCacheHandler.get(subscriptionId);
+        dmiSubscriptionsPerDmi.forEach((dmiPluginName, dmiSubscriptionDetails) -> {
+            final DmiInEvent dmiInEvent = mappersFacade.toDmiInEvent(
+                    dmiSubscriptionDetails.getDmiCmSubscriptionPredicates());
+            eventsFacade.publishDmiInEvent(subscriptionId, dmiPluginName,
+                    "subscriptionDeleteRequest", dmiInEvent);
+        });
+    }
+}
\ No newline at end of file
@@ -18,7 +18,7 @@
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription.consumer;
+package org.onap.cps.ncmp.impl.cmnotificationsubscription.ncmp;
 
 import static org.onap.cps.ncmp.utils.events.CloudEventMapper.toTargetEvent;
 
@@ -27,44 +27,43 @@ import java.util.List;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.kafka.clients.consumer.ConsumerRecord;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.service.CmNotificationSubscriptionHandlerService;
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.client_to_ncmp.CmNotificationSubscriptionNcmpInEvent;
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.client_to_ncmp.Predicate;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.client_to_ncmp.NcmpInEvent;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.client_to_ncmp.Predicate;
 import org.springframework.kafka.annotation.KafkaListener;
 import org.springframework.stereotype.Component;
 
 @Component
 @Slf4j
 @RequiredArgsConstructor
-public class CmNotificationSubscriptionNcmpInEventConsumer {
+public class NcmpInEventConsumer {
 
-    private final CmNotificationSubscriptionHandlerService cmNotificationSubscriptionHandlerService;
+    private final CmSubscriptionHandler cmSubscriptionHandler;
 
     /**
      * Consume the specified event.
      *
-     * @param subscriptionEventConsumerRecord the event to be consumed
+     * @param ncmpInEventAsConsumerRecord the event to be consumed
      */
     @KafkaListener(topics = "${app.ncmp.avc.cm-subscription-ncmp-in}",
             containerFactory = "cloudEventConcurrentKafkaListenerContainerFactory")
-    public void consumeSubscriptionEvent(final ConsumerRecord<String, CloudEvent> subscriptionEventConsumerRecord) {
-        final CloudEvent cloudEvent = subscriptionEventConsumerRecord.value();
-        final CmNotificationSubscriptionNcmpInEvent cmNotificationSubscriptionNcmpInEvent =
-                toTargetEvent(cloudEvent, CmNotificationSubscriptionNcmpInEvent.class);
+    public void consumeSubscriptionEvent(final ConsumerRecord<String, CloudEvent> ncmpInEventAsConsumerRecord) {
+        final CloudEvent cloudEvent = ncmpInEventAsConsumerRecord.value();
+        final NcmpInEvent ncmpInEvent =
+                toTargetEvent(cloudEvent, NcmpInEvent.class);
         log.info("Subscription with name {} to be mapped to hazelcast object...",
-                cmNotificationSubscriptionNcmpInEvent.getData().getSubscriptionId());
+                ncmpInEvent.getData().getSubscriptionId());
 
-        final String subscriptionId = cmNotificationSubscriptionNcmpInEvent.getData().getSubscriptionId();
-        final List<Predicate> predicates = cmNotificationSubscriptionNcmpInEvent.getData().getPredicates();
+        final String subscriptionId = ncmpInEvent.getData().getSubscriptionId();
+        final List<Predicate> predicates = ncmpInEvent.getData().getPredicates();
         if ("subscriptionCreateRequest".equals(cloudEvent.getType())) {
             log.info("Subscription create request for source {} with subscription id {} ...",
                     cloudEvent.getSource(), subscriptionId);
-            cmNotificationSubscriptionHandlerService.processSubscriptionCreateRequest(subscriptionId, predicates);
+            cmSubscriptionHandler.processSubscriptionCreateRequest(subscriptionId, predicates);
         }
         if ("subscriptionDeleteRequest".equals(cloudEvent.getType())) {
             log.info("Subscription delete request for source {} with subscription id {} ...",
                     cloudEvent.getSource(), subscriptionId);
-            cmNotificationSubscriptionHandlerService.processSubscriptionDeleteRequest(subscriptionId, predicates);
+            cmSubscriptionHandler.processSubscriptionDeleteRequest(subscriptionId, predicates);
         }
     }
 }
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventMapper.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventMapper.java
new file mode 100644 (file)
index 0000000..ffd4b01
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2024 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.impl.cmnotificationsubscription.ncmp;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import lombok.RequiredArgsConstructor;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.CmSubscriptionStatus;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionDetails;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionPredicate;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_client.Data;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_client.NcmpOutEvent;
+import org.springframework.stereotype.Component;
+
+@Component
+@RequiredArgsConstructor
+public class NcmpOutEventMapper {
+
+    /**
+     * Mapper to form a response for the client for the Cm Notification Subscription.
+     *
+     * @param subscriptionId                          Cm Notification Subscription Id
+     * @param dmiSubscriptionsPerDmi contains CmNotificationSubscriptionDetails per dmi plugin
+     * @return CmNotificationSubscriptionNcmpOutEvent to sent back to the client
+     */
+    public NcmpOutEvent toNcmpOutEvent(final String subscriptionId,
+            final Map<String, DmiCmSubscriptionDetails> dmiSubscriptionsPerDmi) {
+
+        final NcmpOutEvent ncmpOutEvent = new NcmpOutEvent();
+        final Data cmSubscriptionData = new Data();
+        cmSubscriptionData.setSubscriptionId(subscriptionId);
+        populateNcmpOutEventWithCmHandleIds(dmiSubscriptionsPerDmi,
+                cmSubscriptionData);
+        ncmpOutEvent.setData(cmSubscriptionData);
+
+        return ncmpOutEvent;
+    }
+
+    /**
+     * Mapper to form a rejected response for the client for the Cm Notification Subscription Request.
+     *
+     * @param subscriptionId subscription id
+     * @param rejectedTargetFilters list of rejected target filters for the subscription request
+     * @return to sent back to the client
+     */
+    public NcmpOutEvent toNcmpOutEventForRejectedRequest(final String subscriptionId,
+            final List<String> rejectedTargetFilters) {
+        final NcmpOutEvent ncmpOutEvent = new NcmpOutEvent();
+        final Data cmSubscriptionData = new Data();
+        cmSubscriptionData.setSubscriptionId(subscriptionId);
+        cmSubscriptionData.setRejectedTargets(rejectedTargetFilters);
+        ncmpOutEvent.setData(cmSubscriptionData);
+        return ncmpOutEvent;
+    }
+
+    private void populateNcmpOutEventWithCmHandleIds(
+            final Map<String, DmiCmSubscriptionDetails> dmiSubscriptionsPerDmi,
+            final Data cmSubscriptionData) {
+
+        final List<String> acceptedCmHandleIds = new ArrayList<>();
+        final List<String> pendingCmHandleIds = new ArrayList<>();
+        final List<String> rejectedCmHandleIds = new ArrayList<>();
+
+        dmiSubscriptionsPerDmi.forEach((dmiPluginName, dmiSubscriptionDetails) -> {
+            final CmSubscriptionStatus cmSubscriptionStatus =
+                    dmiSubscriptionDetails.getCmSubscriptionStatus();
+            final List<DmiCmSubscriptionPredicate> dmiCmSubscriptionPredicates =
+                    dmiSubscriptionDetails.getDmiCmSubscriptionPredicates();
+
+            switch (cmSubscriptionStatus) {
+                case ACCEPTED -> acceptedCmHandleIds.addAll(
+                        extractCmHandleIds(dmiCmSubscriptionPredicates));
+                case PENDING -> pendingCmHandleIds.addAll(extractCmHandleIds(dmiCmSubscriptionPredicates));
+                default -> rejectedCmHandleIds.addAll(extractCmHandleIds(dmiCmSubscriptionPredicates));
+            }
+        });
+
+        cmSubscriptionData.setAcceptedTargets(acceptedCmHandleIds);
+        cmSubscriptionData.setPendingTargets(pendingCmHandleIds);
+        cmSubscriptionData.setRejectedTargets(rejectedCmHandleIds);
+
+    }
+
+    private List<String> extractCmHandleIds(
+            final List<DmiCmSubscriptionPredicate> dmiCmSubscriptionPredicates) {
+        final List<String> cmHandleIds = new ArrayList<>();
+        dmiCmSubscriptionPredicates.forEach(dmiSubscriptionPredicate -> cmHandleIds.addAll(
+                dmiSubscriptionPredicate.getTargetCmHandleIds()));
+
+        return cmHandleIds;
+    }
+
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventProducer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventProducer.java
new file mode 100644 (file)
index 0000000..92800f4
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2024 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.impl.cmnotificationsubscription.ncmp;
+
+import io.cloudevents.CloudEvent;
+import io.cloudevents.core.builder.CloudEventBuilder;
+import java.net.URI;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.events.EventsPublisher;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.MappersFacade;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.cache.DmiCacheHandler;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_client.NcmpOutEvent;
+import org.onap.cps.utils.JsonObjectMapper;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Component;
+
+@Component
+@Slf4j
+@RequiredArgsConstructor
+@ConditionalOnProperty(name = "notification.enabled", havingValue = "true", matchIfMissing = true)
+public class NcmpOutEventProducer {
+
+    @Value("${app.ncmp.avc.cm-subscription-ncmp-out}")
+    private String ncmpOutEventTopic;
+
+    @Value("${ncmp.timers.subscription-forwarding.dmi-response-timeout-ms}")
+    private Integer dmiOutEventTimeoutInMs;
+
+    private final EventsPublisher<CloudEvent> eventsPublisher;
+    private final JsonObjectMapper jsonObjectMapper;
+    private final MappersFacade mappersFacade;
+    private final DmiCacheHandler dmiCacheHandler;
+    private final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
+    private static final Map<String, ScheduledFuture<?>> scheduledTasksPerSubscriptionId = new ConcurrentHashMap<>();
+
+    /**
+     * Publish the event to the client who requested the subscription with key as subscription id and event is Cloud
+     * Event compliant.
+     *
+     * @param subscriptionId   Cm Subscription Id
+     * @param eventType        Type of event
+     * @param ncmpOutEvent     Cm Notification Subscription Event for the
+     *                         client
+     * @param isScheduledEvent Determines if the event is to be scheduled
+     *                         or published now
+     */
+    public void publishNcmpOutEvent(final String subscriptionId, final String eventType,
+            final NcmpOutEvent ncmpOutEvent, final boolean isScheduledEvent) {
+
+        if (isScheduledEvent && !scheduledTasksPerSubscriptionId.containsKey(subscriptionId)) {
+            final ScheduledFuture<?> scheduledFuture = scheduleAndPublishNcmpOutEvent(subscriptionId, eventType);
+            scheduledTasksPerSubscriptionId.putIfAbsent(subscriptionId, scheduledFuture);
+            log.debug("Scheduled the CmNotificationSubscriptionEvent for subscriptionId : {}", subscriptionId);
+        } else {
+            cancelScheduledTaskForSubscriptionId(subscriptionId);
+            publishNcmpOutEventNow(subscriptionId, eventType, ncmpOutEvent);
+            log.info("Published CmNotificationSubscriptionEvent on demand for subscriptionId : {}", subscriptionId);
+        }
+    }
+
+    private ScheduledFuture<?> scheduleAndPublishNcmpOutEvent(final String subscriptionId, final String eventType) {
+        final NcmpOutEventPublishingTask ncmpOutEventPublishingTask =
+                new NcmpOutEventPublishingTask(ncmpOutEventTopic, subscriptionId, eventType, eventsPublisher,
+                        jsonObjectMapper, mappersFacade, dmiCacheHandler);
+        return scheduledExecutorService.schedule(ncmpOutEventPublishingTask, dmiOutEventTimeoutInMs,
+                TimeUnit.MILLISECONDS);
+    }
+
+    private void cancelScheduledTaskForSubscriptionId(final String subscriptionId) {
+
+        final ScheduledFuture<?> scheduledFuture = scheduledTasksPerSubscriptionId.get(subscriptionId);
+        if (scheduledFuture != null) {
+            scheduledFuture.cancel(true);
+            scheduledTasksPerSubscriptionId.remove(subscriptionId);
+        }
+
+    }
+
+
+    private void publishNcmpOutEventNow(final String subscriptionId, final String eventType,
+            final NcmpOutEvent ncmpOutEvent) {
+        final CloudEvent ncmpOutEventAsCloudEvent =
+                buildAndGetNcmpOutEventAsCloudEvent(jsonObjectMapper, subscriptionId, eventType,
+                        ncmpOutEvent);
+        eventsPublisher.publishCloudEvent(ncmpOutEventTopic, subscriptionId,
+                ncmpOutEventAsCloudEvent);
+        dmiCacheHandler.removeAcceptedAndRejectedDmiSubscriptionEntries(subscriptionId);
+    }
+
+    /**
+     * Get an NCMP out event as cloud event.
+     *
+     * @param jsonObjectMapper JSON object mapper
+     * @param subscriptionId   subscription id
+     * @param eventType        event type
+     * @param ncmpOutEvent     cm notification subscription NCMP out event
+     * @return cm notification subscription NCMP out event as cloud event
+     */
+    public static CloudEvent buildAndGetNcmpOutEventAsCloudEvent(final JsonObjectMapper jsonObjectMapper,
+            final String subscriptionId, final String eventType, final NcmpOutEvent ncmpOutEvent) {
+
+        return CloudEventBuilder.v1().withId(UUID.randomUUID().toString()).withType(eventType)
+                       .withSource(URI.create("NCMP")).withDataSchema(URI.create("org.onap.ncmp.cm.subscription:1.0.0"))
+                       .withExtension("correlationid", subscriptionId)
+                       .withData(jsonObjectMapper.asJsonBytes(ncmpOutEvent)).build();
+    }
+
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventPublishingTask.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventPublishingTask.java
new file mode 100644 (file)
index 0000000..5636237
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2024 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.impl.cmnotificationsubscription.ncmp;
+
+import static org.onap.cps.ncmp.impl.cmnotificationsubscription.ncmp.NcmpOutEventProducer.buildAndGetNcmpOutEventAsCloudEvent;
+
+import io.cloudevents.CloudEvent;
+import java.util.Map;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.events.EventsPublisher;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.MappersFacade;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.cache.DmiCacheHandler;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionDetails;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_client.NcmpOutEvent;
+import org.onap.cps.utils.JsonObjectMapper;
+
+@Slf4j
+@RequiredArgsConstructor
+public class NcmpOutEventPublishingTask implements Runnable {
+
+    private final String topicName;
+    private final String subscriptionId;
+    private final String eventType;
+    private final EventsPublisher<CloudEvent> eventsPublisher;
+    private final JsonObjectMapper jsonObjectMapper;
+    private final MappersFacade mappersFacade;
+    private final DmiCacheHandler dmiCacheHandler;
+
+    /**
+     * Delegating the responsibility of publishing NcmpOutEvent as a separate task which will
+     * be called after a specified delay.
+     */
+    @Override
+    public void run() {
+        final Map<String, DmiCmSubscriptionDetails> dmiSubscriptionsPerDmi =
+                dmiCacheHandler.get(subscriptionId);
+        final NcmpOutEvent ncmpOutEvent = mappersFacade.toNcmpOutEvent(subscriptionId,
+                dmiSubscriptionsPerDmi);
+        eventsPublisher.publishCloudEvent(topicName, subscriptionId,
+                buildAndGetNcmpOutEventAsCloudEvent(jsonObjectMapper, subscriptionId, eventType,
+                        ncmpOutEvent));
+        dmiCacheHandler.removeAcceptedAndRejectedDmiSubscriptionEntries(subscriptionId);
+    }
+}
@@ -1,7 +1,6 @@
 /*
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2024 Nordix Foundation
- *  Modifications Copyright (C) 2024 TechMahindra Ltd.
  *  ================================================================================
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -19,7 +18,7 @@
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription.service;
+package org.onap.cps.ncmp.impl.cmnotificationsubscription.utils;
 
 import static org.onap.cps.spi.FetchDescendantsOption.DIRECT_CHILDREN_ONLY;
 import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS;
@@ -43,7 +42,10 @@ import org.springframework.stereotype.Service;
 @Slf4j
 @Service
 @RequiredArgsConstructor
-public class CmNotificationSubscriptionPersistenceServiceImpl implements CmNotificationSubscriptionPersistenceService {
+public class CmSubscriptionPersistenceService {
+
+    private static final String NCMP_DATASPACE_NAME = "NCMP-Admin";
+    private static final String CM_SUBSCRIPTIONS_ANCHOR_NAME = "cm-data-subscriptions";
 
     private static final String SUBSCRIPTION_ANCHOR_NAME = "cm-data-subscriptions";
     private static final String CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_WITH_DATASTORE_AND_CMHANDLE = """
@@ -64,22 +66,40 @@ public class CmNotificationSubscriptionPersistenceServiceImpl implements CmNotif
     private final CpsQueryService cpsQueryService;
     private final CpsDataService cpsDataService;
 
-    @Override
-    public boolean isOngoingCmNotificationSubscription(final DatastoreType datastoreType, final String cmHandleId,
-                                                       final String xpath) {
-        return !getOngoingCmNotificationSubscriptionIds(datastoreType, cmHandleId, xpath).isEmpty();
+    /**
+     * Check if we have an ongoing cm subscription based on the parameters.
+     *
+     * @param datastoreType the susbcription target datastore type
+     * @param cmHandleId    the id of the cm handle for the susbcription
+     * @param xpath         the target xpath
+     * @return true for ongoing cmsubscription , otherwise false
+     */
+    public boolean isOngoingCmSubscription(final DatastoreType datastoreType, final String cmHandleId,
+            final String xpath) {
+        return !getOngoingCmSubscriptionIds(datastoreType, cmHandleId, xpath).isEmpty();
     }
 
-    @Override
+    /**
+     * Check if the subscription ID is unique against ongoing subscriptions.
+     *
+     * @param subscriptionId subscription ID
+     * @return true if subscriptionId is not used in active subscriptions, otherwise false
+     */
     public boolean isUniqueSubscriptionId(final String subscriptionId) {
         return cpsQueryService.queryDataNodes(NCMP_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME,
-                CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_WITH_ID.formatted(subscriptionId),
-                OMIT_DESCENDANTS).isEmpty();
+                CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_WITH_ID.formatted(subscriptionId), OMIT_DESCENDANTS).isEmpty();
     }
 
-    @Override
-    public Collection<String> getOngoingCmNotificationSubscriptionIds(final DatastoreType datastoreType,
-                                                                      final String cmHandleId, final String xpath) {
+    /**
+     * Get all ongoing cm notification subscription based on the parameters.
+     *
+     * @param datastoreType the susbcription target datastore type
+     * @param cmHandleId    the id of the cm handle for the susbcription
+     * @param xpath         the target xpath
+     * @return collection of subscription ids of ongoing cm notification subscription
+     */
+    public Collection<String> getOngoingCmSubscriptionIds(final DatastoreType datastoreType,
+            final String cmHandleId, final String xpath) {
 
         final String isOngoingCmSubscriptionCpsPathQuery =
                 CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_WITH_DATASTORE_CMHANDLE_AND_XPATH.formatted(
@@ -93,24 +113,38 @@ public class CmNotificationSubscriptionPersistenceServiceImpl implements CmNotif
         return (List<String>) existingNodes.iterator().next().getLeaves().get("subscriptionIds");
     }
 
-    @Override
-    public void addCmNotificationSubscription(final DatastoreType datastoreType, final String cmHandleId,
-                                              final String xpath, final String subscriptionId) {
-        final Collection<String> subscriptionIds = getOngoingCmNotificationSubscriptionIds(datastoreType,
-                cmHandleId, xpath);
+    /**
+     * Add cm notification subscription.
+     *
+     * @param datastoreType     the susbcription target datastore type
+     * @param cmHandleId        the id of the cm handle for the susbcription
+     * @param xpath             the target xpath
+     * @param newSubscriptionId subscription id to be added
+     */
+    public void addCmSubscription(final DatastoreType datastoreType, final String cmHandleId,
+            final String xpath, final String newSubscriptionId) {
+        final Collection<String> subscriptionIds =
+                getOngoingCmSubscriptionIds(datastoreType, cmHandleId, xpath);
         if (subscriptionIds.isEmpty()) {
-            addFirstSubscriptionForDatastoreCmHandleAndXpath(datastoreType, cmHandleId, xpath, subscriptionId);
-        } else if (!subscriptionIds.contains(subscriptionId)) {
-            subscriptionIds.add(subscriptionId);
+            addFirstSubscriptionForDatastoreCmHandleAndXpath(datastoreType, cmHandleId, xpath, newSubscriptionId);
+        } else if (!subscriptionIds.contains(newSubscriptionId)) {
+            subscriptionIds.add(newSubscriptionId);
             saveSubscriptionDetails(datastoreType, cmHandleId, xpath, subscriptionIds);
         }
     }
 
-    @Override
-    public void removeCmNotificationSubscription(final DatastoreType datastoreType, final String cmHandleId,
-                                                 final String xpath, final String subscriptionId) {
-        final Collection<String> subscriptionIds = getOngoingCmNotificationSubscriptionIds(datastoreType,
-                cmHandleId, xpath);
+    /**
+     * Remove cm notification Subscription.
+     *
+     * @param datastoreType  the susbcription target datastore type
+     * @param cmHandleId     the id of the cm handle for the susbcription
+     * @param xpath          the target xpath
+     * @param subscriptionId subscription id to remove
+     */
+    public void removeCmSubscription(final DatastoreType datastoreType, final String cmHandleId,
+            final String xpath, final String subscriptionId) {
+        final Collection<String> subscriptionIds =
+                getOngoingCmSubscriptionIds(datastoreType, cmHandleId, xpath);
         if (subscriptionIds.remove(subscriptionId)) {
             saveSubscriptionDetails(datastoreType, cmHandleId, xpath, subscriptionIds);
             log.info("There are subscribers left for the following cps path {} :",
@@ -126,16 +160,17 @@ public class CmNotificationSubscriptionPersistenceServiceImpl implements CmNotif
     }
 
     private void deleteListOfSubscriptionsFor(final DatastoreType datastoreType, final String cmHandleId,
-                                              final String xpath) {
+            final String xpath) {
         cpsDataService.deleteDataNode(NCMP_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME,
                 CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_WITH_DATASTORE_CMHANDLE_AND_XPATH.formatted(
                         datastoreType.getDatastoreName(), cmHandleId, escapeQuotesByDoublingThem(xpath)),
                 OffsetDateTime.now());
         final Collection<DataNode> existingFiltersForCmHandle =
                 cpsQueryService.queryDataNodes(NCMP_DATASPACE_NAME, CM_SUBSCRIPTIONS_ANCHOR_NAME,
-                        CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_FILTERS_WITH_DATASTORE_AND_CMHANDLE.formatted(
-                                datastoreType.getDatastoreName(), cmHandleId),
-                        DIRECT_CHILDREN_ONLY).iterator().next().getChildDataNodes();
+                                CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_FILTERS_WITH_DATASTORE_AND_CMHANDLE.formatted(
+                                        datastoreType.getDatastoreName(), cmHandleId),
+                                DIRECT_CHILDREN_ONLY).iterator().next()
+                        .getChildDataNodes();
         if (existingFiltersForCmHandle.isEmpty()) {
             removeCmHandleFromDatastore(datastoreType.getDatastoreName(), cmHandleId);
         }
@@ -143,46 +178,43 @@ public class CmNotificationSubscriptionPersistenceServiceImpl implements CmNotif
 
     private void removeCmHandleFromDatastore(final String datastoreName, final String cmHandleId) {
         cpsDataService.deleteDataNode(NCMP_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME,
-                CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_WITH_DATASTORE_AND_CMHANDLE.formatted(
-                        datastoreName, cmHandleId), OffsetDateTime.now());
+                CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_WITH_DATASTORE_AND_CMHANDLE.formatted(datastoreName, cmHandleId),
+                OffsetDateTime.now());
     }
 
     private boolean isFirstSubscriptionForCmHandle(final DatastoreType datastoreType, final String cmHandleId) {
         return cpsQueryService.queryDataNodes(NCMP_DATASPACE_NAME, CM_SUBSCRIPTIONS_ANCHOR_NAME,
                 CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_FILTERS_WITH_DATASTORE_AND_CMHANDLE.formatted(
-                        datastoreType.getDatastoreName(), cmHandleId),
-                OMIT_DESCENDANTS).isEmpty();
+                        datastoreType.getDatastoreName(), cmHandleId), OMIT_DESCENDANTS).isEmpty();
     }
 
     private void addFirstSubscriptionForDatastoreCmHandleAndXpath(final DatastoreType datastoreType,
-                                                                  final String cmHandleId,
-                                                                  final String xpath,
-                                                                  final String subscriptionId) {
+            final String cmHandleId, final String xpath, final String subscriptionId) {
         final Collection<String> newSubscriptionList = Collections.singletonList(subscriptionId);
         final String subscriptionDetailsAsJson = getSubscriptionDetailsAsJson(xpath, newSubscriptionList);
         if (isFirstSubscriptionForCmHandle(datastoreType, cmHandleId)) {
-            final String parentXpath = "/datastores/datastore[@name='%s']/cm-handles"
-                    .formatted(datastoreType.getDatastoreName());
-            final String subscriptionAsJson = String.format("{\"cm-handle\":[{\"id\":\"%s\",\"filters\":%s}]}",
-                    cmHandleId, subscriptionDetailsAsJson);
+            final String parentXpath =
+                    "/datastores/datastore[@name='%s']/cm-handles".formatted(datastoreType.getDatastoreName());
+            final String subscriptionAsJson =
+                    String.format("{\"cm-handle\":[{\"id\":\"%s\",\"filters\":%s}]}", cmHandleId,
+                            subscriptionDetailsAsJson);
             cpsDataService.saveData(NCMP_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME, parentXpath, subscriptionAsJson,
                     OffsetDateTime.now(), ContentType.JSON);
         } else {
             cpsDataService.saveListElements(NCMP_DATASPACE_NAME, CM_SUBSCRIPTIONS_ANCHOR_NAME,
                     CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_FILTERS_WITH_DATASTORE_AND_CMHANDLE.formatted(
-                            datastoreType.getDatastoreName(), cmHandleId),
-                    subscriptionDetailsAsJson, OffsetDateTime.now());
+                            datastoreType.getDatastoreName(), cmHandleId), subscriptionDetailsAsJson,
+                    OffsetDateTime.now());
         }
     }
 
-    private void saveSubscriptionDetails(final DatastoreType datastoreType, final String cmHandleId,
-                                         final String xpath,
-                                         final  Collection<String> subscriptionIds) {
+    private void saveSubscriptionDetails(final DatastoreType datastoreType, final String cmHandleId, final String xpath,
+            final Collection<String> subscriptionIds) {
         final String subscriptionDetailsAsJson = getSubscriptionDetailsAsJson(xpath, subscriptionIds);
         cpsDataService.updateNodeLeaves(NCMP_DATASPACE_NAME, CM_SUBSCRIPTIONS_ANCHOR_NAME,
                 CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_FILTERS_WITH_DATASTORE_AND_CMHANDLE.formatted(
-                        datastoreType.getDatastoreName(), cmHandleId), subscriptionDetailsAsJson,
-                OffsetDateTime.now(), ContentType.JSON);
+                        datastoreType.getDatastoreName(), cmHandleId), subscriptionDetailsAsJson, OffsetDateTime.now(),
+                ContentType.JSON);
     }
 
     private String getSubscriptionDetailsAsJson(final String xpath, final Collection<String> subscriptionIds) {
@@ -194,4 +226,6 @@ public class CmNotificationSubscriptionPersistenceServiceImpl implements CmNotif
     private static String escapeQuotesByDoublingThem(final String inputXpath) {
         return inputXpath.replace("'", "''");
     }
+
 }
+
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionDeltaSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionDeltaSpec.groovy
deleted file mode 100644 (file)
index 89ccc7e..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (c) 2024 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.events.cmsubscription
-
-import org.onap.cps.ncmp.api.data.models.DatastoreType
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionPredicate
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.service.CmNotificationSubscriptionPersistenceService
-import spock.lang.Specification
-
-class CmNotificationSubscriptionDeltaSpec extends Specification {
-
-    def mockCmNotificationSubscriptionPersistenceService = Mock(CmNotificationSubscriptionPersistenceService)
-    def objectUnderTest = new CmNotificationSubscriptionDelta(mockCmNotificationSubscriptionPersistenceService)
-
-    def 'Find Delta of given list of predicates'() {
-        given: 'A list of predicates'
-            def predicateList = [new DmiCmNotificationSubscriptionPredicate(['ch-1','ch-2'].toSet(), DatastoreType.PASSTHROUGH_OPERATIONAL, ['a/1/','b/2'].toSet())]
-        and: '3 positive responses and 1 negative.'
-            mockCmNotificationSubscriptionPersistenceService.isOngoingCmNotificationSubscription(DatastoreType.PASSTHROUGH_OPERATIONAL, 'ch-1', 'a/1/') >>> true
-            mockCmNotificationSubscriptionPersistenceService.isOngoingCmNotificationSubscription(DatastoreType.PASSTHROUGH_OPERATIONAL, 'ch-1', 'b/2') >>> true
-            mockCmNotificationSubscriptionPersistenceService.isOngoingCmNotificationSubscription(DatastoreType.PASSTHROUGH_OPERATIONAL, 'ch-2', 'a/1/') >>> true
-            mockCmNotificationSubscriptionPersistenceService.isOngoingCmNotificationSubscription(DatastoreType.PASSTHROUGH_OPERATIONAL, 'ch-2', 'b/2') >>> false
-        when: 'getDelta is called'
-            def result = objectUnderTest.getDelta(predicateList)
-        then: 'verify correct delta is returned'
-            assert result.size() == 1
-            assert result[0].targetCmHandleIds[0] == 'ch-2'
-            assert result[0].xpaths[0] == 'b/2'
-
-    }
-
-    def 'Find Delta of given list of predicates when it is an ongoing Cm Subscription'() {
-        given: 'A list of predicates'
-            def predicateList = [new DmiCmNotificationSubscriptionPredicate(['ch-1'].toSet(), DatastoreType.PASSTHROUGH_OPERATIONAL, ['a/1/'].toSet())]
-        and: 'its already present'
-            mockCmNotificationSubscriptionPersistenceService.isOngoingCmNotificationSubscription(DatastoreType.PASSTHROUGH_OPERATIONAL, 'ch-1', 'a/1/') >>> true
-        when: 'getDelta is called'
-            def result = objectUnderTest.getDelta(predicateList)
-        then: 'verify correct delta is returned'
-            assert result.size() == 0
-    }
-
-}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionNcmpOutEventProducerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionNcmpOutEventProducerSpec.groovy
deleted file mode 100644 (file)
index 1fb5837..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-package org.onap.cps.ncmp.api.impl.events.cmsubscription
-
-import com.fasterxml.jackson.databind.ObjectMapper
-import io.cloudevents.CloudEvent
-import org.onap.cps.events.EventsPublisher
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.producer.CmNotificationSubscriptionNcmpOutEventProducer
-import org.onap.cps.ncmp.events.cmsubscription_merge1_0_0.ncmp_to_client.CmNotificationSubscriptionNcmpOutEvent
-import org.onap.cps.ncmp.events.cmsubscription_merge1_0_0.ncmp_to_client.Data
-import org.onap.cps.ncmp.utils.events.CloudEventMapper
-import org.onap.cps.utils.JsonObjectMapper
-import spock.lang.Specification
-
-class CmNotificationSubscriptionNcmpOutEventProducerSpec extends Specification {
-
-    def mockEventsPublisher = Mock(EventsPublisher)
-    def jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
-    def mockCmNotificationSubscriptionMappersHandler = Mock(CmNotificationSubscriptionMappersHandler)
-    def mockDmiCmNotificationSubscriptionCacheHandler = Mock(DmiCmNotificationSubscriptionCacheHandler)
-
-    def objectUnderTest = new CmNotificationSubscriptionNcmpOutEventProducer(mockEventsPublisher, jsonObjectMapper,
-        mockCmNotificationSubscriptionMappersHandler, mockDmiCmNotificationSubscriptionCacheHandler)
-
-    def 'Create and #scenario Cm Notification Subscription NCMP out event'() {
-        given: 'a cm subscription response for the client'
-            def subscriptionId = 'test-subscription-id-2'
-            def eventType = 'subscriptionCreateResponse'
-            def cmNotificationSubscriptionNcmpOutEvent = new CmNotificationSubscriptionNcmpOutEvent(data: new Data(subscriptionId: 'test-subscription-id-2', acceptedTargets: ['ch-1', 'ch-2']))
-        and: 'also we have target topic for publishing to client'
-            objectUnderTest.cmNotificationSubscriptionNcmpOutEventTopic = 'client-test-topic'
-        and: 'a deadline to an event'
-            objectUnderTest.cmNotificationSubscriptionDmiOutEventTimeoutInMs = 1000
-        when: 'the event is published'
-            objectUnderTest.publishCmNotificationSubscriptionNcmpOutEvent(subscriptionId, eventType, cmNotificationSubscriptionNcmpOutEvent, eventPublishingTaskToBeScheduled)
-        then: 'we conditionally wait for a while'
-            Thread.sleep(delayInMs)
-        then: 'the event contains the required attributes'
-            1 * mockEventsPublisher.publishCloudEvent(_, _, _) >> {
-                args ->
-                    {
-                        assert args[0] == 'client-test-topic'
-                        assert args[1] == subscriptionId
-                        def cmNotificationSubscriptionNcmpOutEventAsCloudEvent = (args[2] as CloudEvent)
-                        assert cmNotificationSubscriptionNcmpOutEventAsCloudEvent.getExtension('correlationid') == subscriptionId
-                        assert cmNotificationSubscriptionNcmpOutEventAsCloudEvent.type == 'subscriptionCreateResponse'
-                        assert cmNotificationSubscriptionNcmpOutEventAsCloudEvent.source.toString() == 'NCMP'
-                        assert CloudEventMapper.toTargetEvent(cmNotificationSubscriptionNcmpOutEventAsCloudEvent, CmNotificationSubscriptionNcmpOutEvent) == cmNotificationSubscriptionNcmpOutEvent
-                    }
-            }
-        where: 'following scenarios are considered'
-            scenario                                          | delayInMs | eventPublishingTaskToBeScheduled
-            'publish event now'                               | 0         | false
-            'schedule and publish after the configured time ' | 1500      | true
-    }
-
-    def 'Schedule Cm Notification Subscription NCMP out event but later publish it on demand'() {
-        given: 'a cm subscription response for the client'
-            def subscriptionId = 'test-subscription-id-3'
-            def eventType = 'subscriptionCreateResponse'
-            def cmNotificationSubscriptionNcmpOutEvent = new CmNotificationSubscriptionNcmpOutEvent(data: new Data(subscriptionId: 'test-subscription-id-3', acceptedTargets: ['ch-2', 'ch-3']))
-        and: 'also we have target topic for publishing to client'
-            objectUnderTest.cmNotificationSubscriptionNcmpOutEventTopic = 'client-test-topic'
-        and: 'a deadline to an event'
-            objectUnderTest.cmNotificationSubscriptionDmiOutEventTimeoutInMs = 1000
-        when: 'the event is scheduled to be published'
-            objectUnderTest.publishCmNotificationSubscriptionNcmpOutEvent(subscriptionId, eventType, cmNotificationSubscriptionNcmpOutEvent, true)
-        then: 'we wait for 10ms and then we receive response from DMI'
-            Thread.sleep(10)
-        and: 'we receive response from DMI so we publish the message on demand'
-            objectUnderTest.publishCmNotificationSubscriptionNcmpOutEvent(subscriptionId, eventType, cmNotificationSubscriptionNcmpOutEvent, false)
-        then: 'the event contains the required attributes'
-            1 * mockEventsPublisher.publishCloudEvent(_, _, _) >> {
-                args ->
-                    {
-                        assert args[0] == 'client-test-topic'
-                        assert args[1] == subscriptionId
-                        def cmNotificationSubscriptionNcmpOutEventAsCloudEvent = (args[2] as CloudEvent)
-                        assert cmNotificationSubscriptionNcmpOutEventAsCloudEvent.getExtension('correlationid') == subscriptionId
-                        assert cmNotificationSubscriptionNcmpOutEventAsCloudEvent.type == 'subscriptionCreateResponse'
-                        assert cmNotificationSubscriptionNcmpOutEventAsCloudEvent.source.toString() == 'NCMP'
-                        assert CloudEventMapper.toTargetEvent(cmNotificationSubscriptionNcmpOutEventAsCloudEvent, CmNotificationSubscriptionNcmpOutEvent) == cmNotificationSubscriptionNcmpOutEvent
-                    }
-            }
-        then: 'the cache handler is called once to remove accepted and rejected entries in cache'
-            1 * mockDmiCmNotificationSubscriptionCacheHandler.removeAcceptedAndRejectedDmiCmNotificationSubscriptionEntries(subscriptionId)
-    }
-
-
-}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/mapper/CmNotificationSubscriptionNcmpOutEventMapperSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/mapper/CmNotificationSubscriptionNcmpOutEventMapperSpec.groovy
deleted file mode 100644 (file)
index 179cf36..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- *  Copyright (C) 2024 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.events.cmsubscription.mapper
-
-import org.onap.cps.ncmp.api.data.models.DatastoreType
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.CmNotificationSubscriptionStatus
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionDetails
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionPredicate
-import spock.lang.Specification
-
-class CmNotificationSubscriptionNcmpOutEventMapperSpec extends Specification {
-
-    static Map<String, DmiCmNotificationSubscriptionDetails> dmiCmNotificationSubscriptionDetailsMap
-
-    def objectUnderTest = new CmNotificationSubscriptionNcmpOutEventMapper()
-
-    def setup() {
-        def dmiCmNotificationSubscriptionPredicateA = new DmiCmNotificationSubscriptionPredicate(['ch-A'] as Set, DatastoreType.PASSTHROUGH_RUNNING, ['/a'] as Set)
-        def dmiCmNotificationSubscriptionPredicateB = new DmiCmNotificationSubscriptionPredicate(['ch-B'] as Set, DatastoreType.PASSTHROUGH_OPERATIONAL, ['/b'] as Set)
-        def dmiCmNotificationSubscriptionPredicateC = new DmiCmNotificationSubscriptionPredicate(['ch-C'] as Set, DatastoreType.PASSTHROUGH_OPERATIONAL, ['/c'] as Set)
-        dmiCmNotificationSubscriptionDetailsMap = ['dmi-1': new DmiCmNotificationSubscriptionDetails([dmiCmNotificationSubscriptionPredicateA], CmNotificationSubscriptionStatus.PENDING),
-                                                   'dmi-2': new DmiCmNotificationSubscriptionDetails([dmiCmNotificationSubscriptionPredicateB], CmNotificationSubscriptionStatus.ACCEPTED),
-                                                   'dmi-3': new DmiCmNotificationSubscriptionDetails([dmiCmNotificationSubscriptionPredicateC], CmNotificationSubscriptionStatus.REJECTED)
-        ]
-    }
-
-    def 'Check for Cm Notification Subscription Outgoing event mapping'() {
-        when: 'we try to map the event to send it to client'
-            def result = objectUnderTest.toCmNotificationSubscriptionNcmpOutEvent('test-subscription', dmiCmNotificationSubscriptionDetailsMap)
-        then: 'event is mapped correctly for the subscription'
-            result.data.subscriptionId == 'test-subscription'
-        and: 'the cm handle ids are part of correct list'
-            result.data.pendingTargets == ['ch-A']
-            result.data.acceptedTargets == ['ch-B']
-            result.data.rejectedTargets == ['ch-C']
-    }
-
-    def 'Check for Cm Notification Rejected Subscription Outgoing event mapping'() {
-        when: 'we try to map the event to send it to client'
-            def result = objectUnderTest.toCmNotificationSubscriptionNcmpOutEventForRejectedRequest('test-subscription', ['ch-1', 'ch-2'])
-        then: 'event is mapped correctly for the subscription id'
-            result.data.subscriptionId == 'test-subscription'
-        and: 'the cm handle ids are part of correct list'
-            result.data.withRejectedTargets(['ch-1', 'ch-2'])
-    }
-}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionHandlerServiceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionHandlerServiceImplSpec.groovy
deleted file mode 100644 (file)
index 55a817e..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (c) 2024 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.events.cmsubscription.service
-
-import com.fasterxml.jackson.databind.ObjectMapper
-import org.onap.cps.ncmp.api.data.models.DatastoreType
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.CmNotificationSubscriptionDelta
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.CmNotificationSubscriptionEventsHandler
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.CmNotificationSubscriptionMappersHandler
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.DmiCmNotificationSubscriptionCacheHandler
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.CmNotificationSubscriptionStatus
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionDetails
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionPredicate
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.client_to_ncmp.CmNotificationSubscriptionNcmpInEvent
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.ncmp_to_dmi.CmNotificationSubscriptionDmiInEvent
-import org.onap.cps.ncmp.events.cmsubscription_merge1_0_0.ncmp_to_client.CmNotificationSubscriptionNcmpOutEvent
-import org.onap.cps.ncmp.utils.TestUtils
-import org.onap.cps.utils.JsonObjectMapper
-import spock.lang.Specification
-
-class CmNotificationSubscriptionHandlerServiceImplSpec extends Specification{
-
-    def jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
-    def mockCmNotificationSubscriptionPersistenceService = Mock(CmNotificationSubscriptionPersistenceService);
-    def mockCmNotificationSubscriptionDelta = Mock(CmNotificationSubscriptionDelta);
-    def mockCmNotificationSubscriptionMappersHandler = Mock(CmNotificationSubscriptionMappersHandler);
-    def mockCmNotificationSubscriptionEventsHandler = Mock(CmNotificationSubscriptionEventsHandler);
-    def mockDmiCmNotificationSubscriptionCacheHandler = Mock(DmiCmNotificationSubscriptionCacheHandler);
-
-    def objectUnderTest = new CmNotificationSubscriptionHandlerServiceImpl(mockCmNotificationSubscriptionPersistenceService,
-        mockCmNotificationSubscriptionDelta, mockCmNotificationSubscriptionMappersHandler,
-        mockCmNotificationSubscriptionEventsHandler, mockDmiCmNotificationSubscriptionCacheHandler)
-
-    def testSubscriptionDetailsMap = ["dmi-1":new DmiCmNotificationSubscriptionDetails([], CmNotificationSubscriptionStatus.PENDING)]
-
-    def 'Consume valid and unique CmNotificationSubscriptionNcmpInEvent create message'() {
-        given: 'a cmNotificationSubscriptionNcmp in event with unique subscription id'
-            def jsonData = TestUtils.getResourceFileContent('cmSubscription/cmNotificationSubscriptionNcmpInEvent.json')
-            def testEventConsumed = jsonObjectMapper.convertJsonString(jsonData, CmNotificationSubscriptionNcmpInEvent.class)
-            def testListOfDeltaPredicates = [new DmiCmNotificationSubscriptionPredicate(['ch1'].toSet(), DatastoreType.PASSTHROUGH_OPERATIONAL, ['/a/b'].toSet())]
-            mockCmNotificationSubscriptionPersistenceService.isUniqueSubscriptionId("test-id") >> true
-        and: 'relevant details is extracted from the event'
-            def subscriptionId = testEventConsumed.getData().getSubscriptionId()
-            def predicates = testEventConsumed.getData().getPredicates()
-        and: 'the cache handler returns for relevant subscription id'
-            1 * mockDmiCmNotificationSubscriptionCacheHandler.get("test-id") >> testSubscriptionDetailsMap
-        and: 'the delta predicates is returned'
-            1 * mockCmNotificationSubscriptionDelta.getDelta(_) >> testListOfDeltaPredicates
-        and: 'the DMI in event mapper returns cm notification subscription event'
-            def testDmiInEvent = new CmNotificationSubscriptionDmiInEvent()
-            1 *  mockCmNotificationSubscriptionMappersHandler
-                .toCmNotificationSubscriptionDmiInEvent(testListOfDeltaPredicates) >> testDmiInEvent
-        when: 'the valid and unique event is consumed'
-            objectUnderTest.processSubscriptionCreateRequest(subscriptionId, predicates)
-        then: 'the subscription cache handler is called once'
-            1 * mockDmiCmNotificationSubscriptionCacheHandler.add('test-id',_)
-        and: 'the events handler method to publish DMI event is called correct number of times with the correct parameters'
-            testSubscriptionDetailsMap.size() * mockCmNotificationSubscriptionEventsHandler.publishCmNotificationSubscriptionDmiInEvent(
-                "test-id", "dmi-1", "subscriptionCreateRequest", testDmiInEvent)
-        and: 'we schedule to send the response after configured time from the cache'
-            1 * mockCmNotificationSubscriptionEventsHandler.publishCmNotificationSubscriptionNcmpOutEvent(
-                "test-id", "subscriptionCreateResponse", null, true)
-    }
-
-    def 'Consume valid and Overlapping Cm Notification Subscription NcmpIn Event'() {
-        given: 'a cmNotificationSubscriptionNcmp in event with unique subscription id'
-            def jsonData = TestUtils.getResourceFileContent('cmSubscription/cmNotificationSubscriptionNcmpInEvent.json')
-            def testEventConsumed = jsonObjectMapper.convertJsonString(jsonData, CmNotificationSubscriptionNcmpInEvent.class)
-            def noDeltaPredicates = []
-            mockCmNotificationSubscriptionPersistenceService.isUniqueSubscriptionId("test-id") >> true
-        and: 'the cache handler returns for relevant subscription id'
-            1 * mockDmiCmNotificationSubscriptionCacheHandler.get("test-id") >> testSubscriptionDetailsMap
-        and: 'the delta predicates is returned'
-            1 * mockCmNotificationSubscriptionDelta.getDelta(_) >> noDeltaPredicates
-        when: 'the valid and unique event is consumed'
-            objectUnderTest.processSubscriptionCreateRequest('test-id', noDeltaPredicates)
-        then: 'the subscription cache handler is called once'
-            1 * mockDmiCmNotificationSubscriptionCacheHandler.add('test-id', _)
-        and: 'the subscription details are updated in the cache'
-            1 * mockDmiCmNotificationSubscriptionCacheHandler.updateDmiCmNotificationSubscriptionStatusPerDmi('test-id', _, CmNotificationSubscriptionStatus.ACCEPTED)
-        and: 'we schedule to send the response after configured time from the cache'
-            1 * mockCmNotificationSubscriptionEventsHandler.publishCmNotificationSubscriptionNcmpOutEvent(
-                "test-id", "subscriptionCreateResponse", null, true)
-    }
-
-    def 'Consume valid and but non-unique CmNotificationSubscription create message'() {
-        given: 'a cmNotificationSubscriptionNcmp in event'
-            def jsonData = TestUtils.getResourceFileContent('cmSubscription/cmNotificationSubscriptionNcmpInEvent.json')
-            def testEventConsumed = jsonObjectMapper.convertJsonString(jsonData, CmNotificationSubscriptionNcmpInEvent.class)
-            mockCmNotificationSubscriptionPersistenceService.isUniqueSubscriptionId('test-id') >> false
-        and: 'relevant details is extracted from the event'
-            def subscriptionId = testEventConsumed.getData().getSubscriptionId()
-            def predicates = testEventConsumed.getData().getPredicates()
-        and: 'the NCMP out in event mapper returns an event for rejected request'
-            def testNcmpOutEvent = new CmNotificationSubscriptionNcmpOutEvent()
-            1 * mockCmNotificationSubscriptionMappersHandler.toCmNotificationSubscriptionNcmpOutEventForRejectedRequest(
-                "test-id",_) >> testNcmpOutEvent
-        when: 'the valid but non-unique event is consumed'
-            objectUnderTest.processSubscriptionCreateRequest(subscriptionId, predicates)
-        then: 'the events handler method to publish DMI event is never called'
-            0 * mockCmNotificationSubscriptionEventsHandler.publishCmNotificationSubscriptionDmiInEvent(_,_,_,_)
-        and: 'the events handler method to publish NCMP out event is called once'
-            1 * mockCmNotificationSubscriptionEventsHandler.publishCmNotificationSubscriptionNcmpOutEvent(
-                'test-id', 'subscriptionCreateResponse', testNcmpOutEvent, false)
-    }
-
-    def 'Consume valid CmNotificationSubscriptionNcmpInEvent delete message'() {
-        given: 'a cmNotificationSubscriptionNcmp in event for delete'
-            def jsonData = TestUtils.getResourceFileContent('cmSubscription/cmNotificationSubscriptionNcmpInEvent.json')
-            def testEventConsumed = jsonObjectMapper.convertJsonString(jsonData, CmNotificationSubscriptionNcmpInEvent.class)
-        and: 'relevant details is extracted from the event'
-            def subscriptionId = testEventConsumed.getData().getSubscriptionId()
-            def predicates = testEventConsumed.getData().getPredicates()
-        and: 'the cache handler returns for relevant subscription id'
-            1 * mockDmiCmNotificationSubscriptionCacheHandler.get('test-id') >> testSubscriptionDetailsMap
-        when: 'the valid and unique event is consumed'
-            objectUnderTest.processSubscriptionDeleteRequest(subscriptionId, predicates)
-        then: 'the subscription cache handler is called once'
-            1 * mockDmiCmNotificationSubscriptionCacheHandler.add('test-id', predicates)
-        and: 'the mapper handler to get DMI in event is called once'
-            1 * mockCmNotificationSubscriptionMappersHandler.toCmNotificationSubscriptionDmiInEvent(_)
-        and: 'the events handler method to publish DMI event is called correct number of times with the correct parameters'
-            testSubscriptionDetailsMap.size() * mockCmNotificationSubscriptionEventsHandler.publishCmNotificationSubscriptionDmiInEvent(
-                'test-id', 'dmi-1', 'subscriptionDeleteRequest', _)
-        and: 'we schedule to send the response after configured time from the cache'
-            1 * mockCmNotificationSubscriptionEventsHandler.publishCmNotificationSubscriptionNcmpOutEvent(
-                'test-id', 'subscriptionDeleteResponse', null, true)
-    }
-}
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription
+package org.onap.cps.ncmp.impl.cmnotificationsubscription
 
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.producer.CmNotificationSubscriptionNcmpOutEventProducer
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.producer.CmNotificationSubscriptionDmiInEventProducer
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.ncmp_to_dmi.CmNotificationSubscriptionDmiInEvent
-import org.onap.cps.ncmp.events.cmsubscription_merge1_0_0.ncmp_to_client.CmNotificationSubscriptionNcmpOutEvent
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.dmi.DmiInEventProducer
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.ncmp.NcmpOutEventProducer
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_client.NcmpOutEvent
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_dmi.DmiInEvent
 import spock.lang.Specification
 
-class CmNotificationSubscriptionEventsHandlerSpec extends Specification {
+class EventsFacadeSpec extends Specification {
 
-    def mockCmNotificationSubscriptionNcmpOutEventProducer = Mock(CmNotificationSubscriptionNcmpOutEventProducer)
-    def mockCmNotificationSubscriptionDmiInEventProducer = Mock(CmNotificationSubscriptionDmiInEventProducer)
+    def mockCmNotificationSubscriptionNcmpOutEventProducer = Mock(NcmpOutEventProducer)
+    def mockCmNotificationSubscriptionDmiInEventProducer = Mock(DmiInEventProducer)
 
-    def objectUnderTest = new CmNotificationSubscriptionEventsHandler(mockCmNotificationSubscriptionNcmpOutEventProducer,
+    def objectUnderTest = new EventsFacade(mockCmNotificationSubscriptionNcmpOutEventProducer,
         mockCmNotificationSubscriptionDmiInEventProducer)
 
     def 'Publish cm notification subscription ncmp out event'() {
         given: 'an ncmp out event'
-            def cmNotificationSubscriptionNcmpOutEvent = new CmNotificationSubscriptionNcmpOutEvent()
+            def ncmpOutEvent = new NcmpOutEvent()
         when: 'the method to publish cm notification subscription ncmp out event is called'
-            objectUnderTest.publishCmNotificationSubscriptionNcmpOutEvent("some-id",
-                "some-event", cmNotificationSubscriptionNcmpOutEvent, true)
+            objectUnderTest.publishNcmpOutEvent("some-id",
+                "some-event", ncmpOutEvent, true)
         then: 'the parameters is delegated to the correct method once'
-            1 * mockCmNotificationSubscriptionNcmpOutEventProducer.publishCmNotificationSubscriptionNcmpOutEvent(
-                "some-id", "some-event", cmNotificationSubscriptionNcmpOutEvent, true)
+            1 * mockCmNotificationSubscriptionNcmpOutEventProducer.publishNcmpOutEvent(
+                "some-id", "some-event", ncmpOutEvent, true)
     }
 
     def 'Publish cm notification subscription dmi in event'() {
         given: 'a dmi in event'
-            def cmNotificationSubscriptionDmiInEvent = new CmNotificationSubscriptionDmiInEvent()
+            def dmiInEvent = new DmiInEvent()
         when: 'the method to publish cm notification subscription ncmp out event is called'
-            objectUnderTest.publishCmNotificationSubscriptionDmiInEvent("some-id",
-                "some-dmi", "some-event", cmNotificationSubscriptionDmiInEvent)
+            objectUnderTest.publishDmiInEvent("some-id",
+                "some-dmi", "some-event", dmiInEvent)
         then: 'the parameters is delegated to the correct method once'
-            1 * mockCmNotificationSubscriptionDmiInEventProducer.publishCmNotificationSubscriptionDmiInEvent("some-id",
-                "some-dmi", "some-event", cmNotificationSubscriptionDmiInEvent)
+            1 * mockCmNotificationSubscriptionDmiInEventProducer.publishDmiInEvent("some-id",
+                "some-dmi", "some-event", dmiInEvent)
     }
 }
\ No newline at end of file
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription
+package org.onap.cps.ncmp.impl.cmnotificationsubscription
 
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.mapper.CmNotificationSubscriptionDmiInEventMapper
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.mapper.CmNotificationSubscriptionNcmpOutEventMapper
+
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.dmi.DmiInEventMapper
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.ncmp.NcmpOutEventMapper
 import spock.lang.Specification
 
-class CmNotificationSubscriptionMappersHandlerSpec extends Specification{
+class MappersFacadeSpec extends Specification{
 
-    def mockCmNotificationDmiInEventMapper = Mock(CmNotificationSubscriptionDmiInEventMapper)
-    def mockCmNotificationNcmpOutEventMapper = Mock(CmNotificationSubscriptionNcmpOutEventMapper)
+    def mockCmNotificationDmiInEventMapper = Mock(DmiInEventMapper)
+    def mockCmNotificationNcmpOutEventMapper = Mock(NcmpOutEventMapper)
 
-    def objectUnderTest = new CmNotificationSubscriptionMappersHandler(mockCmNotificationDmiInEventMapper,
+    def objectUnderTest = new MappersFacade(mockCmNotificationDmiInEventMapper,
         mockCmNotificationNcmpOutEventMapper)
 
     def 'Get cm notification subscription DMI in event'() {
         given: 'a list of predicates'
             def testListOfPredicates = []
         when: 'method to create a cm notification subscription dmi in event is called with predicates'
-            objectUnderTest.toCmNotificationSubscriptionDmiInEvent(testListOfPredicates)
+            objectUnderTest.toDmiInEvent(testListOfPredicates)
         then: 'the parameters is delegated to the correct dmi in event mapper method'
-            1 * mockCmNotificationDmiInEventMapper.toCmNotificationSubscriptionDmiInEvent(testListOfPredicates)
+            1 * mockCmNotificationDmiInEventMapper.toDmiInEvent(testListOfPredicates)
     }
 
     def 'Get cm notification subscription ncmp out event'() {
         given: 'a subscription details map'
             def testSubscriptionDetailsMap = [:]
         when: 'method to create cm notification subscription ncmp out event is called with the following parameters'
-            objectUnderTest.toCmNotificationSubscriptionNcmpOutEvent("test-id", testSubscriptionDetailsMap)
+            objectUnderTest.toNcmpOutEvent("test-id", testSubscriptionDetailsMap)
         then: 'the parameters is delegated to the correct ncmp out event mapper method'
-            1 * mockCmNotificationNcmpOutEventMapper.toCmNotificationSubscriptionNcmpOutEvent("test-id",
+            1 * mockCmNotificationNcmpOutEventMapper.toNcmpOutEvent("test-id",
             testSubscriptionDetailsMap)
     }
 
@@ -55,10 +56,10 @@ class CmNotificationSubscriptionMappersHandlerSpec extends Specification{
         given: 'a list of target filters'
             def testRejectedTargetFilters = []
         when: 'method to create cm notification subscription ncmp out event is called with the following parameters'
-            objectUnderTest.toCmNotificationSubscriptionNcmpOutEventForRejectedRequest(
+            objectUnderTest.toNcmpOutEventForRejectedRequest(
                 "test-id", testRejectedTargetFilters)
         then: 'the parameters is delegated to the correct ncmp out event mapper method'
-            1 * mockCmNotificationNcmpOutEventMapper.toCmNotificationSubscriptionNcmpOutEventForRejectedRequest(
+            1 * mockCmNotificationNcmpOutEventMapper.toNcmpOutEventForRejectedRequest(
                 "test-id", testRejectedTargetFilters)
     }
 }
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.config.embeddedcache
+package org.onap.cps.ncmp.impl.cmnotificationsubscription.cache
 
 import com.hazelcast.core.Hazelcast
 import com.hazelcast.map.IMap
 import org.onap.cps.ncmp.api.data.models.DatastoreType
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.CmNotificationSubscriptionStatus
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionDetails
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionPredicate
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.CmSubscriptionStatus
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionDetails
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionPredicate
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.boot.test.context.SpringBootTest
 import spock.lang.Specification
 
-@SpringBootTest(classes = [CmNotificationSubscriptionCacheConfig])
-class CmNotificationSubscriptionCacheConfigSpec extends Specification {
+@SpringBootTest(classes = [CmSubscriptionConfig])
+class CmSubscriptionConfigSpec extends Specification {
 
     @Autowired
-    IMap<String, Map<String, DmiCmNotificationSubscriptionDetails>> cmNotificationSubscriptionCache;
+    IMap<String, Map<String, DmiCmSubscriptionDetails>> cmNotificationSubscriptionCache;
 
     def 'Embedded (hazelcast) cache for Cm Notification Subscription Cache.'() {
         expect: 'system is able to create an instance of the Cm Notification Subscription Cache'
@@ -49,15 +49,15 @@ class CmNotificationSubscriptionCacheConfigSpec extends Specification {
         given: 'a cm subscription properties'
             def subscriptionId = 'sub123'
             def dmiPluginName = 'dummydmi'
-            def cmSubscriptionPredicate = new DmiCmNotificationSubscriptionPredicate(['cmhandle1', 'cmhandle2'].toSet(), DatastoreType.PASSTHROUGH_RUNNING, ['/a/b/c'].toSet())
-            def cmSubscriptionCacheObject = new DmiCmNotificationSubscriptionDetails([cmSubscriptionPredicate], CmNotificationSubscriptionStatus.PENDING)
+            def cmSubscriptionPredicates = new DmiCmSubscriptionPredicate(['cmhandle1', 'cmhandle2'].toSet(), DatastoreType.PASSTHROUGH_RUNNING, ['/a/b/c'].toSet())
+            def cmSubscriptionCacheObject = new DmiCmSubscriptionDetails([cmSubscriptionPredicates], CmSubscriptionStatus.PENDING)
         when: 'the cache is populated'
             cmNotificationSubscriptionCache.put(subscriptionId, [(dmiPluginName): cmSubscriptionCacheObject])
         then: 'the values are present in memory'
             assert cmNotificationSubscriptionCache.get(subscriptionId) != null
         and: 'properties match'
             assert dmiPluginName == cmNotificationSubscriptionCache.get(subscriptionId).keySet()[0]
-            assert cmSubscriptionCacheObject.cmNotificationSubscriptionStatus == cmNotificationSubscriptionCache.get(subscriptionId).values().cmNotificationSubscriptionStatus[0]
-            assert cmSubscriptionCacheObject.dmiCmNotificationSubscriptionPredicates[0].targetCmHandleIds == cmNotificationSubscriptionCache.get(subscriptionId).values().dmiCmNotificationSubscriptionPredicates[0].targetCmHandleIds[0]
+            assert cmSubscriptionCacheObject.cmSubscriptionStatus == cmNotificationSubscriptionCache.get(subscriptionId).values().cmSubscriptionStatus[0]
+            assert cmSubscriptionCacheObject.dmiCmSubscriptionPredicates[0].targetCmHandleIds == cmNotificationSubscriptionCache.get(subscriptionId).values().dmiCmSubscriptionPredicates[0].targetCmHandleIds[0]
     }
 }
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription
+package org.onap.cps.ncmp.impl.cmnotificationsubscription.cache
 
 import com.fasterxml.jackson.databind.ObjectMapper
 import io.cloudevents.CloudEvent
 import io.cloudevents.core.builder.CloudEventBuilder
 import org.apache.kafka.clients.consumer.ConsumerRecord
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.CmNotificationSubscriptionStatus
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionDetails
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.service.CmNotificationSubscriptionPersistenceService
 import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.client_to_ncmp.CmNotificationSubscriptionNcmpInEvent
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.CmSubscriptionStatus
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionDetails
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.utils.CmSubscriptionPersistenceService
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.client_to_ncmp.NcmpInEvent
 import org.onap.cps.ncmp.impl.inventory.InventoryPersistence
 import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle
 import org.onap.cps.ncmp.utils.TestUtils
@@ -40,7 +40,7 @@ import org.springframework.boot.test.context.SpringBootTest
 import static org.onap.cps.ncmp.utils.events.CloudEventMapper.toTargetEvent
 
 @SpringBootTest(classes = [ObjectMapper, JsonObjectMapper])
-class DmiCmNotificationSubscriptionCacheHandlerSpec extends MessagingBaseSpec {
+class DmiCacheHandlerSpec extends MessagingBaseSpec {
 
     @Autowired
     JsonObjectMapper jsonObjectMapper
@@ -49,12 +49,12 @@ class DmiCmNotificationSubscriptionCacheHandlerSpec extends MessagingBaseSpec {
     @SpringBean
     InventoryPersistence mockInventoryPersistence = Mock(InventoryPersistence)
     @SpringBean
-    CmNotificationSubscriptionPersistenceService mockCmNotificationSubscriptionPersistenceService = Mock(CmNotificationSubscriptionPersistenceService)
+    CmSubscriptionPersistenceService mockCmSubscriptionPersistenceService = Mock(CmSubscriptionPersistenceService)
 
     def testCache = [:]
-    def objectUnderTest = new DmiCmNotificationSubscriptionCacheHandler(mockCmNotificationSubscriptionPersistenceService, testCache, mockInventoryPersistence)
+    def objectUnderTest = new DmiCacheHandler(mockCmSubscriptionPersistenceService, testCache, mockInventoryPersistence)
 
-    CmNotificationSubscriptionNcmpInEvent cmNotificationSubscriptionNcmpInEvent
+    NcmpInEvent ncmpInEvent
     def yangModelCmHandle1 = new YangModelCmHandle(id:'ch1',dmiServiceName:'dmi-1')
     def yangModelCmHandle2 = new YangModelCmHandle(id:'ch2',dmiServiceName:'dmi-2')
     def yangModelCmHandle3 = new YangModelCmHandle(id:'ch3',dmiServiceName:'dmi-1')
@@ -67,9 +67,9 @@ class DmiCmNotificationSubscriptionCacheHandlerSpec extends MessagingBaseSpec {
 
     def 'Load CM subscription event to cache'() {
         given: 'a valid subscription event with Id'
-            def subscriptionId = cmNotificationSubscriptionNcmpInEvent.getData().getSubscriptionId()
+            def subscriptionId = ncmpInEvent.getData().getSubscriptionId()
         and: 'list of predicates'
-            def predicates = cmNotificationSubscriptionNcmpInEvent.getData().getPredicates()
+            def predicates = ncmpInEvent.getData().getPredicates()
         when: 'a valid event object loaded in cache'
             objectUnderTest.add(subscriptionId, predicates)
         then: 'the cache contains the correct entry with #subscriptionId subscription ID'
@@ -89,19 +89,19 @@ class DmiCmNotificationSubscriptionCacheHandlerSpec extends MessagingBaseSpec {
         given: 'a map as the value for cache entry for some-id'
             def testMap = [:]
             testMap.put("dmi-1",
-                new DmiCmNotificationSubscriptionDetails([],CmNotificationSubscriptionStatus.ACCEPTED))
+                new DmiCmSubscriptionDetails([],CmSubscriptionStatus.ACCEPTED))
             testMap.put("dmi-2",
-                new DmiCmNotificationSubscriptionDetails([],CmNotificationSubscriptionStatus.REJECTED))
+                new DmiCmSubscriptionDetails([],CmSubscriptionStatus.REJECTED))
             testMap.put("dmi-3",
-                new DmiCmNotificationSubscriptionDetails([],CmNotificationSubscriptionStatus.PENDING))
+                new DmiCmSubscriptionDetails([],CmSubscriptionStatus.PENDING))
             testCache.put("test-id", testMap)
             assert testCache.get("test-id").size() == 3
         when: 'the method to remove accepted and rejected entries for test-id is called'
-            objectUnderTest.removeAcceptedAndRejectedDmiCmNotificationSubscriptionEntries("test-id")
+            objectUnderTest.removeAcceptedAndRejectedDmiSubscriptionEntries("test-id")
         then: 'all entries with status accepted/rejected are no longer present for test-id'
             testCache.get("test-id").each { key, testResultMap ->
-                assert testResultMap.cmNotificationSubscriptionStatus != CmNotificationSubscriptionStatus.ACCEPTED
-                    || testResultMap.cmNotificationSubscriptionStatus != CmNotificationSubscriptionStatus.REJECTED
+                assert testResultMap.cmSubscriptionStatus != CmSubscriptionStatus.ACCEPTED
+                    || testResultMap.cmSubscriptionStatus != CmSubscriptionStatus.REJECTED
             }
         and: 'the size of the map for cache entry test-id is as expected'
             assert testCache.get("test-id").size() == 1
@@ -109,9 +109,9 @@ class DmiCmNotificationSubscriptionCacheHandlerSpec extends MessagingBaseSpec {
 
     def 'Create map for DMI cm notification subscription per DMI service name'() {
         given: 'list of predicates from the create subscription event'
-            def predicates = cmNotificationSubscriptionNcmpInEvent.getData().getPredicates()
+            def predicates = ncmpInEvent.getData().getPredicates()
         when: 'method to create map of DMI cm notification subscription per DMI service name is called'
-            def result = objectUnderTest.createDmiCmNotificationSubscriptionsPerDmi(predicates)
+            def result = objectUnderTest.createDmiSubscriptionsPerDmi(predicates)
         then: 'the result size of resulting map is correct to the number of DMIs'
             assert result.size() == 2
         and: 'the cache objects per DMI exists'
@@ -120,28 +120,28 @@ class DmiCmNotificationSubscriptionCacheHandlerSpec extends MessagingBaseSpec {
             assert resultMapForDmi1 != null
             assert resultMapForDmi2 != null
         and: 'the size of predicates in each object is correct'
-            assert resultMapForDmi1.dmiCmNotificationSubscriptionPredicates.size() == 2
-            assert resultMapForDmi2.dmiCmNotificationSubscriptionPredicates.size() == 2
+            assert resultMapForDmi1.dmiCmSubscriptionPredicates.size() == 2
+            assert resultMapForDmi2.dmiCmSubscriptionPredicates.size() == 2
         and: 'the subscription status in each object is correct'
-            assert resultMapForDmi1.cmNotificationSubscriptionStatus.toString() == 'PENDING'
-            assert resultMapForDmi2.cmNotificationSubscriptionStatus.toString() == 'PENDING'
+            assert resultMapForDmi1.cmSubscriptionStatus.toString() == 'PENDING'
+            assert resultMapForDmi2.cmSubscriptionStatus.toString() == 'PENDING'
         and: 'the target cmHandles for each predicate is correct'
-            assert resultMapForDmi1.dmiCmNotificationSubscriptionPredicates[0].targetCmHandleIds == ['ch1'].toSet()
-            assert resultMapForDmi1.dmiCmNotificationSubscriptionPredicates[1].targetCmHandleIds == ['ch3'].toSet()
+            assert resultMapForDmi1.dmiCmSubscriptionPredicates[0].targetCmHandleIds == ['ch1'].toSet()
+            assert resultMapForDmi1.dmiCmSubscriptionPredicates[1].targetCmHandleIds == ['ch3'].toSet()
 
-            assert resultMapForDmi2.dmiCmNotificationSubscriptionPredicates[0].targetCmHandleIds == ['ch2'].toSet()
-            assert resultMapForDmi2.dmiCmNotificationSubscriptionPredicates[1].targetCmHandleIds == ['ch4'].toSet()
+            assert resultMapForDmi2.dmiCmSubscriptionPredicates[0].targetCmHandleIds == ['ch2'].toSet()
+            assert resultMapForDmi2.dmiCmSubscriptionPredicates[1].targetCmHandleIds == ['ch4'].toSet()
         and: 'the list of xpath for each is correct'
-            assert resultMapForDmi1.dmiCmNotificationSubscriptionPredicates[0].xpaths
-                && resultMapForDmi2.dmiCmNotificationSubscriptionPredicates[0].xpaths == ['/x1/y1','x2/y2'].toSet()
+            assert resultMapForDmi1.dmiCmSubscriptionPredicates[0].xpaths
+                && resultMapForDmi2.dmiCmSubscriptionPredicates[0].xpaths == ['/x1/y1', 'x2/y2'].toSet()
 
-            assert resultMapForDmi1.dmiCmNotificationSubscriptionPredicates[1].xpaths
-                && resultMapForDmi2.dmiCmNotificationSubscriptionPredicates[1].xpaths == ['/x3/y3','x4/y4'].toSet()
+            assert resultMapForDmi1.dmiCmSubscriptionPredicates[1].xpaths
+                && resultMapForDmi2.dmiCmSubscriptionPredicates[1].xpaths == ['/x3/y3', 'x4/y4'].toSet()
     }
 
     def 'Get map for cm handle IDs by DMI service name'() {
         given: 'the predicate from the test request CM subscription event'
-            def targetFilter = cmNotificationSubscriptionNcmpInEvent.getData().getPredicates().get(0).getTargetFilter()
+            def targetFilter = ncmpInEvent.getData().getPredicates().get(0).getTargetFilter()
         when: 'the method to group all target CM handles by DMI service name is called'
             def mapOfCMHandleIDsByDmi = objectUnderTest.groupTargetCmHandleIdsByDmi(targetFilter)
         then: 'the size of the resulting map is correct'
@@ -153,41 +153,41 @@ class DmiCmNotificationSubscriptionCacheHandlerSpec extends MessagingBaseSpec {
 
     def 'Update subscription status in cache per DMI service name'() {
         given: 'populated cache'
-            def predicates = cmNotificationSubscriptionNcmpInEvent.getData().getPredicates()
-            def subscriptionId = cmNotificationSubscriptionNcmpInEvent.getData().getSubscriptionId()
+            def predicates = ncmpInEvent.getData().getPredicates()
+            def subscriptionId = ncmpInEvent.getData().getSubscriptionId()
             objectUnderTest.add(subscriptionId, predicates)
         when: 'subscription status per dmi is updated in cache'
-            objectUnderTest.updateDmiCmNotificationSubscriptionStatusPerDmi(subscriptionId,'dmi-1', CmNotificationSubscriptionStatus.ACCEPTED)
+            objectUnderTest.updateDmiSubscriptionStatusPerDmi(subscriptionId,'dmi-1', CmSubscriptionStatus.ACCEPTED)
         then: 'verify status has been updated in cache'
             def predicate = testCache.get(subscriptionId)
-            assert predicate.get('dmi-1').cmNotificationSubscriptionStatus == CmNotificationSubscriptionStatus.ACCEPTED
+            assert predicate.get('dmi-1').cmSubscriptionStatus == CmSubscriptionStatus.ACCEPTED
     }
 
     def 'Persist Cache into database per dmi'() {
         given: 'populated cache'
-            def predicates = cmNotificationSubscriptionNcmpInEvent.getData().getPredicates()
-            def subscriptionId = cmNotificationSubscriptionNcmpInEvent.getData().getSubscriptionId()
+            def predicates = ncmpInEvent.getData().getPredicates()
+            def subscriptionId = ncmpInEvent.getData().getSubscriptionId()
             objectUnderTest.add(subscriptionId, predicates)
         when: 'subscription is persisted in database'
             objectUnderTest.persistIntoDatabasePerDmi(subscriptionId,'dmi-1')
         then: 'persistence service is called the correct number of times per dmi'
-            4 * mockCmNotificationSubscriptionPersistenceService.addCmNotificationSubscription(_,_,_,subscriptionId)
+            4 * mockCmSubscriptionPersistenceService.addCmSubscription(_,_,_,subscriptionId)
     }
 
     def 'Remove subscription from database per dmi'() {
         given: 'populated cache'
-            def predicates = cmNotificationSubscriptionNcmpInEvent.getData().getPredicates()
-            def subscriptionId = cmNotificationSubscriptionNcmpInEvent.getData().getSubscriptionId()
+            def predicates = ncmpInEvent.getData().getPredicates()
+            def subscriptionId = ncmpInEvent.getData().getSubscriptionId()
             objectUnderTest.add(subscriptionId, predicates)
         when: 'subscription is persisted in database'
             objectUnderTest.removeFromDatabasePerDmi(subscriptionId,'dmi-1')
         then: 'persistence service is called the correct number of times per dmi'
-            4 * mockCmNotificationSubscriptionPersistenceService.removeCmNotificationSubscription(_,_,_,subscriptionId)
+            4 * mockCmSubscriptionPersistenceService.removeCmSubscription(_,_,_,subscriptionId)
     }
 
     def setUpTestEvent(){
         def jsonData = TestUtils.getResourceFileContent('cmSubscription/cmNotificationSubscriptionNcmpInEvent.json')
-        def testEventSent = jsonObjectMapper.convertJsonString(jsonData, CmNotificationSubscriptionNcmpInEvent.class)
+        def testEventSent = jsonObjectMapper.convertJsonString(jsonData, NcmpInEvent.class)
         def testCloudEventSent = CloudEventBuilder.v1()
             .withData(objectMapper.writeValueAsBytes(testEventSent))
             .withId('subscriptionCreated')
@@ -197,7 +197,7 @@ class DmiCmNotificationSubscriptionCacheHandlerSpec extends MessagingBaseSpec {
         def consumerRecord = new ConsumerRecord<String, CloudEvent>('topic-name', 0, 0, 'event-key', testCloudEventSent)
         def cloudEvent = consumerRecord.value()
 
-        cmNotificationSubscriptionNcmpInEvent = toTargetEvent(cloudEvent, CmNotificationSubscriptionNcmpInEvent.class);
+        ncmpInEvent = toTargetEvent(cloudEvent, NcmpInEvent.class);
     }
 
     def initialiseMockInventoryPersistenceResponses(){
@@ -18,7 +18,7 @@
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.avc
+package org.onap.cps.ncmp.impl.cmnotificationsubscription.cmavc
 
 import com.fasterxml.jackson.databind.ObjectMapper
 import io.cloudevents.CloudEvent
@@ -42,16 +42,16 @@ import java.time.Duration
 
 import static org.onap.cps.ncmp.utils.events.CloudEventMapper.toTargetEvent
 
-@SpringBootTest(classes = [EventsPublisher, AvcEventConsumer, ObjectMapper, JsonObjectMapper])
+@SpringBootTest(classes = [EventsPublisher, CmAvcEventConsumer, ObjectMapper, JsonObjectMapper])
 @Testcontainers
 @DirtiesContext
-class AvcEventConsumerSpec extends MessagingBaseSpec {
+class CmAvcEventConsumerSpec extends MessagingBaseSpec {
 
     @SpringBean
     EventsPublisher eventsPublisher = new EventsPublisher<CloudEvent>(legacyEventKafkaTemplate, cloudEventKafkaTemplate)
 
     @SpringBean
-    AvcEventConsumer acvEventConsumer = new AvcEventConsumer(eventsPublisher)
+    CmAvcEventConsumer acvEventConsumer = new CmAvcEventConsumer(eventsPublisher)
 
     @Autowired
     JsonObjectMapper jsonObjectMapper
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription.mapper
+package org.onap.cps.ncmp.impl.cmnotificationsubscription.dmi
 
 
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionPredicate
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionPredicate
 import org.onap.cps.ncmp.impl.inventory.InventoryPersistence
 import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle
 import spock.lang.Specification
@@ -29,11 +29,11 @@ import spock.lang.Specification
 import static org.onap.cps.ncmp.api.data.models.DatastoreType.PASSTHROUGH_OPERATIONAL
 import static org.onap.cps.ncmp.api.data.models.DatastoreType.PASSTHROUGH_RUNNING
 
-class CmNotificationSubscriptionDmiInEventMapperSpec extends Specification {
+class DmiInEventMapperSpec extends Specification {
 
     def mockInventoryPersistence = Mock(InventoryPersistence)
 
-    def objectUnderTest = new CmNotificationSubscriptionDmiInEventMapper(mockInventoryPersistence)
+    def objectUnderTest = new DmiInEventMapper(mockInventoryPersistence)
 
     def setup() {
         def yangModelCmHandles = [new YangModelCmHandle(id: 'ch-1', dmiProperties: [new YangModelCmHandle.Property('k1', 'v1')], publicProperties: []),
@@ -43,10 +43,10 @@ class CmNotificationSubscriptionDmiInEventMapperSpec extends Specification {
 
     def 'Check for Cm Notification Subscription DMI In Event mapping'() {
         given: 'a collection of cm subscription predicates'
-            def dmiCmNotificationSubscriptionPredicates = [new DmiCmNotificationSubscriptionPredicate(['ch-1'].toSet(), PASSTHROUGH_RUNNING, ['/ch-1'].toSet()),
-                                                           new DmiCmNotificationSubscriptionPredicate(['ch-2'].toSet(), PASSTHROUGH_OPERATIONAL, ['/ch-2'].toSet())]
+            def dmiSubscriptionPredicates = [new DmiCmSubscriptionPredicate(['ch-1'].toSet(), PASSTHROUGH_RUNNING, ['/ch-1'].toSet()),
+                                                           new DmiCmSubscriptionPredicate(['ch-2'].toSet(), PASSTHROUGH_OPERATIONAL, ['/ch-2'].toSet())]
         when: 'we try to map the values'
-            def result = objectUnderTest.toCmNotificationSubscriptionDmiInEvent(dmiCmNotificationSubscriptionPredicates)
+            def result = objectUnderTest.toDmiInEvent(dmiSubscriptionPredicates)
         then: 'it contains correct cm notification subscription cmhandle object'
             assert result.data.cmHandles.cmhandleId.containsAll(['ch-1', 'ch-2'])
             assert result.data.cmHandles.privateProperties.containsAll([['k1': 'v1'], ['k2': 'v2']])
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription
+package org.onap.cps.ncmp.impl.cmnotificationsubscription.dmi
 
 import com.fasterxml.jackson.databind.ObjectMapper
 import io.cloudevents.CloudEvent
 import org.onap.cps.events.EventsPublisher
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.producer.CmNotificationSubscriptionDmiInEventProducer
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.ncmp_to_dmi.CmHandle
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.ncmp_to_dmi.CmNotificationSubscriptionDmiInEvent
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.ncmp_to_dmi.Data
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_dmi.CmHandle
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_dmi.Data
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_dmi.DmiInEvent
 import org.onap.cps.ncmp.utils.events.CloudEventMapper
 import org.onap.cps.utils.JsonObjectMapper
 import spock.lang.Specification
 
-class CmNotificationSubscriptionDmiInEventProducerSpec extends Specification {
+class DmiInEventProducerSpec extends Specification {
 
     def mockEventsPublisher = Mock(EventsPublisher)
     def jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
 
-    def objectUnderTest = new CmNotificationSubscriptionDmiInEventProducer(mockEventsPublisher, jsonObjectMapper)
+    def objectUnderTest = new DmiInEventProducer(mockEventsPublisher, jsonObjectMapper)
 
     def 'Create and Publish Cm Notification Subscription DMI In Event'() {
         given: 'a cm subscription for a dmi plugin'
             def subscriptionId = 'test-subscription-id'
             def dmiPluginName = 'test-dmiplugin'
             def eventType = 'subscriptionCreateRequest'
-            def cmNotificationSubscriptionDmiInEvent = new CmNotificationSubscriptionDmiInEvent(data: new Data(cmHandles: [new CmHandle(cmhandleId: 'test-1', privateProperties: [:])]))
+            def dmiInEvent = new DmiInEvent(data: new Data(cmHandles: [new CmHandle(cmhandleId: 'test-1', privateProperties: [:])]))
         and: 'also we have target topic for dmiPlugin'
-            objectUnderTest.cmNotificationSubscriptionDmiInEventTopic = 'dmiplugin-test-topic'
+            objectUnderTest.dmiInEventTopic = 'dmiplugin-test-topic'
         when: 'the event is published'
-            objectUnderTest.publishCmNotificationSubscriptionDmiInEvent(subscriptionId, dmiPluginName, eventType, cmNotificationSubscriptionDmiInEvent)
+            objectUnderTest.publishDmiInEvent(subscriptionId, dmiPluginName, eventType, dmiInEvent)
         then: 'the event contains the required attributes'
             1 * mockEventsPublisher.publishCloudEvent(_, _, _) >> {
                 args ->
                     {
                         assert args[0] == 'dmiplugin-test-topic'
                         assert args[1] == subscriptionId
-                        def cmNotificationSubscriptionDmiInEventAsCloudEvent = (args[2] as CloudEvent)
-                        assert cmNotificationSubscriptionDmiInEventAsCloudEvent.getExtension('correlationid') == subscriptionId + '#' + dmiPluginName
-                        assert cmNotificationSubscriptionDmiInEventAsCloudEvent.type == 'subscriptionCreateRequest'
-                        assert cmNotificationSubscriptionDmiInEventAsCloudEvent.source.toString() == 'NCMP'
-                        assert CloudEventMapper.toTargetEvent(cmNotificationSubscriptionDmiInEventAsCloudEvent, CmNotificationSubscriptionDmiInEvent) == cmNotificationSubscriptionDmiInEvent
+                        def dmiInEventAsCloudEvent = (args[2] as CloudEvent)
+                        assert dmiInEventAsCloudEvent.getExtension('correlationid') == subscriptionId + '#' + dmiPluginName
+                        assert dmiInEventAsCloudEvent.type == 'subscriptionCreateRequest'
+                        assert dmiInEventAsCloudEvent.source.toString() == 'NCMP'
+                        assert CloudEventMapper.toTargetEvent(dmiInEventAsCloudEvent, DmiInEvent) == dmiInEvent
                     }
             }
     }
@@ -18,7 +18,7 @@
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription
+package org.onap.cps.ncmp.impl.cmnotificationsubscription.dmi
 
 import ch.qos.logback.classic.Level
 import ch.qos.logback.classic.Logger
@@ -28,19 +28,23 @@ import com.fasterxml.jackson.databind.ObjectMapper
 import io.cloudevents.CloudEvent
 import io.cloudevents.core.builder.CloudEventBuilder
 import org.apache.kafka.clients.consumer.ConsumerRecord
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.consumer.CmNotificationSubscriptionDmiOutEventConsumer
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.CmNotificationSubscriptionStatus
 import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.dmi_to_ncmp.CmNotificationSubscriptionDmiOutEvent
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.dmi_to_ncmp.Data
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.EventsFacade
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.MappersFacade
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.cache.DmiCacheHandler
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.dmi_to_ncmp.Data
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.dmi_to_ncmp.DmiOutEvent
 import org.onap.cps.ncmp.utils.TestUtils
 import org.onap.cps.utils.JsonObjectMapper
 import org.slf4j.LoggerFactory
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.boot.test.context.SpringBootTest
 
+import static org.onap.cps.ncmp.impl.cmnotificationsubscription.models.CmSubscriptionStatus.ACCEPTED
+import static org.onap.cps.ncmp.impl.cmnotificationsubscription.models.CmSubscriptionStatus.REJECTED
+
 @SpringBootTest(classes = [ObjectMapper, JsonObjectMapper])
-class CmNotificationSubscriptionDmiOutEventConsumerSpec extends MessagingBaseSpec {
+class DmiOutEventConsumerSpec extends MessagingBaseSpec {
 
     @Autowired
     JsonObjectMapper jsonObjectMapper
@@ -48,27 +52,27 @@ class CmNotificationSubscriptionDmiOutEventConsumerSpec extends MessagingBaseSpe
     @Autowired
     ObjectMapper objectMapper
 
-    def mockDmiCmNotificationSubscriptionCacheHandler = Mock(DmiCmNotificationSubscriptionCacheHandler)
-    def mockCmNotificationSubscriptionEventsHandler = Mock(CmNotificationSubscriptionEventsHandler)
-    def mockCmNotificationSubscriptionMappersHandler = Mock(CmNotificationSubscriptionMappersHandler)
+    def mockDmiCacheHandler = Mock(DmiCacheHandler)
+    def mockEventsHandler = Mock(EventsFacade)
+    def mockMappersHandler = Mock(MappersFacade)
 
-    def objectUnderTest = new CmNotificationSubscriptionDmiOutEventConsumer(mockDmiCmNotificationSubscriptionCacheHandler, mockCmNotificationSubscriptionEventsHandler, mockCmNotificationSubscriptionMappersHandler)
+    def objectUnderTest = new DmiOutEventConsumer(mockDmiCacheHandler, mockEventsHandler, mockMappersHandler)
     def logger = Spy(ListAppender<ILoggingEvent>)
 
     void setup() {
-        ((Logger) LoggerFactory.getLogger(CmNotificationSubscriptionDmiOutEventConsumer.class)).addAppender(logger)
+        ((Logger) LoggerFactory.getLogger(DmiOutEventConsumer.class)).addAppender(logger)
         logger.start()
     }
 
     void cleanup() {
-        ((Logger) LoggerFactory.getLogger(CmNotificationSubscriptionDmiOutEventConsumer.class)).detachAndStopAllAppenders()
+        ((Logger) LoggerFactory.getLogger(DmiOutEventConsumer.class)).detachAndStopAllAppenders()
     }
 
 
     def 'Consume valid CM Subscription response from DMI Plugin'() {
         given: 'a cmsubscription event'
             def jsonData = TestUtils.getResourceFileContent('cmSubscription/cmNotificationSubscriptionDmiOutEvent.json')
-            def testEventSent = jsonObjectMapper.convertJsonString(jsonData, CmNotificationSubscriptionDmiOutEvent.class)
+            def testEventSent = jsonObjectMapper.convertJsonString(jsonData, DmiOutEvent.class)
             def testCloudEventSent = CloudEventBuilder.v1()
                 .withData(objectMapper.writeValueAsBytes(testEventSent))
                 .withId('random-uuid')
@@ -77,7 +81,7 @@ class CmNotificationSubscriptionDmiOutEventConsumerSpec extends MessagingBaseSpe
                 .withExtension('correlationid', 'sub-1#test-dmi-plugin-name').build()
             def consumerRecord = new ConsumerRecord<String, CloudEvent>('topic-name', 0, 0, 'event-key', testCloudEventSent)
         when: 'the valid event is consumed'
-            objectUnderTest.consumeCmNotificationSubscriptionDmiOutEvent(consumerRecord)
+            objectUnderTest.consumeDmiOutEvent(consumerRecord)
         then: 'an event is logged with level INFO'
             def loggingEvent = getLoggingEvent()
             assert loggingEvent.level == Level.INFO
@@ -88,28 +92,28 @@ class CmNotificationSubscriptionDmiOutEventConsumerSpec extends MessagingBaseSpe
     def 'Consume a valid CM Notification Subscription Event and perform correct actions base on status'() {
         given: 'a cmNotificationSubscription event'
             def dmiOutEventData = new Data(statusCode: statusCode, statusMessage: subscriptionStatus.toString())
-            def cmNotificationSubscriptionDmiOutEvent = new CmNotificationSubscriptionDmiOutEvent().withData(dmiOutEventData)
+            def dmiOutEvent = new DmiOutEvent().withData(dmiOutEventData)
             def testCloudEventSent = CloudEventBuilder.v1()
-                .withData(objectMapper.writeValueAsBytes(cmNotificationSubscriptionDmiOutEvent))
+                .withData(objectMapper.writeValueAsBytes(dmiOutEvent))
                 .withId('random-uuid')
                 .withType('subscriptionCreateResponse')
                 .withSource(URI.create('test-dmi-plugin-name'))
                 .withExtension('correlationid', 'sub-1#test-dmi-plugin-name').build()
             def consumerRecord = new ConsumerRecord<String, CloudEvent>('topic-name', 0, 0, 'event-key', testCloudEventSent)
         when: 'the event is consumed'
-            objectUnderTest.consumeCmNotificationSubscriptionDmiOutEvent(consumerRecord)
+            objectUnderTest.consumeDmiOutEvent(consumerRecord)
         then: 'correct number of calls to cache'
-            expectedCacheCalls * mockDmiCmNotificationSubscriptionCacheHandler.updateDmiCmNotificationSubscriptionStatusPerDmi('sub-1','test-dmi-plugin-name', subscriptionStatus)
+            expectedCacheCalls * mockDmiCacheHandler.updateDmiSubscriptionStatusPerDmi('sub-1','test-dmi-plugin-name', subscriptionStatus)
         and: 'correct number of calls to persist cache'
-            expectedPersistenceCalls * mockDmiCmNotificationSubscriptionCacheHandler.persistIntoDatabasePerDmi('sub-1','test-dmi-plugin-name')
+            expectedPersistenceCalls * mockDmiCacheHandler.persistIntoDatabasePerDmi('sub-1','test-dmi-plugin-name')
         and: 'correct number of calls to map the ncmp out event'
-            1 * mockCmNotificationSubscriptionMappersHandler.toCmNotificationSubscriptionNcmpOutEvent('sub-1', _)
+            1 * mockMappersHandler.toNcmpOutEvent('sub-1', _)
         and: 'correct number of calls to publish the ncmp out event to client'
-            1 * mockCmNotificationSubscriptionEventsHandler.publishCmNotificationSubscriptionNcmpOutEvent('sub-1', 'subscriptionCreateResponse', _, false)
+            1 * mockEventsHandler.publishNcmpOutEvent('sub-1', 'subscriptionCreateResponse', _, false)
         where: 'the following parameters are used'
-            scenario          | subscriptionStatus                        | statusCode || expectedCacheCalls | expectedPersistenceCalls
-            'Accepted Status' | CmNotificationSubscriptionStatus.ACCEPTED | '1'        || 1                  | 1
-            'Rejected Status' | CmNotificationSubscriptionStatus.REJECTED | '104'      || 1                  | 0
+            scenario          | subscriptionStatus | statusCode || expectedCacheCalls | expectedPersistenceCalls
+            'Accepted Status' | ACCEPTED           | '1'        || 1                  | 1
+            'Rejected Status' | REJECTED           | '104'      || 1                  | 0
     }
 
     def getLoggingEvent() {
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/CmSubscriptionComparatorSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/CmSubscriptionComparatorSpec.groovy
new file mode 100644 (file)
index 0000000..0ebf9a6
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (c) 2024 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.impl.cmnotificationsubscription.ncmp
+
+
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionPredicate
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.utils.CmSubscriptionPersistenceService
+import spock.lang.Specification
+
+import static org.onap.cps.ncmp.api.data.models.DatastoreType.PASSTHROUGH_OPERATIONAL
+
+class CmSubscriptionComparatorSpec extends Specification {
+
+    def mockCmSubscriptionPersistenceService = Mock(CmSubscriptionPersistenceService)
+    def objectUnderTest = new CmSubscriptionComparator(mockCmSubscriptionPersistenceService)
+
+    def 'Find Delta of given list of predicates'() {
+        given: 'A list of predicates'
+            def predicates = [new DmiCmSubscriptionPredicate(['ch-1', 'ch-2'].toSet(), PASSTHROUGH_OPERATIONAL, ['a/1/', 'b/2'].toSet())]
+        and: '3 positive responses and 1 negative.'
+            mockCmSubscriptionPersistenceService.isOngoingCmSubscription(PASSTHROUGH_OPERATIONAL, 'ch-1', 'a/1/') >>> true
+            mockCmSubscriptionPersistenceService.isOngoingCmSubscription(PASSTHROUGH_OPERATIONAL, 'ch-1', 'b/2') >>> true
+            mockCmSubscriptionPersistenceService.isOngoingCmSubscription(PASSTHROUGH_OPERATIONAL, 'ch-2', 'a/1/') >>> true
+            mockCmSubscriptionPersistenceService.isOngoingCmSubscription(PASSTHROUGH_OPERATIONAL, 'ch-2', 'b/2') >>> false
+        when: 'getDelta is called'
+            def result = objectUnderTest.getNewDmiSubscriptionPredicates(predicates)
+        then: 'verify correct delta is returned'
+            assert result.size() == 1
+            assert result[0].targetCmHandleIds[0] == 'ch-2'
+            assert result[0].xpaths[0] == 'b/2'
+
+    }
+
+    def 'Find Delta of given list of predicates when it is an ongoing Cm Subscription'() {
+        given: 'A list of predicates'
+            def predicates = [new DmiCmSubscriptionPredicate(['ch-1'].toSet(), PASSTHROUGH_OPERATIONAL, ['a/1/'].toSet())]
+        and: 'its already present'
+            mockCmSubscriptionPersistenceService.isOngoingCmSubscription(PASSTHROUGH_OPERATIONAL, 'ch-1', 'a/1/') >>> true
+        when: 'getDelta is called'
+            def result = objectUnderTest.getNewDmiSubscriptionPredicates(predicates)
+        then: 'verify correct delta is returned'
+            assert result.size() == 0
+    }
+
+}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/CmSubscriptionHandlerImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/CmSubscriptionHandlerImplSpec.groovy
new file mode 100644 (file)
index 0000000..caefdee
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (c) 2024 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.impl.cmnotificationsubscription.ncmp
+
+import com.fasterxml.jackson.databind.ObjectMapper
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.EventsFacade
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.MappersFacade
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.cache.DmiCacheHandler
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionDetails
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionPredicate
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.utils.CmSubscriptionPersistenceService
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.client_to_ncmp.NcmpInEvent
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_client.NcmpOutEvent
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_dmi.DmiInEvent
+import org.onap.cps.ncmp.utils.TestUtils
+import org.onap.cps.utils.JsonObjectMapper
+import spock.lang.Specification
+
+import static org.onap.cps.ncmp.api.data.models.DatastoreType.PASSTHROUGH_OPERATIONAL
+import static org.onap.cps.ncmp.impl.cmnotificationsubscription.models.CmSubscriptionStatus.ACCEPTED
+import static org.onap.cps.ncmp.impl.cmnotificationsubscription.models.CmSubscriptionStatus.PENDING
+
+class CmSubscriptionHandlerImplSpec extends Specification {
+
+    def jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
+    def mockCmSubscriptionPersistenceService = Mock(CmSubscriptionPersistenceService);
+    def mockCmSubscriptionComparator = Mock(CmSubscriptionComparator);
+    def mockMappersFacade = Mock(MappersFacade);
+    def mockEventsFacade = Mock(EventsFacade);
+    def mockDmiCacheHandler = Mock(DmiCacheHandler);
+
+    def objectUnderTest = new CmSubscriptionHandlerImpl(mockCmSubscriptionPersistenceService,
+        mockCmSubscriptionComparator, mockMappersFacade,
+        mockEventsFacade, mockDmiCacheHandler)
+
+    def testDmiSubscriptionsPerDmi = ["dmi-1": new DmiCmSubscriptionDetails([], PENDING)]
+
+    def 'Consume valid and unique CmNotificationSubscriptionNcmpInEvent create message'() {
+        given: 'a cmNotificationSubscriptionNcmp in event with unique subscription id'
+            def jsonData = TestUtils.getResourceFileContent('cmSubscription/cmNotificationSubscriptionNcmpInEvent.json')
+            def testEventConsumed = jsonObjectMapper.convertJsonString(jsonData, NcmpInEvent.class)
+            def testListOfDeltaPredicates = [new DmiCmSubscriptionPredicate(['ch1'].toSet(), PASSTHROUGH_OPERATIONAL, ['/a/b'].toSet())]
+            mockCmSubscriptionPersistenceService.isUniqueSubscriptionId("test-id") >> true
+        and: 'relevant details is extracted from the event'
+            def subscriptionId = testEventConsumed.getData().getSubscriptionId()
+            def predicates = testEventConsumed.getData().getPredicates()
+        and: 'the cache handler returns for relevant subscription id'
+            1 * mockDmiCacheHandler.get("test-id") >> testDmiSubscriptionsPerDmi
+        and: 'the delta predicates is returned'
+            1 * mockCmSubscriptionComparator.getNewDmiSubscriptionPredicates(_) >> testListOfDeltaPredicates
+        and: 'the DMI in event mapper returns cm notification subscription event'
+            def testDmiInEvent = new DmiInEvent()
+            1 * mockMappersFacade
+                .toDmiInEvent(testListOfDeltaPredicates) >> testDmiInEvent
+        when: 'the valid and unique event is consumed'
+            objectUnderTest.processSubscriptionCreateRequest(subscriptionId, predicates)
+        then: 'the subscription cache handler is called once'
+            1 * mockDmiCacheHandler.add('test-id', _)
+        and: 'the events handler method to publish DMI event is called correct number of times with the correct parameters'
+            testDmiSubscriptionsPerDmi.size() * mockEventsFacade.publishDmiInEvent(
+                "test-id", "dmi-1", "subscriptionCreateRequest", testDmiInEvent)
+        and: 'we schedule to send the response after configured time from the cache'
+            1 * mockEventsFacade.publishNcmpOutEvent('test-id', 'subscriptionCreateResponse', null, true)
+    }
+
+    def 'Consume valid and Overlapping Cm Notification Subscription NcmpIn Event'() {
+        given: 'a cmNotificationSubscriptionNcmp in event with unique subscription id'
+            def jsonData = TestUtils.getResourceFileContent('cmSubscription/cmNotificationSubscriptionNcmpInEvent.json')
+            def testEventConsumed = jsonObjectMapper.convertJsonString(jsonData, NcmpInEvent.class)
+            def noDeltaPredicates = []
+            mockCmSubscriptionPersistenceService.isUniqueSubscriptionId("test-id") >> true
+        and: 'the cache handler returns for relevant subscription id'
+            1 * mockDmiCacheHandler.get('test-id') >> testDmiSubscriptionsPerDmi
+        and: 'the delta predicates is returned'
+            1 * mockCmSubscriptionComparator.getNewDmiSubscriptionPredicates(_) >> noDeltaPredicates
+        when: 'the valid and unique event is consumed'
+            objectUnderTest.processSubscriptionCreateRequest('test-id', noDeltaPredicates)
+        then: 'the subscription cache handler is called once'
+            1 * mockDmiCacheHandler.add('test-id', _)
+        and: 'the subscription details are updated in the cache'
+            1 * mockDmiCacheHandler.updateDmiSubscriptionStatusPerDmi('test-id', _, ACCEPTED)
+        and: 'we schedule to send the response after configured time from the cache'
+            1 * mockEventsFacade.publishNcmpOutEvent('test-id', 'subscriptionCreateResponse', null, true)
+    }
+
+    def 'Consume valid and but non-unique CmNotificationSubscription create message'() {
+        given: 'a cmNotificationSubscriptionNcmp in event'
+            def jsonData = TestUtils.getResourceFileContent('cmSubscription/cmNotificationSubscriptionNcmpInEvent.json')
+            def testEventConsumed = jsonObjectMapper.convertJsonString(jsonData, NcmpInEvent.class)
+            mockCmSubscriptionPersistenceService.isUniqueSubscriptionId('test-id') >> false
+        and: 'relevant details is extracted from the event'
+            def subscriptionId = testEventConsumed.getData().getSubscriptionId()
+            def predicates = testEventConsumed.getData().getPredicates()
+        and: 'the NCMP out in event mapper returns an event for rejected request'
+            def testNcmpOutEvent = new NcmpOutEvent()
+            1 * mockMappersFacade.toNcmpOutEventForRejectedRequest(
+                "test-id", _) >> testNcmpOutEvent
+        when: 'the valid but non-unique event is consumed'
+            objectUnderTest.processSubscriptionCreateRequest(subscriptionId, predicates)
+        then: 'the events handler method to publish DMI event is never called'
+            0 * mockEventsFacade.publishDmiInEvent(_, _, _, _)
+        and: 'the events handler method to publish NCMP out event is called once'
+            1 * mockEventsFacade.publishNcmpOutEvent('test-id', 'subscriptionCreateResponse', testNcmpOutEvent, false)
+    }
+
+    def 'Consume valid CmNotificationSubscriptionNcmpInEvent delete message'() {
+        given: 'a cmNotificationSubscriptionNcmp in event for delete'
+            def jsonData = TestUtils.getResourceFileContent('cmSubscription/cmNotificationSubscriptionNcmpInEvent.json')
+            def testEventConsumed = jsonObjectMapper.convertJsonString(jsonData, NcmpInEvent.class)
+        and: 'relevant details is extracted from the event'
+            def subscriptionId = testEventConsumed.getData().getSubscriptionId()
+            def predicates = testEventConsumed.getData().getPredicates()
+        and: 'the cache handler returns for relevant subscription id'
+            1 * mockDmiCacheHandler.get('test-id') >> testDmiSubscriptionsPerDmi
+        when: 'the valid and unique event is consumed'
+            objectUnderTest.processSubscriptionDeleteRequest(subscriptionId, predicates)
+        then: 'the subscription cache handler is called once'
+            1 * mockDmiCacheHandler.add('test-id', predicates)
+        and: 'the mapper handler to get DMI in event is called once'
+            1 * mockMappersFacade.toDmiInEvent(_)
+        and: 'the events handler method to publish DMI event is called correct number of times with the correct parameters'
+            testDmiSubscriptionsPerDmi.size() * mockEventsFacade.publishDmiInEvent(
+                'test-id', 'dmi-1', 'subscriptionDeleteRequest', _)
+        and: 'we schedule to send the response after configured time from the cache'
+            1 * mockEventsFacade.publishNcmpOutEvent('test-id', 'subscriptionDeleteResponse', null, true)
+    }
+}
@@ -18,7 +18,7 @@
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription
+package org.onap.cps.ncmp.impl.cmnotificationsubscription.ncmp
 
 import ch.qos.logback.classic.Level
 import ch.qos.logback.classic.Logger
@@ -28,10 +28,8 @@ import com.fasterxml.jackson.databind.ObjectMapper
 import io.cloudevents.CloudEvent
 import io.cloudevents.core.builder.CloudEventBuilder
 import org.apache.kafka.clients.consumer.ConsumerRecord
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.consumer.CmNotificationSubscriptionNcmpInEventConsumer
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.service.CmNotificationSubscriptionHandlerService
 import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.client_to_ncmp.CmNotificationSubscriptionNcmpInEvent
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.client_to_ncmp.NcmpInEvent
 import org.onap.cps.ncmp.utils.TestUtils
 import org.onap.cps.utils.JsonObjectMapper
 import org.slf4j.LoggerFactory
@@ -39,10 +37,10 @@ import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.boot.test.context.SpringBootTest
 
 @SpringBootTest(classes = [ObjectMapper, JsonObjectMapper])
-class CmNotificationSubscriptionNcmpInEventConsumerSpec extends MessagingBaseSpec {
+class NcmpInEventConsumerSpec extends MessagingBaseSpec {
 
-    def mockCmNotificationSubscriptionHandlerService = Mock(CmNotificationSubscriptionHandlerService)
-    def objectUnderTest = new CmNotificationSubscriptionNcmpInEventConsumer(mockCmNotificationSubscriptionHandlerService)
+    def mockCmSubscriptionHandler = Mock(CmSubscriptionHandler)
+    def objectUnderTest = new NcmpInEventConsumer(mockCmSubscriptionHandler)
     def logger = Spy(ListAppender<ILoggingEvent>)
 
     @Autowired
@@ -52,19 +50,19 @@ class CmNotificationSubscriptionNcmpInEventConsumerSpec extends MessagingBaseSpe
     ObjectMapper objectMapper
 
     void setup() {
-        ((Logger) LoggerFactory.getLogger(CmNotificationSubscriptionNcmpInEventConsumer.class)).addAppender(logger)
+        ((Logger) LoggerFactory.getLogger(NcmpInEventConsumer.class)).addAppender(logger)
         logger.start()
     }
 
     void cleanup() {
-        ((Logger) LoggerFactory.getLogger(CmNotificationSubscriptionNcmpInEventConsumer.class)).detachAndStopAllAppenders()
+        ((Logger) LoggerFactory.getLogger(NcmpInEventConsumer.class)).detachAndStopAllAppenders()
     }
 
 
     def 'Consume valid CmNotificationSubscriptionNcmpInEvent create message'() {
         given: 'a cmNotificationSubscription event'
             def jsonData = TestUtils.getResourceFileContent('cmSubscription/cmNotificationSubscriptionNcmpInEvent.json')
-            def testEventSent = jsonObjectMapper.convertJsonString(jsonData, CmNotificationSubscriptionNcmpInEvent.class)
+            def testEventSent = jsonObjectMapper.convertJsonString(jsonData, NcmpInEvent.class)
             def testCloudEventSent = CloudEventBuilder.v1()
                 .withData(objectMapper.writeValueAsBytes(testEventSent))
                 .withId('subscriptionCreated')
@@ -80,13 +78,13 @@ class CmNotificationSubscriptionNcmpInEventConsumerSpec extends MessagingBaseSpe
         and: 'the log indicates the task completed successfully'
             assert loggingEvent.formattedMessage == 'Subscription create request for source some-resource with subscription id test-id ...'
         and: 'the subscription handler service is called once'
-            1 * mockCmNotificationSubscriptionHandlerService.processSubscriptionCreateRequest('test-id',_)
+            1 * mockCmSubscriptionHandler.processSubscriptionCreateRequest('test-id',_)
     }
 
     def 'Consume valid CmNotificationSubscriptionNcmpInEvent delete message'() {
         given: 'a cmNotificationSubscription event'
             def jsonData = TestUtils.getResourceFileContent('cmSubscription/cmNotificationSubscriptionNcmpInEvent.json')
-            def testEventSent = jsonObjectMapper.convertJsonString(jsonData, CmNotificationSubscriptionNcmpInEvent.class)
+            def testEventSent = jsonObjectMapper.convertJsonString(jsonData, NcmpInEvent.class)
             def testCloudEventSent = CloudEventBuilder.v1()
                 .withData(objectMapper.writeValueAsBytes(testEventSent))
                 .withId('sub-id')
@@ -102,7 +100,7 @@ class CmNotificationSubscriptionNcmpInEventConsumerSpec extends MessagingBaseSpe
         and: 'the log indicates the task completed successfully'
             assert loggingEvent.formattedMessage == 'Subscription delete request for source some-resource with subscription id test-id ...'
         and: 'the subscription handler service is called once'
-            1 * mockCmNotificationSubscriptionHandlerService.processSubscriptionDeleteRequest('test-id',_)
+            1 * mockCmSubscriptionHandler.processSubscriptionDeleteRequest('test-id',_)
     }
 
 
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventMapperSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventMapperSpec.groovy
new file mode 100644 (file)
index 0000000..2251a33
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2024 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.impl.cmnotificationsubscription.ncmp
+
+
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionDetails
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionPredicate
+import spock.lang.Specification
+
+import static org.onap.cps.ncmp.api.data.models.DatastoreType.PASSTHROUGH_OPERATIONAL
+import static org.onap.cps.ncmp.api.data.models.DatastoreType.PASSTHROUGH_RUNNING
+import static org.onap.cps.ncmp.impl.cmnotificationsubscription.models.CmSubscriptionStatus.ACCEPTED
+import static org.onap.cps.ncmp.impl.cmnotificationsubscription.models.CmSubscriptionStatus.PENDING
+import static org.onap.cps.ncmp.impl.cmnotificationsubscription.models.CmSubscriptionStatus.REJECTED
+
+class NcmpOutEventMapperSpec extends Specification {
+
+    static Map<String, DmiCmSubscriptionDetails> dmiSubscriptionsPerDmi
+
+    def objectUnderTest = new NcmpOutEventMapper()
+
+    def setup() {
+        def dmiSubscriptionPredicateA = new DmiCmSubscriptionPredicate(['ch-A'] as Set, PASSTHROUGH_RUNNING, ['/a'] as Set)
+        def dmiSubscriptionPredicateB = new DmiCmSubscriptionPredicate(['ch-B'] as Set, PASSTHROUGH_OPERATIONAL, ['/b'] as Set)
+        def dmiSubscriptionPredicateC = new DmiCmSubscriptionPredicate(['ch-C'] as Set, PASSTHROUGH_OPERATIONAL, ['/c'] as Set)
+        dmiSubscriptionsPerDmi = ['dmi-1': new DmiCmSubscriptionDetails([dmiSubscriptionPredicateA], PENDING),
+                                  'dmi-2': new DmiCmSubscriptionDetails([dmiSubscriptionPredicateB], ACCEPTED),
+                                  'dmi-3': new DmiCmSubscriptionDetails([dmiSubscriptionPredicateC], REJECTED)
+        ]
+    }
+
+    def 'Check for Cm Notification Subscription Outgoing event mapping'() {
+        when: 'we try to map the event to send it to client'
+            def result = objectUnderTest.toNcmpOutEvent('test-subscription', dmiSubscriptionsPerDmi)
+        then: 'event is mapped correctly for the subscription'
+            result.data.subscriptionId == 'test-subscription'
+        and: 'the cm handle ids are part of correct list'
+            result.data.pendingTargets == ['ch-A']
+            result.data.acceptedTargets == ['ch-B']
+            result.data.rejectedTargets == ['ch-C']
+    }
+
+    def 'Check for Cm Notification Rejected Subscription Outgoing event mapping'() {
+        when: 'we try to map the event to send it to client'
+            def result = objectUnderTest.toNcmpOutEventForRejectedRequest('test-subscription', ['ch-1', 'ch-2'])
+        then: 'event is mapped correctly for the subscription id'
+            result.data.subscriptionId == 'test-subscription'
+        and: 'the cm handle ids are part of correct list'
+            result.data.withRejectedTargets(['ch-1', 'ch-2'])
+    }
+}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventProducerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventProducerSpec.groovy
new file mode 100644 (file)
index 0000000..f96f3df
--- /dev/null
@@ -0,0 +1,89 @@
+package org.onap.cps.ncmp.impl.cmnotificationsubscription.ncmp
+
+import com.fasterxml.jackson.databind.ObjectMapper
+import io.cloudevents.CloudEvent
+import org.onap.cps.events.EventsPublisher
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.MappersFacade
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.cache.DmiCacheHandler
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_client.Data
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_client.NcmpOutEvent
+import org.onap.cps.ncmp.utils.events.CloudEventMapper
+import org.onap.cps.utils.JsonObjectMapper
+import spock.lang.Specification
+
+class NcmpOutEventProducerSpec extends Specification {
+
+    def mockEventsPublisher = Mock(EventsPublisher)
+    def jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
+    def mockCmNotificationSubscriptionMappersHandler = Mock(MappersFacade)
+    def mockDmiCmNotificationSubscriptionCacheHandler = Mock(DmiCacheHandler)
+
+    def objectUnderTest = new NcmpOutEventProducer(mockEventsPublisher, jsonObjectMapper,
+        mockCmNotificationSubscriptionMappersHandler, mockDmiCmNotificationSubscriptionCacheHandler)
+
+    def 'Create and #scenario Cm Notification Subscription NCMP out event'() {
+        given: 'a cm subscription response for the client'
+            def subscriptionId = 'test-subscription-id-2'
+            def eventType = 'subscriptionCreateResponse'
+            def ncmpOutEvent = new NcmpOutEvent(data: new Data(subscriptionId: 'test-subscription-id-2', acceptedTargets: ['ch-1', 'ch-2']))
+        and: 'also we have target topic for publishing to client'
+            objectUnderTest.ncmpOutEventTopic = 'client-test-topic'
+        and: 'a deadline to an event'
+            objectUnderTest.dmiOutEventTimeoutInMs = 1000
+        when: 'the event is published'
+            objectUnderTest.publishNcmpOutEvent(subscriptionId, eventType, ncmpOutEvent, eventPublishingTaskToBeScheduled)
+        then: 'we conditionally wait for a while'
+            Thread.sleep(delayInMs)
+        then: 'the event contains the required attributes'
+            1 * mockEventsPublisher.publishCloudEvent(_, _, _) >> {
+                args ->
+                    {
+                        assert args[0] == 'client-test-topic'
+                        assert args[1] == subscriptionId
+                        def ncmpOutEventAsCloudEvent = (args[2] as CloudEvent)
+                        assert ncmpOutEventAsCloudEvent.getExtension('correlationid') == subscriptionId
+                        assert ncmpOutEventAsCloudEvent.type == 'subscriptionCreateResponse'
+                        assert ncmpOutEventAsCloudEvent.source.toString() == 'NCMP'
+                        assert CloudEventMapper.toTargetEvent(ncmpOutEventAsCloudEvent, NcmpOutEvent) == ncmpOutEvent
+                    }
+            }
+        where: 'following scenarios are considered'
+            scenario                                          | delayInMs | eventPublishingTaskToBeScheduled
+            'publish event now'                               | 0         | false
+            'schedule and publish after the configured time ' | 1500      | true
+    }
+
+    def 'Schedule Cm Notification Subscription NCMP out event but later publish it on demand'() {
+        given: 'a cm subscription response for the client'
+            def subscriptionId = 'test-subscription-id-3'
+            def eventType = 'subscriptionCreateResponse'
+            def ncmpOutEvent = new NcmpOutEvent(data: new Data(subscriptionId: 'test-subscription-id-3', acceptedTargets: ['ch-2', 'ch-3']))
+        and: 'also we have target topic for publishing to client'
+            objectUnderTest.ncmpOutEventTopic = 'client-test-topic'
+        and: 'a deadline to an event'
+            objectUnderTest.dmiOutEventTimeoutInMs = 1000
+        when: 'the event is scheduled to be published'
+            objectUnderTest.publishNcmpOutEvent(subscriptionId, eventType, ncmpOutEvent, true)
+        then: 'we wait for 10ms and then we receive response from DMI'
+            Thread.sleep(10)
+        and: 'we receive response from DMI so we publish the message on demand'
+            objectUnderTest.publishNcmpOutEvent(subscriptionId, eventType, ncmpOutEvent, false)
+        then: 'the event contains the required attributes'
+            1 * mockEventsPublisher.publishCloudEvent(_, _, _) >> {
+                args ->
+                    {
+                        assert args[0] == 'client-test-topic'
+                        assert args[1] == subscriptionId
+                        def ncmpOutEventAsCloudEvent = (args[2] as CloudEvent)
+                        assert ncmpOutEventAsCloudEvent.getExtension('correlationid') == subscriptionId
+                        assert ncmpOutEventAsCloudEvent.type == 'subscriptionCreateResponse'
+                        assert ncmpOutEventAsCloudEvent.source.toString() == 'NCMP'
+                        assert CloudEventMapper.toTargetEvent(ncmpOutEventAsCloudEvent, NcmpOutEvent) == ncmpOutEvent
+                    }
+            }
+        then: 'the cache handler is called once to remove accepted and rejected entries in cache'
+            1 * mockDmiCmNotificationSubscriptionCacheHandler.removeAcceptedAndRejectedDmiSubscriptionEntries(subscriptionId)
+    }
+
+
+}
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription.service
+package org.onap.cps.ncmp.impl.cmnotificationsubscription.utils
 
 import com.fasterxml.jackson.databind.ObjectMapper
 import org.onap.cps.api.CpsDataService
 import org.onap.cps.api.CpsQueryService
-import org.onap.cps.ncmp.api.data.models.DatastoreType
-import org.onap.cps.spi.FetchDescendantsOption
 import org.onap.cps.spi.model.DataNode
 import org.onap.cps.utils.ContentType
 import org.onap.cps.utils.JsonObjectMapper
 import spock.lang.Specification
 
-import static org.onap.cps.ncmp.api.impl.events.cmsubscription.service.CmNotificationSubscriptionPersistenceServiceImpl.CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_FILTERS_WITH_DATASTORE_AND_CMHANDLE
-import static org.onap.cps.ncmp.api.impl.events.cmsubscription.service.CmNotificationSubscriptionPersistenceServiceImpl.CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_WITH_DATASTORE_CMHANDLE_AND_XPATH
-import static org.onap.cps.ncmp.api.impl.events.cmsubscription.service.CmNotificationSubscriptionPersistenceServiceImpl.CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_WITH_ID
+import static CmSubscriptionPersistenceService.CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_FILTERS_WITH_DATASTORE_AND_CMHANDLE
+import static CmSubscriptionPersistenceService.CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_WITH_DATASTORE_CMHANDLE_AND_XPATH
+import static CmSubscriptionPersistenceService.CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_WITH_ID
+import static org.onap.cps.ncmp.api.data.models.DatastoreType.PASSTHROUGH_OPERATIONAL
+import static org.onap.cps.ncmp.api.data.models.DatastoreType.PASSTHROUGH_RUNNING
+import static org.onap.cps.spi.FetchDescendantsOption.DIRECT_CHILDREN_ONLY
+import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS
 
-class CmNotificationSubscriptionPersistenceServiceImplSpec extends Specification {
+class CmSubscriptionPersistenceServiceSpec extends Specification {
 
     def jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
     def mockCpsQueryService = Mock(CpsQueryService)
     def mockCpsDataService = Mock(CpsDataService)
 
-    def objectUnderTest = new CmNotificationSubscriptionPersistenceServiceImpl(jsonObjectMapper, mockCpsQueryService, mockCpsDataService)
+    def objectUnderTest = new CmSubscriptionPersistenceService(jsonObjectMapper, mockCpsQueryService, mockCpsDataService)
 
     def 'Check ongoing cm subscription #scenario'() {
         given: 'a valid cm subscription query'
-            def cpsPathQuery = "/datastores/datastore[@name='ncmp-datastore:passthrough-running']/cm-handles/cm-handle[@id='ch-1']/filters/filter[@xpath='/cps/path']";
+            def cpsPathQuery = "/datastores/datastore[@name='ncmp-datastore:passthrough-running']/cm-handles/cm-handle[@id='ch-1']/filters/filter[@xpath='/cps/path']"
         and: 'datanodes optionally returned'
             1 * mockCpsQueryService.queryDataNodes('NCMP-Admin', 'cm-data-subscriptions',
-                cpsPathQuery, FetchDescendantsOption.OMIT_DESCENDANTS) >> dataNode
+                cpsPathQuery, OMIT_DESCENDANTS) >> dataNode
         when: 'we check for an ongoing cm subscription'
-            def response = objectUnderTest.isOngoingCmNotificationSubscription(DatastoreType.PASSTHROUGH_RUNNING, 'ch-1', '/cps/path')
+            def response = objectUnderTest.isOngoingCmSubscription(PASSTHROUGH_RUNNING, 'ch-1', '/cps/path')
         then: 'we get expected response'
             assert response == isOngoingCmSubscription
         where: 'following scenarios are used'
@@ -63,7 +65,7 @@ class CmNotificationSubscriptionPersistenceServiceImplSpec extends Specification
         given: 'a cps path with a subscription ID for querying'
             def cpsPathQuery = CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_WITH_ID.formatted('some-sub')
         and: 'relevant datanodes are returned'
-            1 * mockCpsQueryService.queryDataNodes('NCMP-Admin', 'cm-data-subscriptions', cpsPathQuery, FetchDescendantsOption.OMIT_DESCENDANTS) >>
+            1 * mockCpsQueryService.queryDataNodes('NCMP-Admin', 'cm-data-subscriptions', cpsPathQuery, OMIT_DESCENDANTS) >>
                 dataNodes
         when: 'a subscription ID is tested for uniqueness'
             def result = objectUnderTest.isUniqueSubscriptionId('some-sub')
@@ -77,18 +79,18 @@ class CmNotificationSubscriptionPersistenceServiceImplSpec extends Specification
 
     def 'Add new subscriber to an ongoing cm notification subscription'() {
         given: 'a valid cm subscription path query'
-            def cpsPathQuery =CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_WITH_DATASTORE_CMHANDLE_AND_XPATH.formatted('ncmp-datastore:passthrough-running', 'ch-1', '/x/y')
+            def cpsPathQuery = CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_WITH_DATASTORE_CMHANDLE_AND_XPATH.formatted('ncmp-datastore:passthrough-running', 'ch-1', '/x/y')
         and: 'a dataNode exists for the given cps path query'
             mockCpsQueryService.queryDataNodes('NCMP-Admin', 'cm-data-subscriptions',
-                cpsPathQuery, FetchDescendantsOption.OMIT_DESCENDANTS) >> [new DataNode(xpath: cpsPathQuery, leaves: ['xpath': '/x/y','subscriptionIds': ['sub-1']])]
+                cpsPathQuery, OMIT_DESCENDANTS) >> [new DataNode(xpath: cpsPathQuery, leaves: ['xpath': '/x/y', 'subscriptionIds': ['sub-1']])]
         when: 'the method to add/update cm notification subscription is called'
-            objectUnderTest.addCmNotificationSubscription(DatastoreType.PASSTHROUGH_RUNNING, 'ch-1','/x/y', 'newSubId')
+            objectUnderTest.addCmSubscription(PASSTHROUGH_RUNNING, 'ch-1', '/x/y', 'newSubId')
         then: 'data service method to update list of subscribers is called once'
             1 * mockCpsDataService.updateNodeLeaves(
                 'NCMP-Admin',
                 'cm-data-subscriptions',
                 '/datastores/datastore[@name=\'ncmp-datastore:passthrough-running\']/cm-handles/cm-handle[@id=\'ch-1\']/filters',
-                objectUnderTest.getSubscriptionDetailsAsJson('/x/y', ['sub-1','newSubId']), _,ContentType.JSON)
+                objectUnderTest.getSubscriptionDetailsAsJson('/x/y', ['sub-1', 'newSubId']), _, ContentType.JSON)
     }
 
     def 'Add new cm notification subscription for #datastoreType'() {
@@ -100,25 +102,25 @@ class CmNotificationSubscriptionPersistenceServiceImplSpec extends Specification
         and: 'a datanode does not exist for cm subscription path query'
             mockCpsQueryService.queryDataNodes('NCMP-Admin', 'cm-data-subscriptions',
                 cmSubscriptionCpsPathQuery,
-                FetchDescendantsOption.OMIT_DESCENDANTS) >> []
+                OMIT_DESCENDANTS) >> []
         and: 'a datanode does not exist for the given cm handle subscription path query'
             mockCpsQueryService.queryDataNodes('NCMP-Admin', 'cm-data-subscriptions',
-                cmHandleForSubscriptionPathQuery, FetchDescendantsOption.OMIT_DESCENDANTS) >> []
+                cmHandleForSubscriptionPathQuery, OMIT_DESCENDANTS) >> []
         and: 'subscription is mapped as JSON'
             def subscriptionAsJson = '{"cm-handle":[{"id":"ch-1","filters":' +
                 objectUnderTest.getSubscriptionDetailsAsJson('/x/y', ['newSubId']) + '}]}'
         when: 'the method to add/update cm notification subscription is called'
-            objectUnderTest.addCmNotificationSubscription(datastoreType, 'ch-1','/x/y', 'newSubId')
+            objectUnderTest.addCmSubscription(datastoreType, 'ch-1', '/x/y', 'newSubId')
         then: 'data service method to create new subscription for given subscriber is called once with the correct parameters'
             1 * mockCpsDataService.saveData(
                 'NCMP-Admin',
                 'cm-data-subscriptions',
                 parentNodeXpath.formatted(datastoreName),
-                subscriptionAsJson,_, ContentType.JSON)
+                subscriptionAsJson, _, ContentType.JSON)
         where:
-            scenario                  | datastoreType                          || datastoreName
-            'passthrough_running'     | DatastoreType.PASSTHROUGH_RUNNING      || "ncmp-datastore:passthrough-running"
-            'passthrough_operational' | DatastoreType.PASSTHROUGH_OPERATIONAL  || "ncmp-datastore:passthrough-operational"
+            scenario                  | datastoreType           || datastoreName
+            'passthrough_running'     | PASSTHROUGH_RUNNING     || 'ncmp-datastore:passthrough-running'
+            'passthrough_operational' | PASSTHROUGH_OPERATIONAL || 'ncmp-datastore:passthrough-operational'
     }
 
     def 'Add new cm notification subscription when xpath does not exist for existing subscription cm handle'() {
@@ -129,52 +131,49 @@ class CmNotificationSubscriptionPersistenceServiceImplSpec extends Specification
             def parentNodeXpath = '/datastores/datastore[@name=\'%s\']/cm-handles/cm-handle[@id=\'%s\']/filters'
         and: 'a datanode does not exist for cm subscription path query'
             mockCpsQueryService.queryDataNodes('NCMP-Admin', 'cm-data-subscriptions',
-                cmSubscriptionCpsPathQuery, FetchDescendantsOption.OMIT_DESCENDANTS) >> []
+                cmSubscriptionCpsPathQuery, OMIT_DESCENDANTS) >> []
         and: 'a datanode exists for the given cm handle subscription path query'
             mockCpsQueryService.queryDataNodes('NCMP-Admin', 'cm-data-subscriptions',
-                cmHandleForSubscriptionPathQuery, FetchDescendantsOption.OMIT_DESCENDANTS) >> [new DataNode()]
+                cmHandleForSubscriptionPathQuery, OMIT_DESCENDANTS) >> [new DataNode()]
         when: 'the method to add/update cm notification subscription is called'
-            objectUnderTest.addCmNotificationSubscription(datastoreType, 'ch-1','/x/y', 'newSubId')
+            objectUnderTest.addCmSubscription(datastoreType, 'ch-1', '/x/y', 'newSubId')
         then: 'data service method to create new subscription for given subscriber is called once with the correct parameters'
             1 * mockCpsDataService.saveListElements(
                 'NCMP-Admin',
                 'cm-data-subscriptions',
                 parentNodeXpath.formatted(datastoreName, 'ch-1'),
-                objectUnderTest.getSubscriptionDetailsAsJson('/x/y', ['newSubId']),_)
+                objectUnderTest.getSubscriptionDetailsAsJson('/x/y', ['newSubId']), _)
         where:
-            scenario                  | datastoreType                          || datastoreName
-            'passthrough_running'     | DatastoreType.PASSTHROUGH_RUNNING      || "ncmp-datastore:passthrough-running"
-            'passthrough_operational' | DatastoreType.PASSTHROUGH_OPERATIONAL  || "ncmp-datastore:passthrough-operational"
+            scenario                  | datastoreType           || datastoreName
+            'passthrough_running'     | PASSTHROUGH_RUNNING     || 'ncmp-datastore:passthrough-running'
+            'passthrough_operational' | PASSTHROUGH_OPERATIONAL || 'ncmp-datastore:passthrough-operational'
     }
 
     def 'Remove subscriber from a list of an ongoing cm notification subscription'() {
         given: 'a subscription exists when queried'
             def cpsPathQuery = CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_WITH_DATASTORE_CMHANDLE_AND_XPATH.formatted('ncmp-datastore:passthrough-running', 'ch-1', '/x/y')
             mockCpsQueryService.queryDataNodes('NCMP-Admin', 'cm-data-subscriptions',
-                cpsPathQuery, FetchDescendantsOption.OMIT_DESCENDANTS) >> [new DataNode(xpath: cpsPathQuery, leaves: ['xpath': '/x/y','subscriptionIds': ['sub-1', 'sub-2']])]
+                cpsPathQuery, OMIT_DESCENDANTS) >> [new DataNode(xpath: cpsPathQuery, leaves: ['xpath': '/x/y', 'subscriptionIds': ['sub-1', 'sub-2']])]
         when: 'the subscriber is removed'
-            objectUnderTest.removeCmNotificationSubscription(DatastoreType.PASSTHROUGH_RUNNING, 'ch-1', '/x/y', 'sub-1')
+            objectUnderTest.removeCmSubscription(PASSTHROUGH_RUNNING, 'ch-1', '/x/y', 'sub-1')
         then: 'the list of subscribers is updated'
             1 * mockCpsDataService.updateNodeLeaves('NCMP-Admin', 'cm-data-subscriptions',
                 '/datastores/datastore[@name=\'ncmp-datastore:passthrough-running\']/cm-handles/cm-handle[@id=\'ch-1\']/filters',
                 objectUnderTest.getSubscriptionDetailsAsJson('/x/y', ['sub-2']), _, ContentType.JSON)
     }
 
-    def 'Removing last ongoing subscription for datastore and cmhandle and xpath'(){
+    def 'Removing last ongoing subscription for datastore and cmhandle and xpath'() {
         given: 'a subscription exists when queried but has only 1 subscriber'
             mockCpsQueryService.queryDataNodes(
-                'NCMP-Admin',
-                'cm-data-subscriptions',
+                'NCMP-Admin', 'cm-data-subscriptions',
                 CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_WITH_DATASTORE_CMHANDLE_AND_XPATH.formatted('ncmp-datastore:passthrough-running', 'ch-1', '/x/y'),
-                FetchDescendantsOption.OMIT_DESCENDANTS) >> [new DataNode(leaves: ['xpath': '/x/y','subscriptionIds': ['sub-1']])]
+                OMIT_DESCENDANTS) >> [new DataNode(leaves: ['xpath': '/x/y', 'subscriptionIds': ['sub-1']])]
         and: 'the #scenario'
-            mockCpsQueryService.queryDataNodes(
-                'NCMP-Admin',
-                'cm-data-subscriptions',
+            mockCpsQueryService.queryDataNodes('NCMP-Admin', 'cm-data-subscriptions',
                 CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_FILTERS_WITH_DATASTORE_AND_CMHANDLE.formatted('ncmp-datastore:passthrough-running', 'ch-1'),
-                FetchDescendantsOption.DIRECT_CHILDREN_ONLY) >> [new DataNode(childDataNodes: listOfChildNodes)]
+                DIRECT_CHILDREN_ONLY) >> [new DataNode(childDataNodes: listOfChildNodes)]
         when: 'that last ongoing subscription is removed'
-            objectUnderTest.removeCmNotificationSubscription(DatastoreType.PASSTHROUGH_RUNNING, 'ch-1', '/x/y', 'sub-1')
+            objectUnderTest.removeCmSubscription(PASSTHROUGH_RUNNING, 'ch-1', '/x/y', 'sub-1')
         then: 'the subscription with empty subscriber list is removed'
             1 * mockCpsDataService.deleteDataNode('NCMP-Admin', 'cm-data-subscriptions',
                 '/datastores/datastore[@name=\'ncmp-datastore:passthrough-running\']/cm-handles/cm-handle[@id=\'ch-1\']/filters/filter[@xpath=\'/x/y\']',
@@ -184,9 +183,9 @@ class CmNotificationSubscriptionPersistenceServiceImplSpec extends Specification
                 '/datastores/datastore[@name=\'ncmp-datastore:passthrough-running\']/cm-handles/cm-handle[@id=\'ch-1\']',
                 _)
         where:
-            scenario                                                            | listOfChildNodes  || numberOfCallsToDeleteCmHandle
-            'cm handle in same datastore is used for other subscriptions'       | [new DataNode()]  || 0
-            'cm handle in same datastore is NOT used for other subscriptions'   | []                || 1
+            scenario                                                          | listOfChildNodes || numberOfCallsToDeleteCmHandle
+            'cm handle in same datastore is used for other subscriptions'     | [new DataNode()] || 0
+            'cm handle in same datastore is NOT used for other subscriptions' | []               || 1
     }
 
 }
index c2768f1..49a4b4d 100644 (file)
@@ -21,7 +21,7 @@
 package org.onap.cps.integration.functional
 
 import org.onap.cps.integration.base.CpsIntegrationSpecBase
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.service.CmNotificationSubscriptionPersistenceService
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.utils.CmSubscriptionPersistenceService
 import org.springframework.beans.factory.annotation.Autowired
 
 import static org.onap.cps.ncmp.api.data.models.DatastoreType.PASSTHROUGH_RUNNING
@@ -29,23 +29,22 @@ import static org.onap.cps.ncmp.api.data.models.DatastoreType.PASSTHROUGH_RUNNIN
 class NcmpCmNotificationSubscriptionSpec extends CpsIntegrationSpecBase {
 
     @Autowired
-    CmNotificationSubscriptionPersistenceService cmNotificationSubscriptionPersistenceService;
+    CmSubscriptionPersistenceService cmSubscriptionPersistenceService
 
     def 'Adding a new cm notification subscription'() {
         given: 'there is no ongoing cm subscription for the following'
             def datastoreType = PASSTHROUGH_RUNNING
             def cmHandleId = 'ch-1'
             def xpath = '/x/y'
-            assert cmNotificationSubscriptionPersistenceService.
-                getOngoingCmNotificationSubscriptionIds(datastoreType,cmHandleId,xpath).size() == 0
+            assert cmSubscriptionPersistenceService.
+                getOngoingCmSubscriptionIds(datastoreType, cmHandleId, xpath).size() == 0
         when: 'we add a new cm notification subscription'
-            cmNotificationSubscriptionPersistenceService.addCmNotificationSubscription(datastoreType,cmHandleId,xpath,
+            cmSubscriptionPersistenceService.addCmSubscription(datastoreType, cmHandleId, xpath,
                 'subId-1')
         then: 'there is an ongoing cm subscription for that CM handle and xpath'
-            assert cmNotificationSubscriptionPersistenceService.isOngoingCmNotificationSubscription(datastoreType,cmHandleId,xpath)
+            assert cmSubscriptionPersistenceService.isOngoingCmSubscription(datastoreType, cmHandleId, xpath)
         and: 'only one subscription id is related to now ongoing cm subscription'
-            assert cmNotificationSubscriptionPersistenceService.
-                getOngoingCmNotificationSubscriptionIds(datastoreType,cmHandleId,xpath).size() == 1
+            assert cmSubscriptionPersistenceService.getOngoingCmSubscriptionIds(datastoreType, cmHandleId, xpath).size() == 1
     }
 
     def 'Adding a cm notification subscription to the already existing cm handle but non existing xpath'() {
@@ -53,18 +52,17 @@ class NcmpCmNotificationSubscriptionSpec extends CpsIntegrationSpecBase {
             def datastoreType = PASSTHROUGH_RUNNING
             def cmHandleId = 'ch-1'
             def existingXpath = '/x/y'
-            assert cmNotificationSubscriptionPersistenceService.isOngoingCmNotificationSubscription(datastoreType,cmHandleId,existingXpath)
+            assert cmSubscriptionPersistenceService.isOngoingCmSubscription(datastoreType, cmHandleId, existingXpath)
         and: 'a non existing cm subscription with same datastore name and cm handle but different xpath'
             def nonExistingXpath = '/x2/y2'
-            assert !cmNotificationSubscriptionPersistenceService.isOngoingCmNotificationSubscription(datastoreType,cmHandleId,nonExistingXpath)
+            assert !cmSubscriptionPersistenceService.isOngoingCmSubscription(datastoreType, cmHandleId, nonExistingXpath)
         when: 'a new cm notification subscription is made for the existing cm handle and non existing xpath'
-            cmNotificationSubscriptionPersistenceService.addCmNotificationSubscription(datastoreType,cmHandleId, nonExistingXpath,
+            cmSubscriptionPersistenceService.addCmSubscription(datastoreType, cmHandleId, nonExistingXpath,
                 'subId-2')
         then: 'there is an ongoing cm subscription for that CM handle and xpath'
-            assert cmNotificationSubscriptionPersistenceService.isOngoingCmNotificationSubscription(datastoreType,cmHandleId,nonExistingXpath)
+            assert cmSubscriptionPersistenceService.isOngoingCmSubscription(datastoreType, cmHandleId, nonExistingXpath)
         and: 'only one subscription id is related to now ongoing cm subscription'
-            assert cmNotificationSubscriptionPersistenceService.
-                getOngoingCmNotificationSubscriptionIds(datastoreType,cmHandleId,nonExistingXpath).size() == 1
+            assert cmSubscriptionPersistenceService.getOngoingCmSubscriptionIds(datastoreType, cmHandleId, nonExistingXpath).size() == 1
     }
 
     def 'Adding a cm notification subscription to the already existing cm handle and xpath'() {
@@ -73,10 +71,10 @@ class NcmpCmNotificationSubscriptionSpec extends CpsIntegrationSpecBase {
             def cmHandleId = 'ch-1'
             def xpath = '/x/y'
         when: 'a new cm notification subscription is made for the SAME CM handle and xpath'
-            cmNotificationSubscriptionPersistenceService.addCmNotificationSubscription(datastoreType,cmHandleId,xpath,
+            cmSubscriptionPersistenceService.addCmSubscription(datastoreType, cmHandleId, xpath,
                 'subId-3')
         then: 'it is added to the ongoing list of subscription ids'
-            def subscriptionIds = cmNotificationSubscriptionPersistenceService.getOngoingCmNotificationSubscriptionIds(datastoreType,cmHandleId,xpath)
+            def subscriptionIds = cmSubscriptionPersistenceService.getOngoingCmSubscriptionIds(datastoreType, cmHandleId, xpath)
             assert subscriptionIds.size() == 2
         and: 'both subscription ids exists for the CM handle and xpath'
             assert subscriptionIds.contains("subId-1") && subscriptionIds.contains("subId-3")
@@ -89,13 +87,12 @@ class NcmpCmNotificationSubscriptionSpec extends CpsIntegrationSpecBase {
             def xpath = '/x/y'
         and: 'the number of subscribers is as follows'
             def originalNumberOfSubscribers =
-                cmNotificationSubscriptionPersistenceService.getOngoingCmNotificationSubscriptionIds(datastoreType,cmHandleId,xpath).size()
+                cmSubscriptionPersistenceService.getOngoingCmSubscriptionIds(datastoreType, cmHandleId, xpath).size()
         when: 'a subscriber is removed'
-            cmNotificationSubscriptionPersistenceService.removeCmNotificationSubscription(datastoreType,cmHandleId,xpath,'subId-3')
+            cmSubscriptionPersistenceService.removeCmSubscription(datastoreType, cmHandleId, xpath, 'subId-3')
         then: 'the number of subscribers is reduced by 1'
-            def updatedNumberOfSubscribers =
-                cmNotificationSubscriptionPersistenceService.getOngoingCmNotificationSubscriptionIds(datastoreType,cmHandleId,xpath).size()
-            assert updatedNumberOfSubscribers == originalNumberOfSubscribers-1
+            def updatedNumberOfSubscribers = cmSubscriptionPersistenceService.getOngoingCmSubscriptionIds(datastoreType, cmHandleId, xpath).size()
+            assert updatedNumberOfSubscribers == originalNumberOfSubscribers - 1
     }
 
     def 'Removing the LAST cm notification subscriber for a given cm handle, datastore and xpath'() {
@@ -104,12 +101,12 @@ class NcmpCmNotificationSubscriptionSpec extends CpsIntegrationSpecBase {
             def cmHandleId = 'ch-1'
             def xpath = '/x/y'
         and: 'there is only one subscriber'
-            assert cmNotificationSubscriptionPersistenceService
-                .getOngoingCmNotificationSubscriptionIds(datastoreType,cmHandleId,xpath).size() == 1
+            assert cmSubscriptionPersistenceService
+                .getOngoingCmSubscriptionIds(datastoreType, cmHandleId, xpath).size() == 1
         when: 'only subscriber is removed'
-            cmNotificationSubscriptionPersistenceService.removeCmNotificationSubscription(datastoreType,cmHandleId,xpath,'subId-1')
+            cmSubscriptionPersistenceService.removeCmSubscription(datastoreType, cmHandleId, xpath, 'subId-1')
         then: 'there are no longer any subscriptions for the cm handle, datastore and xpath'
-            assert !cmNotificationSubscriptionPersistenceService.isOngoingCmNotificationSubscription(datastoreType, cmHandleId, xpath)
+            assert !cmSubscriptionPersistenceService.isOngoingCmSubscription(datastoreType, cmHandleId, xpath)
     }
 
 }