Subscription Creation: Fixes for code review after demo 39/135639/9
authorhalil.cakal <halil.cakal@est.tech>
Tue, 1 Aug 2023 15:35:58 +0000 (16:35 +0100)
committerhalil.cakal <halil.cakal@est.tech>
Fri, 4 Aug 2023 13:41:42 +0000 (14:41 +0100)
- Change missleading subscription details in testware
- Change datastore check to comply with CPS enum
- Remove redundant CloudConstructionException
- Change exception handling in cloud event mappers
  to avoid loss of information
- Remove exception handling from scheduler service
  as discussed in the meeting

Issue-ID: CPS-1732
Change-Id: I9fee2eafd4db97a0eed80e39219463c904f5a980
Signed-off-by: halil.cakal <halil.cakal@est.tech>
22 files changed:
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avcsubscription/ResponseTimeoutTask.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventConsumer.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventForwarder.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseConsumer.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseOutcome.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/CloudEventConstructionException.java [deleted file]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/SubscriptionEventCloudMapper.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/SubscriptionEventResponseCloudMapper.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/SubscriptionOutcomeCloudMapper.java
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/ClientSubscriptionEventMapperSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventConsumerSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventForwarderSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseConsumerSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseMapperSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseOutcomeSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionOutcomeMapperSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/SubscriptionEventCloudMapperSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/SubscriptionEventResponseCloudMapperSpec.groovy [new file with mode: 0644]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/SubscriptionOutcomeCloudMapperSpec.groovy [new file with mode: 0644]
cps-ncmp-service/src/test/resources/avcSubscriptionCreationEvent.json
cps-ncmp-service/src/test/resources/avcSubscriptionEventResponse.json
cps-ncmp-service/src/test/resources/avcSubscriptionOutcomeEvent.json

index 176e644..e3f5297 100644 (file)
@@ -36,17 +36,10 @@ public class ResponseTimeoutTask implements Runnable {
 
     @Override
     public void run() {
-
-        try {
-            generateAndSendResponse();
-        } catch (final Exception exception) {
-            log.info("Caught exception in Runnable for ResponseTimeoutTask. StackTrace: {}",
-                    exception.toString());
-        }
-
+        generateTimeoutResponse();
     }
 
-    private void generateAndSendResponse() {
+    private void generateTimeoutResponse() {
         final String subscriptionClientId = subscriptionEventResponse.getData().getClientId();
         final String subscriptionName = subscriptionEventResponse.getData().getSubscriptionName();
         final String subscriptionEventId = subscriptionClientId + subscriptionName;
index c80b07c..8dfdc3c 100644 (file)
@@ -20,6 +20,9 @@
 
 package org.onap.cps.ncmp.api.impl.events.avcsubscription;
 
+import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_OPERATIONAL;
+import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_RUNNING;
+
 import io.cloudevents.CloudEvent;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -41,6 +44,7 @@ public class SubscriptionEventConsumer {
     private final SubscriptionEventForwarder subscriptionEventForwarder;
     private final SubscriptionEventMapper subscriptionEventMapper;
     private final SubscriptionPersistence subscriptionPersistence;
+    private final SubscriptionEventCloudMapper subscriptionEventCloudMapper;
 
     @Value("${notification.enabled:true}")
     private boolean notificationFeatureEnabled;
@@ -58,11 +62,12 @@ public class SubscriptionEventConsumer {
     public void consumeSubscriptionEvent(final ConsumerRecord<String, CloudEvent> subscriptionEventConsumerRecord) {
         final CloudEvent cloudEvent = subscriptionEventConsumerRecord.value();
         final String eventType = subscriptionEventConsumerRecord.value().getType();
-        final SubscriptionEvent subscriptionEvent = SubscriptionEventCloudMapper.toSubscriptionEvent(cloudEvent);
+        final SubscriptionEvent subscriptionEvent = subscriptionEventCloudMapper.toSubscriptionEvent(cloudEvent);
         final String eventDatastore = subscriptionEvent.getData().getPredicates().getDatastore();
-        if (!(eventDatastore.equals("passthrough-running") || eventDatastore.equals("passthrough-operational"))) {
+        if (!eventDatastore.equals(PASSTHROUGH_RUNNING.getDatastoreName())
+                || eventDatastore.equals(PASSTHROUGH_OPERATIONAL.getDatastoreName())) {
             throw new UnsupportedOperationException(
-                "passthrough datastores are currently only supported for event subscriptions");
+                    "passthrough datastores are currently only supported for event subscriptions");
         }
         if ("CM".equals(subscriptionEvent.getData().getDataType().getDataCategory())) {
             if (subscriptionModelLoaderEnabled) {
index 0eda914..d3bfe81 100644 (file)
@@ -61,6 +61,7 @@ public class SubscriptionEventForwarder {
     private final IMap<String, Set<String>> forwardedSubscriptionEventCache;
     private final SubscriptionEventResponseOutcome subscriptionEventResponseOutcome;
     private final SubscriptionEventMapper subscriptionEventMapper;
+    private final SubscriptionEventCloudMapper subscriptionEventCloudMapper;
     private final ClientSubscriptionEventMapper clientSubscriptionEventMapper;
     private final SubscriptionPersistence subscriptionPersistence;
     private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
@@ -132,12 +133,8 @@ public class SubscriptionEventForwarder {
         final ResponseTimeoutTask responseTimeoutTask =
             new ResponseTimeoutTask(forwardedSubscriptionEventCache, subscriptionEventResponseOutcome,
                     emptySubscriptionEventResponse);
-        try {
-            executorService.schedule(responseTimeoutTask, dmiResponseTimeoutInMs, TimeUnit.MILLISECONDS);
-        } catch (final RuntimeException ex) {
-            log.info("Caught exception in ScheduledExecutorService for ResponseTimeoutTask. StackTrace: {}",
-                    ex.toString());
-        }
+
+        executorService.schedule(responseTimeoutTask, dmiResponseTimeoutInMs, TimeUnit.MILLISECONDS);
     }
 
     private void forwardEventToDmis(final Map<String, Map<String, Map<String, String>>> dmiNameCmHandleMap,
@@ -157,7 +154,7 @@ public class SubscriptionEventForwarder {
             final String dmiAvcSubscriptionTopic = dmiAvcSubscriptionTopicPrefix + dmiName;
 
             final CloudEvent ncmpSubscriptionCloudEvent =
-                    SubscriptionEventCloudMapper.toCloudEvent(ncmpSubscriptionEvent, eventKey, eventType);
+                    subscriptionEventCloudMapper.toCloudEvent(ncmpSubscriptionEvent, eventKey, eventType);
             eventsPublisher.publishCloudEvent(dmiAvcSubscriptionTopic, eventKey, ncmpSubscriptionCloudEvent);
         });
     }
index ddb9fd6..b1c0a32 100644 (file)
@@ -50,6 +50,7 @@ public class SubscriptionEventResponseConsumer {
     private final SubscriptionPersistence subscriptionPersistence;
     private final SubscriptionEventResponseMapper subscriptionEventResponseMapper;
     private final SubscriptionEventResponseOutcome subscriptionEventResponseOutcome;
+    private final SubscriptionEventResponseCloudMapper subscriptionEventResponseCloudMapper;
 
     @Value("${notification.enabled:true}")
     private boolean notificationFeatureEnabled;
@@ -69,7 +70,7 @@ public class SubscriptionEventResponseConsumer {
         final CloudEvent cloudEvent = subscriptionEventResponseConsumerRecord.value();
         final String eventType = subscriptionEventResponseConsumerRecord.value().getType();
         final SubscriptionEventResponse subscriptionEventResponse =
-                SubscriptionEventResponseCloudMapper.toSubscriptionEventResponse(cloudEvent);
+                subscriptionEventResponseCloudMapper.toSubscriptionEventResponse(cloudEvent);
         final String clientId = subscriptionEventResponse.getData().getClientId();
         log.info("subscription event response of clientId: {} is received.", clientId);
         final String subscriptionName = subscriptionEventResponse.getData().getSubscriptionName();
index 9ed6865..822ca55 100644 (file)
@@ -48,6 +48,8 @@ public class SubscriptionEventResponseOutcome {
 
     private final SubscriptionOutcomeMapper subscriptionOutcomeMapper;
 
+    private final SubscriptionOutcomeCloudMapper subscriptionOutcomeCloudMapper;
+
     @Value("${app.ncmp.avc.subscription-outcome-topic:subscription-response}")
     private String subscriptionOutcomeEventTopic;
 
@@ -63,7 +65,7 @@ public class SubscriptionEventResponseOutcome {
         final String subscriptionName = subscriptionEventResponse.getData().getSubscriptionName();
         final String subscriptionEventId = subscriptionClientId + subscriptionName;
         final CloudEvent subscriptionOutcomeCloudEvent =
-                SubscriptionOutcomeCloudMapper.toCloudEvent(subscriptionEventOutcome,
+                subscriptionOutcomeCloudMapper.toCloudEvent(subscriptionEventOutcome,
                 subscriptionEventId, eventKey);
         outcomeEventsPublisher.publishCloudEvent(subscriptionOutcomeEventTopic,
                 subscriptionEventId, subscriptionOutcomeCloudEvent);
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/CloudEventConstructionException.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/CloudEventConstructionException.java
deleted file mode 100644 (file)
index d0be344..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *  ============LICENSE_START=======================================================
- *  Copyright (C) 2020 Pantheon.tech
- *  Modifications Copyright (C) 2020 Bell Canada
- *  Modifications Copyright (C) 2020-2023 Nordix Foundation
- *  ================================================================================
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- *  SPDX-License-Identifier: Apache-2.0
- *  ============LICENSE_END=========================================================
- */
-
-package org.onap.cps.ncmp.api.impl.utils;
-
-import org.onap.cps.spi.exceptions.CpsException;
-
-public class CloudEventConstructionException extends CpsException {
-
-    private static final long serialVersionUID = 7747941311132087621L;
-
-    /**
-     * Constructor.
-     *
-     * @param message the error message
-     * @param details the error details
-     * @param cause   the error cause
-     */
-    public CloudEventConstructionException(final String message, final String details, final Throwable cause) {
-        super(message, details, cause);
-    }
-}
index d0d70cf..1561edc 100644 (file)
@@ -20,6 +20,7 @@
 
 package org.onap.cps.ncmp.api.impl.utils;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import io.cloudevents.CloudEvent;
 import io.cloudevents.core.CloudEventUtils;
@@ -28,16 +29,17 @@ import io.cloudevents.core.data.PojoCloudEventData;
 import io.cloudevents.jackson.PojoCloudEventDataMapper;
 import java.net.URI;
 import java.util.UUID;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.onap.cps.ncmp.events.avcsubscription1_0_0.client_to_ncmp.SubscriptionEvent;
+import org.springframework.stereotype.Component;
 
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
 @Slf4j
+@Component
+@RequiredArgsConstructor
 public class SubscriptionEventCloudMapper {
 
-    private static final ObjectMapper objectMapper = new ObjectMapper();
+    private final ObjectMapper objectMapper;
 
     private static String randomId = UUID.randomUUID().toString();
 
@@ -47,7 +49,7 @@ public class SubscriptionEventCloudMapper {
      * @param cloudEvent object.
      * @return SubscriptionEvent deserialized.
      */
-    public static SubscriptionEvent toSubscriptionEvent(final CloudEvent cloudEvent) {
+    public SubscriptionEvent toSubscriptionEvent(final CloudEvent cloudEvent) {
         final PojoCloudEventData<SubscriptionEvent> deserializedCloudEvent = CloudEventUtils
                 .mapData(cloudEvent, PojoCloudEventDataMapper.from(objectMapper, SubscriptionEvent.class));
         if (deserializedCloudEvent == null) {
@@ -67,7 +69,7 @@ public class SubscriptionEventCloudMapper {
      * @param eventKey as String.
      * @return CloudEvent built.
      */
-    public static CloudEvent toCloudEvent(
+    public CloudEvent toCloudEvent(
             final org.onap.cps.ncmp.events.avcsubscription1_0_0.ncmp_to_dmi.SubscriptionEvent ncmpSubscriptionEvent,
             final String eventKey, final String eventType) {
         try {
@@ -80,9 +82,9 @@ public class SubscriptionEventCloudMapper {
                             + org.onap.cps.ncmp.events.avcsubscription1_0_0.ncmp_to_dmi
                                     .SubscriptionEvent.class.getName() + ":1.0.0"))
                     .withData(objectMapper.writeValueAsBytes(ncmpSubscriptionEvent)).build();
-        } catch (final Exception ex) {
-            throw new CloudEventConstructionException("The Cloud Event could not be constructed", "Invalid object to "
-                    + "serialize or required headers is missing", ex);
+        } catch (final JsonProcessingException jsonProcessingException) {
+            log.error("The Cloud Event could not be constructed", jsonProcessingException);
         }
+        return null;
     }
 }
index 17aba65..e00bb16 100644 (file)
@@ -25,16 +25,17 @@ import io.cloudevents.CloudEvent;
 import io.cloudevents.core.CloudEventUtils;
 import io.cloudevents.core.data.PojoCloudEventData;
 import io.cloudevents.jackson.PojoCloudEventDataMapper;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.onap.cps.ncmp.events.avcsubscription1_0_0.dmi_to_ncmp.SubscriptionEventResponse;
+import org.springframework.stereotype.Component;
 
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
 @Slf4j
+@Component
+@RequiredArgsConstructor
 public class SubscriptionEventResponseCloudMapper {
 
-    private static final ObjectMapper objectMapper = new ObjectMapper();
+    private final ObjectMapper objectMapper;
 
     /**
      * Maps CloudEvent object to SubscriptionEventResponse.
@@ -42,7 +43,7 @@ public class SubscriptionEventResponseCloudMapper {
      * @param cloudEvent object
      * @return SubscriptionEventResponse deserialized
      */
-    public static SubscriptionEventResponse toSubscriptionEventResponse(final CloudEvent cloudEvent) {
+    public SubscriptionEventResponse toSubscriptionEventResponse(final CloudEvent cloudEvent) {
         final PojoCloudEventData<SubscriptionEventResponse> deserializedCloudEvent = CloudEventUtils
                 .mapData(cloudEvent, PojoCloudEventDataMapper.from(objectMapper, SubscriptionEventResponse.class));
         if (deserializedCloudEvent == null) {
index b6cb039..9ea4487 100644 (file)
 
 package org.onap.cps.ncmp.api.impl.utils;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import io.cloudevents.CloudEvent;
 import io.cloudevents.core.builder.CloudEventBuilder;
 import java.net.URI;
 import java.util.UUID;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.onap.cps.ncmp.events.avcsubscription1_0_0.ncmp_to_client.SubscriptionEventOutcome;
+import org.springframework.stereotype.Component;
 
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
 @Slf4j
+@Component
+@RequiredArgsConstructor
 public class SubscriptionOutcomeCloudMapper {
 
-    private static final ObjectMapper objectMapper = new ObjectMapper();
+    private final ObjectMapper objectMapper;
 
     private static String randomId = UUID.randomUUID().toString();
 
@@ -44,7 +46,7 @@ public class SubscriptionOutcomeCloudMapper {
      * @param subscriptionEventOutcome object
      * @return CloudEvent
      */
-    public static CloudEvent toCloudEvent(final SubscriptionEventOutcome subscriptionEventOutcome,
+    public CloudEvent toCloudEvent(final SubscriptionEventOutcome subscriptionEventOutcome,
                                           final String eventKey, final String eventType) {
         try {
             return CloudEventBuilder.v1()
@@ -54,9 +56,9 @@ public class SubscriptionOutcomeCloudMapper {
                     .withExtension("correlationid", eventKey)
                     .withDataSchema(URI.create("urn:cps:" + SubscriptionEventOutcome.class.getName() + ":1.0.0"))
                     .withData(objectMapper.writeValueAsBytes(subscriptionEventOutcome)).build();
-        } catch (final Exception ex) {
-            throw new CloudEventConstructionException("The Cloud Event could not be constructed", "Invalid object to "
-                    + "serialize or required headers is missing", ex);
+        } catch (final JsonProcessingException jsonProcessingException) {
+            log.error("The Cloud Event could not be constructed", jsonProcessingException);
         }
+        return null;
     }
 }
index 85a58cd..b3d81e3 100644 (file)
@@ -54,7 +54,7 @@ class ClientSubscriptionEventMapperSpec extends Specification {
         and: 'predicate targets is null'
             assert result.getData().getPredicates().getTargets() == []
         and: 'datastore is passthrough-running'
-            assert result.getData().getPredicates().getDatastore() == 'passthrough-running'
+            assert result.getData().getPredicates().getDatastore() == 'ncmp-datastore:passthrough-running'
     }
 
 }
index 7fa8155..430d122 100644 (file)
@@ -25,6 +25,7 @@ import io.cloudevents.CloudEvent
 import io.cloudevents.core.builder.CloudEventBuilder
 import org.apache.kafka.clients.consumer.ConsumerRecord
 import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionPersistence
+import org.onap.cps.ncmp.api.impl.utils.SubscriptionEventCloudMapper
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelSubscriptionEvent
 import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec
 import org.onap.cps.ncmp.events.avcsubscription1_0_0.client_to_ncmp.SubscriptionEvent;
@@ -39,7 +40,8 @@ class SubscriptionEventConsumerSpec extends MessagingBaseSpec {
     def mockSubscriptionEventForwarder = Mock(SubscriptionEventForwarder)
     def mockSubscriptionEventMapper = Mock(SubscriptionEventMapper)
     def mockSubscriptionPersistence = Mock(SubscriptionPersistence)
-    def objectUnderTest = new SubscriptionEventConsumer(mockSubscriptionEventForwarder, mockSubscriptionEventMapper, mockSubscriptionPersistence)
+    def subscriptionEventCloudMapper = new SubscriptionEventCloudMapper(new ObjectMapper())
+    def objectUnderTest = new SubscriptionEventConsumer(mockSubscriptionEventForwarder, mockSubscriptionEventMapper, mockSubscriptionPersistence, subscriptionEventCloudMapper)
 
     def yangModelSubscriptionEvent = new YangModelSubscriptionEvent()
 
index 4193f75..dd93bf6 100644 (file)
@@ -30,6 +30,7 @@ import org.mapstruct.factory.Mappers
 import org.onap.cps.ncmp.api.impl.events.EventsPublisher
 import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionPersistence
 import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus
+import org.onap.cps.ncmp.api.impl.utils.SubscriptionEventCloudMapper
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelSubscriptionEvent.TargetCmHandle
 import org.onap.cps.ncmp.api.inventory.InventoryPersistence
@@ -44,7 +45,6 @@ import org.spockframework.spring.SpringBean
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.boot.test.context.SpringBootTest
 import spock.util.concurrent.BlockingVariable
-
 import java.util.concurrent.TimeUnit
 
 @SpringBootTest(classes = [ObjectMapper, JsonObjectMapper, SubscriptionEventForwarder])
@@ -60,6 +60,8 @@ class SubscriptionEventForwarderSpec extends MessagingBaseSpec {
     @SpringBean
     IMap<String, Set<String>> mockForwardedSubscriptionEventCache = Mock(IMap<String, Set<String>>)
     @SpringBean
+    SubscriptionEventCloudMapper subscriptionEventCloudMapper = new SubscriptionEventCloudMapper(new ObjectMapper())
+    @SpringBean
     SubscriptionEventResponseOutcome mockSubscriptionEventResponseOutcome = Mock(SubscriptionEventResponseOutcome)
     @SpringBean
     SubscriptionPersistence mockSubscriptionPersistence = Mock(SubscriptionPersistence)
@@ -69,8 +71,8 @@ class SubscriptionEventForwarderSpec extends MessagingBaseSpec {
     ClientSubscriptionEventMapper clientSubscriptionEventMapper = Mappers.getMapper(ClientSubscriptionEventMapper)
     @Autowired
     JsonObjectMapper jsonObjectMapper
-
-    def objectMapper = new ObjectMapper()
+    @Autowired
+    ObjectMapper objectMapper
 
     def 'Forward valid CM create subscription and simulate timeout'() {
         given: 'an event'
index 7cc40cc..3e6d7a8 100644 (file)
@@ -26,6 +26,7 @@ import io.cloudevents.CloudEvent
 import io.cloudevents.core.builder.CloudEventBuilder
 import org.apache.kafka.clients.consumer.ConsumerRecord
 import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionPersistenceImpl
+import org.onap.cps.ncmp.api.impl.utils.SubscriptionEventResponseCloudMapper
 import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec
 import org.onap.cps.ncmp.events.avcsubscription1_0_0.dmi_to_ncmp.SubscriptionEventResponse
 import org.onap.cps.ncmp.utils.TestUtils
@@ -47,9 +48,10 @@ class SubscriptionEventResponseConsumerSpec extends MessagingBaseSpec {
     def mockSubscriptionPersistence = Mock(SubscriptionPersistenceImpl)
     def mockSubscriptionEventResponseMapper  = Mock(SubscriptionEventResponseMapper)
     def mockSubscriptionEventResponseOutcome = Mock(SubscriptionEventResponseOutcome)
+    def mockSubscriptionEventResponseCloudMapper = new SubscriptionEventResponseCloudMapper(new ObjectMapper())
 
     def objectUnderTest = new SubscriptionEventResponseConsumer(mockForwardedSubscriptionEventCache,
-        mockSubscriptionPersistence, mockSubscriptionEventResponseMapper, mockSubscriptionEventResponseOutcome)
+        mockSubscriptionPersistence, mockSubscriptionEventResponseMapper, mockSubscriptionEventResponseOutcome, mockSubscriptionEventResponseCloudMapper)
 
     def 'Consume Subscription Event Response where all DMIs have responded'() {
         given: 'a consumer record including cloud event having subscription response'
index 4c60281..d07d9bb 100644 (file)
@@ -50,11 +50,11 @@ class SubscriptionEventResponseMapperSpec extends Specification {
         and: 'subscription name'
             assert result.subscriptionName == "cm-subscription-001"
         and: 'predicate targets cm handle size as expected'
-            assert result.predicates.targetCmHandles.size() == 7
+            assert result.predicates.targetCmHandles.size() == 4
         and: 'predicate targets cm handle ids as expected'
-            assert result.predicates.targetCmHandles.cmHandleId == ["CMHandle1", "CMHandle2", "CMHandle3", "CMHandle4", "CMHandle5", "CMHandle6", "CMHandle7"]
+            assert result.predicates.targetCmHandles.cmHandleId == ["CMHandle1", "CMHandle2", "CMHandle3", "CMHandle4"]
         and: 'the status for these targets is set to expected values'
-            assert result.predicates.targetCmHandles.status == [SubscriptionStatus.REJECTED, SubscriptionStatus.REJECTED, SubscriptionStatus.REJECTED, SubscriptionStatus.REJECTED, SubscriptionStatus.PENDING, SubscriptionStatus.PENDING, SubscriptionStatus.PENDING]
+            assert result.predicates.targetCmHandles.status == [SubscriptionStatus.REJECTED, SubscriptionStatus.REJECTED, SubscriptionStatus.PENDING, SubscriptionStatus.PENDING]
     }
 
 }
\ No newline at end of file
index c1c428b..a6c8712 100644 (file)
@@ -49,6 +49,8 @@ class SubscriptionEventResponseOutcomeSpec extends DataNodeBaseSpec {
     EventsPublisher<CloudEvent> mockSubscriptionEventOutcomePublisher = Mock(EventsPublisher<CloudEvent>)
     @SpringBean
     SubscriptionOutcomeMapper subscriptionOutcomeMapper = Mappers.getMapper(SubscriptionOutcomeMapper)
+    @SpringBean
+    SubscriptionOutcomeCloudMapper subscriptionOutcomeCloudMapper = new SubscriptionOutcomeCloudMapper(new ObjectMapper())
 
     @Autowired
     JsonObjectMapper jsonObjectMapper
index f5fbdfc..ea1b9e7 100644 (file)
@@ -48,14 +48,14 @@ class SubscriptionOutcomeMapperSpec extends Specification {
             def result = objectUnderTest.toSubscriptionEventOutcome(subscriptionResponseEvent)
         then: 'the resulting subscription event outcome contains expected pending targets per details grouping'
             def pendingCmHandleTargetsPerDetails = result.getData().getAdditionalInfo().getPending()
-            assert pendingCmHandleTargetsPerDetails.get(0).getDetails() == 'EMS or node connectivity issues, retrying'
-            assert pendingCmHandleTargetsPerDetails.get(0).getTargets() == ['CMHandle5', 'CMHandle6','CMHandle7']
+            assert pendingCmHandleTargetsPerDetails.get(0).getDetails() == 'No reply from DMI yet'
+            assert pendingCmHandleTargetsPerDetails.get(0).getTargets() == ['CMHandle3', 'CMHandle4']
         and: 'the resulting subscription event outcome contains expected rejected targets per details grouping'
             def rejectedCmHandleTargetsPerDetails = result.getData().getAdditionalInfo().getRejected()
-            assert rejectedCmHandleTargetsPerDetails.get(0).getDetails() == 'Target(s) do not exist'
-            assert rejectedCmHandleTargetsPerDetails.get(0).getTargets() == ['CMHandle4']
-            assert rejectedCmHandleTargetsPerDetails.get(1).getDetails() == 'Faulty subscription format for target(s)'
-            assert rejectedCmHandleTargetsPerDetails.get(1).getTargets() == ['CMHandle1', 'CMHandle2','CMHandle3']
+            assert rejectedCmHandleTargetsPerDetails.get(0).getDetails() == 'Some other error message from the DMI'
+            assert rejectedCmHandleTargetsPerDetails.get(0).getTargets() == ['CMHandle2']
+            assert rejectedCmHandleTargetsPerDetails.get(1).getDetails() == 'Some error message from the DMI'
+            assert rejectedCmHandleTargetsPerDetails.get(1).getTargets() == ['CMHandle1']
     }
 
     def 'Map subscription event response with null of subscription status list to subscription event outcome causes an exception'() {
index 4023441..ae61749 100644 (file)
@@ -20,6 +20,7 @@
 
 package org.onap.cps.ncmp.api.impl.utils
 
+import com.fasterxml.jackson.core.JsonProcessingException
 import com.fasterxml.jackson.databind.ObjectMapper
 import io.cloudevents.core.builder.CloudEventBuilder
 import org.onap.cps.ncmp.events.avcsubscription1_0_0.client_to_ncmp.SubscriptionEvent
@@ -38,6 +39,10 @@ class SubscriptionEventCloudMapperSpec extends Specification {
     @Autowired
     ObjectMapper objectMapper
 
+    def spyObjectMapper = Spy(ObjectMapper)
+
+    def objectUnderTest = new SubscriptionEventCloudMapper(spyObjectMapper)
+
     def 'Map the data of the cloud event to subscription event'() {
         given: 'a cloud event having a subscription event in the data part'
             def jsonData = TestUtils.getResourceFileContent('avcSubscriptionCreationEvent.json')
@@ -49,7 +54,7 @@ class SubscriptionEventCloudMapperSpec extends Specification {
                 .withSource(URI.create('some-resource'))
                 .withExtension('correlationid', 'test-cmhandle1').build()
         when: 'the cloud event map to subscription event'
-            def resultSubscriptionEvent = SubscriptionEventCloudMapper.toSubscriptionEvent(testCloudEvent)
+            def resultSubscriptionEvent = objectUnderTest.toSubscriptionEvent(testCloudEvent)
         then: 'the subscription event resulted having expected values'
             resultSubscriptionEvent.getData() == testEventData.getData()
     }
@@ -63,7 +68,7 @@ class SubscriptionEventCloudMapperSpec extends Specification {
                 .withSource(URI.create('some-resource'))
                 .withExtension('correlationid', 'test-cmhandle1').build()
         when: 'the cloud event map to subscription event'
-            def resultSubscriptionEvent = SubscriptionEventCloudMapper.toSubscriptionEvent(testCloudEvent)
+            def resultSubscriptionEvent = objectUnderTest.toSubscriptionEvent(testCloudEvent)
         then: 'the subscription event resulted having a null value'
             resultSubscriptionEvent == null
     }
@@ -81,7 +86,7 @@ class SubscriptionEventCloudMapperSpec extends Specification {
                 .withExtension('correlationid', 'test-cmhandle1').build()
         when: 'the subscription event map to data of cloud event'
             SubscriptionEventCloudMapper.randomId = 'some-id'
-            def resultCloudEvent = SubscriptionEventCloudMapper.toCloudEvent(testEventData, 'some-event-key', 'subscriptionCreated')
+            def resultCloudEvent = objectUnderTest.toCloudEvent(testEventData, 'some-event-key', 'subscriptionCreated')
         then: 'the subscription event resulted having expected values'
             resultCloudEvent.getData() == testCloudEvent.getData()
             resultCloudEvent.getId() == testCloudEvent.getId()
@@ -90,14 +95,20 @@ class SubscriptionEventCloudMapperSpec extends Specification {
             resultCloudEvent.getDataSchema() == URI.create('urn:cps:org.onap.cps.ncmp.events.avcsubscription1_0_0.ncmp_to_dmi.SubscriptionEvent:1.0.0')
     }
 
-    def 'Map the subscription event to data of the cloud event with wrong content causes an exception'() {
-        given: 'an empty ncmp subscription event'
-            def testNcmpSubscriptionEvent = new org.onap.cps.ncmp.events.avcsubscription1_0_0.ncmp_to_dmi.SubscriptionEvent()
-        when: 'the subscription event map to data of cloud event'
-            SubscriptionEventCloudMapper.toCloudEvent(testNcmpSubscriptionEvent, 'some-key', 'some-event-type')
-        then: 'a run time exception is thrown'
-            def exception = thrown(CloudEventConstructionException)
-            exception.details == 'Invalid object to serialize or required headers is missing'
+    def 'Map the subscription event to cloud event with JSON processing exception'() {
+        given: 'a json processing exception during process'
+            def jsonProcessingException = new JsonProcessingException('The Cloud Event could not be constructed')
+            spyObjectMapper.writeValueAsBytes(_) >> { throw jsonProcessingException }
+        and: 'a subscription event of ncmp version'
+            def jsonData = TestUtils.getResourceFileContent('avcSubscriptionCreationEventNcmpVersion.json')
+            def testEventData = jsonObjectMapper.convertJsonString(jsonData,
+                org.onap.cps.ncmp.events.avcsubscription1_0_0.ncmp_to_dmi.SubscriptionEvent.class)
+        when: 'the subscription event map to cloud event'
+            def expectedResult = objectUnderTest.toCloudEvent(testEventData, 'some-key', 'some-event-type')
+        then: 'no exception is thrown since it has been handled already'
+            noExceptionThrown()
+        and: 'expected result should be null'
+            expectedResult == null
     }
 
 }
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/SubscriptionEventResponseCloudMapperSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/SubscriptionEventResponseCloudMapperSpec.groovy
new file mode 100644 (file)
index 0000000..9dcd0a6
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * ============LICENSE_START========================================================
+ * Copyright (c) 2023 Nordix Foundation.
+ *  ================================================================================
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an 'AS IS' BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.api.impl.utils
+
+import com.fasterxml.jackson.databind.ObjectMapper
+import io.cloudevents.core.builder.CloudEventBuilder
+import org.onap.cps.ncmp.events.avcsubscription1_0_0.dmi_to_ncmp.SubscriptionEventResponse
+import org.onap.cps.ncmp.utils.TestUtils
+import org.onap.cps.utils.JsonObjectMapper
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.context.SpringBootTest
+import spock.lang.Specification
+
+@SpringBootTest(classes = [ObjectMapper, JsonObjectMapper])
+class SubscriptionEventResponseCloudMapperSpec extends Specification {
+
+    @Autowired
+    JsonObjectMapper jsonObjectMapper
+
+    @Autowired
+    ObjectMapper objectMapper
+
+    def spyObjectMapper = Spy(ObjectMapper)
+
+    def objectUnderTest = new SubscriptionEventResponseCloudMapper(spyObjectMapper)
+
+    def 'Map the cloud event to subscription event response'() {
+        given: 'a cloud event having a subscription event response in the data part'
+            def jsonData = TestUtils.getResourceFileContent('avcSubscriptionEventResponse.json')
+            def testEventData = jsonObjectMapper.convertJsonString(jsonData, SubscriptionEventResponse.class)
+            def testCloudEvent = CloudEventBuilder.v1()
+                .withData(objectMapper.writeValueAsBytes(testEventData))
+                .withId('some-event-id')
+                .withType('subscriptionCreatedStatus')
+                .withSource(URI.create('some-resource'))
+                .withExtension('correlationid', 'test-cmhandle1').build()
+        when: 'the cloud event map to subscription event response'
+            def resultSubscriptionEvent = objectUnderTest.toSubscriptionEventResponse(testCloudEvent)
+        then: 'the subscription event resulted having expected values'
+            resultSubscriptionEvent.getData() == testEventData.getData()
+    }
+
+    def 'Map null of the data of the cloud event to subscription event response'() {
+        given: 'a cloud event having a null subscription event response in the data part'
+            def testCloudEvent = CloudEventBuilder.v1()
+                .withData(null)
+                .withId('some-event-id')
+                .withType('subscriptionCreatedStatus')
+                .withSource(URI.create('some-resource'))
+                .withExtension('correlationid', 'test-cmhandle1').build()
+        when: 'the cloud event map to subscription event response'
+            def resultSubscriptionEvent = objectUnderTest.toSubscriptionEventResponse(testCloudEvent)
+        then: 'the subscription event response resulted having a null value'
+            resultSubscriptionEvent == null
+    }
+}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/SubscriptionOutcomeCloudMapperSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/SubscriptionOutcomeCloudMapperSpec.groovy
new file mode 100644 (file)
index 0000000..ac055b5
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * ============LICENSE_START========================================================
+ * Copyright (c) 2023 Nordix Foundation.
+ *  ================================================================================
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an 'AS IS' BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.api.impl.utils
+
+import com.fasterxml.jackson.core.JsonProcessingException
+import com.fasterxml.jackson.databind.ObjectMapper
+import io.cloudevents.core.builder.CloudEventBuilder
+import org.onap.cps.ncmp.events.avcsubscription1_0_0.ncmp_to_client.SubscriptionEventOutcome
+import org.onap.cps.ncmp.utils.TestUtils
+import org.onap.cps.utils.JsonObjectMapper
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.context.SpringBootTest
+import spock.lang.Specification
+
+@SpringBootTest(classes = [ObjectMapper, JsonObjectMapper])
+class SubscriptionOutcomeCloudMapperSpec extends Specification {
+
+    @Autowired
+    JsonObjectMapper jsonObjectMapper
+
+    @Autowired
+    ObjectMapper objectMapper
+
+    def spyObjectMapper = Spy(ObjectMapper)
+
+    def objectUnderTest = new SubscriptionOutcomeCloudMapper(spyObjectMapper)
+
+    def 'Map the subscription outcome to cloud event'() {
+        given: 'a subscription event'
+            def jsonData = TestUtils.getResourceFileContent('avcSubscriptionOutcomeEvent.json')
+            def testEventData = jsonObjectMapper.convertJsonString(jsonData, SubscriptionEventOutcome.class)
+            def testCloudEvent = CloudEventBuilder.v1()
+                .withData(objectMapper.writeValueAsBytes(testEventData))
+                .withId('some-id')
+                .withType('subscriptionCreatedStatus')
+                .withSource(URI.create('NCMP'))
+                .withExtension('correlationid', 'test-cmhandle1').build()
+        when: 'the subscription event map to data of cloud event'
+            SubscriptionOutcomeCloudMapper.randomId = 'some-id'
+            def resultCloudEvent = objectUnderTest.toCloudEvent(testEventData, 'some-event-key', 'subscriptionCreatedStatus')
+        then: 'the subscription event resulted having expected values'
+            resultCloudEvent.getData() == testCloudEvent.getData()
+            resultCloudEvent.getId() == testCloudEvent.getId()
+            resultCloudEvent.getType() == testCloudEvent.getType()
+            resultCloudEvent.getSource() == testCloudEvent.getSource()
+            resultCloudEvent.getDataSchema() == URI.create('urn:cps:org.onap.cps.ncmp.events.avcsubscription1_0_0.ncmp_to_client.SubscriptionEventOutcome:1.0.0')
+    }
+
+    def 'Map the subscription outcome to cloud event with JSON processing exception'() {
+        given: 'a json processing exception during process'
+            def jsonProcessingException = new JsonProcessingException('The Cloud Event could not be constructed')
+            spyObjectMapper.writeValueAsBytes(_) >> { throw jsonProcessingException }
+        and: 'a cloud event having a subscription outcome in the data part'
+            def jsonData = TestUtils.getResourceFileContent('avcSubscriptionOutcomeEvent.json')
+            def testEventData = jsonObjectMapper.convertJsonString(jsonData, SubscriptionEventOutcome.class)
+        when: 'the subscription outcome map to cloud event'
+            def expectedResult = objectUnderTest.toCloudEvent(testEventData, 'some-key', 'some-event-type')
+        then: 'no exception is thrown since it has been handled already'
+            noExceptionThrown()
+        and: 'expected result should be null'
+            expectedResult == null
+    }
+
+}
index e4539fb..803fa48 100644 (file)
@@ -15,7 +15,7 @@
         "CMHandle2",
         "CMHandle3"
       ],
-      "datastore": "passthrough-running",
+      "datastore": "ncmp-datastore:passthrough-running",
       "datastore-xpath-filter": "//_3gpp-nr-nrm-gnbdufunction:GNBDUFunction/_3gpp-nr-nrm-nrcelldu:NRCellDU/ | //_3gpp-nr-nrm-gnbcuupfunction:GNBCUUPFunction// | //_3gpp-nr-nrm-gnbcucpfunction:GNBCUCPFunction/_3gpp-nr-nrm-nrcelldu:NRCellCU// | //_3gpp-nr-nrm-nrsectorcarrier:NRSectorCarrier//"
     }
   }
index 52ca1df..dfe8f50 100644 (file)
@@ -7,37 +7,22 @@
       {
         "id": "CMHandle1",
         "status": "REJECTED",
-        "details": "Faulty subscription format for target(s)"
+        "details": "Some error message from the DMI"
       },
       {
         "id": "CMHandle2",
         "status": "REJECTED",
-        "details": "Faulty subscription format for target(s)"
+        "details": "Some other error message from the DMI"
       },
       {
         "id": "CMHandle3",
-        "status": "REJECTED",
-        "details": "Faulty subscription format for target(s)"
-      },
-      {
-        "id": "CMHandle4",
-        "status": "REJECTED",
-        "details": "Target(s) do not exist"
-      },
-      {
-        "id": "CMHandle5",
         "status": "PENDING",
-        "details": "EMS or node connectivity issues, retrying"
+        "details": "No reply from DMI yet"
       },
       {
-        "id": "CMHandle6",
-        "status": "PENDING",
-        "details": "EMS or node connectivity issues, retrying"
-      },
-      {
-        "id": "CMHandle7",
+        "id": "CMHandle4",
         "status": "PENDING",
-        "details": "EMS or node connectivity issues, retrying"
+        "details": "No reply from DMI yet"
       }
     ]
   }
index 2d83bdd..14e8cbb 100644 (file)
@@ -5,18 +5,18 @@
     "additionalInfo": {
       "rejected": [
         {
-          "details": "Target(s) do not exist",
-          "targets": ["CMHandle4"]
+          "details": "Some other error message from the DMI",
+          "targets": ["CMHandle2"]
         },
         {
-          "details": "Faulty subscription format for target(s)",
-          "targets": ["CMHandle1", "CMHandle2", "CMHandle3"]
+          "details": "Some error message from the DMI",
+          "targets": ["CMHandle1"]
         }
       ],
       "pending": [
         {
-          "details": "EMS or node connectivity issues, retrying",
-          "targets": ["CMHandle5", "CMHandle6", "CMHandle7"]
+          "details": "No reply from DMI yet",
+          "targets": ["CMHandle3", "CMHandle4"]
         }
       ]
     }