aboutsummaryrefslogtreecommitdiffstats
path: root/cps-ncmp-service/src/main/java/org/onap
diff options
context:
space:
mode:
Diffstat (limited to 'cps-ncmp-service/src/main/java/org/onap')
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NcmpResponseStatus.java6
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java204
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/exceptions/InvalidDatastoreException.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/InvalidDatastoreException.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/exceptions/InvalidOperationException.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/InvalidOperationException.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/exceptions/OperationNotSupportedException.java32
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/models/CmResourceAddress.java41
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/models/DataOperationDefinition.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DataOperationDefinition.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/models/DataOperationRequest.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DataOperationRequest.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/models/DatastoreType.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DatastoreType.java)4
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/models/OperationType.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/OperationType.java)21
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/DataJobResultService.java45
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/DataJobService.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/DataJobService.java)27
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/DataJobStatusService.java43
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/DataJobMetadata.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/datajob/DataJobMetadata.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/DataJobReadRequest.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/datajob/DataJobReadRequest.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/DataJobWriteRequest.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/datajob/DataJobWriteRequest.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/DmiWriteOperation.java43
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/ProducerKey.java36
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/ReadOperation.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/datajob/ReadOperation.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/SubJobWriteRequest.java44
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/SubJobWriteResponse.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmResourceAddress.java)17
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/WriteOperation.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/datajob/WriteOperation.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/DmiClientRequestException.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/DmiClientRequestException.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/DmiRequestException.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/DmiRequestException.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/InvalidTopicException.java40
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/NcmpException.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/NcmpException.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/PayloadTooLargeException.java31
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/PolicyExecutorException.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/InvalidDmiResourceUrlException.java)23
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/ServerNcmpException.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/ServerNcmpException.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/DataJobServiceImpl.java43
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/client/DmiRestClient.java144
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/DmiWebClientConfiguration.java94
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionDelta.java75
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionEventsHandler.java70
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionMappersHandler.java78
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionNcmpOutEventPublishingTask.java63
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/DmiCmNotificationSubscriptionCacheHandler.java193
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/consumer/CmNotificationSubscriptionDmiOutEventConsumer.java103
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/mapper/CmNotificationSubscriptionNcmpOutEventMapper.java114
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/producer/CmNotificationSubscriptionNcmpOutEventProducer.java146
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionHandlerServiceImpl.java98
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionPersistenceService.java84
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionPersistenceServiceImpl.java166
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java302
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java47
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/AlternateIdChecker.java152
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DataNodeHelper.java100
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilder.java191
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmDataSubscriptionEvent.java76
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/NetworkCmProxyInventoryFacade.java228
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/CmHandleQueryApiParameters.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmHandleQueryApiParameters.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/CmHandleQueryServiceParameters.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmHandleQueryServiceParameters.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/CmHandleRegistrationResponse.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmHandleRegistrationResponse.java)4
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/CompositeState.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CompositeState.java)5
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/CompositeStateBuilder.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CompositeStateBuilder.java)11
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/ConditionApiProperties.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/ConditionApiProperties.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/DmiPluginRegistration.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DmiPluginRegistration.java)6
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/DmiPluginRegistrationResponse.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DmiPluginRegistrationResponse.java)4
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/NcmpServiceCmHandle.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java)7
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/TrustLevel.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/TrustLevel.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/UpgradedCmHandles.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/UpgradedCmHandles.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/YangResource.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/YangResource.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/CpsApplicationContext.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/context/CpsApplicationContext.java)4
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/DmiHttpClientConfig.java57
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/KafkaConfig.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/kafka/KafkaConfig.java)37
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/OpenTelemetryConfig.java141
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/PolicyExecutorHttpClientConfig.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/HttpClientConfiguration.java)40
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/ServiceConfig.java36
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/exceptions/NcmpStartUpException.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/NcmpStartUpException.java)6
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/exceptions/NoAlternateIdMatchFoundException.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/NoAlternateIdParentFoundException.java)9
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/cache/CmSubscriptionConfig.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/CmNotificationSubscriptionCacheConfig.java)8
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/cache/DmiCacheHandler.java227
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/cmavc/CmAvcEventConsumer.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avc/AvcEventConsumer.java)21
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiCmSubscriptionDetailsPerDmiMapper.java103
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiInEventMapper.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/mapper/CmNotificationSubscriptionDmiInEventMapper.java)53
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiInEventProducer.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/producer/CmNotificationSubscriptionDmiInEventProducer.java)32
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiOutEventConsumer.java115
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/models/CmSubscriptionStatus.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/CmNotificationSubscriptionStatus.java)6
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/models/DmiCmSubscriptionDetails.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/DmiCmNotificationSubscriptionDetails.java)8
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/models/DmiCmSubscriptionKey.java30
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/models/DmiCmSubscriptionPredicate.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/DmiCmNotificationSubscriptionPredicate.java)6
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/models/DmiCmSubscriptionTuple.java34
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/CmSubscriptionComparator.java83
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/CmSubscriptionHandler.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionHandlerService.java)24
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/CmSubscriptionHandlerImpl.java229
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpInEventConsumer.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/consumer/CmNotificationSubscriptionNcmpInEventConsumer.java)41
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventMapper.java114
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventProducer.java139
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventPublishingTask.java62
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/utils/CmSubscriptionPersistenceService.java244
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/DmiDataOperations.java310
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NcmpCachedResourceRequestHandler.java75
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NcmpDatastoreRequestHandler.java96
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NcmpPassthroughResourceRequestHandler.java102
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NetworkCmProxyFacade.java129
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NetworkCmProxyQueryService.java50
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NetworkCmProxyQueryServiceImpl.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyQueryServiceImpl.java)13
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/async/AsyncRestRequestResponseEventConsumer.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/AsyncRestRequestResponseEventConsumer.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/async/DataOperationEventConsumer.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/DataOperationEventConsumer.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/async/NcmpAsyncRequestResponseEventMapper.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventMapper.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/async/RecordFilterStrategies.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/RecordFilterStrategies.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/models/DmiDataOperation.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperation.java)6
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/models/DmiDataOperationRequest.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationRequest.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/models/DmiOperationCmHandle.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperationCmHandle.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/policyexecutor/PolicyExecutor.java185
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/utils/DataOperationEventCreator.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/data/operation/DataOperationEventCreator.java)6
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/utils/DmiDataOperationsHelper.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/data/operation/ResourceDataOperationRequestUtils.java)77
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DataJobResultServiceImpl.java55
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DataJobServiceImpl.java67
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DataJobStatusServiceImpl.java66
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DmiSubJobRequestHandler.java96
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/WriteRequestExaminer.java109
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiProperties.java55
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiRestClient.java225
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiServiceNameOrganizer.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceNameOrganizer.java)6
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiWebClientsConfiguration.java68
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/AlternateIdChecker.java115
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleQueryParametersValidator.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/RestQueryParametersValidator.java)8
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleQueryService.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CmHandleQueries.java)34
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleQueryServiceImpl.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CmHandleQueriesImpl.java)51
-rw-r--r--[-rwxr-xr-x]cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationService.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java)359
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServicePropertyHandler.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandler.java)51
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CompositeStateUtils.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CompositeStateUtils.java)4
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/DataStoreSyncState.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/DataStoreSyncState.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/InventoryPersistence.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistence.java)24
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImpl.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImpl.java)68
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/NcmpPersistence.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/ncmppersistence/NcmpPersistence.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/NcmpPersistenceImpl.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/NcmpPersistenceImpl.java)5
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryService.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyCmHandleQueryService.java)21
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryServiceImpl.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandleQueryServiceImpl.java)94
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/models/CmHandleQueryConditions.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/CmHandleQueryConditions.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/models/CmHandleState.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CmHandleState.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/models/InventoryQueryConditions.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/InventoryQueryConditions.java)5
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/models/LockReasonCategory.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/LockReasonCategory.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/models/ModelledDmiServiceLeaves.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/ModelledDmiServiceLeaves.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/models/PropertyType.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/enums/PropertyType.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/models/YangModelCmHandle.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java)16
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/AsyncTaskExecutor.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/executor/AsyncTaskExecutor.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/DataSyncWatchdog.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/DataSyncWatchdog.java)20
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperations.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java)55
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleOperationsUtils.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleOperationsUtils.java)147
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncService.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncService.java)50
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncTasks.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncTasks.java)46
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncWatchdog.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncWatchdog.java)15
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/SynchronizationCacheConfig.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationCacheConfig.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/WatchdogSchedulingConfigurer.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/config/WatchdogSchedulingConfigurer.java)4
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventHeaderMapper.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventHeaderMapper.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventType.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventType.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventsCmHandleStateHandler.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandler.java)6
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventsCmHandleStateHandlerAsyncHelper.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandlerAsyncHelper.java)10
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventsCmHandleStateHandlerImpl.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandlerImpl.java)26
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventsCreator.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreator.java)8
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventsCreatorHelper.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreatorHelper.java)12
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventsService.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsService.java)57
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumer.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/DeviceHeartbeatConsumer.java)22
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDog.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/dmiavailability/DmiPluginWatchDog.java)30
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/TrustLevelCacheConfig.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/TrustLevelCacheConfig.java)4
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/TrustLevelManager.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/TrustLevelManager.java)95
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/models/DmiRequestBody.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiRequestBody.java)5
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/models/RequiredDmiService.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/RequiredDmiService.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/policyexecutor/PolicyExecutorWebClientConfiguration.java46
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/AlternateIdMatcher.java78
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/EventDateTimeFormatter.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/EventDateTimeFormatter.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/YangDataConverter.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/YangDataConverter.java)46
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/RestServiceUrlTemplateBuilder.java134
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/UrlTemplateParameters.java30
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/WebClientConfiguration.java83
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/AbstractModelLoader.java8
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/CmDataSubscriptionModelLoader.java6
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/InventoryModelLoader.java6
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/ModelLoader.java8
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/events/CloudEventMapper.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/mapper/CloudEventMapper.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/events/CmAvcEventPublisher.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avc/ncmptoclient/AvcEventPublisher.java)5
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/events/NcmpEvent.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/NcmpEvent.java)6
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/events/TopicValidator.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyQueryService.java)34
175 files changed, 5334 insertions, 3667 deletions
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NcmpResponseStatus.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NcmpResponseStatus.java
index bdc3dee772..8cfad7dbf6 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NcmpResponseStatus.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NcmpResponseStatus.java
@@ -26,14 +26,12 @@ import lombok.Getter;
public enum NcmpResponseStatus {
SUCCESS("0", "Successfully applied changes"),
- SUCCESSFULLY_APPLIED_SUBSCRIPTION("1", "successfully applied subscription"),
+ CM_DATA_SUBSCRIPTION_ACCEPTED("1", "ACCEPTED"),
CM_HANDLES_NOT_FOUND("100", "cm handle id(s) not found"),
CM_HANDLES_NOT_READY("101", "cm handle(s) not ready"),
DMI_SERVICE_NOT_RESPONDING("102", "dmi plugin service is not responding"),
UNABLE_TO_READ_RESOURCE_DATA("103", "dmi plugin service is not able to read resource data"),
- PARTIALLY_APPLIED_SUBSCRIPTION("104", "partially applied subscription"),
- SUBSCRIPTION_NOT_APPLICABLE("105", "subscription not applicable for all cm handles"),
- SUBSCRIPTION_PENDING("106", "subscription pending for all cm handles"),
+ CM_DATA_SUBSCRIPTION_REJECTED("104", "REJECTED"),
UNKNOWN_ERROR("108", "Unknown error"),
CM_HANDLE_ALREADY_EXIST("109", "cm-handle already exists"),
CM_HANDLE_INVALID_ID("110", "cm-handle has an invalid character(s) in id"),
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java
deleted file mode 100644
index 20545d711d..0000000000
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2021 highstreet technologies GmbH
- * Modifications Copyright (C) 2021-2024 Nordix Foundation
- * Modifications Copyright (C) 2021 Pantheon.tech
- * Modifications Copyright (C) 2022 Bell Canada
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * 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;
-
-import java.util.Collection;
-import java.util.Map;
-import org.onap.cps.ncmp.api.impl.inventory.CompositeState;
-import org.onap.cps.ncmp.api.impl.operations.OperationType;
-import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters;
-import org.onap.cps.ncmp.api.models.CmHandleQueryServiceParameters;
-import org.onap.cps.ncmp.api.models.CmResourceAddress;
-import org.onap.cps.ncmp.api.models.DataOperationRequest;
-import org.onap.cps.ncmp.api.models.DmiPluginRegistration;
-import org.onap.cps.ncmp.api.models.DmiPluginRegistrationResponse;
-import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
-import org.onap.cps.spi.FetchDescendantsOption;
-import org.onap.cps.spi.model.ModuleDefinition;
-import org.onap.cps.spi.model.ModuleReference;
-
-/*
- * Datastore interface for handling CPS data.
- */
-public interface NetworkCmProxyDataService {
-
- /**
- * Registration of New CM Handles.
- *
- * @param dmiPluginRegistration Dmi Plugin Registration
- * @return dmiPluginRegistrationResponse
- */
- DmiPluginRegistrationResponse updateDmiRegistrationAndSyncModule(DmiPluginRegistration dmiPluginRegistration);
-
- /**
- * Get resource data for given data store using dmi.
- *
- * @param cmResourceAddress target datastore, cm handle and resource identifier
- * @param optionsParamInQuery options query
- * @param topicParamInQuery topic name for (triggering) async responses
- * @param requestId unique requestId for async request
- * @param authorization contents of Authorization header, or null if not present
- * @return {@code Object} resource data
- */
- Object getResourceDataForCmHandle(CmResourceAddress cmResourceAddress,
- String optionsParamInQuery,
- String topicParamInQuery,
- String requestId,
- String authorization);
-
- /**
- * Get resource data for operational.
- *
- * @param cmResourceAddress target datastore, cm handle and resource identifier
- * @Link FetchDescendantsOption fetch descendants option
- * @return {@code Object} resource data
- */
- Object getResourceDataForCmHandle(CmResourceAddress cmResourceAddress,
- FetchDescendantsOption fetchDescendantsOption);
-
- /**
- * Execute (async) data operation for group of cm handles using dmi.
- *
- * @param topicParamInQuery topic name for (triggering) async responses
- * @param dataOperationRequest contains a list of operation definitions(multiple operations)
- * @param requestId request ID
- * @param authorization contents of Authorization header, or null if not present
- */
- void executeDataOperationForCmHandles(String topicParamInQuery,
- DataOperationRequest dataOperationRequest,
- String requestId,
- String authorization);
-
-
- /**
- * Write resource data for data store pass-through running using dmi for given cm-handle.
- *
- * @param cmHandleId cm handle identifier
- * @param resourceIdentifier resource identifier
- * @param operationType required operation type
- * @param requestBody request body to create resource
- * @param contentType content type in body
- * @param authorization contents of Authorization header, or null if not present
- * @return {@code Object} return data
- */
- Object writeResourceDataPassThroughRunningForCmHandle(String cmHandleId,
- String resourceIdentifier,
- OperationType operationType,
- String requestBody,
- String contentType,
- String authorization);
-
- /**
- * Retrieve module references for the given cm handle.
- *
- * @param cmHandleId cm handle identifier
- * @return a collection of modules names and revisions
- */
- Collection<ModuleReference> getYangResourcesModuleReferences(String cmHandleId);
-
- /**
- * Retrieve module definitions for the given cm handle.
- *
- * @param cmHandleId cm handle identifier
- * @return a collection of module definition (moduleName, revision and yang resource content)
- */
- Collection<ModuleDefinition> getModuleDefinitionsByCmHandleId(String cmHandleId);
-
- /**
- * Get module definitions for the given parameters.
- *
- * @param cmHandleId cm-handle identifier
- * @param moduleName module name
- * @param moduleRevision the revision of the module
- * @return list of module definitions (module name, revision, yang resource content)
- */
- Collection<ModuleDefinition> getModuleDefinitionsByCmHandleAndModule(String cmHandleId,
- String moduleName,
- String moduleRevision);
-
- /**
- * Query cm handle details by cm handle's name.
- *
- * @param cmHandleId cm handle identifier
- * @return a collection of cm handle details.
- */
- NcmpServiceCmHandle getNcmpServiceCmHandle(String cmHandleId);
-
- /**
- * Get cm handle public properties by cm handle id.
- *
- * @param cmHandleId cm handle identifier
- * @return a collection of cm handle public properties.
- */
- Map<String, String> getCmHandlePublicProperties(String cmHandleId);
-
- /**
- * Get cm handle composite state by cm handle id.
- *
- * @param cmHandleId cm handle identifier
- * @return a cm handle composite state
- */
- CompositeState getCmHandleCompositeState(String cmHandleId);
-
- /**
- * Query and return cm handles that match the given query parameters.
- *
- * @param cmHandleQueryApiParameters the cm handle query parameters
- * @return collection of cm handles
- */
- Collection<NcmpServiceCmHandle> executeCmHandleSearch(CmHandleQueryApiParameters cmHandleQueryApiParameters);
-
- /**
- * Query and return cm handle ids that match the given query parameters.
- *
- * @param cmHandleQueryApiParameters the cm handle query parameters
- * @return collection of cm handle ids
- */
- Collection<String> executeCmHandleIdSearch(CmHandleQueryApiParameters cmHandleQueryApiParameters);
-
- /**
- * Set the data sync enabled flag, along with the data sync state to true or false based on the cm handle id.
- *
- * @param cmHandleId cm handle id
- * @param dataSyncEnabled data sync enabled flag
- */
- void setDataSyncEnabled(String cmHandleId, Boolean dataSyncEnabled);
-
- /**
- * Get all cm handle IDs by DMI plugin identifier.
- *
- * @param dmiPluginIdentifier DMI plugin identifier
- * @return collection of cm handle IDs
- */
- Collection<String> getAllCmHandleIdsByDmiPluginIdentifier(String dmiPluginIdentifier);
-
- /**
- * Get all cm handle IDs by various search criteria.
- *
- * @param cmHandleQueryServiceParameters cm handle query parameters
- * @return collection of cm handle IDs
- */
- Collection<String> executeCmHandleIdSearchForInventory(CmHandleQueryServiceParameters
- cmHandleQueryServiceParameters);
-}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/InvalidDatastoreException.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/exceptions/InvalidDatastoreException.java
index 6cfa159b20..740785e3be 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/InvalidDatastoreException.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/exceptions/InvalidDatastoreException.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.exception;
+package org.onap.cps.ncmp.api.data.exceptions;
public class InvalidDatastoreException extends RuntimeException {
/**
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/InvalidOperationException.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/exceptions/InvalidOperationException.java
index 17069098cb..7669dd05f6 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/InvalidOperationException.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/exceptions/InvalidOperationException.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.exception;
+package org.onap.cps.ncmp.api.data.exceptions;
public class InvalidOperationException extends RuntimeException {
/**
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/exceptions/OperationNotSupportedException.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/exceptions/OperationNotSupportedException.java
new file mode 100644
index 0000000000..eea846a0f6
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/exceptions/OperationNotSupportedException.java
@@ -0,0 +1,32 @@
+/*
+ * ============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.data.exceptions;
+
+public class OperationNotSupportedException extends RuntimeException {
+ /**
+ * Instantiates a new not implemented operation exception.
+ *
+ * @param message the message
+ */
+ public OperationNotSupportedException(final String message) {
+ super(message);
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/models/CmResourceAddress.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/models/CmResourceAddress.java
new file mode 100644
index 0000000000..98a343b92e
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/models/CmResourceAddress.java
@@ -0,0 +1,41 @@
+/*
+ * ============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.data.models;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.onap.cps.ncmp.config.CpsApplicationContext;
+import org.onap.cps.ncmp.impl.utils.AlternateIdMatcher;
+
+@Getter
+@RequiredArgsConstructor
+public class CmResourceAddress {
+
+ private final String datastoreName;
+ @Getter(AccessLevel.NONE)
+ private final String cmHandleReference;
+ private final String resourceIdentifier;
+
+ public String getResolvedCmHandleId() {
+ return CpsApplicationContext.getCpsBean(AlternateIdMatcher.class).getCmHandleId(cmHandleReference);
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DataOperationDefinition.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/models/DataOperationDefinition.java
index 366d845832..d1ff1a5815 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DataOperationDefinition.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/models/DataOperationDefinition.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.models;
+package org.onap.cps.ncmp.api.data.models;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DataOperationRequest.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/models/DataOperationRequest.java
index a4d070c38d..b104f587fb 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DataOperationRequest.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/models/DataOperationRequest.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.models;
+package org.onap.cps.ncmp.api.data.models;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DatastoreType.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/models/DatastoreType.java
index 6520c05c08..a483341b65 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DatastoreType.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/models/DatastoreType.java
@@ -18,14 +18,14 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.operations;
+package org.onap.cps.ncmp.api.data.models;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import lombok.Getter;
-import org.onap.cps.ncmp.api.impl.exception.InvalidDatastoreException;
+import org.onap.cps.ncmp.api.data.exceptions.InvalidDatastoreException;
@Getter
public enum DatastoreType {
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/OperationType.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/models/OperationType.java
index fa00d1a15e..870e24fac4 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/OperationType.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/models/OperationType.java
@@ -18,14 +18,12 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.operations;
+package org.onap.cps.ncmp.api.data.models;
import com.fasterxml.jackson.annotation.JsonValue;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.Locale;
import lombok.Getter;
-import org.onap.cps.ncmp.api.impl.exception.InvalidOperationException;
+import org.onap.cps.ncmp.api.data.exceptions.InvalidOperationException;
@Getter
public enum OperationType {
@@ -48,13 +46,6 @@ public enum OperationType {
return String.valueOf(operationName);
}
- private static final Map<String, OperationType> operationNameToOperationEnum = new HashMap<>();
-
- static {
- Arrays.stream(OperationType.values()).forEach(
- operationType -> operationNameToOperationEnum.put(operationType.getOperationName(), operationType));
- }
-
/**
* From operation name get operation enum type.
*
@@ -62,10 +53,10 @@ public enum OperationType {
* @return the operation enum type
*/
public static OperationType fromOperationName(final String operationName) {
- final OperationType operationType = operationNameToOperationEnum.get(operationName);
- if (null == operationType) {
+ try {
+ return OperationType.valueOf(operationName.toUpperCase(Locale.ENGLISH));
+ } catch (final IllegalArgumentException e) {
throw new InvalidOperationException(operationName + " is an invalid operation name");
}
- return operationType;
}
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/DataJobResultService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/DataJobResultService.java
new file mode 100644
index 0000000000..c6b7a8bd04
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/DataJobResultService.java
@@ -0,0 +1,45 @@
+/*
+ * ============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.datajobs;
+
+/**
+ * Service interface to retrieve the result of a data job.
+ * The operations interact with a DMI Plugin to retrieve data job results.
+ */
+public interface DataJobResultService {
+
+ /**
+ * Retrieves the result of a specific data job.
+ *
+ * @param authorization The authorization header from the REST request.
+ * @param dmiServiceName The name of the DMI Service relevant to the data job.
+ * @param dataProducerId The ID of the producer registered by DMI, used for operations related to this request.
+ * This could include alternate IDs or specific identifiers.
+ * @param dataProducerJobId The identifier of the data producer job within the DMI system.
+ * @param destination The destination of the results: Kafka topic name or S3 bucket name.
+ * @return The result of the data job.
+ */
+ String getDataJobResult(final String authorization,
+ final String dmiServiceName,
+ final String dataProducerId,
+ final String dataProducerJobId,
+ final String destination);
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/DataJobService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/DataJobService.java
index 6122afc808..255b3847eb 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/DataJobService.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/DataJobService.java
@@ -18,29 +18,40 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api;
+package org.onap.cps.ncmp.api.datajobs;
-import org.onap.cps.ncmp.api.models.datajob.DataJobMetadata;
-import org.onap.cps.ncmp.api.models.datajob.DataJobReadRequest;
-import org.onap.cps.ncmp.api.models.datajob.DataJobWriteRequest;
+import java.util.List;
+import org.onap.cps.ncmp.api.datajobs.models.DataJobMetadata;
+import org.onap.cps.ncmp.api.datajobs.models.DataJobReadRequest;
+import org.onap.cps.ncmp.api.datajobs.models.DataJobWriteRequest;
+import org.onap.cps.ncmp.api.datajobs.models.SubJobWriteResponse;
public interface DataJobService {
/**
* process read data job operations.
*
- * @param dataJobId Unique identifier of the job within the request
+ * @param authorization the authorization header from the REST request
+ * @param dataJobId unique identifier of the job within the request
* @param dataJobMetadata data job request headers
* @param dataJobReadRequest read data job request
*/
- void readDataJob(String dataJobId, DataJobMetadata dataJobMetadata, DataJobReadRequest dataJobReadRequest);
+ void readDataJob(String authorization,
+ String dataJobId,
+ DataJobMetadata dataJobMetadata,
+ DataJobReadRequest dataJobReadRequest);
/**
* process write data job operations.
*
- * @param dataJobId Unique identifier of the job within the request
+ * @param authorization the authorization header from the REST request
+ * @param dataJobId unique identifier of the job within the request
* @param dataJobMetadata data job request headers
* @param dataJobWriteRequest write data job request
+ * @return a list of sub-job write responses
*/
- void writeDataJob(String dataJobId, DataJobMetadata dataJobMetadata, DataJobWriteRequest dataJobWriteRequest);
+ List<SubJobWriteResponse> writeDataJob(String authorization,
+ String dataJobId,
+ DataJobMetadata dataJobMetadata,
+ DataJobWriteRequest dataJobWriteRequest);
} \ No newline at end of file
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/DataJobStatusService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/DataJobStatusService.java
new file mode 100644
index 0000000000..9cfc49f1d4
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/DataJobStatusService.java
@@ -0,0 +1,43 @@
+/*
+ * ============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.datajobs;
+
+/**
+ * Service interface to check the status of a data job.
+ * The operations interact with a DMI Plugin to retrieve data job statuses.
+ */
+public interface DataJobStatusService {
+
+ /**
+ * Retrieves the current status of a specific data job.
+ *
+ * @param authorization The authorization header from the REST request.
+ * @param dmiServiceName The name of the DMI Service relevant to the data job.
+ * @param dataProducerId The ID of the producer registered by DMI, used for operations related to this request.
+ * This could include alternate IDs or specific identifiers.
+ * @param dataProducerJobId The identifier of the data producer job within the DMI system.
+ * @return The current status of the data job as a String.
+ */
+ String getDataJobStatus(final String authorization,
+ final String dmiServiceName,
+ final String dataProducerId,
+ final String dataProducerJobId);
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/datajob/DataJobMetadata.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/DataJobMetadata.java
index dc8037b86f..564352d8db 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/datajob/DataJobMetadata.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/DataJobMetadata.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.models.datajob;
+package org.onap.cps.ncmp.api.datajobs.models;
/**
* Metadata of read/write data job request.
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/datajob/DataJobReadRequest.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/DataJobReadRequest.java
index f861c3d498..19408b1da1 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/datajob/DataJobReadRequest.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/DataJobReadRequest.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.models.datajob;
+package org.onap.cps.ncmp.api.datajobs.models;
import java.util.List;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/datajob/DataJobWriteRequest.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/DataJobWriteRequest.java
index 254e198b81..d8961b17c0 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/datajob/DataJobWriteRequest.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/DataJobWriteRequest.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.models.datajob;
+package org.onap.cps.ncmp.api.datajobs.models;
import java.util.List;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/DmiWriteOperation.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/DmiWriteOperation.java
new file mode 100644
index 0000000000..7e9ca7988b
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/DmiWriteOperation.java
@@ -0,0 +1,43 @@
+/*
+ * ============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.datajobs.models;
+
+import java.util.Map;
+
+/**
+ * Describes the write data job operation to be forwarded to dmi.
+ *
+ * @param path Identifier of a managed object (MO) on a network element. Defines the resource on which
+ * operation is executed. Typically, is Fully Distinguished Name (FDN).
+ * @param op Describes the operation to execute. The value can be as below:
+ * e.g. "add", "replace", "remove", "action" etc.
+ * @param moduleSetTag The module set tag of the CM Handle.
+ * @param value The value to be written depends on the type of operation.
+ * @param operationId Unique identifier of the operation within the request.
+ * @param privateProperties Contains the private properties of a Cm Handle.
+ */
+public record DmiWriteOperation(
+ String path,
+ String op,
+ String moduleSetTag,
+ Object value,
+ String operationId,
+ Map<String, String> privateProperties) {}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/ProducerKey.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/ProducerKey.java
new file mode 100644
index 0000000000..ac6b7f8622
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/ProducerKey.java
@@ -0,0 +1,36 @@
+/*
+ * ============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.datajobs.models;
+
+/**
+ * Composite key created from the DMI Service name and a data producer identifier.
+ * Helps to group of the sub job request for a given DMI Plugin.
+ *
+ * @param dmiServiceName Describes the name of the relevant DMI service.
+ * @param dataProducerIdentifier The name of a data producer identifier from a Cm Handle.
+ */
+public record ProducerKey(String dmiServiceName, String dataProducerIdentifier) {
+
+ @Override
+ public String toString() {
+ return dmiServiceName + "#" + dataProducerIdentifier;
+ }
+} \ No newline at end of file
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/datajob/ReadOperation.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/ReadOperation.java
index d2b0738969..2459e4cc2e 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/datajob/ReadOperation.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/ReadOperation.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.models.datajob;
+package org.onap.cps.ncmp.api.datajobs.models;
import java.util.List;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/SubJobWriteRequest.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/SubJobWriteRequest.java
new file mode 100644
index 0000000000..a7a6573279
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/SubJobWriteRequest.java
@@ -0,0 +1,44 @@
+/*
+ * ============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.datajobs.models;
+
+import java.util.Collection;
+
+/**
+ * Request data for a write operation by the DMI Plugin.
+ *
+ * @param destination The destination of the results. ( e.g. S3 Bucket)
+ * @param dataAcceptType Define the data response accept type.
+ * e.g. "application/vnd.3gpp.object-tree-hierarchical+json",
+ * "application/vnd.3gpp.object-tree-flat+json" etc.
+ * @param dataContentType Define the data request content type.
+ * e.g. "application/3gpp-json-patch+json" etc.
+ * @param dataProducerId Identifier of the data producer.
+ * @param dataJobId Identifier for the overall Datajob
+ * @param data A collection of outgoing write operations.
+ */
+public record SubJobWriteRequest (
+ String destination,
+ String dataAcceptType,
+ String dataContentType,
+ String dataProducerId,
+ String dataJobId,
+ Collection<DmiWriteOperation> data) {} \ No newline at end of file
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmResourceAddress.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/SubJobWriteResponse.java
index 21d82fcf56..9cdd8e0590 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmResourceAddress.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/SubJobWriteResponse.java
@@ -1,12 +1,12 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2024 Nordix Foundation
+ * 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
+ * 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,
@@ -18,8 +18,13 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.models;
+package org.onap.cps.ncmp.api.datajobs.models;
-public record CmResourceAddress(String datastoreName, String cmHandleId, String resourceIdentifier) {
-
-}
+/**
+ * Request data for a write operation towards DMI Plugin.
+ *
+ * @param subJobId Identifier of the sub-job from DMI.
+ * @param dmiServiceName The provided name of the DMI service from the request.
+ * @param dataProducerId Identifier of the data producer.
+ */
+public record SubJobWriteResponse(String subJobId, String dmiServiceName, String dataProducerId) {} \ No newline at end of file
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/datajob/WriteOperation.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/WriteOperation.java
index c2f6504ce2..807e03f06f 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/datajob/WriteOperation.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/datajobs/models/WriteOperation.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.models.datajob;
+package org.onap.cps.ncmp.api.datajobs.models;
/**
* Holds information of write data job operation.
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/DmiClientRequestException.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/DmiClientRequestException.java
index ab0fa68938..65ccba8018 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/DmiClientRequestException.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/DmiClientRequestException.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.exception;
+package org.onap.cps.ncmp.api.exceptions;
import lombok.Getter;
import org.onap.cps.ncmp.api.NcmpResponseStatus;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/DmiRequestException.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/DmiRequestException.java
index d41ca70bca..b2cfbc01be 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/DmiRequestException.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/DmiRequestException.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.exception;
+package org.onap.cps.ncmp.api.exceptions;
/**
* Client Based Network CM Proxy exception.
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/InvalidTopicException.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/InvalidTopicException.java
new file mode 100644
index 0000000000..07b186dae4
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/InvalidTopicException.java
@@ -0,0 +1,40 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.api.exceptions;
+
+import lombok.Getter;
+
+public class InvalidTopicException extends RuntimeException {
+
+ @Getter
+ final String details;
+
+ /**
+ * Constructor.
+ *
+ * @param message the error message
+ * @param details the error details
+ */
+ public InvalidTopicException(final String message, final String details) {
+ super(message);
+ this.details = details;
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/NcmpException.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/NcmpException.java
index 2c75b5d992..6754965866 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/NcmpException.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/NcmpException.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.exception;
+package org.onap.cps.ncmp.api.exceptions;
import lombok.Getter;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/PayloadTooLargeException.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/PayloadTooLargeException.java
new file mode 100644
index 0000000000..edb295dbbf
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/PayloadTooLargeException.java
@@ -0,0 +1,31 @@
+/*
+ * ============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.exceptions;
+
+public class PayloadTooLargeException extends RuntimeException {
+
+ /**
+ * Instantiates a new payload too large exception.
+ */
+ public PayloadTooLargeException(final String message) {
+ super(message);
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/InvalidDmiResourceUrlException.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/PolicyExecutorException.java
index 270988b63b..333c12271b 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/InvalidDmiResourceUrlException.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/PolicyExecutorException.java
@@ -18,20 +18,25 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.exception;
+package org.onap.cps.ncmp.api.exceptions;
import lombok.Getter;
+/**
+ * Exception to be used when policy execution fails or does not allow to proceed.
+ */
@Getter
-public class InvalidDmiResourceUrlException extends RuntimeException {
-
- private static final long serialVersionUID = 2928476384584894968L;
+public class PolicyExecutorException extends NcmpException {
- private static final String INVALID_DMI_URL = "Invalid dmi resource url";
- final Integer httpStatus;
+ private static final long serialVersionUID = 6659897770659834798L;
- public InvalidDmiResourceUrlException(final String details, final Integer httpStatus) {
- super(String.format(INVALID_DMI_URL + ": %s", details));
- this.httpStatus = httpStatus;
+ /**
+ * Constructor to form exception for policy executor responses.
+ *
+ * @param message response message
+ * @param details response details
+ */
+ public PolicyExecutorException(final String message, final String details) {
+ super(message, details);
}
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/ServerNcmpException.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/ServerNcmpException.java
index a03a2d3e6c..03dc3bc8dd 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/ServerNcmpException.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/ServerNcmpException.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.exception;
+package org.onap.cps.ncmp.api.exceptions;
/**
* Server Based Network CM Proxy exception.
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/DataJobServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/DataJobServiceImpl.java
deleted file mode 100644
index b4377b84f2..0000000000
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/DataJobServiceImpl.java
+++ /dev/null
@@ -1,43 +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;
-
-import lombok.extern.slf4j.Slf4j;
-import org.onap.cps.ncmp.api.DataJobService;
-import org.onap.cps.ncmp.api.models.datajob.DataJobMetadata;
-import org.onap.cps.ncmp.api.models.datajob.DataJobReadRequest;
-import org.onap.cps.ncmp.api.models.datajob.DataJobWriteRequest;
-
-@Slf4j
-public class DataJobServiceImpl implements DataJobService {
-
- @Override
- public void readDataJob(final String dataJobId, final DataJobMetadata dataJobMetadata,
- final DataJobReadRequest dataJobReadRequest) {
- log.info("data job id for read operation is: {}", dataJobId);
- }
-
- @Override
- public void writeDataJob(final String dataJobId, final DataJobMetadata dataJobMetadata,
- final DataJobWriteRequest dataJobWriteRequest) {
- log.info("data job id for write operation is: {}", dataJobId);
- }
-}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/client/DmiRestClient.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/client/DmiRestClient.java
deleted file mode 100644
index 97ae677c5e..0000000000
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/client/DmiRestClient.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2021-2024 Nordix Foundation
- * Modifications Copyright (C) 2022 Bell Canada
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * 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.client;
-
-import static org.onap.cps.ncmp.api.NcmpResponseStatus.DMI_SERVICE_NOT_RESPONDING;
-import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNABLE_TO_READ_RESOURCE_DATA;
-import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNKNOWN_ERROR;
-import static org.springframework.http.HttpStatus.BAD_REQUEST;
-import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Locale;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.onap.cps.ncmp.api.impl.config.DmiWebClientConfiguration.DmiProperties;
-import org.onap.cps.ncmp.api.impl.exception.DmiClientRequestException;
-import org.onap.cps.ncmp.api.impl.exception.InvalidDmiResourceUrlException;
-import org.onap.cps.ncmp.api.impl.operations.OperationType;
-import org.onap.cps.utils.JsonObjectMapper;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Component;
-import org.springframework.web.client.HttpServerErrorException;
-import org.springframework.web.reactive.function.BodyInserters;
-import org.springframework.web.reactive.function.client.WebClient;
-import org.springframework.web.reactive.function.client.WebClientResponseException;
-
-@Component
-@RequiredArgsConstructor
-@Slf4j
-public class DmiRestClient {
-
- private static final String HEALTH_CHECK_URL_EXTENSION = "/actuator/health";
- private static final String NOT_SPECIFIED = "";
- private static final String NO_AUTHORIZATION = null;
- private final WebClient webClient;
- private final DmiProperties dmiProperties;
- private final JsonObjectMapper jsonObjectMapper;
-
- /**
- * Sends POST operation to DMI with json body containing module references.
- *
- * @param dmiResourceUrl dmi resource url
- * @param requestBodyAsJsonString json data body
- * @param operationType the type of operation being executed (for error reporting only)
- * @param authorization contents of Authorization header, or null if not present
- * @return response entity of type String
- */
- public ResponseEntity<Object> postOperationWithJsonData(final String dmiResourceUrl,
- final String requestBodyAsJsonString,
- final OperationType operationType,
- final String authorization) {
- try {
- return ResponseEntity.ok(webClient.post().uri(toUri(dmiResourceUrl))
- .headers(httpHeaders -> configureHttpHeaders(httpHeaders, authorization))
- .body(BodyInserters.fromValue(requestBodyAsJsonString))
- .retrieve()
- .bodyToMono(Object.class)
- .onErrorMap(httpError -> handleDmiClientException(httpError, operationType.getOperationName()))
- .block());
- } catch (final HttpServerErrorException e) {
- throw handleDmiClientException(e, operationType.getOperationName());
- }
- }
-
- /**
- * Get DMI plugin health status.
- *
- * @param dmiPluginBaseUrl the base URL of the dmi-plugin
- * @return plugin health status ("UP" is all OK, "" (not-specified) in case of any exception)
- */
- public String getDmiHealthStatus(final String dmiPluginBaseUrl) {
- try {
- final JsonNode responseHealthStatus = webClient.get()
- .uri(toUri(dmiPluginBaseUrl + HEALTH_CHECK_URL_EXTENSION))
- .headers(httpHeaders -> configureHttpHeaders(httpHeaders, NO_AUTHORIZATION))
- .retrieve()
- .bodyToMono(JsonNode.class).block();
- return responseHealthStatus == null ? NOT_SPECIFIED :
- responseHealthStatus.get("status").asText();
- } catch (final Exception e) {
- log.warn("Failed to retrieve health status from {}. Error Message: {}", dmiPluginBaseUrl, e.getMessage());
- return NOT_SPECIFIED;
- }
- }
-
- private HttpHeaders configureHttpHeaders(final HttpHeaders httpHeaders, final String authorization) {
- if (dmiProperties.isDmiBasicAuthEnabled()) {
- httpHeaders.setBasicAuth(dmiProperties.getAuthUsername(), dmiProperties.getAuthPassword());
- } else if (authorization != null && authorization.toLowerCase(Locale.getDefault()).startsWith("bearer ")) {
- httpHeaders.add(HttpHeaders.AUTHORIZATION, authorization);
- }
- return httpHeaders;
- }
-
- private static URI toUri(final String dmiResourceUrl) {
- try {
- return new URI(dmiResourceUrl);
- } catch (final URISyntaxException e) {
- throw new InvalidDmiResourceUrlException(dmiResourceUrl, BAD_REQUEST.value());
- }
- }
-
- private DmiClientRequestException handleDmiClientException(final Throwable e, final String operationType) {
- final String exceptionMessage = "Unable to " + operationType + " resource data.";
- if (e instanceof WebClientResponseException wcre) {
- if (wcre.getStatusCode().isSameCodeAs(HttpStatus.REQUEST_TIMEOUT)) {
- throw new DmiClientRequestException(wcre.getStatusCode().value(), wcre.getMessage(),
- jsonObjectMapper.asJsonString(wcre.getResponseBodyAsString()), DMI_SERVICE_NOT_RESPONDING);
- }
- throw new DmiClientRequestException(wcre.getStatusCode().value(), wcre.getMessage(),
- jsonObjectMapper.asJsonString(wcre.getResponseBodyAsString()), UNABLE_TO_READ_RESOURCE_DATA);
-
- }
- if (e instanceof HttpServerErrorException httpServerErrorException) {
- throw new DmiClientRequestException(httpServerErrorException.getStatusCode().value(), exceptionMessage,
- httpServerErrorException.getResponseBodyAsString(), DMI_SERVICE_NOT_RESPONDING);
- }
- throw new DmiClientRequestException(INTERNAL_SERVER_ERROR.value(), exceptionMessage, e.getMessage(),
- UNKNOWN_ERROR);
- }
-}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/DmiWebClientConfiguration.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/DmiWebClientConfiguration.java
deleted file mode 100644
index 21271665fd..0000000000
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/DmiWebClientConfiguration.java
+++ /dev/null
@@ -1,94 +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.config;
-
-import io.netty.channel.ChannelOption;
-import io.netty.handler.timeout.ReadTimeoutHandler;
-import io.netty.handler.timeout.WriteTimeoutHandler;
-import java.util.concurrent.TimeUnit;
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.MediaType;
-import org.springframework.http.client.reactive.ReactorClientHttpConnector;
-import org.springframework.stereotype.Component;
-import org.springframework.web.reactive.function.client.WebClient;
-import reactor.netty.http.client.HttpClient;
-import reactor.netty.resources.ConnectionProvider;
-
-@Configuration
-@RequiredArgsConstructor
-public class DmiWebClientConfiguration {
-
- @Value("${ncmp.dmi.httpclient.connectionTimeoutInSeconds:20000}")
- private Integer connectionTimeoutInSeconds;
-
- @Value("${ncmp.dmi.httpclient.maximumInMemorySizeInMegabytes:1}")
- private Integer maximumInMemorySizeInMegabytes;
-
- @Value("${ncmp.dmi.httpclient.maximumConnectionsTotal:100}")
- private Integer maximumConnectionsTotal;
-
- @Getter
- @Component
- public static class DmiProperties {
- @Value("${ncmp.dmi.auth.username}")
- private String authUsername;
- @Value("${ncmp.dmi.auth.password}")
- private String authPassword;
- @Value("${ncmp.dmi.api.base-path}")
- private String dmiBasePath;
- @Value("${ncmp.dmi.auth.enabled}")
- private boolean dmiBasicAuthEnabled;
- }
-
- /**
- * Configures and create a WebClient bean that triggers an initialization (warmup) of the host name resolver and
- * loads the necessary native libraries to avoid the extra time needed to load resources for first request.
- *
- * @return a WebClient instance.
- */
- @Bean
- public WebClient webClient() {
-
- final ConnectionProvider dmiWebClientConnectionProvider
- = ConnectionProvider.create("dmiWebClientConnectionPool", maximumConnectionsTotal);
-
- final HttpClient httpClient = HttpClient.create(dmiWebClientConnectionProvider)
- .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectionTimeoutInSeconds * 1000)
- .doOnConnected(connection ->
- connection
- .addHandlerLast(new ReadTimeoutHandler(connectionTimeoutInSeconds, TimeUnit.SECONDS))
- .addHandlerLast(new WriteTimeoutHandler(connectionTimeoutInSeconds, TimeUnit.SECONDS)));
- httpClient.warmup().block();
- return WebClient.builder()
- .defaultHeaders(header -> header.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE))
- .defaultHeaders(header -> header.set(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE))
- .clientConnector(new ReactorClientHttpConnector(httpClient))
- .codecs(configurer -> configurer
- .defaultCodecs()
- .maxInMemorySize(maximumInMemorySizeInMegabytes * 1024 * 1024))
- .build();
- }
-}
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
index 8a4beb9560..0000000000
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionDelta.java
+++ /dev/null
@@ -1,75 +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.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionPredicate;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.service.CmNotificationSubscriptionPersistenceService;
-import org.onap.cps.ncmp.api.impl.operations.DatastoreType;
-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);
-
- }
- }
- }
-
- final DmiCmNotificationSubscriptionPredicate predicateDelta =
- new DmiCmNotificationSubscriptionPredicate(targetCmHandleIds, datastoreType, xpaths);
-
- delta.add(predicateDelta);
- }
- return delta;
- }
-
-}
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
index 50a5df537d..0000000000
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionEventsHandler.java
+++ /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
index 73f9563ecf..0000000000
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionMappersHandler.java
+++ /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
index f7dd51e637..0000000000
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionNcmpOutEventPublishingTask.java
+++ /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/DmiCmNotificationSubscriptionCacheHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/DmiCmNotificationSubscriptionCacheHandler.java
deleted file mode 100644
index b5370bf1ed..0000000000
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/DmiCmNotificationSubscriptionCacheHandler.java
+++ /dev/null
@@ -1,193 +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.model.CmNotificationSubscriptionStatus.PENDING;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-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.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.api.impl.inventory.InventoryPersistence;
-import org.onap.cps.ncmp.api.impl.operations.DatastoreType;
-import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.client_to_ncmp.Predicate;
-import org.springframework.stereotype.Component;
-
-@Component
-@RequiredArgsConstructor
-public class DmiCmNotificationSubscriptionCacheHandler {
-
- private final CmNotificationSubscriptionPersistenceService cmNotificationSubscriptionPersistenceService;
- private final Map<String, Map<String, DmiCmNotificationSubscriptionDetails>> cmNotificationSubscriptionCache;
- private final InventoryPersistence inventoryPersistence;
-
- /**
- * Adds new subscription to the subscription cache.
- *
- * @param subscriptionId subscription id
- * @param predicates subscription request predicates
- */
- public void add(final String subscriptionId, final List<Predicate> predicates) {
- cmNotificationSubscriptionCache.put(subscriptionId, createDmiCmNotificationSubscriptionsPerDmi(predicates));
- }
-
- /**
- * Get cm notification subscription cache entry via subscription id.
- *
- * @param subscriptionId subscription id
- * @return map of dmi cm notification subscriptions per dmi
- */
- public Map<String, DmiCmNotificationSubscriptionDetails> get(final String subscriptionId) {
- return cmNotificationSubscriptionCache.get(subscriptionId);
- }
-
-
- /**
- * Remove cache entries with CmNotificationSubscriptionStatus ACCEPTED/REJECTED via subscription id.
- *
- * @param subscriptionId subscription id as key in CM notification Subscription cache.
- */
- public void removeAcceptedAndRejectedDmiCmNotificationSubscriptionEntries(final String subscriptionId) {
- final Map<String, DmiCmNotificationSubscriptionDetails> dmiCmNotificationSubscriptionsPerDmi =
- cmNotificationSubscriptionCache.get(subscriptionId);
- final Map<String, DmiCmNotificationSubscriptionDetails> updatedDmiCmNotificationSubscriptionsPerDmi =
- dmiCmNotificationSubscriptionsPerDmi.entrySet().stream().filter(
- dmiCmNotificationSubscription ->
- !isAcceptedOrRejected(dmiCmNotificationSubscription.getValue()))
- .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
- cmNotificationSubscriptionCache.put(subscriptionId, updatedDmiCmNotificationSubscriptionsPerDmi);
- }
-
- /**
- * Creates map of subscription details per DMI.
- *
- * @param predicates CM Subscription Create Request Predicates
- * @return Map of DmiCmNotificationSubscription per DMI plugin
- */
- public Map<String, DmiCmNotificationSubscriptionDetails> createDmiCmNotificationSubscriptionsPerDmi(
- final List<Predicate> predicates) {
- final Map<String, DmiCmNotificationSubscriptionDetails> dmiCmNotificationSubscriptionDetailsPerDmi =
- new HashMap<>();
- for (final Predicate requestPredicate : predicates) {
- final List<String> targetFilter = requestPredicate.getTargetFilter();
- final DatastoreType datastoreType = DatastoreType.fromDatastoreName(
- requestPredicate.getScopeFilter().getDatastore().toString());
- 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(),
- datastoreType, xpaths);
- updateDmiCmNotificationSubscriptionDetailsPerDmi(targetCmHandlesByDmi.getKey(),
- dmiCmNotificationSubscriptionPredicate,
- dmiCmNotificationSubscriptionDetailsPerDmi);
- }
- }
- return dmiCmNotificationSubscriptionDetailsPerDmi;
- }
-
- /**
- * Update status in map of subscription details per DMI.
- *
- * @param subscriptionId String of subscription Id
- * @param dmiServiceName String of dmiServiceName
- * @param status String of status
- *
- */
- public void updateDmiCmNotificationSubscriptionStatusPerDmi(final String subscriptionId,
- final String dmiServiceName, final CmNotificationSubscriptionStatus status) {
- final Map<String, DmiCmNotificationSubscriptionDetails> dmiCmNotificationSubscriptionDetailsPerDmi =
- cmNotificationSubscriptionCache.get(subscriptionId);
- dmiCmNotificationSubscriptionDetailsPerDmi.get(dmiServiceName).setCmNotificationSubscriptionStatus(status);
- cmNotificationSubscriptionCache.put(subscriptionId, dmiCmNotificationSubscriptionDetailsPerDmi);
-
- }
-
- /**
- * Persist map of subscription details per DMI.
- *
- * @param subscriptionId String of subscription Id
- * @param dmiServiceName String of dmiServiceName
- *
- */
- public void persistIntoDatabasePerDmi(final String subscriptionId, final String dmiServiceName) {
- final List<DmiCmNotificationSubscriptionPredicate> dmiCmNotificationSubscriptionPredicateList =
- 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();
-
- for (final String cmHandle: cmHandles) {
- for (final String xpath: xpaths) {
- cmNotificationSubscriptionPersistenceService.addCmNotificationSubscription(datastoreType, cmHandle,
- xpath, subscriptionId);
- }
- }
- }
- }
-
- private void updateDmiCmNotificationSubscriptionDetailsPerDmi(
- final String dmiServiceName,
- final DmiCmNotificationSubscriptionPredicate dmiCmNotificationSubscriptionPredicate,
- final Map<String, DmiCmNotificationSubscriptionDetails> dmiCmNotificationSubscriptionDetailsPerDmi) {
- if (dmiCmNotificationSubscriptionDetailsPerDmi.containsKey(dmiServiceName)) {
- dmiCmNotificationSubscriptionDetailsPerDmi.get(dmiServiceName)
- .getDmiCmNotificationSubscriptionPredicates().add(dmiCmNotificationSubscriptionPredicate);
- } else {
- dmiCmNotificationSubscriptionDetailsPerDmi.put(dmiServiceName,
- new DmiCmNotificationSubscriptionDetails(
- new ArrayList<>(List.of(dmiCmNotificationSubscriptionPredicate)),
- PENDING));
- }
- }
-
- private Map<String, Set<String>> groupTargetCmHandleIdsByDmi(final List<String> targetCmHandleIds) {
- final Map<String, Set<String>> targetCmHandlesByDmiServiceNames = new HashMap<>();
- final Collection<YangModelCmHandle> yangModelCmHandles =
- inventoryPersistence.getYangModelCmHandles(targetCmHandleIds);
-
- for (final YangModelCmHandle yangModelCmHandle : yangModelCmHandles) {
- final String dmiServiceName = yangModelCmHandle.getDmiServiceName();
- targetCmHandlesByDmiServiceNames.putIfAbsent(dmiServiceName, new HashSet<>());
- targetCmHandlesByDmiServiceNames.get(dmiServiceName).add(yangModelCmHandle.getId());
- }
- return targetCmHandlesByDmiServiceNames;
- }
-
- private boolean isAcceptedOrRejected(
- final DmiCmNotificationSubscriptionDetails dmiCmNotificationSubscription) {
- return dmiCmNotificationSubscription.getCmNotificationSubscriptionStatus().toString().equals("ACCEPTED")
- || dmiCmNotificationSubscription.getCmNotificationSubscriptionStatus().toString().equals("REJECTED");
- }
-} \ No newline at end of file
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
index 3e072b0f91..0000000000
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/consumer/CmNotificationSubscriptionDmiOutEventConsumer.java
+++ /dev/null
@@ -1,103 +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.impl.events.mapper.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.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.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;
-
- /**
- * 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 ("subscriptionCreateResponse".equals(cloudEvent.getType()) && cmNotificationSubscriptionDmiOutEvent != null
- && correlationId != null) {
- handleCmSubscriptionCreate(correlationId, cmNotificationSubscriptionDmiOutEvent);
- }
- }
-
- private void handleCmSubscriptionCreate(final String correlationId,
- final CmNotificationSubscriptionDmiOutEvent cmNotificationSubscriptionDmiOutEvent) {
- final String subscriptionId = correlationId.split("#")[0];
- final String dmiPluginName = correlationId.split("#")[1];
-
- if ("ACCEPTED".equals(cmNotificationSubscriptionDmiOutEvent.getData().getStatusMessage())) {
- handleCacheStatusPerDmi(subscriptionId, dmiPluginName, CmNotificationSubscriptionStatus.ACCEPTED);
- dmiCmNotificationSubscriptionCacheHandler.persistIntoDatabasePerDmi(subscriptionId, dmiPluginName);
- handleEventsStatusPerDmi(subscriptionId);
- }
-
- if ("REJECTED".equals(cmNotificationSubscriptionDmiOutEvent.getData().getStatusMessage())) {
- handleCacheStatusPerDmi(subscriptionId, dmiPluginName, CmNotificationSubscriptionStatus.REJECTED);
- handleEventsStatusPerDmi(subscriptionId);
- }
-
- 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 Map<String, DmiCmNotificationSubscriptionDetails> dmiCmNotificationSubscriptionDetailsPerDmi =
- dmiCmNotificationSubscriptionCacheHandler.get(subscriptionId);
- final CmNotificationSubscriptionNcmpOutEvent cmNotificationSubscriptionNcmpOutEvent =
- cmNotificationSubscriptionMappersHandler.toCmNotificationSubscriptionNcmpOutEvent(subscriptionId,
- dmiCmNotificationSubscriptionDetailsPerDmi);
- cmNotificationSubscriptionEventsHandler.publishCmNotificationSubscriptionNcmpOutEvent(subscriptionId,
- "subscriptionCreateResponse", cmNotificationSubscriptionNcmpOutEvent, false);
- }
-}
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
index ea21751691..0000000000
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/mapper/CmNotificationSubscriptionNcmpOutEventMapper.java
+++ /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
index ed7ed2a0ba..0000000000
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/producer/CmNotificationSubscriptionNcmpOutEventProducer.java
+++ /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
index 7872ba0a34..0000000000
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionHandlerServiceImpl.java
+++ /dev/null
@@ -1,98 +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.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.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 CmNotificationSubscriptionNcmpInEvent cmNotificationSubscriptionNcmpInEvent) {
- final String subscriptionId = cmNotificationSubscriptionNcmpInEvent.getData().getSubscriptionId();
- final List<Predicate> predicates = cmNotificationSubscriptionNcmpInEvent.getData().getPredicates();
-
- if (cmNotificationSubscriptionPersistenceService.isUniqueSubscriptionId(subscriptionId)) {
- dmiCmNotificationSubscriptionCacheHandler.add(subscriptionId, predicates);
- sendSubscriptionCreateRequestToDmi(subscriptionId);
- scheduleCmNotificationSubscriptionNcmpOutEventResponse(subscriptionId);
- } else {
- rejectAndPublishCmNotificationSubscriptionCreateRequest(subscriptionId,
- predicates);
- }
- }
-
- private void scheduleCmNotificationSubscriptionNcmpOutEventResponse(final String subscriptionId) {
- cmNotificationSubscriptionEventsHandler.publishCmNotificationSubscriptionNcmpOutEvent(subscriptionId,
- "subscriptionCreateResponse", 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 sendSubscriptionCreateRequestToDmi(final String subscriptionId) {
- final Map<String, DmiCmNotificationSubscriptionDetails> dmiCmNotificationSubscriptionDetailsMap =
- dmiCmNotificationSubscriptionCacheHandler.get(subscriptionId);
- dmiCmNotificationSubscriptionDetailsMap.forEach((dmiPluginName, dmiCmNotificationSubscriptionDetails) -> {
- final List<DmiCmNotificationSubscriptionPredicate> dmiCmNotificationSubscriptionPredicates =
- cmNotificationSubscriptionDelta.getDelta(
- dmiCmNotificationSubscriptionDetails.getDmiCmNotificationSubscriptionPredicates());
- final CmNotificationSubscriptionDmiInEvent cmNotificationSubscriptionDmiInEvent =
- cmNotificationSubscriptionMappersHandler.toCmNotificationSubscriptionDmiInEvent(
- dmiCmNotificationSubscriptionPredicates);
- cmNotificationSubscriptionEventsHandler.publishCmNotificationSubscriptionDmiInEvent(subscriptionId,
- dmiPluginName, "subscriptionCreateRequest", 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
index 3bb40c3b7e..0000000000
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionPersistenceService.java
+++ /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.impl.operations.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/api/impl/events/cmsubscription/service/CmNotificationSubscriptionPersistenceServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionPersistenceServiceImpl.java
deleted file mode 100644
index 92f3459187..0000000000
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionPersistenceServiceImpl.java
+++ /dev/null
@@ -1,166 +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 static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS;
-
-import java.io.Serializable;
-import java.time.OffsetDateTime;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.onap.cps.api.CpsDataService;
-import org.onap.cps.api.CpsQueryService;
-import org.onap.cps.cpspath.parser.CpsPathUtil;
-import org.onap.cps.ncmp.api.impl.operations.DatastoreType;
-import org.onap.cps.spi.model.DataNode;
-import org.onap.cps.utils.ContentType;
-import org.onap.cps.utils.JsonObjectMapper;
-import org.springframework.stereotype.Service;
-
-@Slf4j
-@Service
-@RequiredArgsConstructor
-public class CmNotificationSubscriptionPersistenceServiceImpl implements CmNotificationSubscriptionPersistenceService {
-
- private static final String SUBSCRIPTION_ANCHOR_NAME = "cm-data-subscriptions";
- private static final String CM_SUBSCRIPTION_CPS_PATH_QUERY = """
- /datastores/datastore[@name='%s']/cm-handles/cm-handle[@id='%s']/filters/filter[@xpath='%s']
- """.trim();
- private static final String SUBSCRIPTION_IDS_CPS_PATH_QUERY = """
- //filter/subscriptionIds[text()='%s']
- """.trim();
-
- private final JsonObjectMapper jsonObjectMapper;
- 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();
- }
-
- @Override
- public boolean isUniqueSubscriptionId(final String subscriptionId) {
- return cpsQueryService.queryDataNodes(NCMP_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME,
- SUBSCRIPTION_IDS_CPS_PATH_QUERY.formatted(subscriptionId),
- OMIT_DESCENDANTS).isEmpty();
- }
-
- @Override
- public Collection<String> getOngoingCmNotificationSubscriptionIds(final DatastoreType datastoreType,
- final String cmHandleId, final String xpath) {
-
- final String isOngoingCmSubscriptionCpsPathQuery =
- CM_SUBSCRIPTION_CPS_PATH_QUERY.formatted(datastoreType.getDatastoreName(), cmHandleId,
- escapeQuotesByDoublingThem(xpath));
- final Collection<DataNode> existingNodes =
- cpsQueryService.queryDataNodes(NCMP_DATASPACE_NAME, CM_SUBSCRIPTIONS_ANCHOR_NAME,
- isOngoingCmSubscriptionCpsPathQuery, OMIT_DESCENDANTS);
- if (existingNodes.isEmpty()) {
- return Collections.emptyList();
- }
- 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) {
- if (isOngoingCmNotificationSubscription(datastoreType, cmHandleId, xpath)
- && (!getOngoingCmNotificationSubscriptionIds(datastoreType, cmHandleId, xpath)
- .contains(subscriptionId))) {
- final DataNode subscriptionAsDataNode = getSubscriptionAsDataNode(datastoreType, cmHandleId, xpath);
- final Collection<String> subscriptionIds = getOngoingCmNotificationSubscriptionIds(datastoreType,
- cmHandleId, xpath);
- subscriptionIds.add(subscriptionId);
- saveSubscriptionDetails(subscriptionAsDataNode, subscriptionIds);
- } else {
- addNewSubscriptionViaDatastore(datastoreType, cmHandleId, xpath, subscriptionId);
- }
- }
-
- @Override
- public void removeCmNotificationSubscription(final DatastoreType datastoreType, final String cmHandleId,
- final String xpath, final String subscriptionId) {
- final DataNode subscriptionAsDataNode = getSubscriptionAsDataNode(datastoreType, cmHandleId, xpath);
- final Collection<String> subscriptionIds = getOngoingCmNotificationSubscriptionIds(datastoreType,
- cmHandleId, xpath);
- subscriptionIds.remove(subscriptionId);
- saveSubscriptionDetails(subscriptionAsDataNode, subscriptionIds);
- if (isOngoingCmNotificationSubscription(datastoreType, cmHandleId, xpath)) {
- log.info("There are subscribers left for the following cps path {} :",
- CM_SUBSCRIPTION_CPS_PATH_QUERY.formatted(datastoreType.getDatastoreName(), cmHandleId,
- escapeQuotesByDoublingThem(xpath)));
- } else {
- log.info("No subscribers left for the following cps path {} :",
- CM_SUBSCRIPTION_CPS_PATH_QUERY.formatted(datastoreType.getDatastoreName(), cmHandleId,
- escapeQuotesByDoublingThem(xpath)));
- deleteListOfSubscriptionsFor(datastoreType, cmHandleId, xpath);
- }
- }
-
- private void deleteListOfSubscriptionsFor(final DatastoreType datastoreType, final String cmHandleId,
- final String xpath) {
- cpsDataService.deleteDataNode(NCMP_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME,
- CM_SUBSCRIPTION_CPS_PATH_QUERY.formatted(datastoreType.getDatastoreName(), cmHandleId,
- escapeQuotesByDoublingThem(xpath)),
- OffsetDateTime.now());
- }
-
- private DataNode getSubscriptionAsDataNode(final DatastoreType datastoreType, final String cmHandleId,
- final String xpath) {
- return cpsQueryService.queryDataNodes(NCMP_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME,
- CM_SUBSCRIPTION_CPS_PATH_QUERY.formatted(datastoreType.getDatastoreName(), cmHandleId,
- escapeQuotesByDoublingThem(xpath)),
- OMIT_DESCENDANTS).iterator().next();
- }
-
- private void addNewSubscriptionViaDatastore(final DatastoreType datastoreType, final String cmHandleId,
- final String xpath, final String newSubscriptionId) {
- final String parentXpath = "/datastores/datastore[@name='%s']/cm-handles"
- .formatted(datastoreType.getDatastoreName());
- final String subscriptionAsJson = String.format("{\"cm-handle\":[{\"id\":\"%s\",\"filters\":{\"filter\":"
- + "[{\"xpath\":\"%s\",\"subscriptionIds\":[\"%s\"]}]}}]}", cmHandleId, xpath, newSubscriptionId);
- cpsDataService.saveData(NCMP_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME, parentXpath, subscriptionAsJson,
- OffsetDateTime.now(), ContentType.JSON);
- }
-
- private void saveSubscriptionDetails(final DataNode subscriptionDetailsAsDataNode,
- final Collection<String> subscriptionIds) {
- final Map<String, Serializable> subscriptionDetailsAsMap = new HashMap<>();
- subscriptionDetailsAsMap.put("xpath", subscriptionDetailsAsDataNode.getLeaves().get("xpath"));
- subscriptionDetailsAsMap.put("subscriptionIds", (Serializable) subscriptionIds);
- final String parentXpath = CpsPathUtil.getNormalizedParentXpath(subscriptionDetailsAsDataNode.getXpath());
- final String subscriptionDetailsAsJson = "{\"filter\":["
- + jsonObjectMapper.asJsonString(subscriptionDetailsAsMap).replace("'", "\"") + "]}";
- cpsDataService.updateNodeLeaves(NCMP_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME, parentXpath,
- subscriptionDetailsAsJson, OffsetDateTime.now());
- }
-
- private static String escapeQuotesByDoublingThem(final String inputXpath) {
- return inputXpath.replace("'", "''");
- }
-}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java
deleted file mode 100644
index c9e193dab1..0000000000
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2021-2024 Nordix Foundation
- * Modifications Copyright (C) 2022 Bell Canada
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * SPDX-License-Identifier: Apache-2.0
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.cps.ncmp.api.impl.operations;
-
-import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_RUNNING;
-import static org.onap.cps.ncmp.api.impl.operations.OperationType.READ;
-
-import io.micrometer.core.annotation.Timed;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-import lombok.extern.slf4j.Slf4j;
-import org.onap.cps.ncmp.api.NcmpResponseStatus;
-import org.onap.cps.ncmp.api.impl.client.DmiRestClient;
-import org.onap.cps.ncmp.api.impl.config.DmiWebClientConfiguration.DmiProperties;
-import org.onap.cps.ncmp.api.impl.exception.DmiClientRequestException;
-import org.onap.cps.ncmp.api.impl.inventory.CmHandleState;
-import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence;
-import org.onap.cps.ncmp.api.impl.utils.DmiServiceUrlBuilder;
-import org.onap.cps.ncmp.api.impl.utils.data.operation.ResourceDataOperationRequestUtils;
-import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
-import org.onap.cps.ncmp.api.models.CmResourceAddress;
-import org.onap.cps.ncmp.api.models.DataOperationRequest;
-import org.onap.cps.spi.exceptions.CpsException;
-import org.onap.cps.utils.JsonObjectMapper;
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Component;
-import org.springframework.util.LinkedMultiValueMap;
-import org.springframework.util.MultiValueMap;
-import org.springframework.web.util.UriComponentsBuilder;
-
-/**
- * Operations class for DMI data.
- */
-@Component
-@Slf4j
-public class DmiDataOperations extends DmiOperations {
-
- public DmiDataOperations(final InventoryPersistence inventoryPersistence,
- final JsonObjectMapper jsonObjectMapper,
- final DmiProperties dmiProperties,
- final DmiRestClient dmiRestClient,
- final DmiServiceUrlBuilder dmiServiceUrlBuilder) {
- super(inventoryPersistence, jsonObjectMapper, dmiProperties, dmiRestClient, dmiServiceUrlBuilder);
- }
-
- /**
- * This method fetches the resource data from operational data store for given cm handle
- * identifier on given resource using dmi client.
- *
- * @param cmResourceAddress target datastore, cm handle and resource identifier
- * @param optionsParamInQuery options query
- * @param topicParamInQuery topic name for (triggering) async responses
- * @param requestId requestId for async responses
- * @param authorization contents of Authorization header, or null if not present
- * @return {@code ResponseEntity} response entity
- */
- @Timed(value = "cps.ncmp.dmi.get",
- description = "Time taken to fetch the resource data from operational data store for given cm handle "
- + "identifier on given resource using dmi client")
- public ResponseEntity<Object> getResourceDataFromDmi(final CmResourceAddress cmResourceAddress,
- final String optionsParamInQuery,
- final String topicParamInQuery,
- final String requestId,
- final String authorization) {
- final YangModelCmHandle yangModelCmHandle = getYangModelCmHandle(cmResourceAddress.cmHandleId());
- final CmHandleState cmHandleState = yangModelCmHandle.getCompositeState().getCmHandleState();
- validateIfCmHandleStateReady(yangModelCmHandle, cmHandleState);
- final String jsonRequestBody = getDmiRequestBody(READ, requestId, null, null, yangModelCmHandle);
-
- final MultiValueMap<String, String> uriQueryParamsMap = getUriQueryParamsMap(
- cmResourceAddress.resourceIdentifier(), optionsParamInQuery,
- topicParamInQuery, yangModelCmHandle.getModuleSetTag());
- final Map<String, Object> uriVariableParamsMap = getUriVariableParamsMap(cmResourceAddress.datastoreName(),
- yangModelCmHandle.resolveDmiServiceName(RequiredDmiService.DATA), cmResourceAddress.cmHandleId());
- final String dmiResourceDataUrl = getDmiRequestUrl(uriQueryParamsMap, uriVariableParamsMap);
-
- return dmiRestClient.postOperationWithJsonData(dmiResourceDataUrl, jsonRequestBody, READ, authorization);
- }
-
- /**
- * This method fetches all the resource data from operational data store for given cm handle
- * identifier using dmi client.
- *
- * @param dataStoreName data store name
- * @param cmHandleId network resource identifier
- * @param requestId requestId for async responses
- * @return {@code ResponseEntity} response entity
- */
- public ResponseEntity<Object> getResourceDataFromDmi(final String dataStoreName,
- final String cmHandleId,
- final String requestId) {
- final YangModelCmHandle yangModelCmHandle = getYangModelCmHandle(cmHandleId);
- final String jsonRequestBody = getDmiRequestBody(READ, requestId, null, null,
- yangModelCmHandle);
-
- final MultiValueMap<String, String> uriQueryParamsMap = getUriQueryParamsMap("/", null,
- null, yangModelCmHandle.getModuleSetTag());
- final Map<String, Object> uriVariableParamsMap = getUriVariableParamsMap(dataStoreName,
- yangModelCmHandle.resolveDmiServiceName(RequiredDmiService.DATA), cmHandleId);
- final String dmiResourceDataUrl = getDmiRequestUrl(uriQueryParamsMap, uriVariableParamsMap);
-
- final CmHandleState cmHandleState = yangModelCmHandle.getCompositeState().getCmHandleState();
- validateIfCmHandleStateReady(yangModelCmHandle, cmHandleState);
- return dmiRestClient.postOperationWithJsonData(dmiResourceDataUrl, jsonRequestBody, READ, null);
- }
-
- /**
- * This method requests the resource data by data store for given list of cm handles using dmi client.
- * The data wil be returned as message on the topic specified.
- *
- * @param topicParamInQuery topic name for (triggering) async responses
- * @param dataOperationRequest data operation request to execute operations
- * @param requestId requestId for as a response
- * @param authorization contents of Authorization header, or null if not present
- */
- public void requestResourceDataFromDmi(final String topicParamInQuery,
- final DataOperationRequest dataOperationRequest,
- final String requestId,
- final String authorization) {
-
- final Set<String> cmHandlesIds
- = getDistinctCmHandleIdsFromDataOperationRequest(dataOperationRequest);
-
- final Collection<YangModelCmHandle> yangModelCmHandles
- = inventoryPersistence.getYangModelCmHandles(cmHandlesIds);
-
- final Map<String, List<DmiDataOperation>> operationsOutPerDmiServiceName
- = ResourceDataOperationRequestUtils.processPerDefinitionInDataOperationsRequest(topicParamInQuery,
- requestId, dataOperationRequest, yangModelCmHandles);
-
- buildDataOperationRequestUrlAndSendToDmiService(topicParamInQuery, requestId, operationsOutPerDmiServiceName,
- authorization);
- }
-
- /**
- * This method creates the resource data from pass-through running data store for given cm handle
- * identifier on given resource using dmi client.
- *
- * @param cmHandleId network resource identifier
- * @param resourceId resource identifier
- * @param operationType operation enum
- * @param requestData the request data
- * @param dataType data type
- * @param authorization contents of Authorization header, or null if not present
- * @return {@code ResponseEntity} response entity
- */
- public ResponseEntity<Object> writeResourceDataPassThroughRunningFromDmi(final String cmHandleId,
- final String resourceId,
- final OperationType operationType,
- final String requestData,
- final String dataType,
- final String authorization) {
- final YangModelCmHandle yangModelCmHandle = getYangModelCmHandle(cmHandleId);
- final String jsonRequestBody = getDmiRequestBody(operationType, null, requestData, dataType,
- yangModelCmHandle);
-
- final MultiValueMap<String, String> uriQueryParamsMap = getUriQueryParamsMap(resourceId, null,
- null, yangModelCmHandle.getModuleSetTag());
- final Map<String, Object> uriVariableParamsMap = getUriVariableParamsMap(PASSTHROUGH_RUNNING.getDatastoreName(),
- yangModelCmHandle.resolveDmiServiceName(RequiredDmiService.DATA), cmHandleId);
- final String dmiUrl = getDmiRequestUrl(uriQueryParamsMap, uriVariableParamsMap);
-
- final CmHandleState cmHandleState = yangModelCmHandle.getCompositeState().getCmHandleState();
- validateIfCmHandleStateReady(yangModelCmHandle, cmHandleState);
- return dmiRestClient.postOperationWithJsonData(dmiUrl, jsonRequestBody, operationType, authorization);
- }
-
- private YangModelCmHandle getYangModelCmHandle(final String cmHandleId) {
- return inventoryPersistence.getYangModelCmHandle(cmHandleId);
- }
-
- private String getDmiRequestBody(final OperationType operationType,
- final String requestId,
- final String requestData,
- final String dataType,
- final YangModelCmHandle yangModelCmHandle) {
- final DmiRequestBody dmiRequestBody = DmiRequestBody.builder()
- .operationType(operationType)
- .requestId(requestId)
- .data(requestData)
- .dataType(dataType)
- .build();
- dmiRequestBody.asDmiProperties(yangModelCmHandle.getDmiProperties());
- return jsonObjectMapper.asJsonString(dmiRequestBody);
- }
-
- private String getDmiRequestUrl(final MultiValueMap<String, String> uriQueryParamsMap,
- final Map<String, Object> uriVariableParamsMap) {
- return dmiServiceUrlBuilder.getDmiDatastoreUrl(uriQueryParamsMap, uriVariableParamsMap);
- }
-
- private MultiValueMap<String, String> getUriQueryParamsMap(final String resourceId,
- final String optionsParamInQuery,
- final String topicParamInQuery,
- final String moduleSetTagParamInQuery) {
- return dmiServiceUrlBuilder.populateQueryParams(resourceId, optionsParamInQuery,
- topicParamInQuery, moduleSetTagParamInQuery);
- }
-
- private Map<String, Object> getUriVariableParamsMap(final String dataStoreName,
- final String dmiServiceName,
- final String cmHandleId) {
- return dmiServiceUrlBuilder.populateUriVariables(dataStoreName, dmiServiceName, cmHandleId);
- }
-
- private String getDmiServiceDataOperationRequestUrl(final String dmiServiceName,
- final String topicParamInQuery,
- final String requestId) {
- final MultiValueMap<String, String> dataOperationRequestQueryParams = dmiServiceUrlBuilder
- .getDataOperationRequestQueryParams(topicParamInQuery, requestId);
- return dmiServiceUrlBuilder.getDataOperationRequestUrl(dataOperationRequestQueryParams,
- dmiServiceUrlBuilder.populateDataOperationRequestUriVariables(dmiServiceName));
- }
-
- private void validateIfCmHandleStateReady(final YangModelCmHandle yangModelCmHandle,
- final CmHandleState cmHandleState) {
- if (cmHandleState != CmHandleState.READY) {
- throw new CpsException("State mismatch exception.", "Cm-Handle not in READY state. "
- + "cm handle state is "
- + yangModelCmHandle.getCompositeState().getCmHandleState());
- }
- }
-
- private static Set<String> getDistinctCmHandleIdsFromDataOperationRequest(final DataOperationRequest
- dataOperationRequest) {
- return dataOperationRequest.getDataOperationDefinitions().stream()
- .flatMap(dataOperationDefinition ->
- dataOperationDefinition.getCmHandleIds().stream()).collect(Collectors.toSet());
- }
-
- private void buildDataOperationRequestUrlAndSendToDmiService(final String topicParamInQuery,
- final String requestId,
- final Map<String, List<DmiDataOperation>>
- groupsOutPerDmiServiceName,
- final String authorization) {
-
- groupsOutPerDmiServiceName.forEach((dmiServiceName, dmiDataOperationRequestBodies) -> {
- final String dmiDataOperationResourceUrl =
- getDmiServiceDataOperationRequestUrl(dmiServiceName, topicParamInQuery, requestId);
- sendDataOperationRequestToDmiService(dmiDataOperationResourceUrl, dmiDataOperationRequestBodies,
- authorization);
- });
- }
-
- private void sendDataOperationRequestToDmiService(final String dataOperationResourceUrl,
- final List<DmiDataOperation> dmiDataOperationRequestBodies,
- final String authorization) {
- final DmiDataOperationRequest dmiDataOperationRequest = DmiDataOperationRequest.builder()
- .operations(dmiDataOperationRequestBodies).build();
- final String dmiDataOperationRequestAsJsonString =
- jsonObjectMapper.asJsonString(dmiDataOperationRequest);
- try {
- dmiRestClient.postOperationWithJsonData(dataOperationResourceUrl, dmiDataOperationRequestAsJsonString, READ,
- authorization);
- } catch (final DmiClientRequestException e) {
- handleTaskCompletionException(e, dataOperationResourceUrl, dmiDataOperationRequestBodies);
- }
- }
-
- private void handleTaskCompletionException(final DmiClientRequestException dmiClientRequestException,
- final String dataOperationResourceUrl,
- final List<DmiDataOperation> dmiDataOperationRequestBodies) {
- final MultiValueMap<String, String> dataOperationResourceUrlParameters =
- UriComponentsBuilder.fromUriString(dataOperationResourceUrl).build().getQueryParams();
- final String topicName = dataOperationResourceUrlParameters.get("topic").get(0);
- final String requestId = dataOperationResourceUrlParameters.get("requestId").get(0);
-
- final MultiValueMap<DmiDataOperation, Map<NcmpResponseStatus, List<String>>>
- cmHandleIdsPerResponseCodesPerOperation = new LinkedMultiValueMap<>();
-
- dmiDataOperationRequestBodies.forEach(dmiDataOperationRequestBody -> {
- final List<String> cmHandleIds = dmiDataOperationRequestBody.getCmHandles().stream()
- .map(DmiOperationCmHandle::getId).toList();
- cmHandleIdsPerResponseCodesPerOperation.add(dmiDataOperationRequestBody,
- Map.of(dmiClientRequestException.getNcmpResponseStatus(), cmHandleIds));
- });
- ResourceDataOperationRequestUtils.publishErrorMessageToClientTopic(topicName, requestId,
- cmHandleIdsPerResponseCodesPerOperation);
- }
-}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java
deleted file mode 100644
index f4166d41bb..0000000000
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2021-2024 Nordix Foundation
- * Modifications Copyright (C) 2022 Bell Canada
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * SPDX-License-Identifier: Apache-2.0
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.cps.ncmp.api.impl.operations;
-
-import lombok.RequiredArgsConstructor;
-import org.onap.cps.ncmp.api.impl.client.DmiRestClient;
-import org.onap.cps.ncmp.api.impl.config.DmiWebClientConfiguration.DmiProperties;
-import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence;
-import org.onap.cps.ncmp.api.impl.utils.DmiServiceUrlBuilder;
-import org.onap.cps.utils.JsonObjectMapper;
-import org.springframework.stereotype.Service;
-
-@RequiredArgsConstructor
-@Service
-public class DmiOperations {
-
- protected final InventoryPersistence inventoryPersistence;
- protected final JsonObjectMapper jsonObjectMapper;
- protected final DmiProperties dmiProperties;
- protected final DmiRestClient dmiRestClient;
- protected final DmiServiceUrlBuilder dmiServiceUrlBuilder;
-
- String getDmiResourceUrl(final String dmiServiceName, final String cmHandle, final String resourceName) {
- return dmiServiceUrlBuilder.getResourceDataBasePathUriBuilder()
- .pathSegment("{resourceName}")
- .buildAndExpand(dmiServiceName, dmiProperties.getDmiBasePath(), cmHandle, resourceName).toUriString();
- }
-}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/AlternateIdChecker.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/AlternateIdChecker.java
deleted file mode 100644
index 60f39fcea0..0000000000
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/AlternateIdChecker.java
+++ /dev/null
@@ -1,152 +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.utils;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
-import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence;
-import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
-import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
-import org.onap.cps.spi.exceptions.DataNodeNotFoundException;
-import org.springframework.stereotype.Service;
-
-@Service
-@Slf4j
-@RequiredArgsConstructor
-public class AlternateIdChecker {
-
- public enum Operation {
- CREATE, UPDATE
- }
-
- private final InventoryPersistence inventoryPersistence;
-
- private static final String NO_CURRENT_ALTERNATE_ID = "";
-
- /**
- * Check if the alternate can be applied to the given cm handle (id).
- * Conditions:
- * - proposed alternate is blank (it wil be ignored)
- * - proposed alternate is same as current (no change)
- * - proposed alternate is not in use for a different cm handle (in the DB)
- *
- * @param cmHandleId cm handle id
- * @param proposedAlternateId proposed alternate id
- * @return true if the new alternate id not in use or equal to current alternate id, false otherwise
- */
- public boolean canApplyAlternateId(final String cmHandleId, final String proposedAlternateId) {
- String currentAlternateId = "";
- try {
- final YangModelCmHandle yangModelCmHandle = inventoryPersistence.getYangModelCmHandle(cmHandleId);
- currentAlternateId = yangModelCmHandle.getAlternateId();
- } catch (final DataNodeNotFoundException dataNodeNotFoundException) {
- // work with blank current alternate id
- }
- return this.canApplyAlternateId(cmHandleId, currentAlternateId, proposedAlternateId);
- }
-
- /**
- * Check if the alternate can be applied to the given cm handle.
- * Conditions:
- * - proposed alternate is blank (it wil be ignored)
- * - proposed alternate is same as current (no change)
- * - proposed alternate is not in use for a different cm handle (in the DB)
- *
- * @param cmHandleId cm handle id
- * @param currentAlternateId current alternate id
- * @param proposedAlternateId new alternate id
- * @return true if the new alternate id not in use or equal to current alternate id, false otherwise
- */
- public boolean canApplyAlternateId(final String cmHandleId,
- final String currentAlternateId,
- final String proposedAlternateId) {
- if (StringUtils.isBlank(currentAlternateId)) {
- if (alternateIdAlreadyInDb(proposedAlternateId)) {
- log.warn("Alternate id update ignored, cannot update cm handle {}, alternate id is already "
- + "assigned to a different cm handle", cmHandleId);
- return false;
- }
- return true;
- }
- if (currentAlternateId.equals(proposedAlternateId)) {
- return true;
- }
- log.warn("Alternate id update ignored, cannot update cm handle {}, already has an alternate id of {}",
- cmHandleId, currentAlternateId);
- return false;
- }
-
- /**
- * Check all alternate ids of a batch of cm handles.
- * Includes cross-checks in the batch itself for duplicates. Only the first entry encountered wil be accepted.
- *
- * @param newNcmpServiceCmHandles the proposed new cm handles
- * @param operation type of operation being executed
- * @return collection of cm handles ids which are acceptable
- */
- public Collection<String> getIdsOfCmHandlesWithRejectedAlternateId(
- final Collection<NcmpServiceCmHandle> newNcmpServiceCmHandles,
- final Operation operation) {
- final Set<String> acceptedAlternateIds = new HashSet<>(newNcmpServiceCmHandles.size());
- final Collection<String> rejectedCmHandleIds = new ArrayList<>();
- for (final NcmpServiceCmHandle ncmpServiceCmHandle : newNcmpServiceCmHandles) {
- final String cmHandleId = ncmpServiceCmHandle.getCmHandleId();
- final String proposedAlternateId = ncmpServiceCmHandle.getAlternateId();
- if (isProposedAlternateIdAcceptable(proposedAlternateId, operation, acceptedAlternateIds, cmHandleId)) {
- acceptedAlternateIds.add(proposedAlternateId);
- } else {
- rejectedCmHandleIds.add(cmHandleId);
- }
- }
- return rejectedCmHandleIds;
- }
-
- private boolean isProposedAlternateIdAcceptable(final String proposedAlternateId, final Operation operation,
- final Set<String> acceptedAlternateIds, final String cmHandleId) {
- if (StringUtils.isEmpty(proposedAlternateId)) {
- return true;
- }
- if (acceptedAlternateIds.contains(proposedAlternateId)) {
- log.warn("Alternate id update ignored, cannot update cm handle {}, alternate id is already "
- + "assigned to a different cm handle (in this batch)", cmHandleId);
- return false;
- }
- if (Operation.CREATE.equals(operation)) {
- return canApplyAlternateId(cmHandleId, NO_CURRENT_ALTERNATE_ID, proposedAlternateId);
- }
- return canApplyAlternateId(cmHandleId, proposedAlternateId);
- }
-
- private boolean alternateIdAlreadyInDb(final String alternateId) {
- try {
- inventoryPersistence.getCmHandleDataNodeByAlternateId(alternateId);
- } catch (final DataNodeNotFoundException dataNodeNotFoundException) {
- return false;
- }
- return true;
- }
-
-}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DataNodeHelper.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DataNodeHelper.java
deleted file mode 100644
index c032d1e8a4..0000000000
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DataNodeHelper.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2023 Nordix Foundation
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * SPDX-License-Identifier: Apache-2.0
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.cps.ncmp.api.impl.utils;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import org.onap.cps.spi.model.DataNode;
-
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class DataNodeHelper {
-
- /**
- * The nested DataNode object is being flattened.
- *
- * @param dataNode object.
- * @return DataNode as stream.
- */
- public static Stream<DataNode> flatten(final DataNode dataNode) {
- return Stream.concat(Stream.of(dataNode),
- dataNode.getChildDataNodes().stream().flatMap(DataNodeHelper::flatten));
- }
-
- /**
- * The leaves for each DataNode is listed as map.
- *
- * @param dataNodes as collection
- * @return list of map for the all leaves
- */
- public static List<Map<String, Serializable>> getDataNodeLeaves(final Collection<DataNode> dataNodes) {
- return dataNodes.stream()
- .flatMap(DataNodeHelper::flatten)
- .map(DataNode::getLeaves)
- .collect(Collectors.toList());
- }
-
- /**
- * Extracts the mapping of cm handle id to status with details from nodes leaves.
- *
- * @param dataNodeLeaves as a list of map
- * @return cm handle id to status and details mapping
- */
- public static Map<String, Map<String, String>> cmHandleIdToStatusAndDetailsAsMap(
- final List<Map<String, Serializable>> dataNodeLeaves) {
- return dataNodeLeaves.stream()
- .filter(entryset -> entryset.values().contains("PENDING")
- || entryset.values().contains("ACCEPTED")
- || entryset.values().contains("REJECTED"))
- .collect(
- HashMap<String, Map<String, String>>::new,
- (result, entry) -> {
- final String cmHandleId = (String) entry.get("cmHandleId");
- final String status = (String) entry.get("status");
- final String details = (String) entry.get("details");
-
- if (cmHandleId != null && status != null) {
- result.put(cmHandleId, new HashMap<>());
- result.get(cmHandleId).put("status", status);
- result.get(cmHandleId).put("details", details == null ? "" : details);
- }
- },
- HashMap::putAll
- );
- }
-
- /**
- * Extracts the mapping of cm handle id to status with details from data node collection.
- *
- * @param dataNodes as a collection
- * @return cm handle id to status and details mapping
- */
- public static Map<String, Map<String, String>> cmHandleIdToStatusAndDetailsAsMapFromDataNode(
- final Collection<DataNode> dataNodes) {
- return cmHandleIdToStatusAndDetailsAsMap(getDataNodeLeaves(dataNodes));
- }
-}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilder.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilder.java
deleted file mode 100644
index ac6d093721..0000000000
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilder.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2022-2023 Nordix Foundation
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * SPDX-License-Identifier: Apache-2.0
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.cps.ncmp.api.impl.utils;
-
-import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
-import java.util.Map;
-import lombok.RequiredArgsConstructor;
-import org.apache.logging.log4j.util.Strings;
-import org.apache.logging.log4j.util.TriConsumer;
-import org.onap.cps.ncmp.api.impl.config.DmiWebClientConfiguration.DmiProperties;
-import org.onap.cps.spi.utils.CpsValidator;
-import org.springframework.stereotype.Component;
-import org.springframework.util.LinkedMultiValueMap;
-import org.springframework.util.MultiValueMap;
-import org.springframework.web.util.UriComponentsBuilder;
-
-@Component
-@RequiredArgsConstructor
-public class DmiServiceUrlBuilder {
- private final DmiProperties dmiProperties;
- private final CpsValidator cpsValidator;
-
- /**
- * This method creates the dmi service url.
- *
- * @param queryParams query param map as key,value pair
- * @param uriVariables uri param map as key (placeholder),value pair
- * @return {@code String} dmi service url as string
- */
- public String getDmiDatastoreUrl(final MultiValueMap<String, String> queryParams,
- final Map<String, Object> uriVariables) {
- return getUriComponentsBuilder(getResourceDataBasePathUriBuilder(), queryParams, uriVariables)
- .buildAndExpand().toUriString();
- }
-
- /**
- * This method builds data operation request url.
- *
- * @param dataoperationRequestQueryParams query param map as key, value pair
- * @param dataoperationRequestUriVariables uri param map as key (placeholder), value pair
- * @return {@code String} data operation request url as string
- */
- public String getDataOperationRequestUrl(final MultiValueMap<String, String> dataoperationRequestQueryParams,
- final Map<String, Object> dataoperationRequestUriVariables) {
- return getDataOperationResourceDataBasePathUriBuilder()
- .queryParams(dataoperationRequestQueryParams)
- .uriVariables(dataoperationRequestUriVariables)
- .buildAndExpand().toUriString();
- }
-
- /**
- * This method creates the dmi service url builder object with path variables.
- *
- * @return {@code UriComponentsBuilder} dmi service url builder object
- */
- public UriComponentsBuilder getResourceDataBasePathUriBuilder() {
- return UriComponentsBuilder.newInstance()
- .path("{dmiServiceName}")
- .pathSegment("{dmiBasePath}")
- .pathSegment("v1")
- .pathSegment("ch")
- .pathSegment("{cmHandleId}");
- }
-
- /**
- * This method creates the dmi service url builder object with path variables for data operation request.
- *
- * @return {@code UriComponentsBuilder} dmi service url builder object
- */
- public UriComponentsBuilder getDataOperationResourceDataBasePathUriBuilder() {
- return UriComponentsBuilder.newInstance()
- .path("{dmiServiceName}")
- .pathSegment("{dmiBasePath}")
- .pathSegment("v1")
- .pathSegment("data");
- }
-
- /**
- * This method populates uri variables.
- *
- * @param dataStoreName data store name
- * @param dmiServiceName dmi service name
- * @param cmHandleId cm handle id for dmi registration
- * @return {@code String} dmi service url as string
- */
- public Map<String, Object> populateUriVariables(final String dataStoreName,
- final String dmiServiceName,
- final String cmHandleId) {
- cpsValidator.validateNameCharacters(cmHandleId);
- final Map<String, Object> uriVariables = new HashMap<>();
- final String dmiBasePath = dmiProperties.getDmiBasePath();
- uriVariables.put("dmiServiceName", dmiServiceName);
- uriVariables.put("dmiBasePath", dmiBasePath);
- uriVariables.put("cmHandleId", cmHandleId);
- uriVariables.put("dataStore", dataStoreName);
- return uriVariables;
- }
-
- /**
- * This method populates uri variables for data operation request.
- *
- * @param dmiServiceName dmi service name
- * @return {@code Map<String, Object>} uri variables as map
- */
- public Map<String, Object> populateDataOperationRequestUriVariables(final String dmiServiceName) {
- final Map<String, Object> uriVariables = new HashMap<>();
- final String dmiBasePath = dmiProperties.getDmiBasePath();
- uriVariables.put("dmiServiceName", dmiServiceName);
- uriVariables.put("dmiBasePath", dmiBasePath);
- return uriVariables;
- }
-
- /**
- * This method is used to populate map from query params.
- *
- * @param resourceId unique id of response for valid topic
- * @param optionsParamInQuery options as provided by client
- * @param topicParamInQuery topic as provided by client
- * @param moduleSetTag module set tag associated with the given cm handle
- * @return all valid query params as map
- */
- public MultiValueMap<String, String> populateQueryParams(final String resourceId,
- final String optionsParamInQuery,
- final String topicParamInQuery,
- final String moduleSetTag) {
- final MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
- getQueryParamConsumer().accept("resourceIdentifier", resourceId, queryParams);
- getQueryParamConsumer().accept("options", optionsParamInQuery, queryParams);
- if (Strings.isNotEmpty(topicParamInQuery)) {
- getQueryParamConsumer().accept("topic", topicParamInQuery, queryParams);
- }
- if (Strings.isNotEmpty(moduleSetTag)) {
- getQueryParamConsumer().accept("moduleSetTag", moduleSetTag, queryParams);
- }
- return queryParams;
- }
-
- /**
- * This method is used to populate map from query params for data operation request.
- *
- * @param topicParamInQuery topic into url param
- * @param requestId unique id of response for valid topic
- * @return all valid query params as map
- */
- public MultiValueMap<String, String> getDataOperationRequestQueryParams(final String topicParamInQuery,
- final String requestId) {
- final MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
- getQueryParamConsumer().accept("topic", topicParamInQuery, queryParams);
- getQueryParamConsumer().accept("requestId", requestId, queryParams);
- return queryParams;
- }
-
- private TriConsumer<String, String, MultiValueMap<String, String>> getQueryParamConsumer() {
- return (paramName, paramValue, paramMap) -> {
- if (Strings.isNotEmpty(paramValue)) {
- paramMap.add(paramName, URLEncoder.encode(paramValue, StandardCharsets.UTF_8));
- }
- };
- }
-
- private UriComponentsBuilder getUriComponentsBuilder(final UriComponentsBuilder uriComponentsBuilder,
- final MultiValueMap<String, String> queryParams,
- final Map<String, Object> uriVariables) {
- return uriComponentsBuilder
- .pathSegment("data")
- .pathSegment("ds")
- .pathSegment("{dataStore}")
- .queryParams(queryParams)
- .uriVariables(uriVariables);
- }
-}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmDataSubscriptionEvent.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmDataSubscriptionEvent.java
deleted file mode 100644
index e527d99f2f..0000000000
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmDataSubscriptionEvent.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * ============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.yangmodels;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonInclude.Include;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import java.util.List;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.Setter;
-
-/**
- * Subscription event model to persist data into DB.
- * Yang model subscription event
- */
-@Getter
-@Setter
-@NoArgsConstructor
-@JsonInclude(Include.NON_NULL)
-@EqualsAndHashCode(onlyExplicitlyIncluded = true)
-public class YangModelCmDataSubscriptionEvent {
-
- @EqualsAndHashCode.Include
- @JsonProperty("name")
- private String name;
-
- private List<CmHandle> cmHandles;
-
- @AllArgsConstructor
- @Data
- @JsonInclude(JsonInclude.Include.NON_NULL)
- public static class CmHandle {
-
- @JsonProperty()
- private final String id;
-
- private final List<Filter> filters;
- }
-
- @AllArgsConstructor
- @Data
- @JsonInclude(JsonInclude.Include.NON_NULL)
- public static class Filter {
-
- @JsonProperty()
- private final String id;
-
- @JsonProperty()
- private final List<String> subscribers;
- }
-}
-
-
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/NetworkCmProxyInventoryFacade.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/NetworkCmProxyInventoryFacade.java
new file mode 100644
index 0000000000..cde4eacbf2
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/NetworkCmProxyInventoryFacade.java
@@ -0,0 +1,228 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 highstreet technologies GmbH
+ * Modifications Copyright (C) 2021-2024 Nordix Foundation
+ * Modifications Copyright (C) 2021 Pantheon.tech
+ * Modifications Copyright (C) 2021-2022 Bell Canada
+ * Modifications Copyright (C) 2023 TechMahindra Ltd.
+ * ================================================================================
+ * 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.inventory;
+
+import static org.onap.cps.ncmp.impl.inventory.CmHandleQueryParametersValidator.validateCmHandleQueryParameters;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.inventory.models.CmHandleQueryApiParameters;
+import org.onap.cps.ncmp.api.inventory.models.CmHandleQueryServiceParameters;
+import org.onap.cps.ncmp.api.inventory.models.CompositeState;
+import org.onap.cps.ncmp.api.inventory.models.DmiPluginRegistration;
+import org.onap.cps.ncmp.api.inventory.models.DmiPluginRegistrationResponse;
+import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle;
+import org.onap.cps.ncmp.impl.inventory.CmHandleQueryService;
+import org.onap.cps.ncmp.impl.inventory.CmHandleRegistrationService;
+import org.onap.cps.ncmp.impl.inventory.InventoryPersistence;
+import org.onap.cps.ncmp.impl.inventory.ParameterizedCmHandleQueryService;
+import org.onap.cps.ncmp.impl.inventory.models.CmHandleQueryConditions;
+import org.onap.cps.ncmp.impl.inventory.models.InventoryQueryConditions;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
+import org.onap.cps.ncmp.impl.inventory.trustlevel.TrustLevelManager;
+import org.onap.cps.ncmp.impl.models.RequiredDmiService;
+import org.onap.cps.ncmp.impl.utils.AlternateIdMatcher;
+import org.onap.cps.ncmp.impl.utils.YangDataConverter;
+import org.onap.cps.spi.model.ModuleDefinition;
+import org.onap.cps.spi.model.ModuleReference;
+import org.onap.cps.utils.JsonObjectMapper;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class NetworkCmProxyInventoryFacade {
+
+ private final CmHandleRegistrationService cmHandleRegistrationService;
+ private final CmHandleQueryService cmHandleQueryService;
+ private final ParameterizedCmHandleQueryService parameterizedCmHandleQueryService;
+ private final InventoryPersistence inventoryPersistence;
+ private final JsonObjectMapper jsonObjectMapper;
+ private final TrustLevelManager trustLevelManager;
+ private final AlternateIdMatcher alternateIdMatcher;
+
+ /**
+ * Registration of Created, Removed, Updated or Upgraded CM Handles.
+ *
+ * @param dmiPluginRegistration Dmi Plugin Registration details
+ * @return dmiPluginRegistrationResponse
+ */
+ public DmiPluginRegistrationResponse updateDmiRegistrationAndSyncModule(
+ final DmiPluginRegistration dmiPluginRegistration) {
+ return cmHandleRegistrationService.updateDmiRegistrationAndSyncModule(dmiPluginRegistration);
+ }
+
+ /**
+ * Get all cm handle IDs by DMI plugin identifier.
+ *
+ * @param dmiPluginIdentifier DMI plugin identifier
+ * @return collection of cm handle IDs
+ */
+ public Collection<String> getAllCmHandleIdsByDmiPluginIdentifier(final String dmiPluginIdentifier) {
+ return cmHandleQueryService.getCmHandleIdsByDmiPluginIdentifier(dmiPluginIdentifier);
+ }
+
+ /**
+ * Get all cm handle IDs by various properties.
+ *
+ * @param cmHandleQueryServiceParameters cm handle query parameters
+ * @return collection of cm handle IDs
+ */
+ public Collection<String> executeParameterizedCmHandleIdSearch(
+ final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
+ validateCmHandleQueryParameters(cmHandleQueryServiceParameters, InventoryQueryConditions.ALL_CONDITION_NAMES);
+ return parameterizedCmHandleQueryService.queryCmHandleIdsForInventory(cmHandleQueryServiceParameters);
+ }
+
+
+ /**
+ * Retrieve module references for the given cm handle reference.
+ *
+ * @param cmHandleReference cm handle or alternate id identifier
+ * @return a collection of modules names and revisions
+ */
+ public Collection<ModuleReference> getYangResourcesModuleReferences(final String cmHandleReference) {
+ final String cmHandleId = alternateIdMatcher.getCmHandleId(cmHandleReference);
+ return inventoryPersistence.getYangResourcesModuleReferences(cmHandleId);
+ }
+
+ /**
+ * Retrieve module definitions for the given cm handle.
+ *
+ * @param cmHandleReference cm handle or alternate id identifier
+ * @return a collection of module definition (moduleName, revision and yang resource content)
+ */
+ public Collection<ModuleDefinition> getModuleDefinitionsByCmHandleReference(final String cmHandleReference) {
+ final String cmHandleId = alternateIdMatcher.getCmHandleId(cmHandleReference);
+ return inventoryPersistence.getModuleDefinitionsByCmHandleId(cmHandleId);
+ }
+
+ /**
+ * Get module definitions for the given parameters.
+ *
+ * @param cmHandleReference cm handle or alternate id identifier
+ * @param moduleName module name
+ * @param moduleRevision the revision of the module
+ * @return list of module definitions (module name, revision, yang resource content)
+ */
+ public Collection<ModuleDefinition> getModuleDefinitionsByCmHandleAndModule(final String cmHandleReference,
+ final String moduleName,
+ final String moduleRevision) {
+ final String cmHandleId = alternateIdMatcher.getCmHandleId(cmHandleReference);
+ return inventoryPersistence.getModuleDefinitionsByCmHandleAndModule(cmHandleId, moduleName, moduleRevision);
+ }
+
+ /**
+ * Retrieve cm handles with details for the given query parameters.
+ *
+ * @param cmHandleQueryApiParameters cm handle query parameters
+ * @return cm handles with details
+ */
+ public Collection<NcmpServiceCmHandle> executeCmHandleSearch(
+ final CmHandleQueryApiParameters cmHandleQueryApiParameters) {
+ final CmHandleQueryServiceParameters cmHandleQueryServiceParameters = jsonObjectMapper.convertToValueType(
+ cmHandleQueryApiParameters, CmHandleQueryServiceParameters.class);
+ validateCmHandleQueryParameters(cmHandleQueryServiceParameters, CmHandleQueryConditions.ALL_CONDITION_NAMES);
+ final Collection<YangModelCmHandle> yangModelCmHandles =
+ parameterizedCmHandleQueryService.queryCmHandles(cmHandleQueryServiceParameters);
+ final Collection<NcmpServiceCmHandle> ncmpServiceCmHandles = new ArrayList<>(yangModelCmHandles.size());
+ for (final YangModelCmHandle yangModelCmHandle : yangModelCmHandles) {
+ final NcmpServiceCmHandle ncmpServiceCmHandle = toNcmpServiceCmHandleWithTrustLevel(yangModelCmHandle);
+ ncmpServiceCmHandles.add(ncmpServiceCmHandle);
+ }
+ return ncmpServiceCmHandles;
+ }
+
+ /**
+ * Retrieve cm handle ids for the given query parameters.
+ *
+ * @param cmHandleQueryApiParameters cm handle query parameters
+ * @return cm handle ids
+ */
+ public Collection<String> executeCmHandleIdSearch(final CmHandleQueryApiParameters cmHandleQueryApiParameters) {
+ final CmHandleQueryServiceParameters cmHandleQueryServiceParameters = jsonObjectMapper.convertToValueType(
+ cmHandleQueryApiParameters, CmHandleQueryServiceParameters.class);
+ validateCmHandleQueryParameters(cmHandleQueryServiceParameters, CmHandleQueryConditions.ALL_CONDITION_NAMES);
+ return parameterizedCmHandleQueryService.queryCmHandleIds(cmHandleQueryServiceParameters);
+ }
+
+ /**
+ * Set the data sync enabled flag, along with the data sync state
+ * based on the data sync enabled boolean for the cm handle id provided.
+ *
+ * @param cmHandleId cm handle id
+ * @param dataSyncEnabledTargetValue data sync enabled flag
+ */
+ public void setDataSyncEnabled(final String cmHandleId, final Boolean dataSyncEnabledTargetValue) {
+ cmHandleRegistrationService.setDataSyncEnabled(cmHandleId, dataSyncEnabledTargetValue);
+ }
+
+ /**
+ * Retrieve cm handle details for a given cm handle reference.
+ *
+ * @param cmHandleReference cm handle or alternate identifier
+ * @return cm handle details
+ */
+ public NcmpServiceCmHandle getNcmpServiceCmHandle(final String cmHandleReference) {
+ final String cmHandleId = alternateIdMatcher.getCmHandleId(cmHandleReference);
+ final YangModelCmHandle yangModelCmHandle = inventoryPersistence.getYangModelCmHandle(cmHandleId);
+ return toNcmpServiceCmHandleWithTrustLevel(yangModelCmHandle);
+ }
+
+ /**
+ * Get cm handle public properties for a given cm handle or alternate id.
+ *
+ * @param cmHandleReference cm handle or alternate identifier
+ * @return cm handle public properties
+ */
+ public Map<String, String> getCmHandlePublicProperties(final String cmHandleReference) {
+ final String cmHandleId = alternateIdMatcher.getCmHandleId(cmHandleReference);
+ final YangModelCmHandle yangModelCmHandle = inventoryPersistence.getYangModelCmHandle(cmHandleId);
+ return YangDataConverter.toPropertiesMap(yangModelCmHandle.getPublicProperties());
+ }
+
+ /**
+ * Get cm handle composite state for a given cm handle id.
+ *
+ * @param cmHandleReference cm handle or alternate identifier
+ * @return cm handle state
+ */
+ public CompositeState getCmHandleCompositeState(final String cmHandleReference) {
+ final String cmHandleId = alternateIdMatcher.getCmHandleId(cmHandleReference);
+ return inventoryPersistence.getYangModelCmHandle(cmHandleId).getCompositeState();
+ }
+
+ private NcmpServiceCmHandle toNcmpServiceCmHandleWithTrustLevel(final YangModelCmHandle yangModelCmHandle) {
+ final NcmpServiceCmHandle ncmpServiceCmHandle = YangDataConverter.toNcmpServiceCmHandle(yangModelCmHandle);
+ final String dmiServiceName = yangModelCmHandle.resolveDmiServiceName(RequiredDmiService.DATA);
+ ncmpServiceCmHandle.setCurrentTrustLevel(
+ trustLevelManager.getEffectiveTrustLevel(dmiServiceName, ncmpServiceCmHandle.getCmHandleId()));
+ return ncmpServiceCmHandle;
+ }
+
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmHandleQueryApiParameters.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/CmHandleQueryApiParameters.java
index dd8dcd60ac..596fb94a36 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmHandleQueryApiParameters.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/CmHandleQueryApiParameters.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.models;
+package org.onap.cps.ncmp.api.inventory.models;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmHandleQueryServiceParameters.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/CmHandleQueryServiceParameters.java
index 5eeafaca33..13915918e5 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmHandleQueryServiceParameters.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/CmHandleQueryServiceParameters.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.models;
+package org.onap.cps.ncmp.api.inventory.models;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmHandleRegistrationResponse.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/CmHandleRegistrationResponse.java
index 52b8d6926a..7523f77af2 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmHandleRegistrationResponse.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/CmHandleRegistrationResponse.java
@@ -19,7 +19,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.models;
+package org.onap.cps.ncmp.api.inventory.models;
import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNKNOWN_ERROR;
@@ -31,7 +31,7 @@ import lombok.Builder;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.ncmp.api.NcmpResponseStatus;
-import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
+import org.onap.cps.ncmp.impl.utils.YangDataConverter;
@Data
@Builder
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CompositeState.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/CompositeState.java
index 5b88f560eb..ca4fde2b62 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CompositeState.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/CompositeState.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.inventory;
+package org.onap.cps.ncmp.api.inventory.models;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
@@ -29,6 +29,9 @@ import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
+import org.onap.cps.ncmp.impl.inventory.DataStoreSyncState;
+import org.onap.cps.ncmp.impl.inventory.models.CmHandleState;
+import org.onap.cps.ncmp.impl.inventory.models.LockReasonCategory;
/**
* State Model to store state corresponding to the Yang resource dmi-registry model.
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CompositeStateBuilder.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/CompositeStateBuilder.java
index 2fbe2b2f78..59d7aa2b44 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CompositeStateBuilder.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/CompositeStateBuilder.java
@@ -19,11 +19,14 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.inventory;
+package org.onap.cps.ncmp.api.inventory.models;
-import org.onap.cps.ncmp.api.impl.inventory.CompositeState.DataStores;
-import org.onap.cps.ncmp.api.impl.inventory.CompositeState.LockReason;
-import org.onap.cps.ncmp.api.impl.inventory.CompositeState.Operational;
+import org.onap.cps.ncmp.api.inventory.models.CompositeState.DataStores;
+import org.onap.cps.ncmp.api.inventory.models.CompositeState.LockReason;
+import org.onap.cps.ncmp.api.inventory.models.CompositeState.Operational;
+import org.onap.cps.ncmp.impl.inventory.DataStoreSyncState;
+import org.onap.cps.ncmp.impl.inventory.models.CmHandleState;
+import org.onap.cps.ncmp.impl.inventory.models.LockReasonCategory;
import org.onap.cps.spi.model.DataNode;
public class CompositeStateBuilder {
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/ConditionApiProperties.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/ConditionApiProperties.java
index 5cb2ed376c..61d9f4a250 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/ConditionApiProperties.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/ConditionApiProperties.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.models;
+package org.onap.cps.ncmp.api.inventory.models;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DmiPluginRegistration.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/DmiPluginRegistration.java
index 7d6a8e1407..44e2ebe320 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DmiPluginRegistration.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/DmiPluginRegistration.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.models;
+package org.onap.cps.ncmp.api.inventory.models;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
@@ -27,8 +27,8 @@ import java.util.Collections;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
-import org.onap.cps.ncmp.api.impl.exception.DmiRequestException;
-import org.onap.cps.ncmp.api.impl.exception.NcmpException;
+import org.onap.cps.ncmp.api.exceptions.DmiRequestException;
+import org.onap.cps.ncmp.api.exceptions.NcmpException;
/**
* Dmi Registry request object.
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DmiPluginRegistrationResponse.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/DmiPluginRegistrationResponse.java
index ee034176e3..736ca620d0 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DmiPluginRegistrationResponse.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/DmiPluginRegistrationResponse.java
@@ -19,7 +19,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.models;
+package org.onap.cps.ncmp.api.inventory.models;
import java.util.Collections;
import java.util.List;
@@ -33,4 +33,4 @@ public class DmiPluginRegistrationResponse {
private List<CmHandleRegistrationResponse> updatedCmHandles = Collections.emptyList();
private List<CmHandleRegistrationResponse> removedCmHandles = Collections.emptyList();
private List<CmHandleRegistrationResponse> upgradedCmHandles = Collections.emptyList();
-} \ No newline at end of file
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/NcmpServiceCmHandle.java
index 676eebc4d6..3ebceed9d7 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/NcmpServiceCmHandle.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.models;
+package org.onap.cps.ncmp.api.inventory.models;
import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.annotation.Nulls;
@@ -27,8 +27,6 @@ import java.util.Map;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
-import org.onap.cps.ncmp.api.impl.inventory.CompositeState;
-import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevel;
import org.springframework.validation.annotation.Validated;
/**
@@ -59,6 +57,9 @@ public class NcmpServiceCmHandle {
private TrustLevel registrationTrustLevel;
@JsonSetter(nulls = Nulls.AS_EMPTY)
+ private TrustLevel currentTrustLevel;
+
+ @JsonSetter(nulls = Nulls.AS_EMPTY)
private String alternateId;
@JsonSetter(nulls = Nulls.AS_EMPTY)
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/TrustLevel.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/TrustLevel.java
index f130604a64..83e6ecf912 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/TrustLevel.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/TrustLevel.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.trustlevel;
+package org.onap.cps.ncmp.api.inventory.models;
import lombok.Getter;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/UpgradedCmHandles.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/UpgradedCmHandles.java
index 61cd99ac8f..9f48ae968c 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/UpgradedCmHandles.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/UpgradedCmHandles.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.models;
+package org.onap.cps.ncmp.api.inventory.models;
import com.fasterxml.jackson.annotation.JsonInclude;
import java.util.Collections;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/YangResource.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/YangResource.java
index 7975777aa5..1c0ca5d8cd 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/YangResource.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/models/YangResource.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.models;
+package org.onap.cps.ncmp.api.inventory.models;
import lombok.Data;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/context/CpsApplicationContext.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/CpsApplicationContext.java
index b14cf0d0db..fbc31adcf3 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/context/CpsApplicationContext.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/CpsApplicationContext.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.utils.context;
+package org.onap.cps.ncmp.config;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
@@ -48,4 +48,4 @@ public class CpsApplicationContext implements ApplicationContextAware {
private static synchronized void setCpsApplicationContext(final ApplicationContext cpsApplicationContext) {
CpsApplicationContext.applicationContext = cpsApplicationContext;
}
-} \ No newline at end of file
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/DmiHttpClientConfig.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/DmiHttpClientConfig.java
new file mode 100644
index 0000000000..8eebb89a0a
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/DmiHttpClientConfig.java
@@ -0,0 +1,57 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2023-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.config;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Getter
+@Setter
+@Configuration
+@ConfigurationProperties(prefix = "ncmp.dmi.httpclient")
+public class DmiHttpClientConfig {
+
+ private final DataServices dataServices = new DataServices();
+ private final ModelServices modelServices = new ModelServices();
+ private final HealthCheckServices healthCheckServices = new HealthCheckServices();
+
+ @Getter
+ @Setter
+ public static class DataServices extends ServiceConfig {
+ private String connectionProviderName = "dataConnectionPool";
+ }
+
+ @Getter
+ @Setter
+ public static class ModelServices extends ServiceConfig {
+ private String connectionProviderName = "modelConnectionPool";
+ }
+
+ @Getter
+ @Setter
+ public static class HealthCheckServices extends ServiceConfig {
+ private String connectionProviderName = "healthConnectionPool";
+ private int maximumConnectionsTotal = 10;
+ private int pendingAcquireMaxCount = 5;
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/kafka/KafkaConfig.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/KafkaConfig.java
index 167df5a98d..3d3c3db482 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/kafka/KafkaConfig.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/KafkaConfig.java
@@ -18,13 +18,17 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.config.kafka;
+package org.onap.cps.ncmp.config;
import io.cloudevents.CloudEvent;
+import io.opentelemetry.instrumentation.kafkaclients.v2_6.TracingConsumerInterceptor;
+import io.opentelemetry.instrumentation.kafkaclients.v2_6.TracingProducerInterceptor;
import java.time.Duration;
import java.util.Map;
import lombok.RequiredArgsConstructor;
+import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.producer.ProducerConfig;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.kafka.KafkaProperties;
import org.springframework.boot.ssl.SslBundles;
import org.springframework.context.annotation.Bean;
@@ -52,6 +56,9 @@ public class KafkaConfig<T> {
private final KafkaProperties kafkaProperties;
+ @Value("${cps.tracing.enabled:false}")
+ private boolean tracingEnabled;
+
private static final SslBundles NO_SSL = null;
/**
@@ -64,6 +71,10 @@ public class KafkaConfig<T> {
public ProducerFactory<String, T> legacyEventProducerFactory() {
final Map<String, Object> producerConfigProperties = kafkaProperties.buildProducerProperties(NO_SSL);
producerConfigProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
+ if (tracingEnabled) {
+ producerConfigProperties.put(
+ ProducerConfig.INTERCEPTOR_CLASSES_CONFIG, TracingProducerInterceptor.class.getName());
+ }
return new DefaultKafkaProducerFactory<>(producerConfigProperties);
}
@@ -77,6 +88,10 @@ public class KafkaConfig<T> {
public ConsumerFactory<String, T> legacyEventConsumerFactory() {
final Map<String, Object> consumerConfigProperties = kafkaProperties.buildConsumerProperties(NO_SSL);
consumerConfigProperties.put("spring.deserializer.value.delegate.class", JsonDeserializer.class);
+ if (tracingEnabled) {
+ consumerConfigProperties.put(
+ ConsumerConfig.INTERCEPTOR_CLASSES_CONFIG, TracingConsumerInterceptor.class.getName());
+ }
return new DefaultKafkaConsumerFactory<>(consumerConfigProperties);
}
@@ -90,6 +105,9 @@ public class KafkaConfig<T> {
public KafkaTemplate<String, T> legacyEventKafkaTemplate() {
final KafkaTemplate<String, T> kafkaTemplate = new KafkaTemplate<>(legacyEventProducerFactory());
kafkaTemplate.setConsumerFactory(legacyEventConsumerFactory());
+ if (tracingEnabled) {
+ kafkaTemplate.setObservationEnabled(true);
+ }
return kafkaTemplate;
}
@@ -104,6 +122,9 @@ public class KafkaConfig<T> {
new ConcurrentKafkaListenerContainerFactory<>();
containerFactory.setConsumerFactory(legacyEventConsumerFactory());
containerFactory.getContainerProperties().setAuthExceptionRetryInterval(Duration.ofSeconds(10));
+ if (tracingEnabled) {
+ containerFactory.getContainerProperties().setObservationEnabled(true);
+ }
return containerFactory;
}
@@ -116,6 +137,10 @@ public class KafkaConfig<T> {
@Bean
public ProducerFactory<String, CloudEvent> cloudEventProducerFactory() {
final Map<String, Object> producerConfigProperties = kafkaProperties.buildProducerProperties(NO_SSL);
+ if (tracingEnabled) {
+ producerConfigProperties.put(
+ ProducerConfig.INTERCEPTOR_CLASSES_CONFIG, TracingProducerInterceptor.class.getName());
+ }
return new DefaultKafkaProducerFactory<>(producerConfigProperties);
}
@@ -128,6 +153,10 @@ public class KafkaConfig<T> {
@Bean
public ConsumerFactory<String, CloudEvent> cloudEventConsumerFactory() {
final Map<String, Object> consumerConfigProperties = kafkaProperties.buildConsumerProperties(NO_SSL);
+ if (tracingEnabled) {
+ consumerConfigProperties.put(
+ ConsumerConfig.INTERCEPTOR_CLASSES_CONFIG, TracingConsumerInterceptor.class.getName());
+ }
return new DefaultKafkaConsumerFactory<>(consumerConfigProperties);
}
@@ -142,6 +171,9 @@ public class KafkaConfig<T> {
final KafkaTemplate<String, CloudEvent> kafkaTemplate =
new KafkaTemplate<>(cloudEventProducerFactory());
kafkaTemplate.setConsumerFactory(cloudEventConsumerFactory());
+ if (tracingEnabled) {
+ kafkaTemplate.setObservationEnabled(true);
+ }
return kafkaTemplate;
}
@@ -157,6 +189,9 @@ public class KafkaConfig<T> {
new ConcurrentKafkaListenerContainerFactory<>();
containerFactory.setConsumerFactory(cloudEventConsumerFactory());
containerFactory.getContainerProperties().setAuthExceptionRetryInterval(Duration.ofSeconds(10));
+ if (tracingEnabled) {
+ containerFactory.getContainerProperties().setObservationEnabled(true);
+ }
return containerFactory;
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/OpenTelemetryConfig.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/OpenTelemetryConfig.java
new file mode 100644
index 0000000000..a6a82b7936
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/OpenTelemetryConfig.java
@@ -0,0 +1,141 @@
+/*
+ * ============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.config;
+
+import io.micrometer.observation.ObservationPredicate;
+import io.micrometer.observation.ObservationRegistry;
+import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
+import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
+import io.opentelemetry.sdk.extension.trace.jaeger.sampler.JaegerRemoteSampler;
+import io.opentelemetry.sdk.trace.samplers.Sampler;
+import jakarta.annotation.PostConstruct;
+import java.time.Duration;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.actuate.autoconfigure.observation.ObservationRegistryCustomizer;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.server.observation.ServerRequestObservationContext;
+import org.springframework.util.AntPathMatcher;
+import org.springframework.util.PathMatcher;
+
+/**
+ * Configuration class for setting up OpenTelemetry tracing in a Spring Boot application.
+ * This class provides beans for OTLP exporters (gRPC and HTTP), a Jaeger remote sampler,
+ * and customizes the ObservationRegistry to exclude certain endpoints from being observed.
+ */
+@Configuration
+public class OpenTelemetryConfig {
+
+ @Value("${spring.application.name:cps-application}")
+ private String serviceId;
+
+ @Value("${cps.tracing.exporter.endpoint:http://onap-otel-collector:4317}")
+ private String tracingExporterEndpointUrl;
+
+ @Value("${cps.tracing.sampler.jaeger_remote.endpoint:http://onap-otel-collector:14250}")
+ private String jaegerRemoteSamplerUrl;
+
+ @Value("${cps.tracing.excluded-observation-names:tasks.scheduled.execution}")
+ private String excludedObservationNamesAsCsv;
+
+ private static final int JAEGER_REMOTE_SAMPLER_POLLING_INTERVAL_IN_SECONDS = 30;
+
+ private List<String> excludedObservationNames;
+
+ /**
+ * Initializes the excludedObservationNames after the bean's properties have been set.
+ * This method is called by the Spring container during bean initialization.
+ */
+ @PostConstruct
+ public void init() {
+ excludedObservationNames = Arrays.stream(excludedObservationNamesAsCsv.split(","))
+ .map(String::trim)
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * Creates an OTLP Exporter with gRPC protocol.
+ *
+ * @return OtlpGrpcSpanExporter bean if tracing is enabled and the exporter protocol is gRPC
+ */
+ @Bean
+ @ConditionalOnExpression(
+ "${cps.tracing.enabled} && 'grpc'.equals('${cps.tracing.exporter.protocol}')")
+ public OtlpGrpcSpanExporter createOtlpExporterGrpc() {
+ return OtlpGrpcSpanExporter.builder().setEndpoint(tracingExporterEndpointUrl).build();
+ }
+
+ /**
+ * Creates an OTLP Exporter with HTTP protocol.
+ *
+ * @return OtlpHttpSpanExporter bean if tracing is enabled and the exporter protocol is HTTP
+ */
+ @Bean
+ @ConditionalOnExpression(
+ "${cps.tracing.enabled} && 'http'.equals('${cps.tracing.exporter.protocol}')")
+ public OtlpHttpSpanExporter createOtlpExporterHttp() {
+ return OtlpHttpSpanExporter.builder().setEndpoint(tracingExporterEndpointUrl).build();
+ }
+
+ /**
+ * Creates a Jaeger Remote Sampler.
+ *
+ * @return JaegerRemoteSampler bean if tracing is enabled
+ */
+ @Bean
+ @ConditionalOnProperty("cps.tracing.enabled")
+ public JaegerRemoteSampler createJaegerRemoteSampler() {
+ return JaegerRemoteSampler.builder()
+ .setEndpoint(jaegerRemoteSamplerUrl)
+ .setPollingInterval(Duration.ofSeconds(JAEGER_REMOTE_SAMPLER_POLLING_INTERVAL_IN_SECONDS))
+ .setInitialSampler(Sampler.alwaysOff())
+ .setServiceName(serviceId)
+ .build();
+ }
+
+ /**
+ * Customizes the ObservationRegistry to exclude /actuator/** endpoints from being observed.
+ *
+ * @return ObservationRegistryCustomizer bean if tracing is enabled
+ */
+ @Bean
+ @ConditionalOnProperty("cps.tracing.enabled")
+ public ObservationRegistryCustomizer<ObservationRegistry> skipActuatorEndpointsFromObservation() {
+ final PathMatcher pathMatcher = new AntPathMatcher("/");
+ return registry ->
+ registry.observationConfig().observationPredicate(observationPredicate(pathMatcher));
+ }
+
+ private ObservationPredicate observationPredicate(final PathMatcher pathMatcher) {
+ return (observationName, context) -> {
+ if (context instanceof ServerRequestObservationContext observationContext) {
+ return !pathMatcher.match("/actuator/**", observationContext.getCarrier().getRequestURI());
+ } else {
+ return !excludedObservationNames.contains(observationName);
+ }
+ };
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/HttpClientConfiguration.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/PolicyExecutorHttpClientConfig.java
index d547e31c68..0903c671b5 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/HttpClientConfiguration.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/PolicyExecutorHttpClientConfig.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2023 Nordix Foundation.
+ * 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.
@@ -18,40 +18,24 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.config;
+package org.onap.cps.ncmp.config;
-import java.time.Duration;
-import java.time.temporal.ChronoUnit;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.boot.convert.DurationUnit;
+import org.springframework.context.annotation.Configuration;
@Getter
@Setter
-@ConfigurationProperties(prefix = "ncmp.dmi.httpclient", ignoreUnknownFields = true)
-public class HttpClientConfiguration {
+@Configuration
+@ConfigurationProperties(prefix = "ncmp.policy-executor.httpclient")
+public class PolicyExecutorHttpClientConfig {
- /**
- * The maximum time to establish a connection.
- */
- @DurationUnit(ChronoUnit.SECONDS)
- private Duration connectionTimeoutInSeconds = Duration.ofSeconds(180);
-
- /**
- * The maximum number of open connections per route.
- */
- private int maximumConnectionsPerRoute = 50;
-
- /**
- * The maximum total number of open connections.
- */
- private int maximumConnectionsTotal = maximumConnectionsPerRoute * 2;
-
- /**
- * The duration after which idle connections are evicted.
- */
- @DurationUnit(ChronoUnit.SECONDS)
- private Duration idleConnectionEvictionThresholdInSeconds = Duration.ofSeconds(5);
+ private final AllServices allServices = new AllServices();
+ @Getter
+ @Setter
+ public static class AllServices extends ServiceConfig {
+ private String connectionProviderName = "policyExecutorConfig";
+ }
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/ServiceConfig.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/ServiceConfig.java
new file mode 100644
index 0000000000..f1fce0c7c6
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/ServiceConfig.java
@@ -0,0 +1,36 @@
+/*
+ * ============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.config;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public abstract class ServiceConfig {
+ private String connectionProviderName = "";
+ private int maximumInMemorySizeInMegabytes = 1;
+ private int maximumConnectionsTotal = 1;
+ private int pendingAcquireMaxCount = 1;
+ private Integer connectionTimeoutInSeconds = 1;
+ private long readTimeoutInSeconds = 1;
+ private long writeTimeoutInSeconds = 1;
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/NcmpStartUpException.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/exceptions/NcmpStartUpException.java
index 7ac26f54fd..7ffbe2e5cb 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/NcmpStartUpException.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/exceptions/NcmpStartUpException.java
@@ -18,7 +18,9 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.exception;
+package org.onap.cps.ncmp.exceptions;
+
+import org.onap.cps.ncmp.api.exceptions.NcmpException;
/**
* NCMP start up exception.
@@ -34,4 +36,4 @@ public class NcmpStartUpException extends NcmpException {
public NcmpStartUpException(final String message, final String details) {
super(message, details);
}
-} \ No newline at end of file
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/NoAlternateIdParentFoundException.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/exceptions/NoAlternateIdMatchFoundException.java
index 2e6cd3308c..7c5fc3be2b 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/NoAlternateIdParentFoundException.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/exceptions/NoAlternateIdMatchFoundException.java
@@ -18,22 +18,23 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.exception;
+package org.onap.cps.ncmp.exceptions;
import java.io.Serial;
+import org.onap.cps.ncmp.api.exceptions.NcmpException;
-public class NoAlternateIdParentFoundException extends NcmpException {
+public class NoAlternateIdMatchFoundException extends NcmpException {
@Serial
private static final long serialVersionUID = -2412915490233422945L;
- private static final String ALTERNATE_ID_NOT_FOUND = "No matching (parent) cm handle found using alternate ids";
+ private static final String ALTERNATE_ID_NOT_FOUND = "No matching cm handle found using alternate ids";
/**
* Constructor.
*
* @param cpsPath datanode cpsPath
*/
- public NoAlternateIdParentFoundException(final String cpsPath) {
+ public NoAlternateIdMatchFoundException(final String cpsPath) {
super(ALTERNATE_ID_NOT_FOUND, String.format("cannot find a datanode with alternate id %s", cpsPath));
}
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/CmNotificationSubscriptionCacheConfig.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/cache/CmSubscriptionConfig.java
index 1d6da90a9a..a4f9be357f 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/CmNotificationSubscriptionCacheConfig.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/cache/CmSubscriptionConfig.java
@@ -18,18 +18,18 @@
* ============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");
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/cache/DmiCacheHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/cache/DmiCacheHandler.java
new file mode 100644
index 0000000000..b5ab7f6525
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/cache/DmiCacheHandler.java
@@ -0,0 +1,227 @@
+/*
+ * ============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.cache;
+
+import static org.onap.cps.ncmp.impl.cmnotificationsubscription.models.CmSubscriptionStatus.PENDING;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+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.data.models.DatastoreType;
+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 DmiCacheHandler {
+
+ private final CmSubscriptionPersistenceService cmSubscriptionPersistenceService;
+ private final Map<String, Map<String, DmiCmSubscriptionDetails>> cmNotificationSubscriptionCache;
+ private final InventoryPersistence inventoryPersistence;
+
+ /**
+ * Adds subscription to the subscription cache.
+ *
+ * @param subscriptionId subscription id
+ * @param predicates subscription request predicates
+ */
+ public void add(final String subscriptionId, final List<Predicate> predicates) {
+ cmNotificationSubscriptionCache.put(subscriptionId, createDmiSubscriptionsPerDmi(predicates));
+ }
+
+ /**
+ * Adds subscription to the subscription cache.
+ *
+ * @param subscriptionId subscription id
+ * @param dmiCmSubscriptionDetailsPerDmi map of dmi cm notification subscription details per dmi
+ */
+ public void add(final String subscriptionId,
+ final Map<String, DmiCmSubscriptionDetails>
+ dmiCmSubscriptionDetailsPerDmi) {
+ cmNotificationSubscriptionCache.put(subscriptionId, dmiCmSubscriptionDetailsPerDmi);
+ }
+
+ /**
+ * Get cm notification subscription cache entry via subscription id.
+ *
+ * @param subscriptionId subscription id
+ * @return map of dmi cm notification subscriptions per dmi
+ */
+ public Map<String, DmiCmSubscriptionDetails> get(final String subscriptionId) {
+ return cmNotificationSubscriptionCache.get(subscriptionId);
+ }
+
+
+ /**
+ * Remove cache entries with CmNotificationSubscriptionStatus ACCEPTED/REJECTED via subscription id.
+ *
+ * @param subscriptionId subscription id as key in CM notification Subscription cache.
+ */
+ public void removeAcceptedAndRejectedDmiSubscriptionEntries(final String subscriptionId) {
+ final Map<String, DmiCmSubscriptionDetails> dmiSubscriptionsPerDmi =
+ cmNotificationSubscriptionCache.get(subscriptionId);
+ 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, updatedDmiSubscriptionsPerDmi);
+ }
+
+ /**
+ * Creates map of subscription details per DMI.
+ *
+ * @param predicates CM Subscription Create Request Predicates
+ * @return Map of DmiCmNotificationSubscription per DMI plugin
+ */
+ public Map<String, DmiCmSubscriptionDetails> createDmiSubscriptionsPerDmi(
+ final List<Predicate> predicates) {
+ final Map<String, DmiCmSubscriptionDetails> dmiSubscriptionsPerDmi =
+ new HashMap<>();
+ for (final Predicate requestPredicate : predicates) {
+ final List<String> targetFilter = requestPredicate.getTargetFilter();
+ final DatastoreType datastoreType = DatastoreType.fromDatastoreName(
+ requestPredicate.getScopeFilter().getDatastore().toString());
+ 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 DmiCmSubscriptionPredicate dmiCmSubscriptionPredicate =
+ new DmiCmSubscriptionPredicate(targetCmHandlesByDmi.getValue(),
+ datastoreType, xpaths);
+ updateDmiSubscriptionDetailsPerDmi(targetCmHandlesByDmi.getKey(),
+ dmiCmSubscriptionPredicate,
+ dmiSubscriptionsPerDmi);
+ }
+ }
+ return dmiSubscriptionsPerDmi;
+ }
+
+ /**
+ * Update status in map of subscription details per DMI.
+ *
+ * @param subscriptionId String of subscription Id
+ * @param dmiServiceName String of dmiServiceName
+ * @param status String of status
+ *
+ */
+ public void updateDmiSubscriptionStatus(final String subscriptionId, final String dmiServiceName,
+ final CmSubscriptionStatus status) {
+ final Map<String, DmiCmSubscriptionDetails> dmiSubscriptionsPerDmi =
+ cmNotificationSubscriptionCache.get(subscriptionId);
+ dmiSubscriptionsPerDmi.get(dmiServiceName).setCmSubscriptionStatus(status);
+ cmNotificationSubscriptionCache.put(subscriptionId, dmiSubscriptionsPerDmi);
+ }
+
+ /**
+ * Persist map of subscription details per DMI.
+ *
+ * @param subscriptionId String of subscription Id
+ * @param dmiServiceName String of dmiServiceName
+ *
+ */
+ public void persistIntoDatabasePerDmi(final String subscriptionId, final String dmiServiceName) {
+ final List<DmiCmSubscriptionPredicate> dmiCmSubscriptionPredicates =
+ cmNotificationSubscriptionCache.get(subscriptionId).get(dmiServiceName)
+ .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) {
+ cmSubscriptionPersistenceService.addCmSubscription(datastoreType, cmHandle,
+ xpath, subscriptionId);
+ }
+ }
+ }
+ }
+
+ /**
+ * Remove subscription from database per DMI service name.
+ *
+ * @param subscriptionId String of subscription id
+ * @param dmiServiceName String of dmiServiceName
+ *
+ */
+ public void removeFromDatabase(final String subscriptionId, final String dmiServiceName) {
+ final List<DmiCmSubscriptionPredicate> dmiCmSubscriptionPredicates =
+ cmNotificationSubscriptionCache.get(subscriptionId).get(dmiServiceName)
+ .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) {
+ cmSubscriptionPersistenceService.removeCmSubscription(datastoreType,
+ cmHandle, xpath, subscriptionId);
+ }
+ }
+ }
+ }
+
+ private void updateDmiSubscriptionDetailsPerDmi(
+ final String dmiServiceName,
+ final DmiCmSubscriptionPredicate dmiCmSubscriptionPredicate,
+ final Map<String, DmiCmSubscriptionDetails> dmiSubscriptionsPerDmi) {
+ if (dmiSubscriptionsPerDmi.containsKey(dmiServiceName)) {
+ dmiSubscriptionsPerDmi.get(dmiServiceName)
+ .getDmiCmSubscriptionPredicates().add(dmiCmSubscriptionPredicate);
+ } else {
+ dmiSubscriptionsPerDmi.put(dmiServiceName,
+ new DmiCmSubscriptionDetails(
+ new ArrayList<>(List.of(dmiCmSubscriptionPredicate)),
+ PENDING));
+ }
+ }
+
+ private Map<String, Set<String>> groupTargetCmHandleIdsByDmi(final List<String> targetCmHandleIds) {
+ final Map<String, Set<String>> targetCmHandlesByDmiServiceNames = new HashMap<>();
+ final Collection<YangModelCmHandle> yangModelCmHandles =
+ inventoryPersistence.getYangModelCmHandles(targetCmHandleIds);
+
+ for (final YangModelCmHandle yangModelCmHandle : yangModelCmHandles) {
+ final String dmiServiceName = yangModelCmHandle.getDmiServiceName();
+ targetCmHandlesByDmiServiceNames.putIfAbsent(dmiServiceName, new HashSet<>());
+ targetCmHandlesByDmiServiceNames.get(dmiServiceName).add(yangModelCmHandle.getId());
+ }
+ return targetCmHandlesByDmiServiceNames;
+ }
+
+ private boolean isAcceptedOrRejected(final DmiCmSubscriptionDetails dmiCmSubscription) {
+ return dmiCmSubscription.getCmSubscriptionStatus().toString().equals("ACCEPTED")
+ || dmiCmSubscription.getCmSubscriptionStatus().toString().equals("REJECTED");
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avc/AvcEventConsumer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/cmavc/CmAvcEventConsumer.java
index f635f1a80b..9e90eabbc4 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avc/AvcEventConsumer.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/cmavc/CmAvcEventConsumer.java
@@ -18,11 +18,9 @@
* ============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;
-import java.util.UUID;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.ConsumerRecord;
@@ -33,13 +31,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 +48,14 @@ 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());
- final String newEventId = UUID.randomUUID().toString();
- final CloudEvent outgoingAvcEvent =
- CloudEventBuilder.from(avcEventConsumerRecord.value()).withId(newEventId).build();
- eventsPublisher.publishCloudEvent(cmEventsTopicName, newEventId, outgoingAvcEvent);
+ public void consumeAndForward(
+ final ConsumerRecord<String, CloudEvent> cmAvcEventAsConsumerRecord) {
+ final CloudEvent outgoingAvcEvent = cmAvcEventAsConsumerRecord.value();
+ log.debug("Consuming AVC event {} ...", outgoingAvcEvent);
+ eventsPublisher.publishCloudEvent(cmEventsTopicName, outgoingAvcEvent.getId(), outgoingAvcEvent);
}
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiCmSubscriptionDetailsPerDmiMapper.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiCmSubscriptionDetailsPerDmiMapper.java
new file mode 100644
index 0000000000..423c603a92
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiCmSubscriptionDetailsPerDmiMapper.java
@@ -0,0 +1,103 @@
+/*
+ * ============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.data.models.DatastoreType.fromDatastoreName;
+import static org.onap.cps.ncmp.impl.cmnotificationsubscription.models.CmSubscriptionStatus.PENDING;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.onap.cps.ncmp.api.data.models.DatastoreType;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionDetails;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionKey;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionPredicate;
+import org.springframework.stereotype.Component;
+
+@Component
+public class DmiCmSubscriptionDetailsPerDmiMapper {
+
+ /**
+ * Maps Dmi Subscription Keys grouped by Dmi Plugin to DmiCmSubscriptionDetails per Dmi plugin.
+ *
+ * @param subscribersPerDmi Details managed by each dmi plugin
+ * @return Grouped Dmi Subscription details per dmi plugin
+ */
+ public Map<String, DmiCmSubscriptionDetails> toDmiCmSubscriptionsPerDmi(
+ final Map<String, Collection<DmiCmSubscriptionKey>> subscribersPerDmi) {
+
+ final Map<String, DmiCmSubscriptionDetails> dmiSubscriptionsPerDmi = new HashMap<>();
+
+ subscribersPerDmi.forEach((dmiPluginName, dmiCmSubscriptionKeys) -> {
+ final Map<DatastoreTypeAndXpath, List<DmiCmSubscriptionKey>> groupedByDatastoreTypeAndXpath =
+ groupByDatastoreTypeAndXpath(dmiCmSubscriptionKeys);
+
+ final List<DmiCmSubscriptionPredicate> dmiSubscriptionPredicates =
+ createDmiCmSubscriptionPredicates(groupedByDatastoreTypeAndXpath);
+
+ final DmiCmSubscriptionDetails dmiCmSubscriptionDetails =
+ new DmiCmSubscriptionDetails(dmiSubscriptionPredicates, PENDING);
+
+ dmiSubscriptionsPerDmi.put(dmiPluginName, dmiCmSubscriptionDetails);
+ });
+
+ return dmiSubscriptionsPerDmi;
+ }
+
+ private static Map<DatastoreTypeAndXpath, List<DmiCmSubscriptionKey>> groupByDatastoreTypeAndXpath(
+ final Collection<DmiCmSubscriptionKey> dmiCmSubscriptionKeys) {
+ return dmiCmSubscriptionKeys.stream().collect(Collectors.groupingBy(
+ datastoreTypeAndXpath -> new DatastoreTypeAndXpath(
+ fromDatastoreName(datastoreTypeAndXpath.datastoreName()), datastoreTypeAndXpath.xpath())));
+ }
+
+ private static List<DmiCmSubscriptionPredicate> createDmiCmSubscriptionPredicates(
+ final Map<DatastoreTypeAndXpath, List<DmiCmSubscriptionKey>> groupedByDatastoreTypeAndXpath) {
+ final List<DmiCmSubscriptionPredicate> dmiCmSubscriptionPredicates = new ArrayList<>();
+
+ for (final Map.Entry<DatastoreTypeAndXpath, List<DmiCmSubscriptionKey>> datastoreTypeXpathGroupEntry :
+ groupedByDatastoreTypeAndXpath.entrySet()) {
+ final DatastoreTypeAndXpath datastoreTypeAndXpath = datastoreTypeXpathGroupEntry.getKey();
+ final Set<String> cmHandleIds = new HashSet<>();
+
+ for (final DmiCmSubscriptionKey dmiCmSubscriptionKey : datastoreTypeXpathGroupEntry.getValue()) {
+ cmHandleIds.add(dmiCmSubscriptionKey.cmHandleId());
+ }
+
+ final Set<String> xpaths = Collections.singleton(datastoreTypeAndXpath.xpath());
+ dmiCmSubscriptionPredicates.add(
+ new DmiCmSubscriptionPredicate(cmHandleIds, datastoreTypeAndXpath.datastoreType(), xpaths));
+ }
+
+ return dmiCmSubscriptionPredicates;
+ }
+
+
+ private record DatastoreTypeAndXpath(DatastoreType datastoreType, String xpath) { }
+
+}
+
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/mapper/CmNotificationSubscriptionDmiInEventMapper.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiInEventMapper.java
index 489401f26e..4ce4ef36cf 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/mapper/CmNotificationSubscriptionDmiInEventMapper.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiInEventMapper.java
@@ -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.api.impl.inventory.InventoryPersistence;
-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.Cmhandle;
-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,12 +79,12 @@ 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<>();
+ final List<CmHandle> cmSubscriptionCmHandles = new ArrayList<>();
inventoryPersistence.getYangModelCmHandles(cmHandleIds).forEach(yangModelCmHandle -> {
- final Cmhandle cmhandle = new Cmhandle();
+ final CmHandle cmhandle = new CmHandle();
final Map<String, String> cmhandleDmiProperties = new LinkedHashMap<>();
yangModelCmHandle.getDmiProperties()
.forEach(dmiProperty -> cmhandleDmiProperties.put(dmiProperty.getName(), dmiProperty.getValue()));
@@ -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;
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/producer/CmNotificationSubscriptionDmiInEventProducer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiInEventProducer.java
index 3273c556c6..c62916f05c 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/producer/CmNotificationSubscriptionDmiInEventProducer.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiInEventProducer.java
@@ -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
index 0000000000..20c7c7b13d
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiOutEventConsumer.java
@@ -0,0 +1,115 @@
+/*
+ * ============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.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.ncmp.NcmpOutEventMapper;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.ncmp.NcmpOutEventProducer;
+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 NcmpOutEventProducer ncmpOutEventProducer;
+ private final NcmpOutEventMapper ncmpOutEventMapper;
+
+ 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.removeFromDatabase(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.updateDmiSubscriptionStatus(subscriptionId, dmiPluginName,
+ cmSubscriptionStatus);
+ }
+
+ private void handleEventsStatusPerDmi(final String subscriptionId, final String eventType) {
+ final Map<String, DmiCmSubscriptionDetails> dmiSubscriptionsPerDmi = dmiCacheHandler.get(subscriptionId);
+ final NcmpOutEvent ncmpOutEvent = ncmpOutEventMapper.toNcmpOutEvent(subscriptionId, dmiSubscriptionsPerDmi);
+ ncmpOutEventProducer.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());
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/CmNotificationSubscriptionStatus.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/models/CmSubscriptionStatus.java
index 68d54fac95..5b7c46ed00 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/CmNotificationSubscriptionStatus.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/models/CmSubscriptionStatus.java
@@ -18,15 +18,15 @@
* ============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;
}
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/DmiCmNotificationSubscriptionDetails.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/models/DmiCmSubscriptionDetails.java
index 95757e7240..dbc607ad27 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/DmiCmNotificationSubscriptionDetails.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/models/DmiCmSubscriptionDetails.java
@@ -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;
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/models/DmiCmSubscriptionKey.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/models/DmiCmSubscriptionKey.java
new file mode 100644
index 0000000000..edc3c566be
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/models/DmiCmSubscriptionKey.java
@@ -0,0 +1,30 @@
+/*
+ * ============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.models;
+
+/**
+ * Key used to find the records to be sent to the DMI plugin.
+ *
+ * @param datastoreName datastore name
+ * @param cmHandleId cmhandle id
+ * @param xpath xpath
+ */
+public record DmiCmSubscriptionKey(String datastoreName, String cmHandleId, String xpath) { }
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/DmiCmNotificationSubscriptionPredicate.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/models/DmiCmSubscriptionPredicate.java
index 9c4c3f64e3..84d3aead8c 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/DmiCmNotificationSubscriptionPredicate.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/models/DmiCmSubscriptionPredicate.java
@@ -18,18 +18,18 @@
* ============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;
import lombok.Getter;
import lombok.Setter;
-import org.onap.cps.ncmp.api.impl.operations.DatastoreType;
+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/models/DmiCmSubscriptionTuple.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/models/DmiCmSubscriptionTuple.java
new file mode 100644
index 0000000000..cd4a15af47
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/models/DmiCmSubscriptionTuple.java
@@ -0,0 +1,34 @@
+/*
+ * ============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.models;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Tuple to be used during for to delete usecase.
+ *
+ * @param lastRemainingSubscriptionsPerDmi subscriptions that are used by only one subscriber grouped per dmi
+ * @param overlappingSubscriptionsPerDmi subscriptions that are shared by multiple subscribers grouped per dmi
+ */
+public record DmiCmSubscriptionTuple(Map<String, Collection<DmiCmSubscriptionKey>> lastRemainingSubscriptionsPerDmi,
+ Map<String, Collection<DmiCmSubscriptionKey>> overlappingSubscriptionsPerDmi) {
+}
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
index 0000000000..d7f15a2c72
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/CmSubscriptionComparator.java
@@ -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);
+ }
+ }
+
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionHandlerService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/CmSubscriptionHandler.java
index 536693ee4e..90c5c575e6 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionHandlerService.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/CmSubscriptionHandler.java
@@ -18,18 +18,26 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.events.cmsubscription.service;
+package org.onap.cps.ncmp.impl.cmnotificationsubscription.ncmp;
-import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.client_to_ncmp.CmNotificationSubscriptionNcmpInEvent;
+import java.util.List;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.client_to_ncmp.Predicate;
-public interface CmNotificationSubscriptionHandlerService {
+public interface CmSubscriptionHandler {
/**
- * Process cm notification subscription request.
+ * Process cm notification subscription create request.
*
- * @param cmNotificationSubscriptionNcmpInEvent CM Notification Subscription event
+ * @param subscriptionId subscription id
+ * @param predicates subscription predicates
*/
- void processSubscriptionCreateRequest(
- final CmNotificationSubscriptionNcmpInEvent cmNotificationSubscriptionNcmpInEvent);
+ void processSubscriptionCreateRequest(final String subscriptionId, final List<Predicate> predicates);
-}
+ /**
+ * Process cm notification subscription delete request.
+ *
+ * @param subscriptionId subscription id
+ */
+ void processSubscriptionDeleteRequest(final String subscriptionId);
+
+} \ No newline at end of file
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
index 0000000000..1cdc7ed3e0
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/CmSubscriptionHandlerImpl.java
@@ -0,0 +1,229 @@
+/*
+ * ============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.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import lombok.RequiredArgsConstructor;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.cache.DmiCacheHandler;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.dmi.DmiCmSubscriptionDetailsPerDmiMapper;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.dmi.DmiInEventMapper;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.dmi.DmiInEventProducer;
+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.DmiCmSubscriptionKey;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionPredicate;
+import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionTuple;
+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.onap.cps.ncmp.impl.inventory.InventoryPersistence;
+import org.onap.cps.spi.model.DataNode;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class CmSubscriptionHandlerImpl implements CmSubscriptionHandler {
+
+ private static final Pattern SUBSCRIPTION_KEY_FROM_XPATH_PATTERN = Pattern.compile(
+ "^/datastores/datastore\\[@name='([^']*)']/cm-handles/cm-handle\\[@id='([^']*)']/"
+ + "filters/filter\\[@xpath='(.*)']$");
+
+ private final CmSubscriptionPersistenceService cmSubscriptionPersistenceService;
+ private final CmSubscriptionComparator cmSubscriptionComparator;
+ private final NcmpOutEventMapper ncmpOutEventMapper;
+ private final DmiInEventMapper dmiInEventMapper;
+ private final DmiCmSubscriptionDetailsPerDmiMapper dmiCmSubscriptionDetailsPerDmiMapper;
+ private final NcmpOutEventProducer ncmpOutEventProducer;
+ private final DmiInEventProducer dmiInEventProducer;
+ private final DmiCacheHandler dmiCacheHandler;
+ private final InventoryPersistence inventoryPersistence;
+
+ @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 Collection<DataNode> subscriptionDataNodes =
+ cmSubscriptionPersistenceService.getAllNodesForSubscriptionId(subscriptionId);
+ final DmiCmSubscriptionTuple dmiCmSubscriptionTuple =
+ getLastRemainingAndOverlappingSubscriptionsPerDmi(subscriptionDataNodes);
+ dmiCacheHandler.add(subscriptionId, mergeDmiCmSubscriptionDetailsPerDmiMaps(dmiCmSubscriptionTuple));
+ if (dmiCmSubscriptionTuple.lastRemainingSubscriptionsPerDmi().isEmpty()) {
+ acceptAndPublishDeleteRequest(subscriptionId);
+ } else {
+ sendSubscriptionDeleteRequestToDmi(subscriptionId,
+ dmiCmSubscriptionDetailsPerDmiMapper.toDmiCmSubscriptionsPerDmi(
+ dmiCmSubscriptionTuple.lastRemainingSubscriptionsPerDmi()));
+ scheduleNcmpOutEventResponse(subscriptionId, "subscriptionDeleteResponse");
+ }
+ }
+
+ private Map<String, DmiCmSubscriptionDetails> mergeDmiCmSubscriptionDetailsPerDmiMaps(
+ final DmiCmSubscriptionTuple dmiCmSubscriptionTuple) {
+ final Map<String, DmiCmSubscriptionDetails> lastRemainingDmiSubscriptionsPerDmi =
+ dmiCmSubscriptionDetailsPerDmiMapper.toDmiCmSubscriptionsPerDmi(
+ dmiCmSubscriptionTuple.lastRemainingSubscriptionsPerDmi());
+ final Map<String, DmiCmSubscriptionDetails> overlappingDmiSubscriptionsPerDmi =
+ dmiCmSubscriptionDetailsPerDmiMapper.toDmiCmSubscriptionsPerDmi(
+ dmiCmSubscriptionTuple.overlappingSubscriptionsPerDmi());
+ final Map<String, DmiCmSubscriptionDetails> mergedDmiSubscriptionsPerDmi =
+ new HashMap<>(lastRemainingDmiSubscriptionsPerDmi);
+ overlappingDmiSubscriptionsPerDmi.forEach((dmiServiceName, dmiCmSubscriptionDetails) ->
+ mergedDmiSubscriptionsPerDmi.merge(dmiServiceName, dmiCmSubscriptionDetails,
+ this::mergeDmiCmSubscriptionDetails));
+ return mergedDmiSubscriptionsPerDmi;
+ }
+
+ private DmiCmSubscriptionDetails mergeDmiCmSubscriptionDetails(
+ final DmiCmSubscriptionDetails dmiCmSubscriptionDetails,
+ final DmiCmSubscriptionDetails otherDmiCmSubscriptionDetails) {
+ final List<DmiCmSubscriptionPredicate> mergedDmiCmSubscriptionPredicates =
+ new ArrayList<>(dmiCmSubscriptionDetails.getDmiCmSubscriptionPredicates());
+ mergedDmiCmSubscriptionPredicates.addAll(otherDmiCmSubscriptionDetails.getDmiCmSubscriptionPredicates());
+ return new DmiCmSubscriptionDetails(mergedDmiCmSubscriptionPredicates, CmSubscriptionStatus.PENDING);
+ }
+
+ private void scheduleNcmpOutEventResponse(final String subscriptionId, final String eventType) {
+ ncmpOutEventProducer.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 = ncmpOutEventMapper.toNcmpOutEventForRejectedRequest(subscriptionId,
+ new ArrayList<>(subscriptionTargetFilters));
+ ncmpOutEventProducer.publishNcmpOutEvent(subscriptionId, "subscriptionCreateResponse", ncmpOutEvent, false);
+ }
+
+ private void acceptAndPublishDeleteRequest(final String subscriptionId) {
+ final Set<String> dmiServiceNames = dmiCacheHandler.get(subscriptionId).keySet();
+ for (final String dmiServiceName : dmiServiceNames) {
+ dmiCacheHandler.updateDmiSubscriptionStatus(subscriptionId, dmiServiceName,
+ CmSubscriptionStatus.ACCEPTED);
+ dmiCacheHandler.removeFromDatabase(subscriptionId, dmiServiceName);
+ }
+ final NcmpOutEvent ncmpOutEvent = ncmpOutEventMapper.toNcmpOutEvent(subscriptionId,
+ dmiCacheHandler.get(subscriptionId));
+ ncmpOutEventProducer.publishNcmpOutEvent(subscriptionId, "subscriptionDeleteResponse", 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()) {
+ acceptAndPersistCmSubscriptionPerDmi(subscriptionId, dmiPluginName);
+ } else {
+ publishDmiInEventPerDmi(subscriptionId, dmiPluginName, dmiCmSubscriptionPredicates);
+ }
+ });
+ }
+
+ private void publishDmiInEventPerDmi(final String subscriptionId, final String dmiPluginName,
+ final List<DmiCmSubscriptionPredicate> dmiCmSubscriptionPredicates) {
+ final DmiInEvent dmiInEvent = dmiInEventMapper.toDmiInEvent(dmiCmSubscriptionPredicates);
+ dmiInEventProducer.publishDmiInEvent(subscriptionId, dmiPluginName,
+ "subscriptionCreateRequest", dmiInEvent);
+ }
+
+ private void acceptAndPersistCmSubscriptionPerDmi(final String subscriptionId, final String dmiPluginName) {
+ dmiCacheHandler.updateDmiSubscriptionStatus(subscriptionId, dmiPluginName,
+ CmSubscriptionStatus.ACCEPTED);
+ dmiCacheHandler.persistIntoDatabasePerDmi(subscriptionId, dmiPluginName);
+ }
+
+ private void sendSubscriptionDeleteRequestToDmi(final String subscriptionId,
+ final Map<String, DmiCmSubscriptionDetails>
+ dmiCmSubscriptionsPerDmi) {
+ dmiCmSubscriptionsPerDmi.forEach((dmiPluginName, dmiCmSubscriptionDetails) -> {
+ final DmiInEvent dmiInEvent =
+ dmiInEventMapper.toDmiInEvent(
+ dmiCmSubscriptionDetails.getDmiCmSubscriptionPredicates());
+ dmiInEventProducer.publishDmiInEvent(subscriptionId,
+ dmiPluginName, "subscriptionDeleteRequest", dmiInEvent);
+ });
+ }
+
+
+ private DmiCmSubscriptionTuple getLastRemainingAndOverlappingSubscriptionsPerDmi(
+ final Collection<DataNode> subscriptionNodes) {
+ final Map<String, Collection<DmiCmSubscriptionKey>> lastRemainingSubscriptionsPerDmi = new HashMap<>();
+ final Map<String, Collection<DmiCmSubscriptionKey>> overlappingSubscriptionsPerDmi = new HashMap<>();
+
+ for (final DataNode subscriptionNode : subscriptionNodes) {
+ final DmiCmSubscriptionKey dmiCmSubscriptionKey = extractCmSubscriptionKey(subscriptionNode.getXpath());
+ final String dmiServiceName = inventoryPersistence.getYangModelCmHandle(
+ dmiCmSubscriptionKey.cmHandleId()).getDmiServiceName();
+ final List<String> subscribers = (List<String>) subscriptionNode.getLeaves().get("subscriptionIds");
+ populateDmiCmSubscriptionTuple(subscribers, overlappingSubscriptionsPerDmi,
+ lastRemainingSubscriptionsPerDmi, dmiServiceName, dmiCmSubscriptionKey);
+ }
+ return new DmiCmSubscriptionTuple(lastRemainingSubscriptionsPerDmi, overlappingSubscriptionsPerDmi);
+ }
+
+ private static void populateDmiCmSubscriptionTuple(final List<String> subscribers,
+ final Map<String, Collection<DmiCmSubscriptionKey>>
+ overlappingSubscriptionsPerDmi,
+ final Map<String, Collection<DmiCmSubscriptionKey>>
+ lastRemainingSubscriptionsPerDmi,
+ final String dmiServiceName,
+ final DmiCmSubscriptionKey dmiCmSubscriptionKey) {
+ final Map<String, Collection<DmiCmSubscriptionKey>> targetMap =
+ subscribers.size() > 1 ? overlappingSubscriptionsPerDmi : lastRemainingSubscriptionsPerDmi;
+ targetMap.computeIfAbsent(dmiServiceName, dmiName -> new HashSet<>()).add(dmiCmSubscriptionKey);
+ }
+
+ private DmiCmSubscriptionKey extractCmSubscriptionKey(final String xpath) {
+ final Matcher matcher = SUBSCRIPTION_KEY_FROM_XPATH_PATTERN.matcher(xpath);
+ if (matcher.find()) {
+ final String datastoreName = matcher.group(1);
+ final String cmHandleId = matcher.group(2);
+ final String filterXpath = matcher.group(3);
+ return new DmiCmSubscriptionKey(datastoreName, cmHandleId, filterXpath);
+ }
+ throw new IllegalArgumentException("DataNode xpath does not represent a subscription key");
+ }
+
+} \ No newline at end of file
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/consumer/CmNotificationSubscriptionNcmpInEventConsumer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpInEventConsumer.java
index 2c544b7b6a..cba64e0e94 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/consumer/CmNotificationSubscriptionNcmpInEventConsumer.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpInEventConsumer.java
@@ -18,45 +18,52 @@
* ============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.api.impl.events.mapper.CloudEventMapper.toTargetEvent;
+import static org.onap.cps.ncmp.utils.events.CloudEventMapper.toTargetEvent;
import io.cloudevents.CloudEvent;
+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.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 String subscriptionId = ncmpInEvent.getData().getSubscriptionId();
+ final List<Predicate> predicates = ncmpInEvent.getData().getPredicates();
if ("subscriptionCreateRequest".equals(cloudEvent.getType())) {
- log.info("Subscription for source {} with subscription id {} ...", cloudEvent.getSource(), subscriptionId);
- cmNotificationSubscriptionHandlerService.processSubscriptionCreateRequest(
- cmNotificationSubscriptionNcmpInEvent);
+ log.info("Subscription create request for source {} with subscription id {} ...",
+ cloudEvent.getSource(), subscriptionId);
+ cmSubscriptionHandler.processSubscriptionCreateRequest(subscriptionId, predicates);
+ }
+ if ("subscriptionDeleteRequest".equals(cloudEvent.getType())) {
+ log.info("Subscription delete request for source {} with subscription id {} ...",
+ cloudEvent.getSource(), subscriptionId);
+ cmSubscriptionHandler.processSubscriptionDeleteRequest(subscriptionId);
}
}
-} \ No newline at end of file
+}
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
index 0000000000..afff9d1298
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventMapper.java
@@ -0,0 +1,114 @@
+/*
+ * ============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.Collection;
+import java.util.HashSet;
+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 Collection<String> acceptedCmHandleIds = new HashSet<>();
+ final Collection<String> pendingCmHandleIds = new HashSet<>();
+ final Collection<String> rejectedCmHandleIds = new HashSet<>();
+
+ 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
index 0000000000..3371d59f7a
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventProducer.java
@@ -0,0 +1,139 @@
+/*
+ * ============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.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 NcmpOutEventMapper ncmpOutEventMapper;
+ private final DmiCacheHandler dmiCacheHandler;
+ private final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
+ private static final Map<String, ScheduledFuture<?>> scheduledTasksPerSubscriptionIdAndEventType =
+ 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) {
+
+ final String taskKey = subscriptionId.concat(eventType);
+
+ if (isScheduledEvent && !scheduledTasksPerSubscriptionIdAndEventType.containsKey(taskKey)) {
+ final ScheduledFuture<?> scheduledFuture = scheduleAndPublishNcmpOutEvent(subscriptionId, eventType);
+ scheduledTasksPerSubscriptionIdAndEventType.putIfAbsent(taskKey, scheduledFuture);
+ log.debug("Scheduled the Cm Subscription Event for subscriptionId : {} and eventType : {}", subscriptionId,
+ eventType);
+ } else {
+ cancelScheduledTask(taskKey);
+ if (ncmpOutEvent != null) {
+ publishNcmpOutEventNow(subscriptionId, eventType, ncmpOutEvent);
+ log.debug("Published Cm Subscription Event on demand for subscriptionId : {} and eventType : {}",
+ subscriptionId, eventType);
+ }
+ }
+ }
+
+ private ScheduledFuture<?> scheduleAndPublishNcmpOutEvent(final String subscriptionId, final String eventType) {
+ final NcmpOutEventPublishingTask ncmpOutEventPublishingTask =
+ new NcmpOutEventPublishingTask(ncmpOutEventTopic, subscriptionId, eventType, eventsPublisher,
+ jsonObjectMapper, ncmpOutEventMapper, dmiCacheHandler);
+ return scheduledExecutorService.schedule(ncmpOutEventPublishingTask, dmiOutEventTimeoutInMs,
+ TimeUnit.MILLISECONDS);
+ }
+
+ private void cancelScheduledTask(final String taskKey) {
+
+ final ScheduledFuture<?> scheduledFuture = scheduledTasksPerSubscriptionIdAndEventType.get(taskKey);
+ if (scheduledFuture != null) {
+ scheduledFuture.cancel(true);
+ scheduledTasksPerSubscriptionIdAndEventType.remove(taskKey);
+ }
+
+ }
+
+
+ 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
index 0000000000..f8f253d275
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventPublishingTask.java
@@ -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 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.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 NcmpOutEventMapper ncmpOutEventMapper;
+ 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 = ncmpOutEventMapper.toNcmpOutEvent(subscriptionId,
+ dmiSubscriptionsPerDmi);
+ eventsPublisher.publishCloudEvent(topicName, subscriptionId,
+ buildAndGetNcmpOutEventAsCloudEvent(jsonObjectMapper, subscriptionId, eventType,
+ ncmpOutEvent));
+ dmiCacheHandler.removeAcceptedAndRejectedDmiSubscriptionEntries(subscriptionId);
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/utils/CmSubscriptionPersistenceService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/utils/CmSubscriptionPersistenceService.java
new file mode 100644
index 0000000000..6b5ed908b8
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/utils/CmSubscriptionPersistenceService.java
@@ -0,0 +1,244 @@
+/*
+ * ============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.
+ * 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.utils;
+
+import static org.onap.cps.spi.FetchDescendantsOption.DIRECT_CHILDREN_ONLY;
+import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS;
+
+import java.io.Serializable;
+import java.time.OffsetDateTime;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+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.model.DataNode;
+import org.onap.cps.utils.ContentType;
+import org.onap.cps.utils.JsonObjectMapper;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+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 = """
+ /datastores/datastore[@name='%s']/cm-handles/cm-handle[@id='%s']
+ """.trim();
+ private static final String CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_FILTERS_WITH_DATASTORE_AND_CMHANDLE =
+ CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_WITH_DATASTORE_AND_CMHANDLE + "/filters";
+
+ private static final String CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_WITH_DATASTORE_CMHANDLE_AND_XPATH =
+ CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_FILTERS_WITH_DATASTORE_AND_CMHANDLE + "/filter[@xpath='%s']";
+
+
+ private static final String CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_WITH_ID = """
+ //filter/subscriptionIds[text()='%s']
+ """.trim();
+
+ private final JsonObjectMapper jsonObjectMapper;
+ private final CpsQueryService cpsQueryService;
+ private final CpsDataService cpsDataService;
+
+ /**
+ * 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();
+ }
+
+ /**
+ * 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();
+ }
+
+ /**
+ * 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(
+ datastoreType.getDatastoreName(), cmHandleId, escapeQuotesByDoublingThem(xpath));
+ final Collection<DataNode> existingNodes =
+ cpsQueryService.queryDataNodes(NCMP_DATASPACE_NAME, CM_SUBSCRIPTIONS_ANCHOR_NAME,
+ isOngoingCmSubscriptionCpsPathQuery, OMIT_DESCENDANTS);
+ if (existingNodes.isEmpty()) {
+ return Collections.emptyList();
+ }
+ return (List<String>) existingNodes.iterator().next().getLeaves().get("subscriptionIds");
+ }
+
+ /**
+ * 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, newSubscriptionId);
+ } else if (!subscriptionIds.contains(newSubscriptionId)) {
+ subscriptionIds.add(newSubscriptionId);
+ saveSubscriptionDetails(datastoreType, cmHandleId, xpath, subscriptionIds);
+ }
+ }
+
+ /**
+ * 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 {} :",
+ CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_WITH_DATASTORE_CMHANDLE_AND_XPATH.formatted(
+ datastoreType.getDatastoreName(), cmHandleId, escapeQuotesByDoublingThem(xpath)));
+ if (subscriptionIds.isEmpty()) {
+ log.info("No subscribers left for the following cps path {} :",
+ CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_WITH_DATASTORE_CMHANDLE_AND_XPATH.formatted(
+ datastoreType.getDatastoreName(), cmHandleId, escapeQuotesByDoublingThem(xpath)));
+ deleteListOfSubscriptionsFor(datastoreType, cmHandleId, xpath);
+ }
+ }
+ }
+
+ /**
+ * Retrieve all existing dataNodes for given subscription id.
+ *
+ * @param subscriptionId subscription id
+ * @return collection of DataNodes
+ */
+ public Collection<DataNode> getAllNodesForSubscriptionId(final String subscriptionId) {
+ return cpsQueryService.queryDataNodes(NCMP_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME,
+ CPS_PATH_QUERY_FOR_CM_SUBSCRIPTION_WITH_ID.formatted(subscriptionId),
+ OMIT_DESCENDANTS);
+ }
+
+ private void deleteListOfSubscriptionsFor(final DatastoreType datastoreType, final String cmHandleId,
+ 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();
+ if (existingFiltersForCmHandle.isEmpty()) {
+ removeCmHandleFromDatastore(datastoreType.getDatastoreName(), cmHandleId);
+ }
+ }
+
+ 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());
+ }
+
+ 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();
+ }
+
+ private void addFirstSubscriptionForDatastoreCmHandleAndXpath(final DatastoreType datastoreType,
+ 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);
+ 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(), ContentType.JSON);
+ }
+ }
+
+ 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);
+ }
+
+ private String getSubscriptionDetailsAsJson(final String xpath, final Collection<String> subscriptionIds) {
+ final Map<String, Serializable> subscriptionDetailsAsMap =
+ Map.of("xpath", xpath, "subscriptionIds", (Serializable) subscriptionIds);
+ return "{\"filter\":[" + jsonObjectMapper.asJsonString(subscriptionDetailsAsMap) + "]}";
+ }
+
+ private static String escapeQuotesByDoublingThem(final String inputXpath) {
+ return inputXpath.replace("'", "''");
+ }
+
+}
+
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/DmiDataOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/DmiDataOperations.java
new file mode 100644
index 0000000000..301b8195e4
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/DmiDataOperations.java
@@ -0,0 +1,310 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021-2024 Nordix Foundation
+ * Modifications Copyright (C) 2022 Bell Canada
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.data;
+
+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.api.data.models.OperationType.READ;
+import static org.onap.cps.ncmp.impl.models.RequiredDmiService.DATA;
+
+import io.micrometer.core.annotation.Timed;
+import java.util.Collection;
+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.NcmpResponseStatus;
+import org.onap.cps.ncmp.api.data.models.CmResourceAddress;
+import org.onap.cps.ncmp.api.data.models.DataOperationRequest;
+import org.onap.cps.ncmp.api.data.models.OperationType;
+import org.onap.cps.ncmp.api.exceptions.DmiClientRequestException;
+import org.onap.cps.ncmp.impl.data.models.DmiDataOperation;
+import org.onap.cps.ncmp.impl.data.models.DmiDataOperationRequest;
+import org.onap.cps.ncmp.impl.data.models.DmiOperationCmHandle;
+import org.onap.cps.ncmp.impl.data.policyexecutor.PolicyExecutor;
+import org.onap.cps.ncmp.impl.data.utils.DmiDataOperationsHelper;
+import org.onap.cps.ncmp.impl.dmi.DmiProperties;
+import org.onap.cps.ncmp.impl.dmi.DmiRestClient;
+import org.onap.cps.ncmp.impl.inventory.InventoryPersistence;
+import org.onap.cps.ncmp.impl.inventory.models.CmHandleState;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
+import org.onap.cps.ncmp.impl.models.DmiRequestBody;
+import org.onap.cps.ncmp.impl.utils.http.RestServiceUrlTemplateBuilder;
+import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters;
+import org.onap.cps.spi.exceptions.CpsException;
+import org.onap.cps.utils.JsonObjectMapper;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.util.UriComponentsBuilder;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+/**
+ * Operations class for DMI data.
+ */
+@RequiredArgsConstructor
+@Service
+public class DmiDataOperations {
+
+ private final InventoryPersistence inventoryPersistence;
+ private final JsonObjectMapper jsonObjectMapper;
+ private final DmiProperties dmiProperties;
+ private final DmiRestClient dmiRestClient;
+ private final PolicyExecutor policyExecutor;
+
+ /**
+ * This method fetches the resource data from the operational data store for a given CM handle
+ * identifier on the specified resource using the DMI client.
+ *
+ * @param cmResourceAddress Target datastore, CM handle, and resource identifier.
+ * @param options Options query string.
+ * @param topic Topic name for triggering asynchronous responses.
+ * @param requestId Request ID for asynchronous responses.
+ * @param authorization Contents of the Authorization header, or null if not present.
+ * @return {@code Mono<ResponseEntity<Object>>} A reactive type representing the response entity.
+ */
+ @Timed(value = "cps.ncmp.dmi.get",
+ description = "Time taken to fetch the resource data from operational data store for given cm handle "
+ + "identifier on given resource using dmi client")
+ public Mono<ResponseEntity<Object>> getResourceDataFromDmi(final CmResourceAddress cmResourceAddress,
+ final String options,
+ final String topic,
+ final String requestId,
+ final String authorization) {
+ final YangModelCmHandle yangModelCmHandle = getYangModelCmHandle(cmResourceAddress.getResolvedCmHandleId());
+ final CmHandleState cmHandleState = yangModelCmHandle.getCompositeState().getCmHandleState();
+ validateIfCmHandleStateReady(yangModelCmHandle, cmHandleState);
+ final String jsonRequestBody = getDmiRequestBody(READ, requestId, null, null, yangModelCmHandle);
+ final UrlTemplateParameters urlTemplateParameters = getUrlTemplateParameters(cmResourceAddress
+ .getDatastoreName(), yangModelCmHandle, cmResourceAddress.getResourceIdentifier(), options, topic);
+ return dmiRestClient.asynchronousPostOperationWithJsonData(DATA, urlTemplateParameters, jsonRequestBody, READ,
+ authorization);
+ }
+
+ /**
+ * This method fetches all the resource data from operational data store for given cm handle
+ * identifier using dmi client.
+ * Note: this method is only used for DataSync
+ *
+ * @param cmHandleId network resource identifier
+ * @param requestId requestId for async responses
+ * @return {@code ResponseEntity} response entity
+ */
+ public ResponseEntity<Object> getAllResourceDataFromDmi(final String cmHandleId, final String requestId) {
+ final YangModelCmHandle yangModelCmHandle = getYangModelCmHandle(cmHandleId);
+ final CmHandleState cmHandleState = yangModelCmHandle.getCompositeState().getCmHandleState();
+ validateIfCmHandleStateReady(yangModelCmHandle, cmHandleState);
+
+ final String jsonRequestBody = getDmiRequestBody(READ, requestId, null, null, yangModelCmHandle);
+ final UrlTemplateParameters urlTemplateParameters = getUrlTemplateParameters(
+ PASSTHROUGH_OPERATIONAL.getDatastoreName(), yangModelCmHandle, "/", null,
+ null);
+ return dmiRestClient.synchronousPostOperationWithJsonData(DATA, urlTemplateParameters, jsonRequestBody, READ,
+ null);
+ }
+
+ /**
+ * This method requests the resource data by data store for given list of cm handles using dmi client.
+ * The data wil be returned as message on the topic specified.
+ *
+ * @param topicParamInQuery topic name for (triggering) async responses
+ * @param dataOperationRequest data operation request to execute operations
+ * @param requestId requestId for as a response
+ * @param authorization contents of Authorization header, or null if not present
+ */
+ public void requestResourceDataFromDmi(final String topicParamInQuery,
+ final DataOperationRequest dataOperationRequest,
+ final String requestId,
+ final String authorization) {
+
+ final Set<String> cmHandlesIds = getDistinctCmHandleIds(dataOperationRequest);
+
+ final Collection<YangModelCmHandle> yangModelCmHandles
+ = inventoryPersistence.getYangModelCmHandles(cmHandlesIds);
+
+ final Map<String, List<DmiDataOperation>> operationsOutPerDmiServiceName
+ = DmiDataOperationsHelper.processPerDefinitionInDataOperationsRequest(topicParamInQuery,
+ requestId, dataOperationRequest, yangModelCmHandles);
+
+ asyncSendMultipleRequest(requestId, topicParamInQuery, operationsOutPerDmiServiceName,
+ authorization);
+ }
+
+ /**
+ * This method creates the resource data from pass-through running data store for given cm handle
+ * identifier on given resource using dmi client.
+ *
+ * @param cmHandleId network resource identifier
+ * @param resourceId resource identifier
+ * @param operationType operation enum
+ * @param requestData the request data
+ * @param dataType data type
+ * @param authorization contents of Authorization header, or null if not present
+ * @return {@code ResponseEntity} response entity
+ */
+ public ResponseEntity<Object> writeResourceDataPassThroughRunningFromDmi(final String cmHandleId,
+ final String resourceId,
+ final OperationType operationType,
+ final String requestData,
+ final String dataType,
+ final String authorization) {
+ final CmResourceAddress cmResourceAddress =
+ new CmResourceAddress(PASSTHROUGH_RUNNING.getDatastoreName(), cmHandleId, resourceId);
+
+ final YangModelCmHandle yangModelCmHandle = getYangModelCmHandle(cmResourceAddress.getResolvedCmHandleId());
+
+ policyExecutor.checkPermission(yangModelCmHandle, operationType, authorization, resourceId, requestData);
+
+ final CmHandleState cmHandleState = yangModelCmHandle.getCompositeState().getCmHandleState();
+ validateIfCmHandleStateReady(yangModelCmHandle, cmHandleState);
+
+ final String jsonRequestBody = getDmiRequestBody(operationType, null, requestData, dataType,
+ yangModelCmHandle);
+ final UrlTemplateParameters urlTemplateParameters = getUrlTemplateParameters(
+ PASSTHROUGH_RUNNING.getDatastoreName(), yangModelCmHandle, resourceId, null,
+ null);
+ return dmiRestClient.synchronousPostOperationWithJsonData(DATA, urlTemplateParameters, jsonRequestBody,
+ operationType, authorization);
+ }
+
+ private YangModelCmHandle getYangModelCmHandle(final String cmHandleId) {
+ return inventoryPersistence.getYangModelCmHandle(cmHandleId);
+ }
+
+ private String getDmiRequestBody(final OperationType operationType,
+ final String requestId,
+ final String requestData,
+ final String dataType,
+ final YangModelCmHandle yangModelCmHandle) {
+ final DmiRequestBody dmiRequestBody = DmiRequestBody.builder()
+ .operationType(operationType)
+ .requestId(requestId)
+ .data(requestData)
+ .dataType(dataType)
+ .moduleSetTag(yangModelCmHandle.getModuleSetTag())
+ .build();
+ dmiRequestBody.asDmiProperties(yangModelCmHandle.getDmiProperties());
+ return jsonObjectMapper.asJsonString(dmiRequestBody);
+ }
+
+ private UrlTemplateParameters getUrlTemplateParameters(final String datastoreName,
+ final YangModelCmHandle yangModelCmHandle,
+ final String resourceIdentifier,
+ final String optionsParamInQuery,
+ final String topicParamInQuery) {
+ final String dmiServiceName = yangModelCmHandle.resolveDmiServiceName(DATA);
+ return RestServiceUrlTemplateBuilder.newInstance()
+ .fixedPathSegment("ch")
+ .variablePathSegment("cmHandleId", yangModelCmHandle.getId())
+ .fixedPathSegment("data")
+ .fixedPathSegment("ds")
+ .variablePathSegment("datastore", datastoreName)
+ .queryParameter("resourceIdentifier", resourceIdentifier)
+ .queryParameter("options", optionsParamInQuery)
+ .queryParameter("topic", topicParamInQuery)
+ .createUrlTemplateParameters(dmiServiceName, dmiProperties.getDmiBasePath());
+ }
+
+ private UrlTemplateParameters getUrlTemplateParameters(final String dmiServiceName,
+ final String requestId,
+ final String topicParamInQuery) {
+ return RestServiceUrlTemplateBuilder.newInstance()
+ .fixedPathSegment("data")
+ .queryParameter("requestId", requestId)
+ .queryParameter("topic", topicParamInQuery)
+ .createUrlTemplateParameters(dmiServiceName, dmiProperties.getDmiBasePath());
+ }
+
+ private void validateIfCmHandleStateReady(final YangModelCmHandle yangModelCmHandle,
+ final CmHandleState cmHandleState) {
+ if (cmHandleState != CmHandleState.READY) {
+ throw new CpsException("State mismatch exception.", "Cm-Handle not in READY state. "
+ + "cm handle state is "
+ + yangModelCmHandle.getCompositeState().getCmHandleState());
+ }
+ }
+
+ private static Set<String> getDistinctCmHandleIds(final DataOperationRequest dataOperationRequest) {
+ return dataOperationRequest.getDataOperationDefinitions().stream()
+ .flatMap(dataOperationDefinition ->
+ dataOperationDefinition.getCmHandleIds().stream()).collect(Collectors.toSet());
+ }
+
+ private void asyncSendMultipleRequest(final String requestId, final String topicParamInQuery,
+ final Map<String, List<DmiDataOperation>> dmiDataOperationsPerDmi,
+ final String authorization) {
+
+ Flux.fromIterable(dmiDataOperationsPerDmi.entrySet())
+ .flatMap(entry -> {
+ final String dmiServiceName = entry.getKey();
+ final UrlTemplateParameters urlTemplateParameters = getUrlTemplateParameters(dmiServiceName,
+ requestId, topicParamInQuery);
+ final List<DmiDataOperation> dmiDataOperations = entry.getValue();
+ final String dmiDataOperationRequestAsJsonString
+ = createDmiDataOperationRequestAsJsonString(dmiDataOperations);
+ return dmiRestClient.asynchronousPostOperationWithJsonData(DATA, urlTemplateParameters,
+ dmiDataOperationRequestAsJsonString, READ, authorization)
+ .then()
+ .onErrorResume(DmiClientRequestException.class, dmiClientRequestException -> {
+ final String dataOperationResourceUrl = UriComponentsBuilder
+ .fromUriString(urlTemplateParameters.urlTemplate())
+ .buildAndExpand(urlTemplateParameters.urlVariables())
+ .toUriString();
+ handleTaskCompletionException(dmiClientRequestException, dataOperationResourceUrl,
+ dmiDataOperations);
+ return Mono.empty();
+ });
+ }).subscribe();
+ }
+
+ private String createDmiDataOperationRequestAsJsonString(
+ final List<DmiDataOperation> dmiDataOperationRequestBodies) {
+ final DmiDataOperationRequest dmiDataOperationRequest = DmiDataOperationRequest.builder()
+ .operations(dmiDataOperationRequestBodies)
+ .build();
+ return jsonObjectMapper.asJsonString(dmiDataOperationRequest);
+ }
+
+ private void handleTaskCompletionException(final DmiClientRequestException dmiClientRequestException,
+ final String dataOperationResourceUrl,
+ final List<DmiDataOperation> dmiDataOperations) {
+ final MultiValueMap<String, String> dataOperationResourceUrlParameters =
+ UriComponentsBuilder.fromUriString(dataOperationResourceUrl).build().getQueryParams();
+ final String topicName = dataOperationResourceUrlParameters.get("topic").get(0);
+ final String requestId = dataOperationResourceUrlParameters.get("requestId").get(0);
+
+ final MultiValueMap<DmiDataOperation, Map<NcmpResponseStatus, List<String>>>
+ cmHandleIdsPerResponseCodesPerOperation = new LinkedMultiValueMap<>();
+
+ dmiDataOperations.forEach(dmiDataOperationRequestBody -> {
+ final List<String> cmHandleIds = dmiDataOperationRequestBody.getCmHandles().stream()
+ .map(DmiOperationCmHandle::getId).toList();
+ cmHandleIdsPerResponseCodesPerOperation.add(dmiDataOperationRequestBody,
+ Map.of(dmiClientRequestException.getNcmpResponseStatus(), cmHandleIds));
+ });
+ DmiDataOperationsHelper.publishErrorMessageToClientTopic(topicName, requestId,
+ cmHandleIdsPerResponseCodesPerOperation);
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NcmpCachedResourceRequestHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NcmpCachedResourceRequestHandler.java
new file mode 100644
index 0000000000..01022cc03e
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NcmpCachedResourceRequestHandler.java
@@ -0,0 +1,75 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022-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.data;
+
+import java.util.Collection;
+import lombok.RequiredArgsConstructor;
+import org.onap.cps.api.CpsDataService;
+import org.onap.cps.ncmp.api.data.models.CmResourceAddress;
+import org.onap.cps.spi.FetchDescendantsOption;
+import org.onap.cps.spi.model.DataNode;
+import org.springframework.stereotype.Service;
+import reactor.core.publisher.Mono;
+
+@Service
+@RequiredArgsConstructor
+public class NcmpCachedResourceRequestHandler extends NcmpDatastoreRequestHandler {
+
+ private final CpsDataService cpsDataService;
+ private final NetworkCmProxyQueryService networkCmProxyQueryService;
+
+ /**
+ * Executes a synchronous query request for given cm handle.
+ * Note. Currently only ncmp-datastore:operational supports query operations.
+ *
+ * @param cmHandleId the cm handle
+ * @param resourceIdentifier the resource identifier
+ * @param includeDescendants whether include descendants
+ * @return a collection of data nodes
+ */
+ public Collection<DataNode> executeRequest(final String cmHandleId, final String resourceIdentifier,
+ final boolean includeDescendants) {
+ final FetchDescendantsOption fetchDescendantsOption = getFetchDescendantsOption(includeDescendants);
+ return networkCmProxyQueryService.queryResourceDataOperational(cmHandleId, resourceIdentifier,
+ fetchDescendantsOption);
+ }
+
+ @Override
+ protected Mono<Object> getResourceDataForCmHandle(final CmResourceAddress cmResourceAddress,
+ final String optionsParamInQuery,
+ final String topicParamInQuery,
+ final String requestId,
+ final boolean includeDescendants,
+ final String authorization) {
+ final FetchDescendantsOption fetchDescendantsOption = getFetchDescendantsOption(includeDescendants);
+
+ final DataNode dataNode = cpsDataService.getDataNodes(cmResourceAddress.getDatastoreName(),
+ cmResourceAddress.getResolvedCmHandleId(),
+ cmResourceAddress.getResourceIdentifier(),
+ fetchDescendantsOption).iterator().next();
+ return Mono.justOrEmpty(dataNode);
+ }
+
+ private static FetchDescendantsOption getFetchDescendantsOption(final boolean includeDescendants) {
+ return includeDescendants ? FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
+ : FetchDescendantsOption.OMIT_DESCENDANTS;
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NcmpDatastoreRequestHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NcmpDatastoreRequestHandler.java
new file mode 100644
index 0000000000..f0a8c6c5d2
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NcmpDatastoreRequestHandler.java
@@ -0,0 +1,96 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022-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.data;
+
+import java.util.Map;
+import java.util.UUID;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.data.models.CmResourceAddress;
+import org.onap.cps.ncmp.utils.events.TopicValidator;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import reactor.core.publisher.Mono;
+
+@Slf4j
+@Service
+public abstract class NcmpDatastoreRequestHandler {
+
+ private static final String NO_REQUEST_ID = null;
+ private static final String NO_TOPIC = null;
+
+ @Value("${notification.async.executor.time-out-value-in-ms:60000}")
+ protected int timeOutInMilliSeconds;
+ @Value("${notification.enabled:true}")
+ protected boolean notificationFeatureEnabled;
+
+ /**
+ * Executes synchronous/asynchronous get request for given cm handle.
+ *
+ * @param cmResourceAddress the name of the datastore, cm handle and resource identifier
+ * @param options options to pass through to dmi client
+ * @param topic topic (optional) for asynchronous responses
+ * @param includeDescendants whether include descendants
+ * @param authorization contents of Authorization header, or null if not present
+ * @return the result object, depends on use op topic. With topic a map object with request id is returned
+ * otherwise the result of the request.
+ */
+ public Object executeRequest(final CmResourceAddress cmResourceAddress,
+ final String options,
+ final String topic,
+ final boolean includeDescendants,
+ final String authorization) {
+
+ final boolean asyncResponseRequested = topic != null;
+ if (asyncResponseRequested && notificationFeatureEnabled) {
+ return getResourceDataAsynchronously(cmResourceAddress, options, topic, includeDescendants, authorization);
+ }
+
+ if (asyncResponseRequested) {
+ log.warn("Asynchronous request is unavailable as notification feature is currently disabled, "
+ + "will use synchronous operation.");
+ }
+ final Mono<Object> resourceDataMono = getResourceDataForCmHandle(cmResourceAddress, options,
+ NO_TOPIC, NO_REQUEST_ID, includeDescendants, authorization);
+ return resourceDataMono.block();
+ }
+
+ private Map<String, String> getResourceDataAsynchronously(final CmResourceAddress cmResourceAddress,
+ final String options,
+ final String topic,
+ final boolean includeDescendants,
+ final String authorization) {
+ TopicValidator.validateTopicName(topic);
+ final String requestId = UUID.randomUUID().toString();
+ getResourceDataForCmHandle(cmResourceAddress, options, topic, requestId, includeDescendants, authorization)
+ .doOnSuccess(result ->
+ log.debug("Async operation succeeded for request id {}: {}", requestId, result))
+ .subscribe();
+ log.debug("Received Async request with id {}", requestId);
+ return Map.of("requestId", requestId);
+ }
+
+ protected abstract Mono<Object> getResourceDataForCmHandle(final CmResourceAddress cmResourceAddress,
+ final String optionsParamInQuery,
+ final String topicParamInQuery,
+ final String requestId,
+ final boolean includeDescendant,
+ final String authorization);
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NcmpPassthroughResourceRequestHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NcmpPassthroughResourceRequestHandler.java
new file mode 100644
index 0000000000..a21210c376
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NcmpPassthroughResourceRequestHandler.java
@@ -0,0 +1,102 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022-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.data;
+
+import static org.onap.cps.ncmp.api.data.models.DatastoreType.OPERATIONAL;
+import static org.onap.cps.ncmp.api.data.models.OperationType.READ;
+
+import java.util.Map;
+import java.util.UUID;
+import lombok.RequiredArgsConstructor;
+import org.onap.cps.ncmp.api.data.exceptions.InvalidDatastoreException;
+import org.onap.cps.ncmp.api.data.exceptions.OperationNotSupportedException;
+import org.onap.cps.ncmp.api.data.models.CmResourceAddress;
+import org.onap.cps.ncmp.api.data.models.DataOperationRequest;
+import org.onap.cps.ncmp.api.data.models.DatastoreType;
+import org.onap.cps.ncmp.api.data.models.OperationType;
+import org.onap.cps.ncmp.api.exceptions.PayloadTooLargeException;
+import org.onap.cps.ncmp.utils.events.TopicValidator;
+import org.springframework.stereotype.Service;
+import reactor.core.publisher.Mono;
+
+@Service
+@RequiredArgsConstructor
+public class NcmpPassthroughResourceRequestHandler extends NcmpDatastoreRequestHandler {
+
+ private final DmiDataOperations dmiDataOperations;
+
+ private static final int MAXIMUM_CM_HANDLES_PER_OPERATION = 200;
+ private static final String PAYLOAD_TOO_LARGE_TEMPLATE = "Operation '%s' affects too many (%d) cm handles";
+
+ /**
+ * Executes asynchronous request for group of cm handles to resource data.
+ *
+ * @param topic the topic param in query
+ * @param dataOperationRequest data operation request details for resource data
+ * @param authorization contents of Authorization header, or null if not present
+ * @return a map with one entry of request Id for success or status and error when async feature is disabled
+ */
+ public Map<String, String> executeAsynchronousRequest(final String topic,
+ final DataOperationRequest dataOperationRequest,
+ final String authorization) {
+ validateDataOperationRequest(topic, dataOperationRequest);
+ if (!notificationFeatureEnabled) {
+ return Map.of("status",
+ "Asynchronous request is unavailable as notification feature is currently disabled.");
+ }
+ final String requestId = UUID.randomUUID().toString();
+ dmiDataOperations.requestResourceDataFromDmi(topic, dataOperationRequest, requestId, authorization);
+ return Map.of("requestId", requestId);
+ }
+
+ @Override
+ protected Mono<Object> getResourceDataForCmHandle(final CmResourceAddress cmResourceAddress,
+ final String options,
+ final String topic,
+ final String requestId,
+ final boolean includeDescendants,
+ final String authorization) {
+
+ return dmiDataOperations.getResourceDataFromDmi(cmResourceAddress, options, topic, requestId, authorization)
+ .flatMap(responseEntity -> Mono.justOrEmpty(responseEntity.getBody()));
+ }
+
+ private void validateDataOperationRequest(final String topicParamInQuery,
+ final DataOperationRequest dataOperationRequest) {
+ TopicValidator.validateTopicName(topicParamInQuery);
+ dataOperationRequest.getDataOperationDefinitions().forEach(dataOperationDefinition -> {
+ if (OperationType.fromOperationName(dataOperationDefinition.getOperation()) != READ) {
+ throw new OperationNotSupportedException(
+ dataOperationDefinition.getOperation() + " operation not yet supported");
+ }
+ if (DatastoreType.fromDatastoreName(dataOperationDefinition.getDatastore()) == OPERATIONAL) {
+ throw new InvalidDatastoreException(dataOperationDefinition.getDatastore()
+ + " datastore is not supported");
+ }
+ if (dataOperationDefinition.getCmHandleIds().size() > MAXIMUM_CM_HANDLES_PER_OPERATION) {
+ final String errorMessage = String.format(PAYLOAD_TOO_LARGE_TEMPLATE,
+ dataOperationDefinition.getOperationId(),
+ dataOperationDefinition.getCmHandleIds().size());
+ throw new PayloadTooLargeException(errorMessage);
+ }
+ });
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NetworkCmProxyFacade.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NetworkCmProxyFacade.java
new file mode 100644
index 0000000000..5343a2e131
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NetworkCmProxyFacade.java
@@ -0,0 +1,129 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 highstreet technologies GmbH
+ * Modifications Copyright (C) 2021-2024 Nordix Foundation
+ * Modifications Copyright (C) 2021 Pantheon.tech
+ * Modifications Copyright (C) 2021-2022 Bell Canada
+ * Modifications Copyright (C) 2023 TechMahindra Ltd.
+ * ================================================================================
+ * 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.data;
+
+import static org.onap.cps.ncmp.api.data.models.DatastoreType.OPERATIONAL;
+
+import java.util.Collection;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.data.models.CmResourceAddress;
+import org.onap.cps.ncmp.api.data.models.DataOperationRequest;
+import org.onap.cps.ncmp.api.data.models.DatastoreType;
+import org.onap.cps.ncmp.api.data.models.OperationType;
+import org.onap.cps.ncmp.impl.utils.AlternateIdMatcher;
+import org.onap.cps.spi.model.DataNode;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class NetworkCmProxyFacade {
+
+ private final NcmpCachedResourceRequestHandler ncmpCachedResourceRequestHandler;
+ private final NcmpPassthroughResourceRequestHandler ncmpPassthroughResourceRequestHandler;
+ private final DmiDataOperations dmiDataOperations;
+ private final AlternateIdMatcher alternateIdMatcher;
+
+ /**
+ * Fetches resource data for a given data store using DMI (Data Management Interface).
+ * This method retrieves data based on the provided CmResourceAddress and additional query parameters.
+ * It supports asynchronous processing and handles authorization if required.
+ *
+ * @param cmResourceAddress The target data store, including the CM handle and resource identifier.
+ * This parameter must not be null.
+ * @param optionsParamInQuery Additional query parameters that may influence the data retrieval process,
+ * such as filters or limits. This parameter can be null.
+ * @param topicParamInQuery The topic name for triggering asynchronous responses. If specified,
+ * the response will be sent to this topic. This parameter can be null.
+ * @param includeDescendants include (all) descendants or not
+ * @param authorization The contents of the Authorization header. This parameter can be null
+ * if authorization is not required.
+ * @return the result object, depends on use op topic. With topic a map object with request id is returned
+ * otherwise the result of the request.
+ */
+ public Object getResourceDataForCmHandle(final CmResourceAddress cmResourceAddress,
+ final String optionsParamInQuery,
+ final String topicParamInQuery,
+ final Boolean includeDescendants,
+ final String authorization) {
+
+ final NcmpDatastoreRequestHandler ncmpDatastoreRequestHandler
+ = getNcmpDatastoreRequestHandler(cmResourceAddress.getDatastoreName());
+ return ncmpDatastoreRequestHandler.executeRequest(cmResourceAddress, optionsParamInQuery,
+ topicParamInQuery, includeDescendants, authorization);
+ }
+
+ /**
+ * Executes asynchronous request for group of cm handles to resource data.
+ *
+ * @param topic the topic param in query
+ * @param dataOperationRequest data operation request details for resource data
+ * @param authorization contents of Authorization header, or null if not present
+ * @return a map with one entry of request Id for success or status and error when async feature is disabled
+ */
+ public Object executeDataOperationForCmHandles(final String topic,
+ final DataOperationRequest dataOperationRequest,
+ final String authorization) {
+ return ncmpPassthroughResourceRequestHandler.executeAsynchronousRequest(topic,
+ dataOperationRequest,
+ authorization);
+ }
+
+ public Collection<DataNode> queryResourceDataForCmHandle(final String cmHandle,
+ final String cpsPath,
+ final Boolean includeDescendants) {
+ return ncmpCachedResourceRequestHandler.executeRequest(cmHandle, cpsPath, includeDescendants);
+ }
+
+ /**
+ * Write resource data for data store pass-through running using dmi for given cm-handle.
+ *
+ * @param cmHandleReference cm handle or alternate identifier
+ * @param resourceIdentifier resource identifier
+ * @param operationType required operation type
+ * @param requestData request body to create resource
+ * @param dataType content type in body
+ * @param authorization contents of Authorization header, or null if not present
+ * @return {@code Object} return data
+ */
+ public Object writeResourceDataPassThroughRunningForCmHandle(final String cmHandleReference,
+ final String resourceIdentifier,
+ final OperationType operationType,
+ final String requestData,
+ final String dataType,
+ final String authorization) {
+ return dmiDataOperations.writeResourceDataPassThroughRunningFromDmi(cmHandleReference, resourceIdentifier,
+ operationType, requestData, dataType, authorization);
+ }
+
+ private NcmpDatastoreRequestHandler getNcmpDatastoreRequestHandler(final String datastoreName) {
+ if (OPERATIONAL.equals(DatastoreType.fromDatastoreName(datastoreName))) {
+ return ncmpCachedResourceRequestHandler;
+ }
+ return ncmpPassthroughResourceRequestHandler;
+ }
+
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NetworkCmProxyQueryService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NetworkCmProxyQueryService.java
new file mode 100644
index 0000000000..39abdc56a0
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NetworkCmProxyQueryService.java
@@ -0,0 +1,50 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022-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.data;
+
+import java.util.Collection;
+import org.onap.cps.spi.FetchDescendantsOption;
+import org.onap.cps.spi.model.DataNode;
+
+/*
+ * Datastore interface for handling cached CPS data query requests.
+ */
+public interface NetworkCmProxyQueryService {
+
+ /**
+ * Fetches operational resource data based on the provided CM handle identifier and CPS path.
+ * This method retrieves data nodes from the specified path within the context of a given CM handle.
+ * It supports options for fetching descendant nodes.
+ *
+ * @param cmHandleId The CM handle identifier, which uniquely identifies the CM handle.
+ * This parameter must not be null.
+ * @param cpsPath The CPS (Control Plane Service) path specifying the location of the
+ * resource data within the CM handle. This parameter must not be null.
+ * @param fetchDescendantsOption The option specifying whether to fetch descendant nodes along with the specified
+ * resource data.
+ * @return {@code Collection<DataNode>} A collection of DataNode objects representing the resource data
+ * retrieved from the specified path. The collection may include descendant nodes based on the
+ * fetchDescendantsOption.
+ */
+ Collection<DataNode> queryResourceDataOperational(String cmHandleId,
+ String cpsPath,
+ FetchDescendantsOption fetchDescendantsOption);
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyQueryServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NetworkCmProxyQueryServiceImpl.java
index d8353f3029..021924a616 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyQueryServiceImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NetworkCmProxyQueryServiceImpl.java
@@ -18,15 +18,16 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl;
+package org.onap.cps.ncmp.impl.data;
-import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME;
+import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME;
+import java.util.Collection;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.api.CpsQueryService;
-import org.onap.cps.ncmp.api.NetworkCmProxyQueryService;
import org.onap.cps.spi.FetchDescendantsOption;
+import org.onap.cps.spi.model.DataNode;
import org.springframework.stereotype.Service;
@Slf4j
@@ -37,9 +38,9 @@ public class NetworkCmProxyQueryServiceImpl implements NetworkCmProxyQueryServic
private final CpsQueryService cpsQueryService;
@Override
- public Object queryResourceDataOperational(final String cmHandleId,
- final String cpsPath,
- final FetchDescendantsOption fetchDescendantsOption) {
+ public Collection<DataNode> queryResourceDataOperational(final String cmHandleId,
+ final String cpsPath,
+ final FetchDescendantsOption fetchDescendantsOption) {
return cpsQueryService.queryDataNodes(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId, cpsPath,
fetchDescendantsOption);
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/AsyncRestRequestResponseEventConsumer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/async/AsyncRestRequestResponseEventConsumer.java
index 993e3d63db..f14bb15842 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/AsyncRestRequestResponseEventConsumer.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/async/AsyncRestRequestResponseEventConsumer.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.async;
+package org.onap.cps.ncmp.impl.data.async;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/DataOperationEventConsumer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/async/DataOperationEventConsumer.java
index 9bb7fae4d9..6f368da2d0 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/DataOperationEventConsumer.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/async/DataOperationEventConsumer.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.async;
+package org.onap.cps.ncmp.impl.data.async;
import io.cloudevents.CloudEvent;
import io.cloudevents.kafka.impl.KafkaHeaders;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventMapper.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/async/NcmpAsyncRequestResponseEventMapper.java
index 46a11b82a0..21d40339b2 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventMapper.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/async/NcmpAsyncRequestResponseEventMapper.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.async;
+package org.onap.cps.ncmp.impl.data.async;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/RecordFilterStrategies.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/async/RecordFilterStrategies.java
index 0404790408..2615672374 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/RecordFilterStrategies.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/async/RecordFilterStrategies.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.async;
+package org.onap.cps.ncmp.impl.data.async;
import io.cloudevents.CloudEvent;
import io.cloudevents.kafka.impl.KafkaHeaders;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperation.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/models/DmiDataOperation.java
index 7baac34b1f..649d3ad374 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperation.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/models/DmiDataOperation.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.operations;
+package org.onap.cps.ncmp.impl.data.models;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@@ -26,7 +26,9 @@ import java.util.ArrayList;
import java.util.List;
import lombok.Builder;
import lombok.Getter;
-import org.onap.cps.ncmp.api.models.DataOperationDefinition;
+import org.onap.cps.ncmp.api.data.models.DataOperationDefinition;
+import org.onap.cps.ncmp.api.data.models.DatastoreType;
+import org.onap.cps.ncmp.api.data.models.OperationType;
@JsonInclude(JsonInclude.Include.NON_NULL)
@Getter
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationRequest.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/models/DmiDataOperationRequest.java
index 8ee1d905bf..f342f04a1a 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationRequest.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/models/DmiDataOperationRequest.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.operations;
+package org.onap.cps.ncmp.impl.data.models;
import com.fasterxml.jackson.annotation.JsonInclude;
import java.util.List;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperationCmHandle.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/models/DmiOperationCmHandle.java
index 1bf2b77dcc..6926b6890e 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperationCmHandle.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/models/DmiOperationCmHandle.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.operations;
+package org.onap.cps.ncmp.impl.data.models;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/policyexecutor/PolicyExecutor.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/policyexecutor/PolicyExecutor.java
new file mode 100644
index 0000000000..96771e30f1
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/policyexecutor/PolicyExecutor.java
@@ -0,0 +1,185 @@
+/*
+ * ============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.data.policyexecutor;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.data.models.OperationType;
+import org.onap.cps.ncmp.api.exceptions.NcmpException;
+import org.onap.cps.ncmp.api.exceptions.PolicyExecutorException;
+import org.onap.cps.ncmp.api.exceptions.ServerNcmpException;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
+import org.onap.cps.ncmp.impl.utils.http.RestServiceUrlTemplateBuilder;
+import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.web.reactive.function.BodyInserters;
+import org.springframework.web.reactive.function.client.WebClient;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class PolicyExecutor {
+
+ @Value("${ncmp.policy-executor.enabled:false}")
+ private boolean enabled;
+
+ @Value("${ncmp.policy-executor.server.address:http://policy-executor}")
+ private String serverAddress;
+
+ @Value("${ncmp.policy-executor.server.port:8080}")
+ private String serverPort;
+
+ @Qualifier("policyExecutorWebClient")
+ private final WebClient policyExecutorWebClient;
+
+ private final ObjectMapper objectMapper;
+
+ /**
+ * Use the Policy Executor to check permission for a cm write operation.
+ * Wil throw an exception when the operation is not permitted (work in progress)
+ *
+ * @param yangModelCmHandle the cm handle involved
+ * @param operationType the write operation
+ * @param authorization the original rest authorization token (can be used to determine the client)
+ * @param resourceIdentifier the resource identifier (can be blank)
+ * @param changeRequestAsJson the change details from the original rest request in json format
+ */
+ public void checkPermission(final YangModelCmHandle yangModelCmHandle,
+ final OperationType operationType,
+ final String authorization,
+ final String resourceIdentifier,
+ final String changeRequestAsJson) {
+ log.trace("Policy Executor Enabled: {}", enabled);
+ if (enabled) {
+ final ResponseEntity<JsonNode> responseEntity =
+ getPolicyExecutorResponse(yangModelCmHandle, operationType, authorization, resourceIdentifier,
+ changeRequestAsJson);
+
+ if (responseEntity == null) {
+ log.warn("No valid response from policy, ignored");
+ return;
+ }
+
+ if (responseEntity.getStatusCode().is2xxSuccessful()) {
+ if (responseEntity.getBody() == null) {
+ log.warn("No valid response body from policy, ignored");
+ return;
+ }
+ processResponse(responseEntity.getBody());
+ } else {
+ log.warn("Policy Executor invocation failed with status {}",
+ responseEntity.getStatusCode().value());
+ throw new ServerNcmpException("Policy Executor invocation failed", "HTTP status code: "
+ + responseEntity.getStatusCode().value());
+ }
+ }
+ }
+
+ private Map<String, Object> getSingleRequestAsMap(final YangModelCmHandle yangModelCmHandle,
+ final OperationType operationType,
+ final String resourceIdentifier,
+ final String changeRequestAsJson) {
+ final Map<String, Object> data = new HashMap<>(4);
+ data.put("cmHandleId", yangModelCmHandle.getId());
+ data.put("resourceIdentifier", resourceIdentifier);
+ data.put("targetIdentifier", yangModelCmHandle.getAlternateId());
+ if (!OperationType.DELETE.equals(operationType)) {
+ try {
+ final Object changeRequestAsObject = objectMapper.readValue(changeRequestAsJson, Object.class);
+ data.put("cmChangeRequest", changeRequestAsObject);
+ } catch (final JsonProcessingException e) {
+ throw new NcmpException("Cannot convert Change Request data to Object",
+ "Invalid Json: " + changeRequestAsJson);
+ }
+ }
+ final Map<String, Object> request = new HashMap<>(2);
+ request.put("schema", getAssociatedPolicyDataSchemaName(operationType));
+ request.put("data", data);
+ return request;
+ }
+
+ private static String getAssociatedPolicyDataSchemaName(final OperationType operationType) {
+ return "urn:cps:org.onap.cps.ncmp.policy-executor.ncmp-" + operationType.getOperationName() + "-schema:1.0.0";
+ }
+
+ private Object createBodyAsObject(final List<Object> requests) {
+ final Map<String, Object> bodyAsMap = new HashMap<>(2);
+ bodyAsMap.put("decisionType", "allow");
+ bodyAsMap.put("requests", requests);
+ return bodyAsMap;
+ }
+
+ private ResponseEntity<JsonNode> getPolicyExecutorResponse(final YangModelCmHandle yangModelCmHandle,
+ final OperationType operationType,
+ final String authorization,
+ final String resourceIdentifier,
+ final String changeRequestAsJson) {
+
+
+ final Map<String, Object> requestAsMap = getSingleRequestAsMap(yangModelCmHandle,
+ operationType,
+ resourceIdentifier,
+ changeRequestAsJson);
+
+ final Object bodyAsObject = createBodyAsObject(Collections.singletonList(requestAsMap));
+
+ final UrlTemplateParameters urlTemplateParameters = RestServiceUrlTemplateBuilder.newInstance()
+ .fixedPathSegment("execute")
+ .createUrlTemplateParameters(String.format("%s:%s", serverAddress, serverPort),
+ "policy-executor/api");
+
+ return policyExecutorWebClient.post()
+ .uri(urlTemplateParameters.urlTemplate(), urlTemplateParameters.urlVariables())
+ .header(HttpHeaders.AUTHORIZATION, authorization)
+ .body(BodyInserters.fromValue(bodyAsObject))
+ .retrieve()
+ .toEntity(JsonNode.class)
+ .block();
+ }
+
+ private static void processResponse(final JsonNode responseBody) {
+ final String decisionId = responseBody.path("decisionId").asText("unknown id");
+ log.trace("Policy Executor Decision ID: {} ", decisionId);
+ final String decision = responseBody.path("decision").asText("unknown");
+ if ("allow".equals(decision)) {
+ log.trace("Policy Executor allows the operation");
+ } else {
+ log.warn("Policy Executor decision: {}", decision);
+ final String details = responseBody.path("message").asText();
+ log.warn("Policy Executor message: {}", details);
+ final String message = "Policy Executor did not allow request. Decision #"
+ + decisionId + " : " + decision;
+ throw new PolicyExecutorException(message, details);
+ }
+ }
+
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/data/operation/DataOperationEventCreator.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/utils/DataOperationEventCreator.java
index 42bad89f52..d74abb9935 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/data/operation/DataOperationEventCreator.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/utils/DataOperationEventCreator.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.utils.data.operation;
+package org.onap.cps.ncmp.impl.data.utils;
import io.cloudevents.CloudEvent;
import java.util.ArrayList;
@@ -29,11 +29,11 @@ import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.ncmp.api.NcmpResponseStatus;
-import org.onap.cps.ncmp.api.impl.events.NcmpEvent;
-import org.onap.cps.ncmp.api.impl.operations.DmiDataOperation;
import org.onap.cps.ncmp.events.async1_0_0.Data;
import org.onap.cps.ncmp.events.async1_0_0.DataOperationEvent;
import org.onap.cps.ncmp.events.async1_0_0.Response;
+import org.onap.cps.ncmp.impl.data.models.DmiDataOperation;
+import org.onap.cps.ncmp.utils.events.NcmpEvent;
import org.springframework.util.MultiValueMap;
@Slf4j
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/data/operation/ResourceDataOperationRequestUtils.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/utils/DmiDataOperationsHelper.java
index dc4108cac0..3104be5539 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/data/operation/ResourceDataOperationRequestUtils.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/utils/DmiDataOperationsHelper.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.utils.data.operation;
+package org.onap.cps.ncmp.impl.data.utils;
import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLES_NOT_FOUND;
import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLES_NOT_READY;
@@ -31,27 +31,26 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.events.EventsPublisher;
import org.onap.cps.ncmp.api.NcmpResponseStatus;
-import org.onap.cps.ncmp.api.impl.inventory.CmHandleState;
-import org.onap.cps.ncmp.api.impl.operations.DmiDataOperation;
-import org.onap.cps.ncmp.api.impl.operations.DmiOperationCmHandle;
-import org.onap.cps.ncmp.api.impl.utils.DmiServiceNameOrganizer;
-import org.onap.cps.ncmp.api.impl.utils.context.CpsApplicationContext;
-import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
-import org.onap.cps.ncmp.api.models.DataOperationDefinition;
-import org.onap.cps.ncmp.api.models.DataOperationRequest;
+import org.onap.cps.ncmp.api.data.models.DataOperationDefinition;
+import org.onap.cps.ncmp.api.data.models.DataOperationRequest;
+import org.onap.cps.ncmp.config.CpsApplicationContext;
+import org.onap.cps.ncmp.impl.data.models.DmiDataOperation;
+import org.onap.cps.ncmp.impl.data.models.DmiOperationCmHandle;
+import org.onap.cps.ncmp.impl.dmi.DmiServiceNameOrganizer;
+import org.onap.cps.ncmp.impl.inventory.models.CmHandleState;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
-@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class ResourceDataOperationRequestUtils {
+@Slf4j
+public class DmiDataOperationsHelper {
private static final String UNKNOWN_SERVICE_NAME = null;
@@ -126,58 +125,6 @@ public class ResourceDataOperationRequestUtils {
}
/**
- * Handles the async task completion for an entire data, publishing errors to client topic on task failure.
- *
- * @param topicParamInQuery client given topic
- * @param requestId unique identifier per request
- * @param dataOperationRequest incoming data operation request details
- * @param throwable error cause, or null if task completed with no exception
- */
- public static void handleAsyncTaskCompletionForDataOperationsRequest(
- final String topicParamInQuery,
- final String requestId,
- final DataOperationRequest dataOperationRequest,
- final Throwable throwable) {
- if (throwable == null) {
- log.info("Data operations request {} completed.", requestId);
- } else if (throwable instanceof TimeoutException) {
- log.error("Data operations request {} timed out.", requestId);
- ResourceDataOperationRequestUtils.publishErrorMessageToClientTopicForEntireOperation(topicParamInQuery,
- requestId, dataOperationRequest, NcmpResponseStatus.DMI_SERVICE_NOT_RESPONDING);
- } else {
- log.error("Data operations request {} failed.", requestId, throwable);
- ResourceDataOperationRequestUtils.publishErrorMessageToClientTopicForEntireOperation(topicParamInQuery,
- requestId, dataOperationRequest, NcmpResponseStatus.UNKNOWN_ERROR);
- }
- }
-
- /**
- * Creates data operation cloud event for when the entire data operation fails and publishes it to client topic.
- *
- * @param topicParamInQuery client given topic
- * @param requestId unique identifier per request
- * @param dataOperationRequestIn incoming data operation request details
- * @param ncmpResponseStatus response code to be sent for all cm handle ids in all operations
- */
- private static void publishErrorMessageToClientTopicForEntireOperation(
- final String topicParamInQuery,
- final String requestId,
- final DataOperationRequest dataOperationRequestIn,
- final NcmpResponseStatus ncmpResponseStatus) {
-
- final MultiValueMap<DmiDataOperation, Map<NcmpResponseStatus, List<String>>>
- cmHandleIdsPerResponseCodesPerOperation = new LinkedMultiValueMap<>();
-
- for (final DataOperationDefinition dataOperationDefinitionIn :
- dataOperationRequestIn.getDataOperationDefinitions()) {
- cmHandleIdsPerResponseCodesPerOperation.add(
- DmiDataOperation.buildDmiDataOperationRequestBodyWithoutCmHandles(dataOperationDefinitionIn),
- Map.of(ncmpResponseStatus, dataOperationDefinitionIn.getCmHandleIds()));
- }
- publishErrorMessageToClientTopic(topicParamInQuery, requestId, cmHandleIdsPerResponseCodesPerOperation);
- }
-
- /**
* Creates data operation cloud event and publish it to client topic.
*
* @param clientTopic client given topic
@@ -193,6 +140,8 @@ public class ResourceDataOperationRequestUtils {
final CloudEvent dataOperationCloudEvent = DataOperationEventCreator.createDataOperationEvent(clientTopic,
requestId, cmHandleIdsPerResponseCodesPerOperation);
final EventsPublisher<CloudEvent> eventsPublisher = CpsApplicationContext.getCpsBean(EventsPublisher.class);
+ log.warn("publishing error message to client topic: {} ,requestId: {}, data operation cloud event id: {}",
+ clientTopic, requestId, dataOperationCloudEvent.getId());
eventsPublisher.publishCloudEvent(clientTopic, requestId, dataOperationCloudEvent);
}
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DataJobResultServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DataJobResultServiceImpl.java
new file mode 100644
index 0000000000..8934c088a1
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DataJobResultServiceImpl.java
@@ -0,0 +1,55 @@
+/*
+ * ============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.datajobs;
+
+import lombok.RequiredArgsConstructor;
+import org.onap.cps.ncmp.api.datajobs.DataJobResultService;
+import org.onap.cps.ncmp.impl.dmi.DmiProperties;
+import org.onap.cps.ncmp.impl.dmi.DmiRestClient;
+import org.onap.cps.ncmp.impl.utils.http.RestServiceUrlTemplateBuilder;
+import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class DataJobResultServiceImpl implements DataJobResultService {
+
+ private final DmiRestClient dmiRestClient;
+ private final DmiProperties dmiProperties;
+
+ @Override
+ public String getDataJobResult(final String authorization,
+ final String dmiServiceName,
+ final String dataProducerId,
+ final String dataProducerJobId,
+ final String destination) {
+ final UrlTemplateParameters urlTemplateParameters = RestServiceUrlTemplateBuilder.newInstance()
+ .fixedPathSegment("cmwriteJob")
+ .fixedPathSegment("dataProducer")
+ .variablePathSegment("dataProducerId", dataProducerId)
+ .fixedPathSegment("dataProducerJob")
+ .variablePathSegment("dataProducerJobId", dataProducerJobId)
+ .fixedPathSegment("result")
+ .queryParameter("destination", destination)
+ .createUrlTemplateParameters(dmiServiceName, dmiProperties.getDmiBasePath());
+ return dmiRestClient.getDataJobResult(urlTemplateParameters, authorization).block();
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DataJobServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DataJobServiceImpl.java
new file mode 100644
index 0000000000..04c3ad2fc6
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DataJobServiceImpl.java
@@ -0,0 +1,67 @@
+/*
+ * ============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.datajobs;
+
+import java.util.List;
+import java.util.Map;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.datajobs.DataJobService;
+import org.onap.cps.ncmp.api.datajobs.models.DataJobMetadata;
+import org.onap.cps.ncmp.api.datajobs.models.DataJobReadRequest;
+import org.onap.cps.ncmp.api.datajobs.models.DataJobWriteRequest;
+import org.onap.cps.ncmp.api.datajobs.models.DmiWriteOperation;
+import org.onap.cps.ncmp.api.datajobs.models.ProducerKey;
+import org.onap.cps.ncmp.api.datajobs.models.SubJobWriteResponse;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class DataJobServiceImpl implements DataJobService {
+
+ private final DmiSubJobRequestHandler dmiSubJobClient;
+ private final WriteRequestExaminer writeRequestExaminer;
+
+ @Override
+ public void readDataJob(final String authorization,
+ final String dataJobId,
+ final DataJobMetadata dataJobMetadata,
+ final DataJobReadRequest dataJobReadRequest) {
+ log.info("data job id for read operation is: {}", dataJobId);
+ }
+
+ @Override
+ public List<SubJobWriteResponse> writeDataJob(final String authorization,
+ final String dataJobId,
+ final DataJobMetadata dataJobMetadata,
+ final DataJobWriteRequest dataJobWriteRequest) {
+ log.info("data job id for write operation is: {}", dataJobId);
+
+ final Map<ProducerKey, List<DmiWriteOperation>> dmiWriteOperationsPerProducerKey =
+ writeRequestExaminer.splitDmiWriteOperationsFromRequest(dataJobId, dataJobWriteRequest);
+
+ return dmiSubJobClient.sendRequestsToDmi(authorization,
+ dataJobId,
+ dataJobMetadata,
+ dmiWriteOperationsPerProducerKey);
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DataJobStatusServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DataJobStatusServiceImpl.java
new file mode 100644
index 0000000000..1cfb8a9dff
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DataJobStatusServiceImpl.java
@@ -0,0 +1,66 @@
+/*
+ * ============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.datajobs;
+
+import lombok.RequiredArgsConstructor;
+import org.onap.cps.ncmp.api.datajobs.DataJobStatusService;
+import org.onap.cps.ncmp.impl.dmi.DmiProperties;
+import org.onap.cps.ncmp.impl.dmi.DmiRestClient;
+import org.onap.cps.ncmp.impl.utils.http.RestServiceUrlTemplateBuilder;
+import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters;
+import org.springframework.stereotype.Service;
+
+/**
+ * Implementation of {@link DataJobStatusService} interface.
+ * The operations interact with a DMI Plugin to retrieve data job statuses.
+ */
+@Service
+@RequiredArgsConstructor
+public class DataJobStatusServiceImpl implements DataJobStatusService {
+
+ private final DmiRestClient dmiRestClient;
+ private final DmiProperties dmiProperties;
+
+ @Override
+ public String getDataJobStatus(final String authorization,
+ final String dmiServiceName,
+ final String dataProducerId,
+ final String dataProducerJobId) {
+
+ final UrlTemplateParameters urlTemplateParameters = buildUrlParameters(dmiServiceName,
+ dataProducerId,
+ dataProducerJobId);
+ return dmiRestClient.getDataJobStatus(urlTemplateParameters, authorization).block();
+ }
+
+ private UrlTemplateParameters buildUrlParameters(final String dmiServiceName,
+ final String dataProducerId,
+ final String dataProducerJobId) {
+ return RestServiceUrlTemplateBuilder.newInstance()
+ .fixedPathSegment("cmwriteJob")
+ .fixedPathSegment("dataProducer")
+ .variablePathSegment("dataProducerId", dataProducerId)
+ .fixedPathSegment("dataProducerJob")
+ .variablePathSegment("dataProducerJobId", dataProducerJobId)
+ .fixedPathSegment("status")
+ .createUrlTemplateParameters(dmiServiceName, dmiProperties.getDmiBasePath());
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DmiSubJobRequestHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DmiSubJobRequestHandler.java
new file mode 100644
index 0000000000..a118d53e7e
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DmiSubJobRequestHandler.java
@@ -0,0 +1,96 @@
+/*
+ * ============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.datajobs;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.data.models.OperationType;
+import org.onap.cps.ncmp.api.datajobs.models.DataJobMetadata;
+import org.onap.cps.ncmp.api.datajobs.models.DmiWriteOperation;
+import org.onap.cps.ncmp.api.datajobs.models.ProducerKey;
+import org.onap.cps.ncmp.api.datajobs.models.SubJobWriteRequest;
+import org.onap.cps.ncmp.api.datajobs.models.SubJobWriteResponse;
+import org.onap.cps.ncmp.impl.dmi.DmiProperties;
+import org.onap.cps.ncmp.impl.dmi.DmiRestClient;
+import org.onap.cps.ncmp.impl.models.RequiredDmiService;
+import org.onap.cps.ncmp.impl.utils.http.RestServiceUrlTemplateBuilder;
+import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters;
+import org.onap.cps.utils.JsonObjectMapper;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class DmiSubJobRequestHandler {
+
+ private final DmiRestClient dmiRestClient;
+ private final DmiProperties dmiProperties;
+ private final JsonObjectMapper jsonObjectMapper;
+
+ /**
+ * Sends sub-job write requests to the DMI Plugin.
+ *
+ * @param authorization the authorization header from the REST request
+ * @param dataJobId data job identifier
+ * @param dataJobMetadata the data job's metadata
+ * @param dmiWriteOperationsPerProducerKey a collection of write requests per producer key
+ * @return a list of sub-job write responses
+ */
+ public List<SubJobWriteResponse> sendRequestsToDmi(final String authorization,
+ final String dataJobId,
+ final DataJobMetadata dataJobMetadata,
+ final Map<ProducerKey, List<DmiWriteOperation>> dmiWriteOperationsPerProducerKey) {
+ final List<SubJobWriteResponse> subJobWriteResponses = new ArrayList<>(dmiWriteOperationsPerProducerKey.size());
+ dmiWriteOperationsPerProducerKey.forEach((producerKey, dmi3ggpWriteOperations) -> {
+ final SubJobWriteRequest subJobWriteRequest = new SubJobWriteRequest(dataJobMetadata.destination(),
+ dataJobMetadata.dataAcceptType(),
+ dataJobMetadata.dataContentType(),
+ producerKey.dataProducerIdentifier(),
+ dataJobId,
+ dmi3ggpWriteOperations);
+
+ final UrlTemplateParameters urlTemplateParameters = getUrlTemplateParameters(dataJobMetadata.destination(),
+ producerKey);
+ final ResponseEntity<Object> responseEntity = dmiRestClient.synchronousPostOperationWithJsonData(
+ RequiredDmiService.DATA,
+ urlTemplateParameters,
+ jsonObjectMapper.asJsonString(subJobWriteRequest),
+ OperationType.CREATE,
+ authorization);
+ final SubJobWriteResponse subJobWriteResponse = jsonObjectMapper
+ .convertToValueType(responseEntity.getBody(), SubJobWriteResponse.class);
+ log.debug("Sub job write response: {}", subJobWriteResponse);
+ subJobWriteResponses.add(subJobWriteResponse);
+ });
+ return subJobWriteResponses;
+ }
+
+ private UrlTemplateParameters getUrlTemplateParameters(final String destination, final ProducerKey producerKey) {
+ return RestServiceUrlTemplateBuilder.newInstance()
+ .fixedPathSegment("cmwriteJob")
+ .queryParameter("destination", destination)
+ .createUrlTemplateParameters(producerKey.dmiServiceName(), dmiProperties.getDmiBasePath());
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/WriteRequestExaminer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/WriteRequestExaminer.java
new file mode 100644
index 0000000000..70d08dccdc
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/WriteRequestExaminer.java
@@ -0,0 +1,109 @@
+/*
+ * ============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.datajobs;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.datajobs.models.DataJobWriteRequest;
+import org.onap.cps.ncmp.api.datajobs.models.DmiWriteOperation;
+import org.onap.cps.ncmp.api.datajobs.models.ProducerKey;
+import org.onap.cps.ncmp.api.datajobs.models.WriteOperation;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
+import org.onap.cps.ncmp.impl.utils.AlternateIdMatcher;
+import org.onap.cps.ncmp.impl.utils.YangDataConverter;
+import org.onap.cps.spi.model.DataNode;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class WriteRequestExaminer {
+
+ private final AlternateIdMatcher alternateIdMatcher;
+ private static final String PATH_SEPARATOR = "/";
+
+ /**
+ * Splitting incoming data job write request into Dmi Write Operations by ProducerKey.
+ *
+ * @param dataJobId data job identifier
+ * @param dataJobWriteRequest incoming data job write request
+ * @return {@code Map} map of Dmi Write Operations per Producer Key
+ */
+ public Map<ProducerKey, List<DmiWriteOperation>> splitDmiWriteOperationsFromRequest(
+ final String dataJobId,
+ final DataJobWriteRequest dataJobWriteRequest) {
+ final Map<ProducerKey, List<DmiWriteOperation>> dmiWriteOperationsPerProducerKey = new HashMap<>();
+ for (final WriteOperation writeOperation : dataJobWriteRequest.data()) {
+ examineWriteOperation(dataJobId, dmiWriteOperationsPerProducerKey, writeOperation);
+ }
+ return dmiWriteOperationsPerProducerKey;
+ }
+
+ private void examineWriteOperation(final String dataJobId,
+ final Map<ProducerKey, List<DmiWriteOperation>> dmiWriteOperationsPerProducerKey,
+ final WriteOperation writeOperation) {
+ log.debug("data job id for write operation is: {}", dataJobId);
+ final DataNode dataNode = alternateIdMatcher
+ .getCmHandleDataNodeByLongestMatchingAlternateId(writeOperation.path(), PATH_SEPARATOR);
+
+ final DmiWriteOperation dmiWriteOperation = createDmiWriteOperation(writeOperation, dataNode);
+
+ final ProducerKey producerKey = createProducerKey(dataNode);
+ final List<DmiWriteOperation> dmiWriteOperations;
+ if (dmiWriteOperationsPerProducerKey.containsKey(producerKey)) {
+ dmiWriteOperations = dmiWriteOperationsPerProducerKey.get(producerKey);
+ } else {
+ dmiWriteOperations = new ArrayList<>();
+ dmiWriteOperationsPerProducerKey.put(producerKey, dmiWriteOperations);
+ }
+ dmiWriteOperations.add(dmiWriteOperation);
+ }
+
+ private ProducerKey createProducerKey(final DataNode dataNode) {
+ return new ProducerKey((String) dataNode.getLeaves().get("dmi-service-name"),
+ (String) dataNode.getLeaves().get("data-producer-identifier"));
+ }
+
+ private DmiWriteOperation createDmiWriteOperation(final WriteOperation writeOperation,
+ final DataNode dataNode) {
+ return new DmiWriteOperation(
+ writeOperation.path(),
+ writeOperation.op(),
+ (String) dataNode.getLeaves().get("module-set-tag"),
+ writeOperation.value(),
+ writeOperation.operationId(),
+ getPrivatePropertiesFromDataNode(dataNode));
+ }
+
+ private Map<String, String> getPrivatePropertiesFromDataNode(final DataNode dataNode) {
+ final YangModelCmHandle yangModelCmHandle = YangDataConverter.toYangModelCmHandle(dataNode);
+ final Map<String, String> cmHandleDmiProperties = new LinkedHashMap<>();
+ yangModelCmHandle.getDmiProperties()
+ .forEach(dmiProperty -> cmHandleDmiProperties.put(dmiProperty.getName(), dmiProperty.getValue()));
+ return cmHandleDmiProperties;
+ }
+
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiProperties.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiProperties.java
new file mode 100644
index 0000000000..2f60460da3
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiProperties.java
@@ -0,0 +1,55 @@
+/*
+ * ============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.dmi;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Getter
+@Component
+public class DmiProperties {
+ @Value("${ncmp.dmi.auth.username}")
+ private String authUsername;
+ @Value("${ncmp.dmi.auth.password}")
+ private String authPassword;
+ @Getter(AccessLevel.NONE)
+ @Value("${ncmp.dmi.api.base-path}")
+ private String dmiBasePath;
+ @Value("${ncmp.dmi.auth.enabled}")
+ private boolean dmiBasicAuthEnabled;
+
+ /**
+ * Removes both leading and trailing slashes if they are present.
+ *
+ * @return dmi base path without any slashes ("/")
+ */
+ public String getDmiBasePath() {
+ if (dmiBasePath.startsWith("/")) {
+ dmiBasePath = dmiBasePath.substring(1);
+ }
+ if (dmiBasePath.endsWith("/")) {
+ dmiBasePath = dmiBasePath.substring(0, dmiBasePath.length() - 1);
+ }
+ return dmiBasePath;
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiRestClient.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiRestClient.java
new file mode 100644
index 0000000000..a177272dff
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiRestClient.java
@@ -0,0 +1,225 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021-2024 Nordix Foundation
+ * Modifications Copyright (C) 2022 Bell Canada
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.dmi;
+
+import static org.onap.cps.ncmp.api.NcmpResponseStatus.DMI_SERVICE_NOT_RESPONDING;
+import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNABLE_TO_READ_RESOURCE_DATA;
+import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNKNOWN_ERROR;
+import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
+import static org.springframework.http.HttpStatus.REQUEST_TIMEOUT;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import java.util.Locale;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.data.models.OperationType;
+import org.onap.cps.ncmp.api.exceptions.DmiClientRequestException;
+import org.onap.cps.ncmp.impl.models.RequiredDmiService;
+import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters;
+import org.onap.cps.utils.JsonObjectMapper;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.HttpServerErrorException;
+import org.springframework.web.reactive.function.BodyInserters;
+import org.springframework.web.reactive.function.client.WebClient;
+import org.springframework.web.reactive.function.client.WebClientRequestException;
+import org.springframework.web.reactive.function.client.WebClientResponseException;
+import reactor.core.publisher.Mono;
+
+@Component
+@RequiredArgsConstructor
+@Slf4j
+public class DmiRestClient {
+
+ private static final String NOT_SPECIFIED = "";
+ private static final String NO_AUTHORIZATION = null;
+
+ private final DmiProperties dmiProperties;
+ private final JsonObjectMapper jsonObjectMapper;
+ @Qualifier("dataServicesWebClient")
+ private final WebClient dataServicesWebClient;
+ @Qualifier("modelServicesWebClient")
+ private final WebClient modelServicesWebClient;
+ @Qualifier("healthChecksWebClient")
+ private final WebClient healthChecksWebClient;
+
+ /**
+ * Sends a synchronous (blocking) POST operation to the DMI with a JSON body containing module references.
+ *
+ * @param requiredDmiService Determines if the required service is for a data or model operation.
+ * @param urlTemplateParameters The DMI resource URL template with variables.
+ * @param requestBodyAsJsonString JSON data body.
+ * @param operationType The type of operation being executed (for error reporting only).
+ * @param authorization Contents of the Authorization header, or null if not present.
+ * @return ResponseEntity containing the response from the DMI.
+ * @throws DmiClientRequestException If there is an error during the DMI request.
+ */
+ public ResponseEntity<Object> synchronousPostOperationWithJsonData(final RequiredDmiService requiredDmiService,
+ final UrlTemplateParameters
+ urlTemplateParameters,
+ final String requestBodyAsJsonString,
+ final OperationType operationType,
+ final String authorization) {
+ final Mono<ResponseEntity<Object>> responseEntityMono =
+ asynchronousPostOperationWithJsonData(requiredDmiService,
+ urlTemplateParameters,
+ requestBodyAsJsonString,
+ operationType,
+ authorization);
+ return responseEntityMono.block();
+ }
+
+ /**
+ * Asynchronously performs an HTTP POST operation with the given JSON data.
+ *
+ * @param requiredDmiService The service object required for retrieving or configuring the WebClient.
+ * @param urlTemplateParameters The URL template with variables for the POST request.
+ * @param requestBodyAsJsonString The JSON string that will be sent as the request body.
+ * @param operationType An enumeration or object that holds information about the type of operation
+ * being performed.
+ * @param authorization The authorization token to be added to the request headers.
+ * @return A Mono emitting the response entity containing the server's response.
+ */
+ public Mono<ResponseEntity<Object>> asynchronousPostOperationWithJsonData(final RequiredDmiService
+ requiredDmiService,
+ final UrlTemplateParameters
+ urlTemplateParameters,
+ final String requestBodyAsJsonString,
+ final OperationType operationType,
+ final String authorization) {
+ final WebClient webClient = getWebClient(requiredDmiService);
+ return webClient.post()
+ .uri(urlTemplateParameters.urlTemplate(), urlTemplateParameters.urlVariables())
+ .headers(httpHeaders -> configureHttpHeaders(httpHeaders, authorization))
+ .body(BodyInserters.fromValue(requestBodyAsJsonString))
+ .retrieve()
+ .toEntity(Object.class)
+ .onErrorMap(throwable -> handleDmiClientException(throwable, operationType.getOperationName()));
+ }
+
+ /**
+ * Retrieves the health status of the DMI plugin.
+ * This method performs an HTTP GET request to the DMI health check endpoint specified by the URL template
+ * parameters. If the response status code indicates a client error (4xx) or a server error (5xx), it logs a warning
+ * and returns an empty Mono. In case of an error during the request, it logs the exception and returns a default
+ * value of "NOT_SPECIFIED". If the response body contains a JSON node with a "status" field, the value of this
+ * field is returned.
+ *
+ * @param urlTemplateParameters the URL template parameters for the DMI health check endpoint
+ * @return a Mono emitting the health status as a String, or "NOT_SPECIFIED" if an error occurs
+ */
+ public Mono<String> getDmiHealthStatus(final UrlTemplateParameters urlTemplateParameters) {
+ return healthChecksWebClient.get()
+ .uri(urlTemplateParameters.urlTemplate(), urlTemplateParameters.urlVariables())
+ .headers(httpHeaders -> configureHttpHeaders(httpHeaders, NO_AUTHORIZATION))
+ .retrieve()
+ .bodyToMono(JsonNode.class)
+ .map(responseHealthStatus -> responseHealthStatus.path("status").asText())
+ .onErrorResume(Exception.class, ex -> {
+ log.warn("Failed to retrieve health status from {}. Status: {}",
+ urlTemplateParameters.urlTemplate(), ex.getMessage());
+ return Mono.empty();
+ })
+ .defaultIfEmpty(NOT_SPECIFIED);
+ }
+
+ /**
+ * Retrieves the status of a data job from the DMI service.
+ *
+ * @param urlTemplateParameters The URL template parameters for the DMI data job status endpoint.
+ * @param authorization The authorization token to be added to the request headers.
+ * @return A Mono emitting the status of the data job as a String.
+ * @throws DmiClientRequestException If there is an error during the DMI request.
+ */
+ public Mono<String> getDataJobStatus(final UrlTemplateParameters urlTemplateParameters,
+ final String authorization) {
+
+ return dataServicesWebClient.get()
+ .uri(urlTemplateParameters.urlTemplate(), urlTemplateParameters.urlVariables())
+ .headers(httpHeaders -> configureHttpHeaders(httpHeaders, authorization))
+ .retrieve()
+ .bodyToMono(JsonNode.class)
+ .map(jsonNode -> jsonNode.path("status").asText())
+ .onErrorMap(throwable -> handleDmiClientException(throwable, OperationType.READ.getOperationName()));
+ }
+
+ /**
+ * Retrieves the result of a data job from the DMI service.
+ *
+ * @param urlTemplateParameters The URL template parameters for the DMI data job status endpoint.
+ * @param authorization The authorization token to be added to the request headers.
+ * @return A Mono emitting the result of the data job as a String.
+ * @throws DmiClientRequestException If there is an error during the DMI request.
+ */
+ public Mono<String> getDataJobResult(final UrlTemplateParameters urlTemplateParameters,
+ final String authorization) {
+ return dataServicesWebClient.get()
+ .uri(urlTemplateParameters.urlTemplate(), urlTemplateParameters.urlVariables())
+ .headers(httpHeaders -> configureHttpHeaders(httpHeaders, authorization))
+ .retrieve().bodyToMono(String.class)
+ .onErrorMap(throwable -> handleDmiClientException(throwable,
+ OperationType.READ.getOperationName()));
+ }
+
+ private WebClient getWebClient(final RequiredDmiService requiredDmiService) {
+ return requiredDmiService.equals(RequiredDmiService.DATA) ? dataServicesWebClient : modelServicesWebClient;
+ }
+
+ private void configureHttpHeaders(final HttpHeaders httpHeaders, final String authorization) {
+ if (dmiProperties.isDmiBasicAuthEnabled()) {
+ httpHeaders.setBasicAuth(dmiProperties.getAuthUsername(), dmiProperties.getAuthPassword());
+ } else if (authorization != null && authorization.toLowerCase(Locale.getDefault()).startsWith("bearer ")) {
+ httpHeaders.add(HttpHeaders.AUTHORIZATION, authorization);
+ }
+ }
+
+ private DmiClientRequestException handleDmiClientException(final Throwable throwable, final String operationType) {
+ if (throwable instanceof WebClientResponseException webClientResponseException) {
+ if (webClientResponseException.getStatusCode().isSameCodeAs(REQUEST_TIMEOUT)) {
+ throw new DmiClientRequestException(webClientResponseException.getStatusCode().value(),
+ webClientResponseException.getMessage(),
+ jsonObjectMapper.asJsonString(webClientResponseException.getResponseBodyAsString()),
+ DMI_SERVICE_NOT_RESPONDING);
+ }
+ throw new DmiClientRequestException(webClientResponseException.getStatusCode().value(),
+ webClientResponseException.getMessage(),
+ jsonObjectMapper.asJsonString(webClientResponseException.getResponseBodyAsString()),
+ UNABLE_TO_READ_RESOURCE_DATA);
+
+ }
+ final String exceptionMessage = "Unable to " + operationType + " resource data.";
+ if (throwable instanceof WebClientRequestException webClientRequestException) {
+ throw new DmiClientRequestException(HttpStatus.SERVICE_UNAVAILABLE.value(),
+ webClientRequestException.getMessage(),
+ exceptionMessage, DMI_SERVICE_NOT_RESPONDING);
+ }
+ if (throwable instanceof HttpServerErrorException httpServerErrorException) {
+ throw new DmiClientRequestException(httpServerErrorException.getStatusCode().value(), exceptionMessage,
+ httpServerErrorException.getResponseBodyAsString(), DMI_SERVICE_NOT_RESPONDING);
+ }
+ throw new DmiClientRequestException(INTERNAL_SERVER_ERROR.value(), exceptionMessage, throwable.getMessage(),
+ UNKNOWN_ERROR);
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceNameOrganizer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiServiceNameOrganizer.java
index 26e94866a1..37e982d8cb 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceNameOrganizer.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiServiceNameOrganizer.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.utils;
+package org.onap.cps.ncmp.impl.dmi;
import java.util.Collection;
import java.util.HashMap;
@@ -27,8 +27,8 @@ import java.util.Map;
import java.util.stream.Collectors;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
-import org.onap.cps.ncmp.api.impl.operations.RequiredDmiService;
-import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
+import org.onap.cps.ncmp.impl.models.RequiredDmiService;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class DmiServiceNameOrganizer {
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiWebClientsConfiguration.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiWebClientsConfiguration.java
new file mode 100644
index 0000000000..4134a56ead
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiWebClientsConfiguration.java
@@ -0,0 +1,68 @@
+/*
+ * ============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.dmi;
+
+import lombok.RequiredArgsConstructor;
+import org.onap.cps.ncmp.config.DmiHttpClientConfig;
+import org.onap.cps.ncmp.impl.utils.http.WebClientConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.reactive.function.client.WebClient;
+
+@Configuration
+@RequiredArgsConstructor
+public class DmiWebClientsConfiguration extends WebClientConfiguration {
+
+ private final DmiHttpClientConfig dmiHttpClientConfig;
+
+ /**
+ * Configures and creates a web client bean for DMI data services.
+ *
+ * @param webClientBuilder The builder instance to create the WebClient.
+ * @return a WebClient instance configured for data services.
+ */
+ @Bean
+ public WebClient dataServicesWebClient(final WebClient.Builder webClientBuilder) {
+ return configureWebClient(webClientBuilder, dmiHttpClientConfig.getDataServices());
+ }
+
+ /**
+ * Configures and creates a web client bean for DMI model services.
+ *
+ * @param webClientBuilder The builder instance to create the WebClient.
+ * @return a WebClient instance configured for model services.
+ */
+ @Bean
+ public WebClient modelServicesWebClient(final WebClient.Builder webClientBuilder) {
+ return configureWebClient(webClientBuilder, dmiHttpClientConfig.getModelServices());
+ }
+
+ /**
+ * Configures and creates a web client bean for DMI health check services.
+ *
+ * @param webClientBuilder The builder instance to create the WebClient.
+ * @return a WebClient instance configured for health check services.
+ */
+ @Bean
+ public WebClient healthChecksWebClient(final WebClient.Builder webClientBuilder) {
+ return configureWebClient(webClientBuilder, dmiHttpClientConfig.getHealthCheckServices());
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/AlternateIdChecker.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/AlternateIdChecker.java
new file mode 100644
index 0000000000..3600d6da32
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/AlternateIdChecker.java
@@ -0,0 +1,115 @@
+/*
+ * ============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.inventory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Set;
+import java.util.stream.Collectors;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle;
+import org.onap.cps.spi.exceptions.DataNodeNotFoundException;
+import org.springframework.stereotype.Service;
+
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public class AlternateIdChecker {
+
+ public enum Operation {
+ CREATE, UPDATE
+ }
+
+ private final InventoryPersistence inventoryPersistence;
+
+ private static final String NO_CURRENT_ALTERNATE_ID = "";
+
+ /**
+ * Check all alternate ids of a batch of cm handles.
+ * Includes cross-checks in the batch itself for duplicates. Only the first entry encountered wil be accepted.
+ *
+ * @param newNcmpServiceCmHandles the proposed new cm handles
+ * @param operation type of operation being executed
+ * @return collection of cm handles ids which are acceptable
+ */
+ public Collection<String> getIdsOfCmHandlesWithRejectedAlternateId(
+ final Collection<NcmpServiceCmHandle> newNcmpServiceCmHandles,
+ final Operation operation) {
+ final Set<String> assignedAlternateIds = getAlternateIdsAlreadyInDb(newNcmpServiceCmHandles);
+ final Collection<String> rejectedCmHandleIds = new ArrayList<>();
+ for (final NcmpServiceCmHandle ncmpServiceCmHandle : newNcmpServiceCmHandles) {
+ final String cmHandleId = ncmpServiceCmHandle.getCmHandleId();
+ final String proposedAlternateId = ncmpServiceCmHandle.getAlternateId();
+ if (isProposedAlternateIdAcceptable(proposedAlternateId, operation, assignedAlternateIds, cmHandleId)) {
+ assignedAlternateIds.add(proposedAlternateId);
+ } else {
+ rejectedCmHandleIds.add(cmHandleId);
+ }
+ }
+ return rejectedCmHandleIds;
+ }
+
+ private boolean isProposedAlternateIdAcceptable(final String proposedAlternateId, final Operation operation,
+ final Set<String> assignedAlternateIds, final String cmHandleId) {
+ if (StringUtils.isBlank(proposedAlternateId)) {
+ return true;
+ }
+ final String currentAlternateId = getCurrentAlternateId(operation, cmHandleId);
+ if (currentAlternateId.equals(proposedAlternateId)) {
+ return true;
+ }
+ if (StringUtils.isNotBlank(currentAlternateId)) {
+ log.warn("Alternate id update ignored, cannot update cm handle {}, already has an alternate id of {}",
+ cmHandleId, currentAlternateId);
+ return false;
+ }
+ if (assignedAlternateIds.contains(proposedAlternateId)) {
+ log.warn("Alternate id update ignored, cannot update cm handle {}, alternate id is already "
+ + "assigned to a different cm handle", cmHandleId);
+ return false;
+ }
+ return true;
+ }
+
+ private Set<String> getAlternateIdsAlreadyInDb(final Collection<NcmpServiceCmHandle> ncmpServiceCmHandles) {
+ final Set<String> alternateIdsToCheck = ncmpServiceCmHandles.stream()
+ .map(NcmpServiceCmHandle::getAlternateId)
+ .filter(StringUtils::isNotBlank)
+ .collect(Collectors.toSet());
+ return inventoryPersistence.getCmHandleDataNodesByAlternateIds(alternateIdsToCheck).stream()
+ .map(dataNode -> (String) dataNode.getLeaves().get("alternate-id"))
+ .collect(Collectors.toSet());
+ }
+
+ private String getCurrentAlternateId(final Operation operation, final String cmHandleId) {
+ if (operation == Operation.UPDATE) {
+ try {
+ return inventoryPersistence.getYangModelCmHandle(cmHandleId).getAlternateId();
+ } catch (final DataNodeNotFoundException dataNodeNotFoundException) {
+ // work with blank current alternate id
+ }
+ }
+ return NO_CURRENT_ALTERNATE_ID;
+ }
+
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/RestQueryParametersValidator.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleQueryParametersValidator.java
index 2ef97cab5c..08954024b7 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/RestQueryParametersValidator.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleQueryParametersValidator.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.utils;
+package org.onap.cps.ncmp.impl.inventory;
import com.google.common.base.Strings;
import java.util.Collection;
@@ -26,12 +26,12 @@ import java.util.Map;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.onap.cps.ncmp.api.models.CmHandleQueryServiceParameters;
+import org.onap.cps.ncmp.api.inventory.models.CmHandleQueryServiceParameters;
import org.onap.cps.spi.exceptions.DataValidationException;
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class RestQueryParametersValidator {
+public class CmHandleQueryParametersValidator {
/**
* Validate query parameters.
@@ -55,7 +55,7 @@ public class RestQueryParametersValidator {
"Empty 'conditionsParameters' - please supply a valid condition parameter.");
}
cmHandleQueryParameter.getConditionParameters().forEach(
- RestQueryParametersValidator::validateConditionParameter
+ CmHandleQueryParametersValidator::validateConditionParameter
);
}
);
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CmHandleQueries.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleQueryService.java
index 81467dbb3e..95c3c77b71 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CmHandleQueries.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleQueryService.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2022-2023 Nordix Foundation
+ * Copyright (C) 2022-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.
@@ -18,26 +18,26 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.inventory;
+package org.onap.cps.ncmp.impl.inventory;
import java.util.Collection;
-import java.util.List;
import java.util.Map;
+import org.onap.cps.ncmp.impl.inventory.models.CmHandleState;
import org.onap.cps.spi.FetchDescendantsOption;
import org.onap.cps.spi.model.DataNode;
-public interface CmHandleQueries {
+public interface CmHandleQueryService {
/**
- * Query CmHandles based on additional (private) properties.
+ * Query Cm Handles based on additional (private) properties.
*
* @param additionalPropertyQueryPairs private properties for query
- * @return Ids of CmHandles which have these private properties
+ * @return Ids of Cm Handles which have these private properties
*/
Collection<String> queryCmHandleAdditionalProperties(Map<String, String> additionalPropertyQueryPairs);
/**
- * Query CmHandles based on public properties.
+ * Query Cm Handles based on public properties.
*
* @param publicPropertyQueryPairs public properties for query
* @return CmHandles which have these public properties
@@ -45,10 +45,10 @@ public interface CmHandleQueries {
Collection<String> queryCmHandlePublicProperties(Map<String, String> publicPropertyQueryPairs);
/**
- * Query CmHandles based on Trust Level.
+ * Query Cm Handles based on Trust Level.
*
* @param trustLevelPropertyQueryPairs trust level properties for query
- * @return CmHandles which have desired trust level
+ * @return Ids of Cm Handles which have desired trust level
*/
Collection<String> queryCmHandlesByTrustLevel(Map<String, String> trustLevelPropertyQueryPairs);
@@ -56,9 +56,9 @@ public interface CmHandleQueries {
* Method which returns cm handles by the cm handles state.
*
* @param cmHandleState cm handle state
- * @return a list of cm handles
+ * @return a list of data nodes representing the cm handles.
*/
- List<DataNode> queryCmHandlesByState(CmHandleState cmHandleState);
+ Collection<DataNode> queryCmHandlesByState(CmHandleState cmHandleState);
/**
* Method to return data nodes with ancestor representing the cm handles.
@@ -66,8 +66,7 @@ public interface CmHandleQueries {
* @param cpsPath cps path for which the cmHandle is requested
* @return a list of data nodes representing the cm handles.
*/
- List<DataNode> queryCmHandleAncestorsByCpsPath(String cpsPath,
- FetchDescendantsOption fetchDescendantsOption);
+ Collection<DataNode> queryCmHandleAncestorsByCpsPath(String cpsPath, FetchDescendantsOption fetchDescendantsOption);
/**
* Method to return data nodes representing the cm handles.
@@ -75,7 +74,7 @@ public interface CmHandleQueries {
* @param cpsPath cps path for which the cmHandle is requested
* @return a list of data nodes representing the cm handles.
*/
- List<DataNode> queryNcmpRegistryByCpsPath(String cpsPath, FetchDescendantsOption fetchDescendantsOption);
+ Collection<DataNode> queryNcmpRegistryByCpsPath(String cpsPath, FetchDescendantsOption fetchDescendantsOption);
/**
* Method to check the state of a cm handle with given id.
@@ -90,15 +89,16 @@ public interface CmHandleQueries {
* Method which returns cm handles by the operational sync state of cm handle.
*
* @param dataStoreSyncState sync state
- * @return a list of cm handles
+ * @return a list of data nodes representing the cm handles.
*/
- List<DataNode> queryCmHandlesByOperationalSyncState(DataStoreSyncState dataStoreSyncState);
+ Collection<DataNode> queryCmHandlesByOperationalSyncState(DataStoreSyncState dataStoreSyncState);
/**
* Get all cm handles ids by DMI plugin identifier.
*
* @param dmiPluginIdentifier DMI plugin identifier
- * @return collection of cm handles
+ * @return collection of cm handle ids
*/
Collection<String> getCmHandleIdsByDmiPluginIdentifier(String dmiPluginIdentifier);
+
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CmHandleQueriesImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleQueryServiceImpl.java
index 6cffb4d274..71e7384208 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CmHandleQueriesImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleQueryServiceImpl.java
@@ -19,38 +19,42 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.inventory;
+package org.onap.cps.ncmp.impl.inventory;
-import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DATASPACE_NAME;
-import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_ANCHOR;
-import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_PARENT;
+import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NCMP_DATASPACE_NAME;
+import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NCMP_DMI_REGISTRY_ANCHOR;
+import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NCMP_DMI_REGISTRY_PARENT;
import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS;
import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
-import org.onap.cps.ncmp.api.impl.config.embeddedcache.TrustLevelCacheConfig;
-import org.onap.cps.ncmp.api.impl.inventory.enums.PropertyType;
-import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevel;
-import org.onap.cps.spi.CpsDataPersistenceService;
+import org.onap.cps.api.CpsDataService;
+import org.onap.cps.api.CpsQueryService;
+import org.onap.cps.cpspath.parser.CpsPathUtil;
+import org.onap.cps.impl.utils.CpsValidator;
+import org.onap.cps.ncmp.api.inventory.models.TrustLevel;
+import org.onap.cps.ncmp.impl.inventory.models.CmHandleState;
+import org.onap.cps.ncmp.impl.inventory.models.ModelledDmiServiceLeaves;
+import org.onap.cps.ncmp.impl.inventory.models.PropertyType;
+import org.onap.cps.ncmp.impl.inventory.trustlevel.TrustLevelCacheConfig;
import org.onap.cps.spi.FetchDescendantsOption;
import org.onap.cps.spi.model.DataNode;
-import org.onap.cps.spi.utils.CpsValidator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@RequiredArgsConstructor
@Component
-public class CmHandleQueriesImpl implements CmHandleQueries {
+public class CmHandleQueryServiceImpl implements CmHandleQueryService {
private static final String DESCENDANT_PATH = "//";
private static final String ANCESTOR_CM_HANDLES = "/ancestor::cm-handles";
- private final CpsDataPersistenceService cpsDataPersistenceService;
+ private final CpsDataService cpsDataService;
+ private final CpsQueryService cpsQueryService;
@Qualifier(TrustLevelCacheConfig.TRUST_LEVEL_PER_DMI_PLUGIN)
private final Map<String, TrustLevel> trustLevelPerDmiPlugin;
@@ -79,21 +83,24 @@ public class CmHandleQueriesImpl implements CmHandleQueries {
}
@Override
- public List<DataNode> queryCmHandlesByState(final CmHandleState cmHandleState) {
+ public Collection<DataNode> queryCmHandlesByState(final CmHandleState cmHandleState) {
return queryCmHandleAncestorsByCpsPath("//state[@cm-handle-state=\"" + cmHandleState + "\"]",
INCLUDE_ALL_DESCENDANTS);
}
@Override
- public List<DataNode> queryNcmpRegistryByCpsPath(final String cpsPath,
+ public Collection<DataNode> queryNcmpRegistryByCpsPath(final String cpsPath,
final FetchDescendantsOption fetchDescendantsOption) {
- return cpsDataPersistenceService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
- cpsPath, fetchDescendantsOption);
+ return cpsQueryService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, cpsPath,
+ fetchDescendantsOption);
}
@Override
- public List<DataNode> queryCmHandleAncestorsByCpsPath(final String cpsPath,
+ public Collection<DataNode> queryCmHandleAncestorsByCpsPath(final String cpsPath,
final FetchDescendantsOption fetchDescendantsOption) {
+ if (CpsPathUtil.getCpsPathQuery(cpsPath).getXpathPrefix().endsWith("/cm-handles")) {
+ return queryNcmpRegistryByCpsPath(cpsPath, fetchDescendantsOption);
+ }
return queryNcmpRegistryByCpsPath(cpsPath + ANCESTOR_CM_HANDLES, fetchDescendantsOption);
}
@@ -105,7 +112,7 @@ public class CmHandleQueriesImpl implements CmHandleQueries {
}
@Override
- public List<DataNode> queryCmHandlesByOperationalSyncState(final DataStoreSyncState dataStoreSyncState) {
+ public Collection<DataNode> queryCmHandlesByOperationalSyncState(final DataStoreSyncState dataStoreSyncState) {
return queryCmHandleAncestorsByCpsPath("//state/datastores" + "/operational[@sync-state=\""
+ dataStoreSyncState + "\"]", FetchDescendantsOption.OMIT_DESCENDANTS);
}
@@ -174,9 +181,9 @@ public class CmHandleQueriesImpl implements CmHandleQueries {
return cmHandleIds;
}
- private List<DataNode> getCmHandlesByDmiPluginIdentifierAndDmiProperty(final String dmiPluginIdentifier,
- final String dmiProperty) {
- return cpsDataPersistenceService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
+ private Collection<DataNode> getCmHandlesByDmiPluginIdentifierAndDmiProperty(final String dmiPluginIdentifier,
+ final String dmiProperty) {
+ return cpsQueryService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@" + dmiProperty + "='" + dmiPluginIdentifier + "']",
OMIT_DESCENDANTS);
}
@@ -184,7 +191,7 @@ public class CmHandleQueriesImpl implements CmHandleQueries {
private DataNode getCmHandleState(final String cmHandleId) {
cpsValidator.validateNameCharacters(cmHandleId);
final String xpath = NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='" + cmHandleId + "']/state";
- return cpsDataPersistenceService.getDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
+ return cpsDataService.getDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
xpath, OMIT_DESCENDANTS).iterator().next();
}
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationService.java
index 6aa09767be..d9f7e38993 100755..100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationService.java
@@ -1,7 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 highstreet technologies GmbH
- * Modifications Copyright (C) 2021-2024 Nordix Foundation
+ * Copyright (C) 2021-2024 Nordix Foundation
* Modifications Copyright (C) 2021 Pantheon.tech
* Modifications Copyright (C) 2021-2022 Bell Canada
* Modifications Copyright (C) 2023 TechMahindra Ltd.
@@ -22,23 +21,23 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl;
+package org.onap.cps.ncmp.impl.inventory;
import static org.onap.cps.ncmp.api.NcmpResponseStatus.ALTERNATE_ID_ALREADY_ASSOCIATED;
import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLES_NOT_FOUND;
import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLES_NOT_READY;
import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLE_ALREADY_EXIST;
import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLE_INVALID_ID;
-import static org.onap.cps.ncmp.api.impl.inventory.LockReasonCategory.MODULE_UPGRADE;
-import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_PARENT;
-import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME;
-import static org.onap.cps.ncmp.api.impl.utils.RestQueryParametersValidator.validateCmHandleQueryParameters;
+import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NCMP_DMI_REGISTRY_PARENT;
+import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME;
+import static org.onap.cps.ncmp.impl.inventory.models.LockReasonCategory.MODULE_UPGRADE;
import com.google.common.collect.Lists;
import com.hazelcast.map.IMap;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -49,77 +48,52 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.onap.cps.api.CpsDataService;
-import org.onap.cps.ncmp.api.NetworkCmProxyCmHandleQueryService;
-import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
-import org.onap.cps.ncmp.api.impl.config.embeddedcache.TrustLevelCacheConfig;
-import org.onap.cps.ncmp.api.impl.events.lcm.LcmEventsCmHandleStateHandler;
-import org.onap.cps.ncmp.api.impl.inventory.CmHandleQueries;
-import org.onap.cps.ncmp.api.impl.inventory.CmHandleState;
-import org.onap.cps.ncmp.api.impl.inventory.CompositeState;
-import org.onap.cps.ncmp.api.impl.inventory.CompositeStateBuilder;
-import org.onap.cps.ncmp.api.impl.inventory.CompositeStateUtils;
-import org.onap.cps.ncmp.api.impl.inventory.DataStoreSyncState;
-import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence;
-import org.onap.cps.ncmp.api.impl.inventory.sync.ModuleOperationsUtils;
-import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations;
-import org.onap.cps.ncmp.api.impl.operations.OperationType;
-import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevel;
-import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevelManager;
-import org.onap.cps.ncmp.api.impl.utils.AlternateIdChecker;
-import org.onap.cps.ncmp.api.impl.utils.CmHandleQueryConditions;
-import org.onap.cps.ncmp.api.impl.utils.InventoryQueryConditions;
-import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
-import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
-import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters;
-import org.onap.cps.ncmp.api.models.CmHandleQueryServiceParameters;
-import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse;
-import org.onap.cps.ncmp.api.models.CmResourceAddress;
-import org.onap.cps.ncmp.api.models.DataOperationRequest;
-import org.onap.cps.ncmp.api.models.DmiPluginRegistration;
-import org.onap.cps.ncmp.api.models.DmiPluginRegistrationResponse;
-import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
-import org.onap.cps.spi.FetchDescendantsOption;
+import org.onap.cps.ncmp.api.inventory.models.CmHandleRegistrationResponse;
+import org.onap.cps.ncmp.api.inventory.models.CompositeState;
+import org.onap.cps.ncmp.api.inventory.models.CompositeStateBuilder;
+import org.onap.cps.ncmp.api.inventory.models.DmiPluginRegistration;
+import org.onap.cps.ncmp.api.inventory.models.DmiPluginRegistrationResponse;
+import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle;
+import org.onap.cps.ncmp.api.inventory.models.TrustLevel;
+import org.onap.cps.ncmp.impl.inventory.models.CmHandleState;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
+import org.onap.cps.ncmp.impl.inventory.sync.ModuleOperationsUtils;
+import org.onap.cps.ncmp.impl.inventory.sync.lcm.LcmEventsCmHandleStateHandler;
+import org.onap.cps.ncmp.impl.inventory.trustlevel.TrustLevelManager;
import org.onap.cps.spi.exceptions.AlreadyDefinedException;
import org.onap.cps.spi.exceptions.CpsException;
import org.onap.cps.spi.exceptions.DataNodeNotFoundException;
import org.onap.cps.spi.exceptions.DataValidationException;
-import org.onap.cps.spi.model.ModuleDefinition;
-import org.onap.cps.spi.model.ModuleReference;
-import org.onap.cps.utils.JsonObjectMapper;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
@Slf4j
@Service
@RequiredArgsConstructor
-public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService {
+public class CmHandleRegistrationService {
private static final int DELETE_BATCH_SIZE = 100;
- private final JsonObjectMapper jsonObjectMapper;
- private final DmiDataOperations dmiDataOperations;
- private final NetworkCmProxyDataServicePropertyHandler networkCmProxyDataServicePropertyHandler;
+
+ private final CmHandleRegistrationServicePropertyHandler cmHandleRegistrationServicePropertyHandler;
private final InventoryPersistence inventoryPersistence;
- private final CmHandleQueries cmHandleQueries;
- private final NetworkCmProxyCmHandleQueryService networkCmProxyCmHandleQueryService;
- private final LcmEventsCmHandleStateHandler lcmEventsCmHandleStateHandler;
private final CpsDataService cpsDataService;
+ private final LcmEventsCmHandleStateHandler lcmEventsCmHandleStateHandler;
private final IMap<String, Object> moduleSyncStartedOnCmHandles;
-
- @Qualifier(TrustLevelCacheConfig.TRUST_LEVEL_PER_DMI_PLUGIN)
- private final Map<String, TrustLevel> trustLevelPerDmiPlugin;
-
private final TrustLevelManager trustLevelManager;
private final AlternateIdChecker alternateIdChecker;
- @Override
+ /**
+ * Registration of Created, Removed, Updated or Upgraded CM Handles.
+ *
+ * @param dmiPluginRegistration Dmi Plugin Registration details
+ * @return dmiPluginRegistrationResponse
+ */
public DmiPluginRegistrationResponse updateDmiRegistrationAndSyncModule(
final DmiPluginRegistration dmiPluginRegistration) {
dmiPluginRegistration.validateDmiPluginRegistration();
final DmiPluginRegistrationResponse dmiPluginRegistrationResponse = new DmiPluginRegistrationResponse();
- setTrustLevelPerDmiPlugin(dmiPluginRegistration);
+ trustLevelManager.registerDmiPlugin(dmiPluginRegistration);
processRemovedCmHandles(dmiPluginRegistration, dmiPluginRegistrationResponse);
@@ -132,95 +106,6 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
return dmiPluginRegistrationResponse;
}
- @Override
- public Object getResourceDataForCmHandle(final CmResourceAddress cmResourceAddress,
- final String optionsParamInQuery,
- final String topicParamInQuery,
- final String requestId,
- final String authorization) {
- final ResponseEntity<?> responseEntity = dmiDataOperations.getResourceDataFromDmi(cmResourceAddress,
- optionsParamInQuery,
- topicParamInQuery,
- requestId,
- authorization);
- return responseEntity.getBody();
- }
-
- @Override
- public Object getResourceDataForCmHandle(final CmResourceAddress cmResourceAddress,
- final FetchDescendantsOption fetchDescendantsOption) {
- return cpsDataService.getDataNodes(cmResourceAddress.datastoreName(),
- cmResourceAddress.cmHandleId(),
- cmResourceAddress.resourceIdentifier(),
- fetchDescendantsOption).iterator().next();
- }
-
- @Override
- public void executeDataOperationForCmHandles(final String topicParamInQuery,
- final DataOperationRequest dataOperationRequest,
- final String requestId,
- final String authorization) {
- dmiDataOperations.requestResourceDataFromDmi(topicParamInQuery, dataOperationRequest, requestId,
- authorization);
- }
-
- @Override
- public Object writeResourceDataPassThroughRunningForCmHandle(final String cmHandleId,
- final String resourceIdentifier,
- final OperationType operationType,
- final String requestData,
- final String dataType,
- final String authorization) {
- return dmiDataOperations.writeResourceDataPassThroughRunningFromDmi(cmHandleId, resourceIdentifier,
- operationType, requestData, dataType, authorization);
- }
-
- @Override
- public Collection<ModuleReference> getYangResourcesModuleReferences(final String cmHandleId) {
- return inventoryPersistence.getYangResourcesModuleReferences(cmHandleId);
- }
-
- @Override
- public Collection<ModuleDefinition> getModuleDefinitionsByCmHandleId(final String cmHandleId) {
- return inventoryPersistence.getModuleDefinitionsByCmHandleId(cmHandleId);
- }
-
- @Override
- public Collection<ModuleDefinition> getModuleDefinitionsByCmHandleAndModule(final String cmHandleId,
- final String moduleName,
- final String moduleRevision) {
- return inventoryPersistence.getModuleDefinitionsByCmHandleAndModule(cmHandleId, moduleName, moduleRevision);
- }
-
- /**
- * Retrieve cm handles with details for the given query parameters.
- *
- * @param cmHandleQueryApiParameters cm handle query parameters
- * @return cm handles with details
- */
- @Override
- public Collection<NcmpServiceCmHandle> executeCmHandleSearch(
- final CmHandleQueryApiParameters cmHandleQueryApiParameters) {
- final CmHandleQueryServiceParameters cmHandleQueryServiceParameters = jsonObjectMapper.convertToValueType(
- cmHandleQueryApiParameters, CmHandleQueryServiceParameters.class);
- validateCmHandleQueryParameters(cmHandleQueryServiceParameters, CmHandleQueryConditions.ALL_CONDITION_NAMES);
- return networkCmProxyCmHandleQueryService.queryCmHandles(cmHandleQueryServiceParameters);
- }
-
- /**
- * Retrieve cm handle ids for the given query parameters.
- *
- * @param cmHandleQueryApiParameters cm handle query parameters
- * @return cm handle ids
- */
- @Override
- public Collection<String> executeCmHandleIdSearch(final CmHandleQueryApiParameters cmHandleQueryApiParameters) {
- final CmHandleQueryServiceParameters cmHandleQueryServiceParameters = jsonObjectMapper.convertToValueType(
- cmHandleQueryApiParameters, CmHandleQueryServiceParameters.class);
- validateCmHandleQueryParameters(cmHandleQueryServiceParameters, CmHandleQueryConditions.ALL_CONDITION_NAMES);
- return networkCmProxyCmHandleQueryService.queryCmHandleIds(cmHandleQueryServiceParameters);
- }
-
/**
* Set the data sync enabled flag, along with the data sync state
* based on the data sync enabled boolean for the cm handle id provided.
@@ -228,7 +113,6 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
* @param cmHandleId cm handle id
* @param dataSyncEnabledTargetValue data sync enabled flag
*/
- @Override
public void setDataSyncEnabled(final String cmHandleId, final Boolean dataSyncEnabledTargetValue) {
final CompositeState compositeState = inventoryPersistence.getCmHandleState(cmHandleId);
if (dataSyncEnabledTargetValue.equals(compositeState.getDataSyncEnabled())) {
@@ -252,70 +136,8 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
}
}
- /**
- * Get all cm handle IDs by DMI plugin identifier.
- *
- * @param dmiPluginIdentifier DMI plugin identifier
- * @return set of cm handle IDs
- */
- @Override
- public Collection<String> getAllCmHandleIdsByDmiPluginIdentifier(final String dmiPluginIdentifier) {
- return cmHandleQueries.getCmHandleIdsByDmiPluginIdentifier(dmiPluginIdentifier);
- }
-
- /**
- * Get all cm handle IDs by various properties.
- *
- * @param cmHandleQueryServiceParameters cm handle query parameters
- * @return set of cm handle IDs
- */
- @Override
- public Collection<String> executeCmHandleIdSearchForInventory(
- final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
- validateCmHandleQueryParameters(cmHandleQueryServiceParameters, InventoryQueryConditions.ALL_CONDITION_NAMES);
- return networkCmProxyCmHandleQueryService.queryCmHandleIdsForInventory(cmHandleQueryServiceParameters);
- }
-
- /**
- * Retrieve cm handle details for a given cm handle.
- *
- * @param cmHandleId cm handle identifier
- * @return cm handle details
- */
- @Override
- public NcmpServiceCmHandle getNcmpServiceCmHandle(final String cmHandleId) {
- return YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle(
- inventoryPersistence.getYangModelCmHandle(cmHandleId));
- }
-
- /**
- * Get cm handle public properties for a given cm handle id.
- *
- * @param cmHandleId cm handle identifier
- * @return cm handle public properties
- */
- @Override
- public Map<String, String> getCmHandlePublicProperties(final String cmHandleId) {
- final YangModelCmHandle yangModelCmHandle = inventoryPersistence.getYangModelCmHandle(cmHandleId);
- final List<YangModelCmHandle.Property> yangModelPublicProperties = yangModelCmHandle.getPublicProperties();
- final Map<String, String> cmHandlePublicProperties = new HashMap<>();
- YangDataConverter.asPropertiesMap(yangModelPublicProperties, cmHandlePublicProperties);
- return cmHandlePublicProperties;
- }
-
- /**
- * Get cm handle composite state for a given cm handle id.
- *
- * @param cmHandleId cm handle identifier
- * @return cm handle state
- */
- @Override
- public CompositeState getCmHandleCompositeState(final String cmHandleId) {
- return inventoryPersistence.getYangModelCmHandle(cmHandleId).getCompositeState();
- }
-
protected void processRemovedCmHandles(final DmiPluginRegistration dmiPluginRegistration,
- final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) {
+ final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) {
final List<String> tobeRemovedCmHandleIds = dmiPluginRegistration.getRemovedCmHandles();
final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses =
new ArrayList<>(tobeRemovedCmHandleIds.size());
@@ -326,7 +148,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
final Set<String> notDeletedCmHandles = new HashSet<>();
for (final List<String> tobeRemovedCmHandleBatch : Lists.partition(tobeRemovedCmHandleIds, DELETE_BATCH_SIZE)) {
try {
- batchDeleteCmHandlesFromDbAndModuleSyncMap(tobeRemovedCmHandleBatch);
+ batchDeleteCmHandlesFromDbAndCaches(tobeRemovedCmHandleBatch);
tobeRemovedCmHandleBatch.forEach(cmHandleId ->
cmHandleRegistrationResponses.add(CmHandleRegistrationResponse.createSuccessResponse(cmHandleId)));
@@ -348,7 +170,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
}
protected void processCreatedCmHandles(final DmiPluginRegistration dmiPluginRegistration,
- final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) {
+ final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) {
final List<NcmpServiceCmHandle> ncmpServiceCmHandles = dmiPluginRegistration.getCreatedCmHandles();
final List<CmHandleRegistrationResponse> failedCmHandleRegistrationResponses = new ArrayList<>();
@@ -378,8 +200,8 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
}
protected void processUpdatedCmHandles(final DmiPluginRegistration dmiPluginRegistration,
- final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) {
- dmiPluginRegistrationResponse.setUpdatedCmHandles(networkCmProxyDataServicePropertyHandler
+ final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) {
+ dmiPluginRegistrationResponse.setUpdatedCmHandles(cmHandleRegistrationServicePropertyHandler
.updateCmHandleProperties(dmiPluginRegistration.getUpdatedCmHandles()));
}
@@ -405,67 +227,24 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
}
} else {
cmHandleUpgradeResponses.add(
- CmHandleRegistrationResponse.createFailureResponse(cmHandleId, CM_HANDLES_NOT_READY));
+ CmHandleRegistrationResponse.createFailureResponse(cmHandleId, CM_HANDLES_NOT_READY));
}
} catch (final DataNodeNotFoundException dataNodeNotFoundException) {
log.error("Unable to find data node for cm handle id : {} , caused by : {}",
- cmHandleId, dataNodeNotFoundException.getMessage());
+ cmHandleId, dataNodeNotFoundException.getMessage());
cmHandleUpgradeResponses.add(
- CmHandleRegistrationResponse.createFailureResponse(cmHandleId, CM_HANDLES_NOT_FOUND));
+ CmHandleRegistrationResponse.createFailureResponse(cmHandleId, CM_HANDLES_NOT_FOUND));
} catch (final DataValidationException dataValidationException) {
log.error("Unable to upgrade cm handle id: {}, caused by : {}",
- cmHandleId, dataValidationException.getMessage());
+ cmHandleId, dataValidationException.getMessage());
cmHandleUpgradeResponses.add(
- CmHandleRegistrationResponse.createFailureResponse(cmHandleId, CM_HANDLE_INVALID_ID));
+ CmHandleRegistrationResponse.createFailureResponse(cmHandleId, CM_HANDLE_INVALID_ID));
}
}
cmHandleUpgradeResponses.addAll(upgradeCmHandles(acceptedCmHandleStatePerCmHandle));
dmiPluginRegistrationResponse.setUpgradedCmHandles(cmHandleUpgradeResponses);
}
- private Collection<String> checkAlternateIds(
- final List<NcmpServiceCmHandle> cmHandlesToBeCreated,
- final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses) {
- final Collection<String> rejectedCmHandleIds = alternateIdChecker
- .getIdsOfCmHandlesWithRejectedAlternateId(cmHandlesToBeCreated, AlternateIdChecker.Operation.CREATE);
- cmHandleRegistrationResponses.addAll(CmHandleRegistrationResponse.createFailureResponses(
- rejectedCmHandleIds, ALTERNATE_ID_ALREADY_ASSOCIATED));
- return rejectedCmHandleIds;
- }
-
- private List<String> persistCmHandlesWithState(final DmiPluginRegistration dmiPluginRegistration,
- final DmiPluginRegistrationResponse dmiPluginRegistrationResponse,
- final List<NcmpServiceCmHandle> cmHandlesToBeCreated,
- final Collection<String> rejectedCmHandleIds) {
- final List<String> succeededCmHandleIds = new ArrayList<>(cmHandlesToBeCreated.size());
- final List<YangModelCmHandle> yangModelCmHandlesToRegister = new ArrayList<>(cmHandlesToBeCreated.size());
- final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses =
- new ArrayList<>(cmHandlesToBeCreated.size());
- for (final NcmpServiceCmHandle ncmpServiceCmHandle: cmHandlesToBeCreated) {
- if (!rejectedCmHandleIds.contains(ncmpServiceCmHandle.getCmHandleId())) {
- yangModelCmHandlesToRegister.add(getYangModelCmHandle(dmiPluginRegistration, ncmpServiceCmHandle));
- cmHandleRegistrationResponses.add(
- CmHandleRegistrationResponse.createSuccessResponse(ncmpServiceCmHandle.getCmHandleId()));
- succeededCmHandleIds.add(ncmpServiceCmHandle.getCmHandleId());
- }
- }
- lcmEventsCmHandleStateHandler.initiateStateAdvised(yangModelCmHandlesToRegister);
- dmiPluginRegistrationResponse.setCreatedCmHandles(cmHandleRegistrationResponses);
- return succeededCmHandleIds;
- }
-
- private YangModelCmHandle getYangModelCmHandle(final DmiPluginRegistration dmiPluginRegistration,
- final NcmpServiceCmHandle ncmpServiceCmHandle) {
- return YangModelCmHandle.toYangModelCmHandle(
- dmiPluginRegistration.getDmiPlugin(),
- dmiPluginRegistration.getDmiDataPlugin(),
- dmiPluginRegistration.getDmiModelPlugin(),
- ncmpServiceCmHandle,
- ncmpServiceCmHandle.getModuleSetTag(),
- ncmpServiceCmHandle.getAlternateId(),
- ncmpServiceCmHandle.getDataProducerIdentifier());
- }
-
private void processTrustLevels(final Collection<NcmpServiceCmHandle> cmHandlesToBeCreated,
final Collection<String> succeededCmHandleIds) {
final Map<String, TrustLevel> initialTrustLevelPerCmHandleId = new HashMap<>(cmHandlesToBeCreated.size());
@@ -475,7 +254,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
ncmpServiceCmHandle.getRegistrationTrustLevel());
}
}
- trustLevelManager.handleInitialRegistrationOfTrustLevels(initialTrustLevelPerCmHandleId);
+ trustLevelManager.registerCmHandles(initialTrustLevelPerCmHandleId);
}
private static boolean moduleUpgradeCanBeSkipped(final YangModelCmHandle yangModelCmHandle,
@@ -489,14 +268,14 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
private static void updateYangModelCmHandleForUpgrade(final YangModelCmHandle yangModelCmHandle,
final String upgradedModuleSetTag) {
final String lockReasonWithModuleSetTag = String.format(ModuleOperationsUtils.MODULE_SET_TAG_MESSAGE_FORMAT,
- upgradedModuleSetTag);
+ upgradedModuleSetTag);
yangModelCmHandle.setCompositeState(new CompositeStateBuilder().withCmHandleState(CmHandleState.READY)
- .withLockReason(MODULE_UPGRADE, lockReasonWithModuleSetTag).build());
+ .withLockReason(MODULE_UPGRADE, lockReasonWithModuleSetTag).build());
}
private CmHandleRegistrationResponse deleteCmHandleAndGetCmHandleRegistrationResponse(final String cmHandleId) {
try {
- deleteCmHandleFromDbAndModuleSyncMap(cmHandleId);
+ deleteCmHandleFromDbAndCaches(cmHandleId);
return CmHandleRegistrationResponse.createSuccessResponse(cmHandleId);
} catch (final DataNodeNotFoundException dataNodeNotFoundException) {
log.error("Unable to find dataNode for cmHandleId : {} , caused by : {}",
@@ -519,15 +298,17 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
lcmEventsCmHandleStateHandler.updateCmHandleStateBatch(cmHandleStatePerCmHandle);
}
- private void deleteCmHandleFromDbAndModuleSyncMap(final String cmHandleId) {
+ private void deleteCmHandleFromDbAndCaches(final String cmHandleId) {
inventoryPersistence.deleteSchemaSetWithCascade(cmHandleId);
inventoryPersistence.deleteDataNode(NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='" + cmHandleId + "']");
+ trustLevelManager.removeCmHandles(Collections.singleton(cmHandleId));
removeDeletedCmHandleFromModuleSyncMap(cmHandleId);
}
- private void batchDeleteCmHandlesFromDbAndModuleSyncMap(final Collection<String> cmHandleIds) {
+ private void batchDeleteCmHandlesFromDbAndCaches(final Collection<String> cmHandleIds) {
inventoryPersistence.deleteSchemaSetsWithCascade(cmHandleIds);
inventoryPersistence.deleteDataNodes(mapCmHandleIdsToXpaths(cmHandleIds));
+ trustLevelManager.removeCmHandles(cmHandleIds);
cmHandleIds.forEach(this::removeDeletedCmHandleFromModuleSyncMap);
}
@@ -561,12 +342,48 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
return cmHandleStatePerCmHandle.keySet().stream().map(YangModelCmHandle::getId).toList();
}
- private void setTrustLevelPerDmiPlugin(final DmiPluginRegistration dmiPluginRegistration) {
- if (DmiPluginRegistration.isNullEmptyOrBlank(dmiPluginRegistration.getDmiDataPlugin())) {
- trustLevelPerDmiPlugin.put(dmiPluginRegistration.getDmiPlugin(), TrustLevel.COMPLETE);
- } else {
- trustLevelPerDmiPlugin.put(dmiPluginRegistration.getDmiDataPlugin(), TrustLevel.COMPLETE);
+ private Collection<String> checkAlternateIds(
+ final List<NcmpServiceCmHandle> cmHandlesToBeCreated,
+ final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses) {
+ final Collection<String> rejectedCmHandleIds = alternateIdChecker
+ .getIdsOfCmHandlesWithRejectedAlternateId(cmHandlesToBeCreated, AlternateIdChecker.Operation.CREATE);
+ cmHandleRegistrationResponses.addAll(CmHandleRegistrationResponse.createFailureResponses(
+ rejectedCmHandleIds, ALTERNATE_ID_ALREADY_ASSOCIATED));
+ return rejectedCmHandleIds;
+ }
+
+ private List<String> persistCmHandlesWithState(final DmiPluginRegistration dmiPluginRegistration,
+ final DmiPluginRegistrationResponse dmiPluginRegistrationResponse,
+ final List<NcmpServiceCmHandle> cmHandlesToBeCreated,
+ final Collection<String> rejectedCmHandleIds) {
+ final List<String> succeededCmHandleIds = new ArrayList<>(cmHandlesToBeCreated.size());
+ final List<YangModelCmHandle> yangModelCmHandlesToRegister = new ArrayList<>(cmHandlesToBeCreated.size());
+ final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses =
+ new ArrayList<>(cmHandlesToBeCreated.size());
+ for (final NcmpServiceCmHandle ncmpServiceCmHandle: cmHandlesToBeCreated) {
+ if (!rejectedCmHandleIds.contains(ncmpServiceCmHandle.getCmHandleId())) {
+ yangModelCmHandlesToRegister.add(getYangModelCmHandle(dmiPluginRegistration, ncmpServiceCmHandle));
+ cmHandleRegistrationResponses.add(
+ CmHandleRegistrationResponse.createSuccessResponse(ncmpServiceCmHandle.getCmHandleId()));
+ succeededCmHandleIds.add(ncmpServiceCmHandle.getCmHandleId());
+ }
}
+ lcmEventsCmHandleStateHandler.initiateStateAdvised(yangModelCmHandlesToRegister);
+ dmiPluginRegistrationResponse.setCreatedCmHandles(cmHandleRegistrationResponses);
+ return succeededCmHandleIds;
}
+ private YangModelCmHandle getYangModelCmHandle(final DmiPluginRegistration dmiPluginRegistration,
+ final NcmpServiceCmHandle ncmpServiceCmHandle) {
+ return YangModelCmHandle.toYangModelCmHandle(
+ dmiPluginRegistration.getDmiPlugin(),
+ dmiPluginRegistration.getDmiDataPlugin(),
+ dmiPluginRegistration.getDmiModelPlugin(),
+ ncmpServiceCmHandle,
+ ncmpServiceCmHandle.getModuleSetTag(),
+ ncmpServiceCmHandle.getAlternateId(),
+ ncmpServiceCmHandle.getDataProducerIdentifier());
+ }
+
+
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServicePropertyHandler.java
index f861910024..308ead1270 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandler.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServicePropertyHandler.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* Copyright (C) 2022-2024 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
- * Modifications Copyright (C) 2023 TechMahindra Ltd.
+ * 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.
@@ -20,16 +20,16 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl;
+package org.onap.cps.ncmp.impl.inventory;
import static org.onap.cps.ncmp.api.NcmpResponseStatus.ALTERNATE_ID_ALREADY_ASSOCIATED;
import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLES_NOT_FOUND;
import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLE_INVALID_ID;
-import static org.onap.cps.ncmp.api.impl.NetworkCmProxyDataServicePropertyHandler.PropertyType.DMI_PROPERTY;
-import static org.onap.cps.ncmp.api.impl.NetworkCmProxyDataServicePropertyHandler.PropertyType.PUBLIC_PROPERTY;
-import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DATASPACE_NAME;
-import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_ANCHOR;
-import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_PARENT;
+import static org.onap.cps.ncmp.impl.inventory.CmHandleRegistrationServicePropertyHandler.PropertyType.DMI_PROPERTY;
+import static org.onap.cps.ncmp.impl.inventory.CmHandleRegistrationServicePropertyHandler.PropertyType.PUBLIC_PROPERTY;
+import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NCMP_DATASPACE_NAME;
+import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NCMP_DMI_REGISTRY_ANCHOR;
+import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NCMP_DMI_REGISTRY_PARENT;
import com.google.common.collect.ImmutableMap;
import java.time.OffsetDateTime;
@@ -44,27 +44,26 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
import org.onap.cps.api.CpsDataService;
-import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence;
-import org.onap.cps.ncmp.api.impl.utils.AlternateIdChecker;
-import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
-import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
-import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse;
-import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
+import org.onap.cps.ncmp.api.inventory.models.CmHandleRegistrationResponse;
+import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
+import org.onap.cps.ncmp.impl.utils.YangDataConverter;
import org.onap.cps.spi.exceptions.DataNodeNotFoundException;
import org.onap.cps.spi.exceptions.DataValidationException;
import org.onap.cps.spi.model.DataNode;
import org.onap.cps.spi.model.DataNodeBuilder;
+import org.onap.cps.utils.ContentType;
import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.stereotype.Service;
-import org.springframework.util.StringUtils;
@Slf4j
@Service
@RequiredArgsConstructor
//Accepting the security hotspot as the string checked is generated from inside code and not user input.
@SuppressWarnings("squid:S5852")
-public class NetworkCmProxyDataServicePropertyHandler {
+public class CmHandleRegistrationServicePropertyHandler {
private final InventoryPersistence inventoryPersistence;
private final CpsDataService cpsDataService;
@@ -113,8 +112,7 @@ public class NetworkCmProxyDataServicePropertyHandler {
private void processUpdates(final DataNode existingCmHandleDataNode,
final NcmpServiceCmHandle updatedNcmpServiceCmHandle) {
- setAndUpdateCmHandleField(
- updatedNcmpServiceCmHandle.getCmHandleId(), "alternate-id", updatedNcmpServiceCmHandle.getAlternateId());
+ updateAlternateId(updatedNcmpServiceCmHandle);
updateDataProducerIdentifier(existingCmHandleDataNode, updatedNcmpServiceCmHandle);
if (!updatedNcmpServiceCmHandle.getPublicProperties().isEmpty()) {
updateProperties(existingCmHandleDataNode, PUBLIC_PROPERTY,
@@ -125,18 +123,27 @@ public class NetworkCmProxyDataServicePropertyHandler {
}
}
+ private void updateAlternateId(final NcmpServiceCmHandle ncmpServiceCmHandle) {
+ final String newAlternateId = ncmpServiceCmHandle.getAlternateId();
+ if (StringUtils.isNotBlank(newAlternateId)) {
+ setAndUpdateCmHandleField(ncmpServiceCmHandle.getCmHandleId(), "alternate-id", newAlternateId);
+ }
+ }
+
private void updateDataProducerIdentifier(final DataNode cmHandleDataNode,
final NcmpServiceCmHandle ncmpServiceCmHandle) {
final String newDataProducerIdentifier = ncmpServiceCmHandle.getDataProducerIdentifier();
- if (StringUtils.hasText(newDataProducerIdentifier)) {
- final YangModelCmHandle yangModelCmHandle =
- YangDataConverter.convertCmHandleToYangModel(cmHandleDataNode);
+ if (StringUtils.isNotBlank(newDataProducerIdentifier)) {
+ final YangModelCmHandle yangModelCmHandle = YangDataConverter.toYangModelCmHandle(cmHandleDataNode);
final String existingDataProducerIdentifier = yangModelCmHandle.getDataProducerIdentifier();
- if (StringUtils.hasText(existingDataProducerIdentifier)) {
+ if (StringUtils.isNotBlank(existingDataProducerIdentifier)) {
if (!existingDataProducerIdentifier.equals(newDataProducerIdentifier)) {
log.warn("Unable to update dataProducerIdentifier for cmHandle {}. "
+ "Value for dataProducerIdentifier has been set previously.",
ncmpServiceCmHandle.getCmHandleId());
+ } else {
+ log.debug("dataProducerIdentifier for cmHandle {} is already set to {}.",
+ ncmpServiceCmHandle.getCmHandleId(), newDataProducerIdentifier);
}
} else {
setAndUpdateCmHandleField(
@@ -222,7 +229,7 @@ public class NetworkCmProxyDataServicePropertyHandler {
cmHandleData.put(fieldName, newFieldValue);
dmiRegistryData.put("cm-handles", cmHandleData);
cpsDataService.updateNodeLeaves(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, NCMP_DMI_REGISTRY_PARENT,
- jsonObjectMapper.asJsonString(dmiRegistryData), OffsetDateTime.now());
+ jsonObjectMapper.asJsonString(dmiRegistryData), OffsetDateTime.now(), ContentType.JSON);
log.debug("Updating {} for cmHandle {} with value : {})", fieldName, cmHandleIdToUpdate, newFieldValue);
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CompositeStateUtils.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CompositeStateUtils.java
index 35ad54fdef..685d204633 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CompositeStateUtils.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CompositeStateUtils.java
@@ -18,11 +18,13 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.inventory;
+package org.onap.cps.ncmp.impl.inventory;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.inventory.models.CompositeState;
+import org.onap.cps.ncmp.impl.inventory.models.CmHandleState;
/**
* It will have all the utility method responsible for handling the composite state.
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/DataStoreSyncState.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/DataStoreSyncState.java
index b92d152bfa..a260ce9cbe 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/DataStoreSyncState.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/DataStoreSyncState.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.inventory;
+package org.onap.cps.ncmp.impl.inventory;
public enum DataStoreSyncState {
SYNCHRONIZED, UNSYNCHRONIZED, NONE_REQUESTED
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistence.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/InventoryPersistence.java
index 184b12570e..a0d3a3eaee 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistence.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/InventoryPersistence.java
@@ -19,13 +19,13 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.inventory;
+package org.onap.cps.ncmp.impl.inventory;
import java.util.Collection;
import java.util.List;
import java.util.Map;
-import org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence;
-import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.ncmp.api.inventory.models.CompositeState;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
import org.onap.cps.spi.model.DataNode;
import org.onap.cps.spi.model.ModuleDefinition;
import org.onap.cps.spi.model.ModuleReference;
@@ -130,14 +130,12 @@ public interface InventoryPersistence extends NcmpPersistence {
DataNode getCmHandleDataNodeByAlternateId(String alternateId);
/**
- * Get data node that matches longest alternate id by removing elements (as defined by the separator string)
- * from right to left.
+ * Get data nodes for the given batch of alternate ids.
*
- * @param alternateId alternate ID
- * @param separator a string that separates each element from the next.
- * @return data node
+ * @param alternateIds alternate IDs
+ * @return data nodes
*/
- DataNode getCmHandleDataNodeByLongestMatchAlternateId(final String alternateId, final String separator);
+ Collection<DataNode> getCmHandleDataNodesByAlternateIds(Collection<String> alternateIds);
/**
* Get collection of data nodes of given cm handles.
@@ -154,4 +152,12 @@ public interface InventoryPersistence extends NcmpPersistence {
* @return Collection of CM handle Ids
*/
Collection<String> getCmHandleIdsWithGivenModules(Collection<String> moduleNamesForQuery);
+
+ /**
+ * Check database if cm handle id exists if not return false.
+ *
+ * @param cmHandleId cmHandle Id
+ * @return Boolean
+ */
+ boolean isExistingCmHandleId(String cmHandleId);
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImpl.java
index bf54fe5d96..06c3f8d2f4 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImpl.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* Copyright (C) 2022-2024 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
- * Modifications Copyright (C) 2023 TechMahindra Ltd.
+ * 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.
@@ -20,7 +20,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.inventory;
+package org.onap.cps.ncmp.impl.inventory;
import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS;
@@ -32,21 +32,23 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
import org.onap.cps.api.CpsAnchorService;
import org.onap.cps.api.CpsDataService;
import org.onap.cps.api.CpsModuleService;
-import org.onap.cps.ncmp.api.impl.exception.NoAlternateIdParentFoundException;
-import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
-import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.impl.utils.CpsValidator;
+import org.onap.cps.ncmp.api.inventory.models.CompositeState;
+import org.onap.cps.ncmp.api.inventory.models.CompositeStateBuilder;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
+import org.onap.cps.ncmp.impl.utils.YangDataConverter;
import org.onap.cps.spi.FetchDescendantsOption;
import org.onap.cps.spi.exceptions.DataNodeNotFoundException;
import org.onap.cps.spi.exceptions.DataValidationException;
import org.onap.cps.spi.model.DataNode;
import org.onap.cps.spi.model.ModuleDefinition;
import org.onap.cps.spi.model.ModuleReference;
-import org.onap.cps.spi.utils.CpsValidator;
+import org.onap.cps.utils.ContentType;
import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.stereotype.Component;
@@ -59,7 +61,7 @@ public class InventoryPersistenceImpl extends NcmpPersistenceImpl implements Inv
private final CpsModuleService cpsModuleService;
private final CpsAnchorService cpsAnchorService;
private final CpsValidator cpsValidator;
- private final CmHandleQueries cmHandleQueries;
+ private final CmHandleQueryService cmHandleQueryService;
/**
* initialize an inventory persistence object.
@@ -72,12 +74,13 @@ public class InventoryPersistenceImpl extends NcmpPersistenceImpl implements Inv
*/
public InventoryPersistenceImpl(final JsonObjectMapper jsonObjectMapper, final CpsDataService cpsDataService,
final CpsModuleService cpsModuleService, final CpsValidator cpsValidator,
- final CpsAnchorService cpsAnchorService, final CmHandleQueries cmHandleQueries) {
+ final CpsAnchorService cpsAnchorService,
+ final CmHandleQueryService cmHandleQueryService) {
super(jsonObjectMapper, cpsDataService, cpsModuleService, cpsValidator);
this.cpsModuleService = cpsModuleService;
this.cpsAnchorService = cpsAnchorService;
this.cpsValidator = cpsValidator;
- this.cmHandleQueries = cmHandleQueries;
+ this.cmHandleQueryService = cmHandleQueryService;
}
@@ -94,7 +97,7 @@ public class InventoryPersistenceImpl extends NcmpPersistenceImpl implements Inv
public void saveCmHandleState(final String cmHandleId, final CompositeState compositeState) {
final String cmHandleJsonData = createStateJsonData(jsonObjectMapper.asJsonString(compositeState));
cpsDataService.updateDataNodeAndDescendants(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
- getXPathForCmHandleById(cmHandleId), cmHandleJsonData, OffsetDateTime.now());
+ getXPathForCmHandleById(cmHandleId), cmHandleJsonData, OffsetDateTime.now(), ContentType.JSON);
}
@Override
@@ -104,14 +107,14 @@ public class InventoryPersistenceImpl extends NcmpPersistenceImpl implements Inv
getXPathForCmHandleById(cmHandleId),
createStateJsonData(jsonObjectMapper.asJsonString(compositeState))));
cpsDataService.updateDataNodesAndDescendants(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
- cmHandlesJsonDataMap, OffsetDateTime.now());
+ cmHandlesJsonDataMap, OffsetDateTime.now(), ContentType.JSON);
}
@Override
public YangModelCmHandle getYangModelCmHandle(final String cmHandleId) {
cpsValidator.validateNameCharacters(cmHandleId);
final DataNode dataNode = getCmHandleDataNodeByCmHandleId(cmHandleId).iterator().next();
- return YangDataConverter.convertCmHandleToYangModel(dataNode);
+ return YangDataConverter.toYangModelCmHandle(dataNode);
}
@Override
@@ -126,7 +129,7 @@ public class InventoryPersistenceImpl extends NcmpPersistenceImpl implements Inv
dataValidationException.getMessage());
}
});
- return YangDataConverter.convertDataNodesToYangModelCmHandles(getCmHandleDataNodes(validCmHandleIds));
+ return YangDataConverter.toYangModelCmHandles(getCmHandleDataNodes(validCmHandleIds));
}
@Override
@@ -160,7 +163,7 @@ public class InventoryPersistenceImpl extends NcmpPersistenceImpl implements Inv
Lists.partition(yangModelCmHandles, CMHANDLE_BATCH_SIZE)) {
final String cmHandlesJsonData = createCmHandlesJsonData(yangModelCmHandleBatch);
cpsDataService.saveListElements(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
- NCMP_DMI_REGISTRY_PARENT, cmHandlesJsonData, NO_TIMESTAMP);
+ NCMP_DMI_REGISTRY_PARENT, cmHandlesJsonData, NO_TIMESTAMP, ContentType.JSON);
}
}
@@ -172,7 +175,7 @@ public class InventoryPersistenceImpl extends NcmpPersistenceImpl implements Inv
@Override
public DataNode getCmHandleDataNodeByAlternateId(final String alternateId) {
final String cpsPathForCmHandleByAlternateId = getCpsPathForCmHandleByAlternateId(alternateId);
- final Collection<DataNode> dataNodes = cmHandleQueries
+ final Collection<DataNode> dataNodes = cmHandleQueryService
.queryNcmpRegistryByCpsPath(cpsPathForCmHandleByAlternateId, OMIT_DESCENDANTS);
if (dataNodes.isEmpty()) {
throw new DataNodeNotFoundException(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
@@ -182,16 +185,12 @@ public class InventoryPersistenceImpl extends NcmpPersistenceImpl implements Inv
}
@Override
- public DataNode getCmHandleDataNodeByLongestMatchAlternateId(final String alternateId, final String separator) {
- String bestMatch = alternateId;
- while (StringUtils.isNotEmpty(bestMatch)) {
- try {
- return getCmHandleDataNodeByAlternateId(bestMatch);
- } catch (final DataNodeNotFoundException ignored) {
- bestMatch = getParentPath(bestMatch, separator);
- }
+ public Collection<DataNode> getCmHandleDataNodesByAlternateIds(final Collection<String> alternateIds) {
+ if (alternateIds.isEmpty()) {
+ return Collections.emptyList();
}
- throw new NoAlternateIdParentFoundException(alternateId);
+ final String cpsPathForCmHandlesByAlternateIds = getCpsPathForCmHandlesByAlternateIds(alternateIds);
+ return cmHandleQueryService.queryNcmpRegistryByCpsPath(cpsPathForCmHandlesByAlternateIds, OMIT_DESCENDANTS);
}
@Override
@@ -206,6 +205,15 @@ public class InventoryPersistenceImpl extends NcmpPersistenceImpl implements Inv
return cpsAnchorService.queryAnchorNames(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, moduleNamesForQuery);
}
+ @Override
+ public boolean isExistingCmHandleId(final String cmHandleId) {
+ try {
+ return !getCmHandleDataNodeByCmHandleId(cmHandleId).isEmpty();
+ } catch (final DataNodeNotFoundException exception) {
+ return false;
+ }
+ }
+
private static String getXPathForCmHandleById(final String cmHandleId) {
return NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='" + cmHandleId + "']";
}
@@ -214,6 +222,11 @@ public class InventoryPersistenceImpl extends NcmpPersistenceImpl implements Inv
return NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@alternate-id='" + alternateId + "']";
}
+ private static String getCpsPathForCmHandlesByAlternateIds(final Collection<String> alternateIds) {
+ return alternateIds.stream().collect(Collectors.joining("' or @alternate-id='",
+ NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@alternate-id='", "']"));
+ }
+
private static String createStateJsonData(final String state) {
return "{\"state\":" + state + "}";
}
@@ -221,9 +234,4 @@ public class InventoryPersistenceImpl extends NcmpPersistenceImpl implements Inv
private String createCmHandlesJsonData(final List<YangModelCmHandle> yangModelCmHandles) {
return "{\"cm-handles\":" + jsonObjectMapper.asJsonString(yangModelCmHandles) + "}";
}
-
- private static String getParentPath(final String path, final String separator) {
- final int lastSeparatorIndex = path.lastIndexOf(separator);
- return lastSeparatorIndex < 0 ? "" : path.substring(0, lastSeparatorIndex);
- }
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/ncmppersistence/NcmpPersistence.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/NcmpPersistence.java
index d72b5d58f1..5271485e3b 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/ncmppersistence/NcmpPersistence.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/NcmpPersistence.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.ncmppersistence;
+package org.onap.cps.ncmp.impl.inventory;
import java.time.OffsetDateTime;
import java.util.Collection;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/NcmpPersistenceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/NcmpPersistenceImpl.java
index 6a2d6d810b..905b09ef74 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/NcmpPersistenceImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/NcmpPersistenceImpl.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.inventory;
+package org.onap.cps.ncmp.impl.inventory;
import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED;
import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS;
@@ -29,11 +29,10 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.api.CpsDataService;
import org.onap.cps.api.CpsModuleService;
-import org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence;
+import org.onap.cps.impl.utils.CpsValidator;
import org.onap.cps.spi.FetchDescendantsOption;
import org.onap.cps.spi.exceptions.SchemaSetNotFoundException;
import org.onap.cps.spi.model.DataNode;
-import org.onap.cps.spi.utils.CpsValidator;
import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.stereotype.Component;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyCmHandleQueryService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryService.java
index 06522f80cf..03ec30b73b 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyCmHandleQueryService.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryService.java
@@ -18,13 +18,13 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api;
+package org.onap.cps.ncmp.impl.inventory;
import java.util.Collection;
-import org.onap.cps.ncmp.api.models.CmHandleQueryServiceParameters;
-import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
+import org.onap.cps.ncmp.api.inventory.models.CmHandleQueryServiceParameters;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
-public interface NetworkCmProxyCmHandleQueryService {
+public interface ParameterizedCmHandleQueryService {
/**
* Query and return cm handle ids that match the given query parameters.
* Supported query types:
@@ -51,21 +51,14 @@ public interface NetworkCmProxyCmHandleQueryService {
Collection<String> queryCmHandleIdsForInventory(CmHandleQueryServiceParameters cmHandleQueryServiceParameters);
/**
- * Query and return cm handle objects that match the given query parameters.
+ * Query and return yang model cm handle objects that match the given query parameters.
* Supported query types:
* public properties
* modules
* cps-path
*
* @param cmHandleQueryServiceParameters the cm handle query parameters
- * @return collection of cm handles
+ * @return collection of yang model cm handles
*/
- Collection<NcmpServiceCmHandle> queryCmHandles(CmHandleQueryServiceParameters cmHandleQueryServiceParameters);
-
- /**
- * Query and return all cm handle objects.
- *
- * @return collection of cm handles
- */
- Collection<NcmpServiceCmHandle> getAllCmHandles();
+ Collection<YangModelCmHandle> queryCmHandles(CmHandleQueryServiceParameters cmHandleQueryServiceParameters);
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandleQueryServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryServiceImpl.java
index 8890d14ae1..84229e2895 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandleQueryServiceImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryServiceImpl.java
@@ -18,16 +18,15 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl;
-
-import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_PARENT;
-import static org.onap.cps.ncmp.api.impl.utils.CmHandleQueryConditions.HAS_ALL_MODULES;
-import static org.onap.cps.ncmp.api.impl.utils.CmHandleQueryConditions.HAS_ALL_PROPERTIES;
-import static org.onap.cps.ncmp.api.impl.utils.CmHandleQueryConditions.WITH_CPS_PATH;
-import static org.onap.cps.ncmp.api.impl.utils.CmHandleQueryConditions.WITH_TRUST_LEVEL;
-import static org.onap.cps.ncmp.api.impl.utils.RestQueryParametersValidator.validateCpsPathConditionProperties;
-import static org.onap.cps.ncmp.api.impl.utils.RestQueryParametersValidator.validateModuleNameConditionProperties;
-import static org.onap.cps.ncmp.api.impl.utils.YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle;
+package org.onap.cps.ncmp.impl.inventory;
+
+import static org.onap.cps.ncmp.impl.inventory.CmHandleQueryParametersValidator.validateCpsPathConditionProperties;
+import static org.onap.cps.ncmp.impl.inventory.CmHandleQueryParametersValidator.validateModuleNameConditionProperties;
+import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NCMP_DMI_REGISTRY_PARENT;
+import static org.onap.cps.ncmp.impl.inventory.models.CmHandleQueryConditions.HAS_ALL_MODULES;
+import static org.onap.cps.ncmp.impl.inventory.models.CmHandleQueryConditions.HAS_ALL_PROPERTIES;
+import static org.onap.cps.ncmp.impl.inventory.models.CmHandleQueryConditions.WITH_CPS_PATH;
+import static org.onap.cps.ncmp.impl.inventory.models.CmHandleQueryConditions.WITH_TRUST_LEVEL;
import static org.onap.cps.spi.FetchDescendantsOption.DIRECT_CHILDREN_ONLY;
import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS;
@@ -40,67 +39,58 @@ import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
import org.onap.cps.cpspath.parser.PathParsingException;
-import org.onap.cps.ncmp.api.NetworkCmProxyCmHandleQueryService;
-import org.onap.cps.ncmp.api.impl.inventory.CmHandleQueries;
-import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence;
-import org.onap.cps.ncmp.api.impl.inventory.enums.PropertyType;
-import org.onap.cps.ncmp.api.impl.utils.InventoryQueryConditions;
-import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
-import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
-import org.onap.cps.ncmp.api.models.CmHandleQueryServiceParameters;
-import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
+import org.onap.cps.ncmp.api.inventory.models.CmHandleQueryServiceParameters;
+import org.onap.cps.ncmp.impl.inventory.models.InventoryQueryConditions;
+import org.onap.cps.ncmp.impl.inventory.models.PropertyType;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
+import org.onap.cps.ncmp.impl.utils.YangDataConverter;
import org.onap.cps.spi.exceptions.DataValidationException;
import org.onap.cps.spi.model.ConditionProperties;
import org.onap.cps.spi.model.DataNode;
import org.springframework.stereotype.Service;
@Service
-@Slf4j
@RequiredArgsConstructor
-public class NetworkCmProxyCmHandleQueryServiceImpl implements NetworkCmProxyCmHandleQueryService {
+public class ParameterizedCmHandleQueryServiceImpl implements ParameterizedCmHandleQueryService {
private static final Collection<String> NO_QUERY_TO_EXECUTE = null;
- private final CmHandleQueries cmHandleQueries;
+ private final CmHandleQueryService cmHandleQueryService;
private final InventoryPersistence inventoryPersistence;
@Override
public Collection<String> queryCmHandleIds(
final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
return executeQueries(cmHandleQueryServiceParameters,
- this::executeCpsPathQuery,
- this::queryCmHandlesByPublicProperties,
- this::executeModuleNameQuery,
+ this::executeCpsPathQuery,
+ this::queryCmHandlesByPublicProperties,
+ this::executeModuleNameQuery,
this::queryCmHandlesByTrustLevel);
}
@Override
public Collection<String> queryCmHandleIdsForInventory(
- final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
+ final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
return executeQueries(cmHandleQueryServiceParameters,
- this::queryCmHandlesByPublicProperties,
- this::queryCmHandlesByPrivateProperties,
- this::queryCmHandlesByDmiPlugin);
+ this::executeCpsPathQuery,
+ this::queryCmHandlesByPublicProperties,
+ this::queryCmHandlesByPrivateProperties,
+ this::queryCmHandlesByDmiPlugin);
}
@Override
- public Collection<NcmpServiceCmHandle> queryCmHandles(
- final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
-
+ public Collection<YangModelCmHandle> queryCmHandles(
+ final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
if (cmHandleQueryServiceParameters.getCmHandleQueryParameters().isEmpty()) {
return getAllCmHandles();
}
-
final Collection<String> cmHandleIds = queryCmHandleIds(cmHandleQueryServiceParameters);
-
- return getNcmpServiceCmHandles(cmHandleIds);
+ return inventoryPersistence.getYangModelCmHandles(cmHandleIds);
}
- @Override
- public Collection<NcmpServiceCmHandle> getAllCmHandles() {
+ private Collection<YangModelCmHandle> getAllCmHandles() {
final DataNode dataNode = inventoryPersistence.getDataNode(NCMP_DMI_REGISTRY_PARENT).iterator().next();
- return dataNode.getChildDataNodes().stream().map(this::createNcmpServiceCmHandle).collect(Collectors.toSet());
+ return dataNode.getChildDataNodes().stream().map(YangDataConverter::toYangModelCmHandle).toList();
}
private Collection<String> queryCmHandlesByDmiPlugin(
@@ -115,7 +105,7 @@ public class NetworkCmProxyCmHandleQueryServiceImpl implements NetworkCmProxyCmH
final String dmiPluginIdentifierValue = dmiPropertyQueryPairs
.get(PropertyType.DMI_PLUGIN.getYangContainerName());
- return cmHandleQueries.getCmHandleIdsByDmiPluginIdentifier(dmiPluginIdentifierValue);
+ return cmHandleQueryService.getCmHandleIdsByDmiPluginIdentifier(dmiPluginIdentifierValue);
}
private Collection<String> queryCmHandlesByPrivateProperties(
@@ -128,7 +118,7 @@ public class NetworkCmProxyCmHandleQueryServiceImpl implements NetworkCmProxyCmH
if (privatePropertyQueryPairs.isEmpty()) {
return NO_QUERY_TO_EXECUTE;
}
- return cmHandleQueries.queryCmHandleAdditionalProperties(privatePropertyQueryPairs);
+ return cmHandleQueryService.queryCmHandleAdditionalProperties(privatePropertyQueryPairs);
}
private Collection<String> queryCmHandlesByPublicProperties(
@@ -141,7 +131,7 @@ public class NetworkCmProxyCmHandleQueryServiceImpl implements NetworkCmProxyCmH
if (publicPropertyQueryPairs.isEmpty()) {
return NO_QUERY_TO_EXECUTE;
}
- return cmHandleQueries.queryCmHandlePublicProperties(publicPropertyQueryPairs);
+ return cmHandleQueryService.queryCmHandlePublicProperties(publicPropertyQueryPairs);
}
private Collection<String> queryCmHandlesByTrustLevel(final CmHandleQueryServiceParameters
@@ -154,7 +144,7 @@ public class NetworkCmProxyCmHandleQueryServiceImpl implements NetworkCmProxyCmH
if (trustLevelPropertyQueryPairs.isEmpty()) {
return NO_QUERY_TO_EXECUTE;
}
- return cmHandleQueries.queryCmHandlesByTrustLevel(trustLevelPropertyQueryPairs);
+ return cmHandleQueryService.queryCmHandlesByTrustLevel(trustLevelPropertyQueryPairs);
}
private Collection<String> executeModuleNameQuery(
@@ -180,7 +170,7 @@ public class NetworkCmProxyCmHandleQueryServiceImpl implements NetworkCmProxyCmH
}
try {
cpsPathQueryResult = collectCmHandleIdsFromDataNodes(
- cmHandleQueries.queryCmHandleAncestorsByCpsPath(
+ cmHandleQueryService.queryCmHandleAncestorsByCpsPath(
cpsPathCondition.get("cpsPath"), OMIT_DESCENDANTS));
} catch (final PathParsingException pathParsingException) {
throw new DataValidationException(pathParsingException.getMessage(), pathParsingException.getDetails(),
@@ -228,22 +218,6 @@ public class NetworkCmProxyCmHandleQueryServiceImpl implements NetworkCmProxyCmH
return collectCmHandleIdsFromDataNodes(dataNode.getChildDataNodes());
}
- private Collection<NcmpServiceCmHandle> getNcmpServiceCmHandles(final Collection<String> cmHandleIds) {
- final Collection<YangModelCmHandle> yangModelcmHandles
- = inventoryPersistence.getYangModelCmHandles(cmHandleIds);
-
- final Collection<NcmpServiceCmHandle> ncmpServiceCmHandles = new ArrayList<>(yangModelcmHandles.size());
-
- yangModelcmHandles.forEach(yangModelcmHandle ->
- ncmpServiceCmHandles.add(YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle(yangModelcmHandle))
- );
- return ncmpServiceCmHandles;
- }
-
- private NcmpServiceCmHandle createNcmpServiceCmHandle(final DataNode dataNode) {
- return convertYangModelCmHandleToNcmpServiceCmHandle(YangDataConverter.convertCmHandleToYangModel(dataNode));
- }
-
private Collection<String> executeQueries(final CmHandleQueryServiceParameters cmHandleQueryServiceParameters,
final Function<CmHandleQueryServiceParameters, Collection<String>>...
queryFunctions) {
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/CmHandleQueryConditions.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/models/CmHandleQueryConditions.java
index a59776036a..6be5c8ba16 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/CmHandleQueryConditions.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/models/CmHandleQueryConditions.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.utils;
+package org.onap.cps.ncmp.impl.inventory.models;
import java.util.Arrays;
import java.util.Collection;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CmHandleState.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/models/CmHandleState.java
index 5485ee7e80..9a4b3e2a83 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CmHandleState.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/models/CmHandleState.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.inventory;
+package org.onap.cps.ncmp.impl.inventory.models;
public enum CmHandleState {
ADVISED, READY, LOCKED, DELETING, DELETED
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/InventoryQueryConditions.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/models/InventoryQueryConditions.java
index 9437cf0bac..e0b54d2197 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/InventoryQueryConditions.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/models/InventoryQueryConditions.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.utils;
+package org.onap.cps.ncmp.impl.inventory.models;
import java.util.Arrays;
import java.util.List;
@@ -32,7 +32,8 @@ public enum InventoryQueryConditions {
HAS_ALL_PROPERTIES("hasAllProperties"),
HAS_ALL_ADDITIONAL_PROPERTIES("hasAllAdditionalProperties"),
- CM_HANDLE_WITH_DMI_PLUGIN("cmHandleWithDmiPlugin");
+ CM_HANDLE_WITH_DMI_PLUGIN("cmHandleWithDmiPlugin"),
+ WITH_CPS_PATH("cmHandleWithCpsPath");
public static final List<String> ALL_CONDITION_NAMES = Arrays.stream(InventoryQueryConditions.values())
.map(InventoryQueryConditions::getName).collect(Collectors.toList());
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/LockReasonCategory.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/models/LockReasonCategory.java
index e2b2c6b4ae..1003aeca2d 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/LockReasonCategory.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/models/LockReasonCategory.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.inventory;
+package org.onap.cps.ncmp.impl.inventory.models;
public enum LockReasonCategory {
MODULE_SYNC_FAILED,
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/ModelledDmiServiceLeaves.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/models/ModelledDmiServiceLeaves.java
index b8a1ba02db..e9c4957d0c 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/ModelledDmiServiceLeaves.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/models/ModelledDmiServiceLeaves.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.inventory;
+package org.onap.cps.ncmp.impl.inventory.models;
public enum ModelledDmiServiceLeaves {
DMI_SERVICE_NAME("dmi-service-name"),
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/enums/PropertyType.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/models/PropertyType.java
index 08bfe98e5c..cc8b094b4c 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/enums/PropertyType.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/models/PropertyType.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.inventory.enums;
+package org.onap.cps.ncmp.impl.inventory.models;
import lombok.AllArgsConstructor;
import lombok.Getter;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/models/YangModelCmHandle.java
index 2ca2b2eb0d..76ee286635 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/models/YangModelCmHandle.java
@@ -18,8 +18,7 @@
* ============LICENSE_END=========================================================
*/
-
-package org.onap.cps.ncmp.api.impl.yangmodels;
+package org.onap.cps.ncmp.impl.inventory.models;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
@@ -34,9 +33,9 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
-import org.onap.cps.ncmp.api.impl.inventory.CompositeState;
-import org.onap.cps.ncmp.api.impl.operations.RequiredDmiService;
-import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
+import org.onap.cps.ncmp.api.inventory.models.CompositeState;
+import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle;
+import org.onap.cps.ncmp.impl.models.RequiredDmiService;
/**
* Cm Handle which follows the Yang resource dmi registry model when persisting data to DMI or the DB.
@@ -126,10 +125,9 @@ public class YangModelCmHandle {
yangModelCmHandle.setDmiServiceName(dmiServiceName);
yangModelCmHandle.setDmiDataServiceName(dmiDataServiceName);
yangModelCmHandle.setDmiModelServiceName(dmiModelServiceName);
- yangModelCmHandle.setModuleSetTag(moduleSetTag == null ? StringUtils.EMPTY : moduleSetTag);
- yangModelCmHandle.setAlternateId(alternateId == null ? StringUtils.EMPTY : alternateId);
- yangModelCmHandle.setDataProducerIdentifier(
- dataProducerIdentifier == null ? StringUtils.EMPTY : dataProducerIdentifier);
+ yangModelCmHandle.setModuleSetTag(StringUtils.trimToEmpty(moduleSetTag));
+ yangModelCmHandle.setAlternateId(StringUtils.trimToEmpty(alternateId));
+ yangModelCmHandle.setDataProducerIdentifier(StringUtils.trimToEmpty(dataProducerIdentifier));
yangModelCmHandle.setDmiProperties(asYangModelCmHandleProperties(ncmpServiceCmHandle.getDmiProperties()));
yangModelCmHandle.setPublicProperties(asYangModelCmHandleProperties(
ncmpServiceCmHandle.getPublicProperties()));
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/executor/AsyncTaskExecutor.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/AsyncTaskExecutor.java
index 2d5e7a1abc..b8bb64f537 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/executor/AsyncTaskExecutor.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/AsyncTaskExecutor.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.inventory.sync.executor;
+package org.onap.cps.ncmp.impl.inventory.sync;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/DataSyncWatchdog.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/DataSyncWatchdog.java
index 6f089a57fb..c3973236f0 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/DataSyncWatchdog.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/DataSyncWatchdog.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2022-2023 Nordix Foundation
+ * Copyright (C) 2022-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.
@@ -18,9 +18,9 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.inventory.sync;
+package org.onap.cps.ncmp.impl.inventory.sync;
-import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME;
+import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME;
import com.hazelcast.map.IMap;
import java.time.OffsetDateTime;
@@ -29,10 +29,9 @@ import java.util.function.Consumer;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.api.CpsDataService;
-import org.onap.cps.ncmp.api.impl.config.embeddedcache.SynchronizationCacheConfig;
-import org.onap.cps.ncmp.api.impl.inventory.CompositeState;
-import org.onap.cps.ncmp.api.impl.inventory.DataStoreSyncState;
-import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence;
+import org.onap.cps.ncmp.api.inventory.models.CompositeState;
+import org.onap.cps.ncmp.impl.inventory.DataStoreSyncState;
+import org.onap.cps.ncmp.impl.inventory.InventoryPersistence;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@@ -61,21 +60,22 @@ public class DataSyncWatchdog {
moduleOperationsUtils.getUnsynchronizedReadyCmHandles().forEach(unSynchronizedReadyCmHandle -> {
final String cmHandleId = unSynchronizedReadyCmHandle.getId();
if (hasPushedIntoSemaphoreMap(cmHandleId)) {
- log.debug("Executing data sync on {}", cmHandleId);
+ log.info("Executing data sync on {}", cmHandleId);
final CompositeState compositeState = inventoryPersistence
.getCmHandleState(cmHandleId);
final String resourceData = moduleOperationsUtils.getResourceData(cmHandleId);
if (resourceData == null) {
- log.debug("Error retrieving resource data for Cm-Handle: {}", cmHandleId);
+ log.error("Error retrieving resource data for Cm-Handle: {}", cmHandleId);
} else {
cpsDataService.saveData(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId,
resourceData, OffsetDateTime.now());
setSyncStateToSynchronized().accept(compositeState);
inventoryPersistence.saveCmHandleState(cmHandleId, compositeState);
updateDataSyncSemaphoreMap(cmHandleId);
+ log.info("Data sync finished for {}", cmHandleId);
}
} else {
- log.debug("{} already processed by another instance", cmHandleId);
+ log.info("{} already processed by another instance", cmHandleId);
}
});
log.debug("No Cm-Handles currently found in READY State and Operational Sync State is UNSYNCHRONIZED");
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperations.java
index 2a9248a165..8ba70b3a31 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperations.java
@@ -19,48 +19,42 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.operations;
+package org.onap.cps.ncmp.impl.inventory.sync;
-import static org.onap.cps.ncmp.api.impl.operations.RequiredDmiService.MODEL;
+import static org.onap.cps.ncmp.api.data.models.OperationType.READ;
+import static org.onap.cps.ncmp.impl.models.RequiredDmiService.MODEL;
import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import org.onap.cps.ncmp.api.impl.client.DmiRestClient;
-import org.onap.cps.ncmp.api.impl.config.DmiWebClientConfiguration.DmiProperties;
-import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence;
-import org.onap.cps.ncmp.api.impl.utils.DmiServiceUrlBuilder;
-import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
-import org.onap.cps.ncmp.api.models.YangResource;
+import lombok.RequiredArgsConstructor;
+import org.onap.cps.ncmp.api.inventory.models.YangResource;
+import org.onap.cps.ncmp.impl.dmi.DmiProperties;
+import org.onap.cps.ncmp.impl.dmi.DmiRestClient;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
+import org.onap.cps.ncmp.impl.models.DmiRequestBody;
+import org.onap.cps.ncmp.impl.utils.http.RestServiceUrlTemplateBuilder;
+import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters;
import org.onap.cps.spi.model.ModuleReference;
import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
/**
* Operations class for DMI Model.
*/
-@Component
-public class DmiModelOperations extends DmiOperations {
+@RequiredArgsConstructor
+@Service
+public class DmiModelOperations {
- /**
- * Constructor for {@code DmiOperations}. This method also manipulates url properties.
- *
- * @param dmiRestClient {@code DmiRestClient}
- */
- public DmiModelOperations(final InventoryPersistence inventoryPersistence,
- final JsonObjectMapper jsonObjectMapper,
- final DmiProperties dmiProperties,
- final DmiRestClient dmiRestClient, final DmiServiceUrlBuilder dmiServiceUrlBuilder) {
- super(inventoryPersistence, jsonObjectMapper, dmiProperties, dmiRestClient, dmiServiceUrlBuilder);
- }
+ private final JsonObjectMapper jsonObjectMapper;
+ private final DmiProperties dmiProperties;
+ private final DmiRestClient dmiRestClient;
/**
* Retrieves module references.
@@ -113,9 +107,13 @@ public class DmiModelOperations extends DmiOperations {
final String jsonRequestBody,
final String cmHandle,
final String resourceName) {
- final String dmiResourceDataUrl = getDmiResourceUrl(dmiServiceName, cmHandle, resourceName);
- return dmiRestClient.postOperationWithJsonData(dmiResourceDataUrl, jsonRequestBody,
- OperationType.READ, null);
+ final UrlTemplateParameters urlTemplateParameters = RestServiceUrlTemplateBuilder.newInstance()
+ .fixedPathSegment("ch")
+ .variablePathSegment("cmHandleId", cmHandle)
+ .fixedPathSegment(resourceName)
+ .createUrlTemplateParameters(dmiServiceName, dmiProperties.getDmiBasePath());
+ return dmiRestClient.synchronousPostOperationWithJsonData(MODEL, urlTemplateParameters, jsonRequestBody, READ,
+ null);
}
private static String getRequestBodyToFetchYangResources(final Collection<ModuleReference> newModuleReferences,
@@ -126,8 +124,7 @@ public class DmiModelOperations extends DmiOperations {
data.add("modules", moduleReferencesAsJson);
final JsonObject jsonRequestObject = new JsonObject();
if (!moduleSetTag.isEmpty()) {
- final JsonElement moduleSetTagAsJson = JsonParser.parseString(moduleSetTag);
- jsonRequestObject.add("moduleSetTag", moduleSetTagAsJson);
+ jsonRequestObject.addProperty("moduleSetTag", moduleSetTag);
}
jsonRequestObject.add("data", data);
jsonRequestObject.add("cmHandleProperties", toJsonObject(dmiProperties));
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleOperationsUtils.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleOperationsUtils.java
index 794ca5b1b6..aae1769968 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleOperationsUtils.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleOperationsUtils.java
@@ -19,15 +19,11 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.inventory.sync;
-
-import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_OPERATIONAL;
+package org.onap.cps.ncmp.impl.inventory.sync;
import com.fasterxml.jackson.databind.JsonNode;
-import java.time.Duration;
-import java.time.OffsetDateTime;
-import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
@@ -38,14 +34,14 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.onap.cps.ncmp.api.impl.inventory.CmHandleQueries;
-import org.onap.cps.ncmp.api.impl.inventory.CmHandleState;
-import org.onap.cps.ncmp.api.impl.inventory.CompositeState;
-import org.onap.cps.ncmp.api.impl.inventory.DataStoreSyncState;
-import org.onap.cps.ncmp.api.impl.inventory.LockReasonCategory;
-import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations;
-import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
-import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.ncmp.api.inventory.models.CompositeState;
+import org.onap.cps.ncmp.impl.data.DmiDataOperations;
+import org.onap.cps.ncmp.impl.inventory.CmHandleQueryService;
+import org.onap.cps.ncmp.impl.inventory.DataStoreSyncState;
+import org.onap.cps.ncmp.impl.inventory.models.CmHandleState;
+import org.onap.cps.ncmp.impl.inventory.models.LockReasonCategory;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
+import org.onap.cps.ncmp.impl.utils.YangDataConverter;
import org.onap.cps.spi.FetchDescendantsOption;
import org.onap.cps.spi.model.DataNode;
import org.onap.cps.utils.JsonObjectMapper;
@@ -57,14 +53,13 @@ import org.springframework.stereotype.Service;
@RequiredArgsConstructor
public class ModuleOperationsUtils {
- private final CmHandleQueries cmHandleQueries;
+ private final CmHandleQueryService cmHandleQueryService;
private final DmiDataOperations dmiDataOperations;
private final JsonObjectMapper jsonObjectMapper;
private static final String RETRY_ATTEMPT_KEY = "attempt";
private static final String MODULE_SET_TAG_KEY = "moduleSetTag";
public static final String MODULE_SET_TAG_MESSAGE_FORMAT = "Upgrade to ModuleSetTag: %s";
- private static final String LOCK_REASON_DETAILS_MSG_FORMAT =
- MODULE_SET_TAG_MESSAGE_FORMAT + " Attempt #%d failed: %s";
+ private static final String LOCK_REASON_DETAILS_MSG_FORMAT = " Attempt #%d failed: %s";
private static final Pattern retryAttemptPattern = Pattern.compile("Attempt #(\\d+) failed:.+");
private static final Pattern moduleSetTagPattern = Pattern.compile("Upgrade to ModuleSetTag: (\\S+)");
private static final String CPS_PATH_CM_HANDLES_MODEL_SYNC_FAILED_OR_UPGRADE = """
@@ -77,8 +72,9 @@ public class ModuleOperationsUtils {
*
* @return cm handles (data nodes) in ADVISED state (empty list if none found)
*/
- public List<DataNode> getAdvisedCmHandles() {
- final List<DataNode> advisedCmHandlesAsDataNodes = cmHandleQueries.queryCmHandlesByState(CmHandleState.ADVISED);
+ public Collection<DataNode> getAdvisedCmHandles() {
+ final Collection<DataNode> advisedCmHandlesAsDataNodes =
+ cmHandleQueryService.queryCmHandlesByState(CmHandleState.ADVISED);
log.debug("Total number of fetched advised cm handle(s) is (are) {}", advisedCmHandlesAsDataNodes.size());
return advisedCmHandlesAsDataNodes;
}
@@ -91,13 +87,13 @@ public class ModuleOperationsUtils {
* return empty list if not found
*/
public List<YangModelCmHandle> getUnsynchronizedReadyCmHandles() {
- final List<DataNode> unsynchronizedCmHandles = cmHandleQueries
+ final Collection<DataNode> unsynchronizedCmHandles = cmHandleQueryService
.queryCmHandlesByOperationalSyncState(DataStoreSyncState.UNSYNCHRONIZED);
final List<YangModelCmHandle> yangModelCmHandles = new ArrayList<>();
for (final DataNode unsynchronizedCmHandle : unsynchronizedCmHandles) {
final String cmHandleId = unsynchronizedCmHandle.getLeaves().get("id").toString();
- if (cmHandleQueries.cmHandleHasState(cmHandleId, CmHandleState.READY)) {
+ if (cmHandleQueryService.cmHandleHasState(cmHandleId, CmHandleState.READY)) {
yangModelCmHandles.addAll(convertCmHandlesDataNodesToYangModelCmHandles(
Collections.singletonList(unsynchronizedCmHandle)));
}
@@ -111,31 +107,33 @@ public class ModuleOperationsUtils {
*
* @return a random LOCKED yang model cm handle, return null if not found
*/
- public List<YangModelCmHandle> getCmHandlesThatFailedModelSyncOrUpgrade() {
- final List<DataNode> lockedCmHandlesAsDataNodeList
- = cmHandleQueries.queryCmHandleAncestorsByCpsPath(CPS_PATH_CM_HANDLES_MODEL_SYNC_FAILED_OR_UPGRADE,
+ public Collection<YangModelCmHandle> getCmHandlesThatFailedModelSyncOrUpgrade() {
+ final Collection<DataNode> lockedCmHandlesAsDataNodeList
+ = cmHandleQueryService.queryCmHandleAncestorsByCpsPath(CPS_PATH_CM_HANDLES_MODEL_SYNC_FAILED_OR_UPGRADE,
FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS);
return convertCmHandlesDataNodesToYangModelCmHandles(lockedCmHandlesAsDataNodeList);
}
/**
- * Update Composite State attempts counter and set new lock reason and details.
+ * Updates the lock reason message and attempt counter for the provided CompositeState.
+ * This method increments the attempt counter and updates the lock reason message,
+ * including the module set tag if available.
*
- * @param lockReasonCategory lock reason category
- * @param errorMessage error message
+ * @param compositeState the composite state of the CM handle
+ * @param lockReasonCategory the lock reason category for the CM handle
+ * @param errorMessage the error message to include in the lock reason message
*/
- public void updateLockReasonDetailsAndAttempts(final CompositeState compositeState,
- final LockReasonCategory lockReasonCategory,
- final String errorMessage) {
- int attempt = 1;
- final Map<String, String> compositeStateDetails
- = getLockedCompositeStateDetails(compositeState.getLockReason());
- if (!compositeStateDetails.isEmpty() && compositeStateDetails.containsKey(RETRY_ATTEMPT_KEY)) {
- attempt = 1 + Integer.parseInt(compositeStateDetails.get(RETRY_ATTEMPT_KEY));
- }
- final String moduleSetTag = compositeStateDetails.getOrDefault(MODULE_SET_TAG_KEY, "");
+ public void updateLockReasonWithAttempts(final CompositeState compositeState,
+ final LockReasonCategory lockReasonCategory,
+ final String errorMessage) {
+ final Map<String, String> lockedStateDetails = getLockedCompositeStateDetails(compositeState.getLockReason());
+ final int nextAttemptCount = calculateNextAttemptCount(lockedStateDetails);
+ final String moduleSetTag = lockedStateDetails.getOrDefault(MODULE_SET_TAG_KEY, "");
+
+ final String lockReasonMessage = buildLockReasonDetails(moduleSetTag, nextAttemptCount, errorMessage);
+
compositeState.setLockReason(CompositeState.LockReason.builder()
- .details(String.format(LOCK_REASON_DETAILS_MSG_FORMAT, moduleSetTag, attempt, errorMessage))
+ .details(lockReasonMessage)
.lockReasonCategory(lockReasonCategory)
.build());
}
@@ -166,48 +164,15 @@ public class ModuleOperationsUtils {
return Collections.emptyMap();
}
-
/**
- * Check if a module sync retry is needed.
- *
- * @param compositeState the composite state currently in the locked state
- * @return if the retry mechanism should be attempted
- */
- public boolean needsModuleSyncRetryOrUpgrade(final CompositeState compositeState) {
- final OffsetDateTime time = OffsetDateTime.parse(compositeState.getLastUpdateTime(),
- DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ"));
- final CompositeState.LockReason lockReason = compositeState.getLockReason();
-
- final boolean moduleUpgrade = LockReasonCategory.MODULE_UPGRADE == lockReason.getLockReasonCategory();
- if (moduleUpgrade) {
- log.info("Locked for module upgrade");
- return true;
- }
-
- final boolean failedDuringModuleSync = LockReasonCategory.MODULE_SYNC_FAILED
- == lockReason.getLockReasonCategory();
- final boolean failedDuringModuleUpgrade = LockReasonCategory.MODULE_UPGRADE_FAILED
- == lockReason.getLockReasonCategory();
-
- if (failedDuringModuleSync || failedDuringModuleUpgrade) {
- log.info("Locked for module {} (last attempt failed).", failedDuringModuleSync ? "sync" : "upgrade");
- return isRetryDue(lockReason, time);
- }
- log.info("Locked for other reason");
- return false;
- }
-
- /**
- * Get the Resourece Data from Node through DMI Passthrough service.
+ * Get the Resource Data from Node through DMI Passthrough service.
*
* @param cmHandleId cm handle id
* @return optional string containing the resource data
*/
public String getResourceData(final String cmHandleId) {
- final ResponseEntity<Object> resourceDataResponseEntity = dmiDataOperations.getResourceDataFromDmi(
- PASSTHROUGH_OPERATIONAL.getDatastoreName(),
- cmHandleId,
- UUID.randomUUID().toString());
+ final ResponseEntity<Object> resourceDataResponseEntity = dmiDataOperations.getAllResourceDataFromDmi(
+ cmHandleId, UUID.randomUUID().toString());
if (resourceDataResponseEntity.getStatusCode().is2xxSuccessful()) {
return getFirstResource(resourceDataResponseEntity.getBody());
}
@@ -239,27 +204,23 @@ public class ModuleOperationsUtils {
return jsonObjectMapper.asJsonString(Map.of(firstElement.getKey(), firstElement.getValue()));
}
- private List<YangModelCmHandle> convertCmHandlesDataNodesToYangModelCmHandles(
- final List<DataNode> cmHandlesAsDataNodeList) {
- return cmHandlesAsDataNodeList.stream().map(YangDataConverter::convertCmHandleToYangModel).toList();
+ private Collection<YangModelCmHandle> convertCmHandlesDataNodesToYangModelCmHandles(
+ final Collection<DataNode> cmHandlesAsDataNodeList) {
+ return cmHandlesAsDataNodeList.stream().map(YangDataConverter::toYangModelCmHandle).toList();
}
- private boolean isRetryDue(final CompositeState.LockReason compositeStateLockReason, final OffsetDateTime time) {
- final int timeInMinutesUntilNextAttempt;
- final Map<String, String> compositeStateDetails = getLockedCompositeStateDetails(compositeStateLockReason);
- if (compositeStateDetails.isEmpty()) {
- timeInMinutesUntilNextAttempt = 1;
- log.info("First Attempt: no current attempts found.");
- } else {
- timeInMinutesUntilNextAttempt = (int) Math.pow(2, Integer.parseInt(compositeStateDetails
- .get(RETRY_ATTEMPT_KEY)));
- }
- final int timeSinceLastAttempt = (int) Duration.between(time, OffsetDateTime.now()).toMinutes();
- if (timeInMinutesUntilNextAttempt >= timeSinceLastAttempt) {
- log.info("Time until next attempt is {} minutes: ", timeInMinutesUntilNextAttempt - timeSinceLastAttempt);
- return false;
+ private int calculateNextAttemptCount(final Map<String, String> compositeStateDetails) {
+ return compositeStateDetails.containsKey(RETRY_ATTEMPT_KEY)
+ ? 1 + Integer.parseInt(compositeStateDetails.get(RETRY_ATTEMPT_KEY))
+ : 1;
+ }
+
+ private String buildLockReasonDetails(final String moduleSetTag, final int attempt, final String errorMessage) {
+ if (moduleSetTag.isEmpty()) {
+ return String.format(LOCK_REASON_DETAILS_MSG_FORMAT, attempt, errorMessage);
}
- log.info("Retry due now");
- return true;
+ return String.format(MODULE_SET_TAG_MESSAGE_FORMAT + " " + LOCK_REASON_DETAILS_MSG_FORMAT,
+ moduleSetTag, attempt, errorMessage);
}
+
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncService.java
index e257112fc3..ca0f1c6a6d 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncService.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncService.java
@@ -1,6 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2022-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.
@@ -18,35 +19,29 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.inventory.sync;
+package org.onap.cps.ncmp.impl.inventory.sync;
-import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DATASPACE_NAME;
-import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_ANCHOR;
-import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_PARENT;
-import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME;
+import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NCMP_DATASPACE_NAME;
+import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NCMP_DMI_REGISTRY_ANCHOR;
+import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NCMP_DMI_REGISTRY_PARENT;
+import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME;
import java.time.OffsetDateTime;
import java.util.Collection;
import java.util.Collections;
-import java.util.List;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
import org.onap.cps.api.CpsAnchorService;
import org.onap.cps.api.CpsDataService;
import org.onap.cps.api.CpsModuleService;
-import org.onap.cps.ncmp.api.impl.inventory.CmHandleQueries;
-import org.onap.cps.ncmp.api.impl.inventory.CmHandleState;
-import org.onap.cps.ncmp.api.impl.operations.DmiModelOperations;
-import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
-import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.ncmp.impl.inventory.models.CmHandleState;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
import org.onap.cps.spi.CascadeDeleteAllowed;
-import org.onap.cps.spi.FetchDescendantsOption;
import org.onap.cps.spi.exceptions.SchemaSetNotFoundException;
-import org.onap.cps.spi.model.DataNode;
import org.onap.cps.spi.model.ModuleReference;
+import org.onap.cps.utils.ContentType;
import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.stereotype.Service;
@@ -57,7 +52,6 @@ public class ModuleSyncService {
private final DmiModelOperations dmiModelOperations;
private final CpsModuleService cpsModuleService;
- private final CmHandleQueries cmHandleQueries;
private final CpsDataService cpsDataService;
private final CpsAnchorService cpsAnchorService;
private final JsonObjectMapper jsonObjectMapper;
@@ -112,40 +106,32 @@ public class ModuleSyncService {
}
private ModuleDelta getModuleDelta(final YangModelCmHandle yangModelCmHandle, final String targetModuleSetTag) {
- final Collection<ModuleReference> allModuleReferences;
final Map<String, String> newYangResources;
-
- final YangModelCmHandle cmHandleWithSameModuleSetTag = getAnyReadyCmHandleByModuleSetTag(targetModuleSetTag);
- if (cmHandleWithSameModuleSetTag == null) {
+ Collection<ModuleReference> allModuleReferences = getModuleReferencesByModuleSetTag(targetModuleSetTag);
+ if (allModuleReferences.isEmpty()) {
allModuleReferences = dmiModelOperations.getModuleReferences(yangModelCmHandle);
newYangResources = dmiModelOperations.getNewYangResourcesFromDmi(yangModelCmHandle,
cpsModuleService.identifyNewModuleReferences(allModuleReferences));
} else {
log.info("Found other cm handle having same module set tag: {}", targetModuleSetTag);
- allModuleReferences = cpsModuleService.getYangResourcesModuleReferences(
- NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleWithSameModuleSetTag.getId());
newYangResources = NO_NEW_MODULES;
}
return new ModuleDelta(allModuleReferences, newYangResources);
}
- private YangModelCmHandle getAnyReadyCmHandleByModuleSetTag(final String moduleSetTag) {
- if (StringUtils.isBlank(moduleSetTag)) {
- return null;
+ private Collection<ModuleReference> getModuleReferencesByModuleSetTag(final String moduleSetTag) {
+ if (moduleSetTag == null || moduleSetTag.trim().isEmpty()) {
+ return Collections.emptyList();
}
- final String escapedModuleSetTag = moduleSetTag.replace("'", "''");
- final List<DataNode> dataNodes = cmHandleQueries.queryNcmpRegistryByCpsPath(
- NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@module-set-tag='" + escapedModuleSetTag + "']",
- FetchDescendantsOption.DIRECT_CHILDREN_ONLY);
- return dataNodes.stream().map(YangDataConverter::convertCmHandleToYangModel)
- .filter(cmHandle -> cmHandle.getCompositeState().getCmHandleState() == CmHandleState.READY)
- .findFirst().orElse(null);
+ return cpsModuleService.getModuleReferencesByAttribute(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
+ Map.of("module-set-tag", moduleSetTag), Map.of("cm-handle-state", CmHandleState.READY.name()));
}
private void setCmHandleModuleSetTag(final YangModelCmHandle yangModelCmHandle, final String newModuleSetTag) {
final String jsonForUpdate = jsonObjectMapper.asJsonString(Map.of(
"cm-handles", Map.of("id", yangModelCmHandle.getId(), "module-set-tag", newModuleSetTag)));
cpsDataService.updateNodeLeaves(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, NCMP_DMI_REGISTRY_PARENT,
- jsonForUpdate, OffsetDateTime.now());
+ jsonForUpdate, OffsetDateTime.now(), ContentType.JSON);
}
+
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncTasks.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncTasks.java
index 590cb56c48..c6deb79d4d 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncTasks.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncTasks.java
@@ -18,24 +18,23 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.inventory.sync;
+package org.onap.cps.ncmp.impl.inventory.sync;
import com.hazelcast.map.IMap;
import java.util.Collection;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.onap.cps.ncmp.api.impl.events.lcm.LcmEventsCmHandleStateHandler;
-import org.onap.cps.ncmp.api.impl.inventory.CmHandleState;
-import org.onap.cps.ncmp.api.impl.inventory.CompositeState;
-import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence;
-import org.onap.cps.ncmp.api.impl.inventory.LockReasonCategory;
-import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
-import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.ncmp.api.inventory.models.CompositeState;
+import org.onap.cps.ncmp.impl.inventory.InventoryPersistence;
+import org.onap.cps.ncmp.impl.inventory.models.CmHandleState;
+import org.onap.cps.ncmp.impl.inventory.models.LockReasonCategory;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
+import org.onap.cps.ncmp.impl.inventory.sync.lcm.LcmEventsCmHandleStateHandler;
+import org.onap.cps.ncmp.impl.utils.YangDataConverter;
import org.onap.cps.spi.model.DataNode;
import org.springframework.stereotype.Component;
@@ -64,8 +63,7 @@ public class ModuleSyncTasks {
= new HashMap<>(cmHandlesAsDataNodes.size());
for (final DataNode cmHandleAsDataNode : cmHandlesAsDataNodes) {
final String cmHandleId = String.valueOf(cmHandleAsDataNode.getLeaves().get("id"));
- final YangModelCmHandle yangModelCmHandle =
- YangDataConverter.convertCmHandleToYangModel(cmHandleAsDataNode);
+ final YangModelCmHandle yangModelCmHandle = YangDataConverter.toYangModelCmHandle(cmHandleAsDataNode);
final CompositeState compositeState = inventoryPersistence.getCmHandleState(cmHandleId);
final boolean inUpgrade = ModuleOperationsUtils.inUpgradeOrUpgradeFailed(compositeState);
try {
@@ -81,7 +79,7 @@ public class ModuleSyncTasks {
log.warn("Processing of {} module failed due to reason {}.", cmHandleId, e.getMessage());
final LockReasonCategory lockReasonCategory = inUpgrade ? LockReasonCategory.MODULE_UPGRADE_FAILED
: LockReasonCategory.MODULE_SYNC_FAILED;
- moduleOperationsUtils.updateLockReasonDetailsAndAttempts(compositeState,
+ moduleOperationsUtils.updateLockReasonWithAttempts(compositeState,
lockReasonCategory, e.getMessage());
setCmHandleStateLocked(yangModelCmHandle, compositeState.getLockReason());
cmHandelStatePerCmHandle.put(yangModelCmHandle, CmHandleState.LOCKED);
@@ -97,23 +95,23 @@ public class ModuleSyncTasks {
}
/**
- * Reset state to "ADVISED" for any previously failed cm handles.
+ * Resets the state of failed CM handles and updates their status to ADVISED for retry.
+
+ * This method processes a collection of failed CM handles, logs their lock reason, and resets their state
+ * to ADVISED. Once reset, it updates the CM handle states in a batch to allow for re-attempt by the module-sync
+ * watchdog.
*
- * @param failedCmHandles previously failed (locked) cm handles
+ * @param failedCmHandles a collection of CM handles that have failed and need their state reset
*/
- public void resetFailedCmHandles(final List<YangModelCmHandle> failedCmHandles) {
+ public void resetFailedCmHandles(final Collection<YangModelCmHandle> failedCmHandles) {
final Map<YangModelCmHandle, CmHandleState> cmHandleStatePerCmHandle = new HashMap<>(failedCmHandles.size());
for (final YangModelCmHandle failedCmHandle : failedCmHandles) {
final CompositeState compositeState = failedCmHandle.getCompositeState();
- final boolean isReadyForRetry = moduleOperationsUtils.needsModuleSyncRetryOrUpgrade(compositeState);
- log.info("Retry for cmHandleId : {} is {}", failedCmHandle.getId(), isReadyForRetry);
- if (isReadyForRetry) {
- final String resetCmHandleId = failedCmHandle.getId();
- log.debug("Reset cm handle {} state to ADVISED to be re-attempted by module-sync watchdog",
- resetCmHandleId);
- cmHandleStatePerCmHandle.put(failedCmHandle, CmHandleState.ADVISED);
- removeResetCmHandleFromModuleSyncMap(resetCmHandleId);
- }
+ final String resetCmHandleId = failedCmHandle.getId();
+ log.debug("Resetting CM handle {} state to ADVISED for retry by the module-sync watchdog. Lock reason: {}",
+ failedCmHandle.getId(), compositeState.getLockReason().getLockReasonCategory().name());
+ cmHandleStatePerCmHandle.put(failedCmHandle, CmHandleState.ADVISED);
+ removeResetCmHandleFromModuleSyncMap(resetCmHandleId);
}
lcmEventsCmHandleStateHandler.updateCmHandleStateBatch(cmHandleStatePerCmHandle);
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncWatchdog.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncWatchdog.java
index 249232d230..bc7d6cdf67 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncWatchdog.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncWatchdog.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2022-2023 Nordix Foundation
+ * Copyright (C) 2022-2024 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,21 +19,18 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.inventory.sync;
+package org.onap.cps.ncmp.impl.inventory.sync;
import com.hazelcast.map.IMap;
import java.util.Collection;
import java.util.HashSet;
-import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.onap.cps.ncmp.api.impl.config.embeddedcache.SynchronizationCacheConfig;
-import org.onap.cps.ncmp.api.impl.inventory.sync.executor.AsyncTaskExecutor;
-import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
import org.onap.cps.spi.model.DataNode;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@@ -85,10 +82,10 @@ public class ModuleSyncWatchdog {
/**
* Find any failed (locked) cm handles and change state back to 'ADVISED'.
*/
- @Scheduled(fixedDelayString = "${ncmp.timers.locked-modules-sync.sleep-time-ms:300000}")
+ @Scheduled(fixedDelayString = "${ncmp.timers.locked-modules-sync.sleep-time-ms:15000}")
public void resetPreviouslyFailedCmHandles() {
log.info("Processing module sync retry-watchdog waking up.");
- final List<YangModelCmHandle> failedCmHandles
+ final Collection<YangModelCmHandle> failedCmHandles
= moduleOperationsUtils.getCmHandlesThatFailedModelSyncOrUpgrade();
log.info("Retrying {} cmHandles", failedCmHandles.size());
moduleSyncTasks.resetFailedCmHandles(failedCmHandles);
@@ -105,7 +102,7 @@ public class ModuleSyncWatchdog {
private void populateWorkQueueIfNeeded() {
if (moduleSyncWorkQueue.isEmpty()) {
- final List<DataNode> advisedCmHandles = moduleOperationsUtils.getAdvisedCmHandles();
+ final Collection<DataNode> advisedCmHandles = moduleOperationsUtils.getAdvisedCmHandles();
log.info("Processing module sync fetched {} advised cm handles from DB", advisedCmHandles.size());
for (final DataNode advisedCmHandle : advisedCmHandles) {
if (!moduleSyncWorkQueue.offer(advisedCmHandle)) {
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationCacheConfig.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/SynchronizationCacheConfig.java
index 62a380ca5c..76b33cc8d9 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationCacheConfig.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/SynchronizationCacheConfig.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.config.embeddedcache;
+package org.onap.cps.ncmp.impl.inventory.sync;
import com.hazelcast.config.MapConfig;
import com.hazelcast.config.QueueConfig;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/config/WatchdogSchedulingConfigurer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/WatchdogSchedulingConfigurer.java
index 1aaee2708f..203c5a1a20 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/config/WatchdogSchedulingConfigurer.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/WatchdogSchedulingConfigurer.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.inventory.sync.config;
+package org.onap.cps.ncmp.impl.inventory.sync;
import java.util.concurrent.ThreadPoolExecutor;
import org.springframework.context.annotation.Bean;
@@ -53,4 +53,4 @@ public class WatchdogSchedulingConfigurer implements SchedulingConfigurer {
taskScheduler.initialize();
return taskScheduler;
}
-} \ No newline at end of file
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventHeaderMapper.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventHeaderMapper.java
index f7707d9f76..7395838306 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventHeaderMapper.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventHeaderMapper.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.events.lcm;
+package org.onap.cps.ncmp.impl.inventory.sync.lcm;
import org.mapstruct.Mapper;
import org.onap.cps.ncmp.events.lcm.v1.LcmEvent;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventType.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventType.java
index a8d00f7e31..4bc2f10218 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventType.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventType.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.events.lcm;
+package org.onap.cps.ncmp.impl.inventory.sync.lcm;
public enum LcmEventType {
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventsCmHandleStateHandler.java
index 8274772d2c..6cce153269 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandler.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventsCmHandleStateHandler.java
@@ -18,12 +18,12 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.events.lcm;
+package org.onap.cps.ncmp.impl.inventory.sync.lcm;
import java.util.Collection;
import java.util.Map;
-import org.onap.cps.ncmp.api.impl.inventory.CmHandleState;
-import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.ncmp.impl.inventory.models.CmHandleState;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
/**
* The implementation of it should handle the persisting of composite state and delegate the request to publish the
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandlerAsyncHelper.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventsCmHandleStateHandlerAsyncHelper.java
index 3742719e26..cf7921c350 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandlerAsyncHelper.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventsCmHandleStateHandlerAsyncHelper.java
@@ -18,15 +18,15 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.events.lcm;
+package org.onap.cps.ncmp.impl.inventory.sync.lcm;
import java.util.Collection;
import lombok.RequiredArgsConstructor;
-import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
-import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
-import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
+import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle;
import org.onap.cps.ncmp.events.lcm.v1.LcmEvent;
import org.onap.cps.ncmp.events.lcm.v1.LcmEventHeader;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
+import org.onap.cps.ncmp.impl.utils.YangDataConverter;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@@ -74,6 +74,6 @@ public class LcmEventsCmHandleStateHandlerAsyncHelper {
}
private static NcmpServiceCmHandle toNcmpServiceCmHandle(final YangModelCmHandle yangModelCmHandle) {
- return YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle(yangModelCmHandle);
+ return YangDataConverter.toNcmpServiceCmHandle(yangModelCmHandle);
}
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandlerImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventsCmHandleStateHandlerImpl.java
index 0ed95adff2..b1b7b955f7 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandlerImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventsCmHandleStateHandlerImpl.java
@@ -18,12 +18,12 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.events.lcm;
+package org.onap.cps.ncmp.impl.inventory.sync.lcm;
-import static org.onap.cps.ncmp.api.impl.inventory.CmHandleState.ADVISED;
-import static org.onap.cps.ncmp.api.impl.inventory.CmHandleState.DELETED;
-import static org.onap.cps.ncmp.api.impl.inventory.CmHandleState.LOCKED;
-import static org.onap.cps.ncmp.api.impl.inventory.CmHandleState.READY;
+import static org.onap.cps.ncmp.impl.inventory.models.CmHandleState.ADVISED;
+import static org.onap.cps.ncmp.impl.inventory.models.CmHandleState.DELETED;
+import static org.onap.cps.ncmp.impl.inventory.models.CmHandleState.LOCKED;
+import static org.onap.cps.ncmp.impl.inventory.models.CmHandleState.READY;
import io.micrometer.core.annotation.Timed;
import java.util.ArrayList;
@@ -37,13 +37,13 @@ import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
-import org.onap.cps.ncmp.api.impl.inventory.CmHandleState;
-import org.onap.cps.ncmp.api.impl.inventory.CompositeState;
-import org.onap.cps.ncmp.api.impl.inventory.CompositeStateUtils;
-import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence;
-import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
-import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
-import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
+import org.onap.cps.ncmp.api.inventory.models.CompositeState;
+import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle;
+import org.onap.cps.ncmp.impl.inventory.CompositeStateUtils;
+import org.onap.cps.ncmp.impl.inventory.InventoryPersistence;
+import org.onap.cps.ncmp.impl.inventory.models.CmHandleState;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
+import org.onap.cps.ncmp.impl.utils.YangDataConverter;
import org.springframework.stereotype.Service;
@Slf4j
@@ -194,7 +194,7 @@ public class LcmEventsCmHandleStateHandlerImpl implements LcmEventsCmHandleState
}
private NcmpServiceCmHandle toNcmpServiceCmHandle(final YangModelCmHandle yangModelCmHandle) {
- return YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle(yangModelCmHandle);
+ return YangDataConverter.toNcmpServiceCmHandle(yangModelCmHandle);
}
@Getter
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreator.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventsCreator.java
index fa27be158a..5137515758 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreator.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventsCreator.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.events.lcm;
+package org.onap.cps.ncmp.impl.inventory.sync.lcm;
import java.util.UUID;
import lombok.Getter;
@@ -26,12 +26,12 @@ import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
-import org.onap.cps.ncmp.api.impl.utils.EventDateTimeFormatter;
-import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
+import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle;
import org.onap.cps.ncmp.events.lcm.v1.Event;
import org.onap.cps.ncmp.events.lcm.v1.LcmEvent;
import org.onap.cps.ncmp.events.lcm.v1.LcmEventHeader;
import org.onap.cps.ncmp.events.lcm.v1.Values;
+import org.onap.cps.ncmp.impl.utils.EventDateTimeFormatter;
import org.springframework.stereotype.Component;
@@ -128,4 +128,4 @@ public class LcmEventsCreator {
private Values newValues;
}
-} \ No newline at end of file
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreatorHelper.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventsCreatorHelper.java
index 19d9ba5c0d..348894d1b4 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreatorHelper.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventsCreatorHelper.java
@@ -18,12 +18,12 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.events.lcm;
+package org.onap.cps.ncmp.impl.inventory.sync.lcm;
-import static org.onap.cps.ncmp.api.impl.events.lcm.LcmEventType.CREATE;
-import static org.onap.cps.ncmp.api.impl.events.lcm.LcmEventType.DELETE;
-import static org.onap.cps.ncmp.api.impl.events.lcm.LcmEventType.UPDATE;
-import static org.onap.cps.ncmp.api.impl.inventory.CmHandleState.DELETED;
+import static org.onap.cps.ncmp.impl.inventory.models.CmHandleState.DELETED;
+import static org.onap.cps.ncmp.impl.inventory.sync.lcm.LcmEventType.CREATE;
+import static org.onap.cps.ncmp.impl.inventory.sync.lcm.LcmEventType.DELETE;
+import static org.onap.cps.ncmp.impl.inventory.sync.lcm.LcmEventType.UPDATE;
import com.google.common.collect.MapDifference;
import com.google.common.collect.Maps;
@@ -33,7 +33,7 @@ import java.util.Map;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
+import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle;
import org.onap.cps.ncmp.events.lcm.v1.Values;
/**
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventsService.java
index f51b58c3ef..192667175e 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsService.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventsService.java
@@ -18,15 +18,20 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.events.lcm;
+package org.onap.cps.ncmp.impl.inventory.sync.lcm;
-import io.micrometer.core.annotation.Timed;
+import io.micrometer.core.instrument.MeterRegistry;
+import io.micrometer.core.instrument.Tag;
+import io.micrometer.core.instrument.Timer;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.events.EventsPublisher;
import org.onap.cps.ncmp.events.lcm.v1.LcmEvent;
import org.onap.cps.ncmp.events.lcm.v1.LcmEventHeader;
+import org.onap.cps.ncmp.events.lcm.v1.Values;
import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.kafka.KafkaException;
@@ -41,8 +46,12 @@ import org.springframework.stereotype.Service;
@RequiredArgsConstructor
public class LcmEventsService {
+ private static final Tag TAG_METHOD = Tag.of("method", "publishLcmEvent");
+ private static final Tag TAG_CLASS = Tag.of("class", LcmEventsService.class.getName());
+ private static final String UNAVAILABLE_CM_HANDLE_STATE = "N/A";
private final EventsPublisher<LcmEvent> eventsPublisher;
private final JsonObjectMapper jsonObjectMapper;
+ private final MeterRegistry meterRegistry;
@Value("${app.lcm.events.topic:ncmp-events}")
private String topicName;
@@ -51,24 +60,58 @@ public class LcmEventsService {
private boolean notificationsEnabled;
/**
- * Publish the LcmEvent with header to the public topic.
+ * Publishes an LCM event to the dedicated topic with optional notification headers.
+ * Capture and log KafkaException If an error occurs while publishing the event to Kafka
*
- * @param cmHandleId Cm Handle Id
- * @param lcmEvent Lcm Event
- * @param lcmEventHeader Lcm Event Header
+ * @param cmHandleId Cm Handle Id associated with the LCM event
+ * @param lcmEvent The LCM event object to be published
+ * @param lcmEventHeader Optional headers associated with the LCM event
*/
- @Timed(value = "cps.ncmp.lcm.events.publish", description = "Time taken to publish a LCM event")
public void publishLcmEvent(final String cmHandleId, final LcmEvent lcmEvent, final LcmEventHeader lcmEventHeader) {
+
if (notificationsEnabled) {
+ final Timer.Sample timerSample = Timer.start(meterRegistry);
try {
final Map<String, Object> lcmEventHeadersMap =
jsonObjectMapper.convertToValueType(lcmEventHeader, Map.class);
eventsPublisher.publishEvent(topicName, cmHandleId, lcmEventHeadersMap, lcmEvent);
} catch (final KafkaException e) {
log.error("Unable to publish message to topic : {} and cause : {}", topicName, e.getMessage());
+ } finally {
+ recordMetrics(lcmEvent, timerSample);
}
} else {
log.debug("Notifications disabled.");
}
}
+
+ private void recordMetrics(final LcmEvent lcmEvent, final Timer.Sample timerSample) {
+ final List<Tag> tags = new ArrayList<>(4);
+ tags.add(TAG_CLASS);
+ tags.add(TAG_METHOD);
+
+ final String oldCmHandleState = extractCmHandleStateValue(lcmEvent.getEvent().getOldValues());
+ tags.add(Tag.of("oldCmHandleState", oldCmHandleState));
+
+ final String newCmHandleState = extractCmHandleStateValue(lcmEvent.getEvent().getNewValues());
+ tags.add(Tag.of("newCmHandleState", newCmHandleState));
+
+ timerSample.stop(Timer.builder("cps.ncmp.lcm.events.publish")
+ .description("Time taken to publish a LCM event")
+ .tags(tags)
+ .register(meterRegistry));
+ }
+
+ /**
+ * Extracts the CM handle state value from the given Values object.
+ * If the provided Values object or its CM handle state is null, returns a default value.
+ *
+ * @param values The Values object containing CM handle state information.
+ * @return The CM handle state value as a string, or a default value if null.
+ */
+ private String extractCmHandleStateValue(final Values values) {
+ return (values != null && values.getCmHandleState() != null)
+ ? values.getCmHandleState().value()
+ : UNAVAILABLE_CM_HANDLE_STATE;
+ }
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/DeviceHeartbeatConsumer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumer.java
index 230a370d65..efcbb78ace 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/DeviceHeartbeatConsumer.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumer.java
@@ -18,41 +18,41 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.trustlevel;
+package org.onap.cps.ncmp.impl.inventory.trustlevel;
import io.cloudevents.CloudEvent;
import io.cloudevents.kafka.impl.KafkaHeaders;
import lombok.RequiredArgsConstructor;
import org.apache.kafka.clients.consumer.ConsumerRecord;
-import org.onap.cps.ncmp.api.impl.events.mapper.CloudEventMapper;
+import org.onap.cps.ncmp.api.inventory.models.TrustLevel;
import org.onap.cps.ncmp.events.trustlevel.DeviceTrustLevel;
+import org.onap.cps.ncmp.utils.events.CloudEventMapper;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
-public class DeviceHeartbeatConsumer {
+public class DeviceTrustLevelMessageConsumer {
private static final String CLOUD_EVENT_ID_HEADER_NAME = "ce_id";
private final TrustLevelManager trustLevelManager;
/**
- * Listening the device heartbeats.
+ * Listening to the device trust level updates.
*
- * @param deviceHeartbeatConsumerRecord Device Heartbeat record.
+ * @param consumerRecord Device trust level record.
*/
@KafkaListener(topics = "${app.dmi.device-heartbeat.topic}",
containerFactory = "cloudEventConcurrentKafkaListenerContainerFactory")
- public void heartbeatListener(final ConsumerRecord<String, CloudEvent> deviceHeartbeatConsumerRecord) {
+ public void deviceTrustLevelListener(final ConsumerRecord<String, CloudEvent> consumerRecord) {
- final String cmHandleId = KafkaHeaders.getParsedKafkaHeader(deviceHeartbeatConsumerRecord.headers(),
+ final String cmHandleId = KafkaHeaders.getParsedKafkaHeader(consumerRecord.headers(),
CLOUD_EVENT_ID_HEADER_NAME);
final DeviceTrustLevel deviceTrustLevel =
- CloudEventMapper.toTargetEvent(deviceHeartbeatConsumerRecord.value(), DeviceTrustLevel.class);
- final TrustLevel newDeviceTrustLevel = TrustLevel.valueOf(deviceTrustLevel.getData().getTrustLevel());
- trustLevelManager.handleUpdateOfDeviceTrustLevel(cmHandleId, newDeviceTrustLevel);
-
+ CloudEventMapper.toTargetEvent(consumerRecord.value(), DeviceTrustLevel.class);
+ final String trustLevelAsString = deviceTrustLevel.getData().getTrustLevel();
+ trustLevelManager.updateCmHandleTrustLevel(cmHandleId, TrustLevel.valueOf(trustLevelAsString));
}
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/dmiavailability/DmiPluginWatchDog.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDog.java
index d6d6fd6bc1..7581c4af7a 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/dmiavailability/DmiPluginWatchDog.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDog.java
@@ -18,17 +18,17 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.trustlevel.dmiavailability;
+package org.onap.cps.ncmp.impl.inventory.trustlevel;
import java.util.Collection;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
-import org.onap.cps.ncmp.api.impl.client.DmiRestClient;
-import org.onap.cps.ncmp.api.impl.config.embeddedcache.TrustLevelCacheConfig;
-import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevel;
-import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevelManager;
+import org.onap.cps.ncmp.api.inventory.models.TrustLevel;
+import org.onap.cps.ncmp.impl.dmi.DmiRestClient;
+import org.onap.cps.ncmp.impl.inventory.CmHandleQueryService;
+import org.onap.cps.ncmp.impl.utils.http.RestServiceUrlTemplateBuilder;
+import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@@ -36,10 +36,10 @@ import org.springframework.stereotype.Service;
@Slf4j
@RequiredArgsConstructor
@Service
-public class DmiPluginWatchDog {
+public class DmiPluginTrustLevelWatchDog {
private final DmiRestClient dmiRestClient;
- private final NetworkCmProxyDataService networkCmProxyDataService;
+ private final CmHandleQueryService cmHandleQueryService;
private final TrustLevelManager trustLevelManager;
@Qualifier(TrustLevelCacheConfig.TRUST_LEVEL_PER_DMI_PLUGIN)
@@ -52,10 +52,8 @@ public class DmiPluginWatchDog {
*/
@Scheduled(fixedDelayString = "${ncmp.timers.trust-level.dmi-availability-watchdog-ms:30000}")
public void checkDmiAvailability() {
- trustLevelPerDmiPlugin.entrySet().forEach(entry -> {
+ trustLevelPerDmiPlugin.forEach((dmiServiceName, oldDmiTrustLevel) -> {
final TrustLevel newDmiTrustLevel;
- final TrustLevel oldDmiTrustLevel = entry.getValue();
- final String dmiServiceName = entry.getKey();
final String dmiHealthStatus = getDmiHealthStatus(dmiServiceName);
log.debug("The health status for dmi-plugin: {} is {}", dmiServiceName, dmiHealthStatus);
@@ -68,13 +66,15 @@ public class DmiPluginWatchDog {
log.debug("The Dmi Plugin: {} has already the same trust level: {}", dmiServiceName, newDmiTrustLevel);
} else {
final Collection<String> cmHandleIds =
- networkCmProxyDataService.getAllCmHandleIdsByDmiPluginIdentifier(dmiServiceName);
- trustLevelManager.handleUpdateOfDmiTrustLevel(dmiServiceName, cmHandleIds, newDmiTrustLevel);
+ cmHandleQueryService.getCmHandleIdsByDmiPluginIdentifier(dmiServiceName);
+ trustLevelManager.updateDmi(dmiServiceName, cmHandleIds, newDmiTrustLevel);
}
});
}
- private String getDmiHealthStatus(final String dmiServiceName) {
- return dmiRestClient.getDmiHealthStatus(dmiServiceName);
+ private String getDmiHealthStatus(final String dmiServiceBaseUrl) {
+ final UrlTemplateParameters urlTemplateParameters = RestServiceUrlTemplateBuilder.newInstance()
+ .createUrlTemplateParametersForHealthCheck(dmiServiceBaseUrl);
+ return dmiRestClient.getDmiHealthStatus(urlTemplateParameters).block();
}
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/TrustLevelCacheConfig.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/TrustLevelCacheConfig.java
index 440cd3ded1..b64d3a24b3 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/TrustLevelCacheConfig.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/TrustLevelCacheConfig.java
@@ -18,12 +18,12 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.config.embeddedcache;
+package org.onap.cps.ncmp.impl.inventory.trustlevel;
import com.hazelcast.config.MapConfig;
import java.util.Map;
import org.onap.cps.cache.HazelcastCacheConfig;
-import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevel;
+import org.onap.cps.ncmp.api.inventory.models.TrustLevel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/TrustLevelManager.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/TrustLevelManager.java
index 9d65a66d8d..aff0e19981 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/TrustLevelManager.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/TrustLevelManager.java
@@ -18,17 +18,18 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.trustlevel;
+package org.onap.cps.ncmp.impl.inventory.trustlevel;
import java.util.Collection;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.onap.cps.ncmp.api.impl.config.embeddedcache.TrustLevelCacheConfig;
-import org.onap.cps.ncmp.api.impl.events.avc.ncmptoclient.AvcEventPublisher;
-import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence;
-import org.onap.cps.ncmp.api.impl.operations.RequiredDmiService;
-import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.ncmp.api.inventory.models.DmiPluginRegistration;
+import org.onap.cps.ncmp.api.inventory.models.TrustLevel;
+import org.onap.cps.ncmp.impl.inventory.InventoryPersistence;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
+import org.onap.cps.ncmp.impl.models.RequiredDmiService;
+import org.onap.cps.ncmp.utils.events.CmAvcEventPublisher;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@@ -44,16 +45,31 @@ public class TrustLevelManager {
private final Map<String, TrustLevel> trustLevelPerDmiPlugin;
private final InventoryPersistence inventoryPersistence;
- private final AvcEventPublisher avcEventPublisher;
+ private final CmAvcEventPublisher cmAvcEventPublisher;
private static final String AVC_CHANGED_ATTRIBUTE_NAME = "trustLevel";
private static final String AVC_NO_OLD_VALUE = null;
/**
+ * Add dmi plugins to the cache.
+ *
+ * @param dmiPluginRegistration a dmi plugin being registered
+ */
+ public void registerDmiPlugin(final DmiPluginRegistration dmiPluginRegistration) {
+ final String dmiServiceName;
+ if (DmiPluginRegistration.isNullEmptyOrBlank(dmiPluginRegistration.getDmiDataPlugin())) {
+ dmiServiceName = dmiPluginRegistration.getDmiPlugin();
+ } else {
+ dmiServiceName = dmiPluginRegistration.getDmiDataPlugin();
+ }
+ trustLevelPerDmiPlugin.put(dmiServiceName, TrustLevel.COMPLETE);
+ }
+
+ /**
* Add cmHandles to the cache and publish notification for initial trust level of cmHandles if it is NONE.
*
* @param cmHandlesToBeCreated a list of cmHandles being created
*/
- public void handleInitialRegistrationOfTrustLevels(final Map<String, TrustLevel> cmHandlesToBeCreated) {
+ public void registerCmHandles(final Map<String, TrustLevel> cmHandlesToBeCreated) {
for (final Map.Entry<String, TrustLevel> entry : cmHandlesToBeCreated.entrySet()) {
final String cmHandleId = entry.getKey();
if (trustLevelPerCmHandle.containsKey(cmHandleId)) {
@@ -65,7 +81,7 @@ public class TrustLevelManager {
}
trustLevelPerCmHandle.put(cmHandleId, initialTrustLevel);
if (TrustLevel.NONE.equals(initialTrustLevel)) {
- avcEventPublisher.publishAvcEvent(cmHandleId,
+ cmAvcEventPublisher.publishAvcEvent(cmHandleId,
AVC_CHANGED_ATTRIBUTE_NAME,
AVC_NO_OLD_VALUE,
initialTrustLevel.name());
@@ -82,15 +98,15 @@ public class TrustLevelManager {
* @param affectedCmHandleIds cm handle ids belonging to dmi service name
* @param newDmiTrustLevel new trust level of the dmi plugin
*/
- public void handleUpdateOfDmiTrustLevel(final String dmiServiceName,
- final Collection<String> affectedCmHandleIds,
- final TrustLevel newDmiTrustLevel) {
+ public void updateDmi(final String dmiServiceName,
+ final Collection<String> affectedCmHandleIds,
+ final TrustLevel newDmiTrustLevel) {
final TrustLevel oldDmiTrustLevel = trustLevelPerDmiPlugin.get(dmiServiceName);
trustLevelPerDmiPlugin.put(dmiServiceName, newDmiTrustLevel);
for (final String affectedCmHandleId : affectedCmHandleIds) {
- final TrustLevel deviceTrustLevel = trustLevelPerCmHandle.get(affectedCmHandleId);
- final TrustLevel oldEffectiveTrustLevel = deviceTrustLevel.getEffectiveTrustLevel(oldDmiTrustLevel);
- final TrustLevel newEffectiveTrustLevel = deviceTrustLevel.getEffectiveTrustLevel(newDmiTrustLevel);
+ final TrustLevel cmHandleTrustLevel = trustLevelPerCmHandle.get(affectedCmHandleId);
+ final TrustLevel oldEffectiveTrustLevel = cmHandleTrustLevel.getEffectiveTrustLevel(oldDmiTrustLevel);
+ final TrustLevel newEffectiveTrustLevel = cmHandleTrustLevel.getEffectiveTrustLevel(newDmiTrustLevel);
sendAvcNotificationIfRequired(affectedCmHandleId, oldEffectiveTrustLevel, newEffectiveTrustLevel);
}
}
@@ -100,23 +116,52 @@ public class TrustLevelManager {
* changed.
*
* @param cmHandleId cm handle id
- * @param newDeviceTrustLevel new trust level of the device
+ * @param newCmHandleTrustLevel new trust level of the device
*/
- public void handleUpdateOfDeviceTrustLevel(final String cmHandleId,
- final TrustLevel newDeviceTrustLevel) {
- final YangModelCmHandle yangModelCmHandle = inventoryPersistence.getYangModelCmHandle(cmHandleId);
- final String dmiServiceName = yangModelCmHandle.resolveDmiServiceName(RequiredDmiService.DATA);
+ public void updateCmHandleTrustLevel(final String cmHandleId,
+ final TrustLevel newCmHandleTrustLevel) {
+ final String dmiServiceName = getDmiServiceName(cmHandleId);
final TrustLevel dmiTrustLevel = trustLevelPerDmiPlugin.get(dmiServiceName);
- final TrustLevel oldDeviceTrustLevel = trustLevelPerCmHandle.get(cmHandleId);
+ final TrustLevel oldCmHandleTrustLevel = trustLevelPerCmHandle.get(cmHandleId);
- final TrustLevel oldEffectiveTrustLevel = oldDeviceTrustLevel.getEffectiveTrustLevel(dmiTrustLevel);
- final TrustLevel newEffectiveTrustLevel = newDeviceTrustLevel.getEffectiveTrustLevel(dmiTrustLevel);
+ final TrustLevel oldEffectiveTrustLevel = oldCmHandleTrustLevel.getEffectiveTrustLevel(dmiTrustLevel);
+ final TrustLevel newEffectiveTrustLevel = newCmHandleTrustLevel.getEffectiveTrustLevel(dmiTrustLevel);
- trustLevelPerCmHandle.put(cmHandleId, newDeviceTrustLevel);
+ trustLevelPerCmHandle.put(cmHandleId, newCmHandleTrustLevel);
sendAvcNotificationIfRequired(cmHandleId, oldEffectiveTrustLevel, newEffectiveTrustLevel);
}
+ /**
+ * Select effective trust level among device and dmi plugin.
+ *
+ * @param cmHandleId cm handle id
+ * @return TrustLevel effective trust level
+ */
+ public TrustLevel getEffectiveTrustLevel(final String dmiServiceName, final String cmHandleId) {
+ final TrustLevel dmiTrustLevel = trustLevelPerDmiPlugin.get(dmiServiceName);
+ final TrustLevel cmHandleTrustLevel = trustLevelPerCmHandle.get(cmHandleId);
+ return dmiTrustLevel.getEffectiveTrustLevel(cmHandleTrustLevel);
+ }
+
+ /**
+ * Remove cm handle trust level from the cache.
+ *
+ * @param cmHandleIds cm handle ids to be removed from the cache
+ */
+ public void removeCmHandles(final Collection<String> cmHandleIds) {
+ for (final String cmHandleId : cmHandleIds) {
+ if (trustLevelPerCmHandle.remove(cmHandleId) == null) {
+ log.debug("Removed Cm handle: {} is not in trust level cache", cmHandleId);
+ }
+ }
+ }
+
+ private String getDmiServiceName(final String cmHandleId) {
+ final YangModelCmHandle yangModelCmHandle = inventoryPersistence.getYangModelCmHandle(cmHandleId);
+ return yangModelCmHandle.resolveDmiServiceName(RequiredDmiService.DATA);
+ }
+
private void sendAvcNotificationIfRequired(final String notificationCandidateCmHandleId,
final TrustLevel oldEffectiveTrustLevel,
final TrustLevel newEffectiveTrustLevel) {
@@ -126,7 +171,7 @@ public class TrustLevelManager {
} else {
log.info("The trust level for Cm Handle: {} is now: {} ", notificationCandidateCmHandleId,
newEffectiveTrustLevel);
- avcEventPublisher.publishAvcEvent(notificationCandidateCmHandleId,
+ cmAvcEventPublisher.publishAvcEvent(notificationCandidateCmHandleId,
AVC_CHANGED_ATTRIBUTE_NAME,
oldEffectiveTrustLevel.name(),
newEffectiveTrustLevel.name());
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiRequestBody.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/models/DmiRequestBody.java
index f1032f818f..6b05385693 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiRequestBody.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/models/DmiRequestBody.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.operations;
+package org.onap.cps.ncmp.impl.models;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
@@ -28,7 +28,8 @@ import java.util.List;
import java.util.Map;
import lombok.Builder;
import lombok.Getter;
-import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.ncmp.api.data.models.OperationType;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
@JsonInclude(JsonInclude.Include.NON_NULL)
@Getter
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/RequiredDmiService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/models/RequiredDmiService.java
index 7e39766f3f..c0c4f73f2a 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/RequiredDmiService.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/models/RequiredDmiService.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.operations;
+package org.onap.cps.ncmp.impl.models;
/**
* Enmm to determine if the required service is for a data or model operation.
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/policyexecutor/PolicyExecutorWebClientConfiguration.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/policyexecutor/PolicyExecutorWebClientConfiguration.java
new file mode 100644
index 0000000000..333030ccd2
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/policyexecutor/PolicyExecutorWebClientConfiguration.java
@@ -0,0 +1,46 @@
+/*
+ * ============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.policyexecutor;
+
+import lombok.RequiredArgsConstructor;
+import org.onap.cps.ncmp.config.PolicyExecutorHttpClientConfig;
+import org.onap.cps.ncmp.impl.utils.http.WebClientConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.reactive.function.client.WebClient;
+
+@Configuration
+@RequiredArgsConstructor
+public class PolicyExecutorWebClientConfiguration extends WebClientConfiguration {
+
+ private final PolicyExecutorHttpClientConfig policyExecutorHttpClientConfig;
+
+ /**
+ * Configures and creates a web client bean for Policy Executor.
+ *
+ * @param webClientBuilder The builder instance to create the WebClient.
+ * @return a WebClient instance configured for Policy Executor.
+ */
+ @Bean
+ public WebClient policyExecutorWebClient(final WebClient.Builder webClientBuilder) {
+ return configureWebClient(webClientBuilder, policyExecutorHttpClientConfig.getAllServices());
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/AlternateIdMatcher.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/AlternateIdMatcher.java
new file mode 100644
index 0000000000..c526dfb297
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/AlternateIdMatcher.java
@@ -0,0 +1,78 @@
+/*
+ * ============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.utils;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.onap.cps.ncmp.exceptions.NoAlternateIdMatchFoundException;
+import org.onap.cps.ncmp.impl.inventory.InventoryPersistence;
+import org.onap.cps.spi.exceptions.DataNodeNotFoundException;
+import org.onap.cps.spi.model.DataNode;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class AlternateIdMatcher {
+
+ private final InventoryPersistence inventoryPersistence;
+
+ /**
+ * Get data node that matches longest alternate id by removing elements (as defined by the separator string)
+ * from right to left.
+ *
+ * @param alternateId alternate ID
+ * @param separator a string that separates each element from the next.
+ * @return data node
+ */
+ public DataNode getCmHandleDataNodeByLongestMatchingAlternateId(final String alternateId, final String separator) {
+ String bestMatch = alternateId;
+ while (StringUtils.isNotEmpty(bestMatch)) {
+ try {
+ return inventoryPersistence.getCmHandleDataNodeByAlternateId(bestMatch);
+ } catch (final DataNodeNotFoundException ignored) {
+ bestMatch = getParentPath(bestMatch, separator);
+ }
+ }
+ throw new NoAlternateIdMatchFoundException(alternateId);
+ }
+
+ /**
+ * Get cm handle Id from given cmHandleReference.
+ *
+ * @param cmHandleReference cm handle or alternate identifier
+ * @return cm handle id string
+ */
+ public String getCmHandleId(final String cmHandleReference) {
+ if (inventoryPersistence.isExistingCmHandleId(cmHandleReference)) {
+ return cmHandleReference;
+ } else {
+ return inventoryPersistence.getCmHandleDataNodeByAlternateId(cmHandleReference)
+ .getLeaves().get("id").toString();
+ }
+ }
+
+ private String getParentPath(final String path, final String separator) {
+ final int lastSeparatorIndex = path.lastIndexOf(separator);
+ return lastSeparatorIndex < 0 ? "" : path.substring(0, lastSeparatorIndex);
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/EventDateTimeFormatter.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/EventDateTimeFormatter.java
index 5dd6827126..9284c0fab7 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/EventDateTimeFormatter.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/EventDateTimeFormatter.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.utils;
+package org.onap.cps.ncmp.impl.utils;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/YangDataConverter.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/YangDataConverter.java
index 07b92892a9..ac0c44e1c3 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/YangDataConverter.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/YangDataConverter.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.utils;
+package org.onap.cps.ncmp.impl.utils;
import java.util.Collection;
import java.util.LinkedHashMap;
@@ -30,10 +30,10 @@ import java.util.stream.Collectors;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.onap.cps.ncmp.api.impl.inventory.CompositeState;
-import org.onap.cps.ncmp.api.impl.inventory.CompositeStateBuilder;
-import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
-import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
+import org.onap.cps.ncmp.api.inventory.models.CompositeState;
+import org.onap.cps.ncmp.api.inventory.models.CompositeStateBuilder;
+import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
import org.onap.cps.spi.model.DataNode;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@@ -43,12 +43,12 @@ public class YangDataConverter {
private static final Pattern cmHandleIdInXpathPattern = Pattern.compile("\\[@id='(.*?)']");
/**
- * This method convert yang model cm handle to ncmp service cm handle.
+ * This method converts yang model cm handle to ncmp service cm handle.
* @param yangModelCmHandle the yang model of the cm handle
* @return ncmp service cm handle
*/
- public static NcmpServiceCmHandle convertYangModelCmHandleToNcmpServiceCmHandle(
- final YangModelCmHandle yangModelCmHandle) {
+ public static NcmpServiceCmHandle toNcmpServiceCmHandle(
+ final YangModelCmHandle yangModelCmHandle) {
final NcmpServiceCmHandle ncmpServiceCmHandle = new NcmpServiceCmHandle();
final List<YangModelCmHandle.Property> dmiProperties = yangModelCmHandle.getDmiProperties();
final List<YangModelCmHandle.Property> publicProperties = yangModelCmHandle.getPublicProperties();
@@ -63,23 +63,24 @@ public class YangDataConverter {
}
/**
- * This method convert yang model cm handle properties to simple map.
+ * This method converts yang model cm handle properties to simple map.
* @param properties the yang model cm handle properties
- * @param propertiesMap the String, String map for the results
+ * @return simple map representing the properties
*/
- public static void asPropertiesMap(final List<YangModelCmHandle.Property> properties,
- final Map<String, String> propertiesMap) {
+ public static Map<String, String> toPropertiesMap(final List<YangModelCmHandle.Property> properties) {
+ final Map<String, String> propertiesMap = new LinkedHashMap<>(properties.size());
for (final YangModelCmHandle.Property property : properties) {
propertiesMap.put(property.getName(), property.getValue());
}
+ return propertiesMap;
}
/**
- * This method convert cm handle data node to yang model cm handle.
+ * This method converts cm handle data node to yang model cm handle.
* @param cmHandleDataNode the datanode of the cm handle
* @return yang model cm handle
*/
- public static YangModelCmHandle convertCmHandleToYangModel(final DataNode cmHandleDataNode) {
+ public static YangModelCmHandle toYangModelCmHandle(final DataNode cmHandleDataNode) {
final NcmpServiceCmHandle ncmpServiceCmHandle = new NcmpServiceCmHandle();
final String cmHandleId = cmHandleDataNode.getLeaves().get("id").toString();
ncmpServiceCmHandle.setCmHandleId(cmHandleId);
@@ -96,18 +97,17 @@ public class YangDataConverter {
}
/**
- * This method convert cm handle data nodes to yang model cm handles.
+ * This method converts cm handle data nodes to yang model cm handles.
* @param cmHandleDataNodes the datanode of the cm handle
* @return yang model cm handles
*/
- public static Collection<YangModelCmHandle> convertDataNodesToYangModelCmHandles(
+ public static Collection<YangModelCmHandle> toYangModelCmHandles(
final Collection<DataNode> cmHandleDataNodes) {
- return cmHandleDataNodes.stream().map(YangDataConverter::convertCmHandleToYangModel)
- .collect(Collectors.toList());
+ return cmHandleDataNodes.stream().map(YangDataConverter::toYangModelCmHandle).collect(Collectors.toList());
}
/**
- * This method extract cm handle id from xpath of data node.
+ * This method extracts cm handle id from xpath of data node.
* @param xpath for data node of the cm handle
* @return cm handle Id
*/
@@ -145,15 +145,11 @@ public class YangDataConverter {
private static void setDmiProperties(final List<YangModelCmHandle.Property> dmiProperties,
final NcmpServiceCmHandle ncmpServiceCmHandle) {
- final Map<String, String> dmiPropertiesMap = new LinkedHashMap<>(dmiProperties.size());
- asPropertiesMap(dmiProperties, dmiPropertiesMap);
- ncmpServiceCmHandle.setDmiProperties(dmiPropertiesMap);
+ ncmpServiceCmHandle.setDmiProperties(toPropertiesMap(dmiProperties));
}
private static void setPublicProperties(final List<YangModelCmHandle.Property> publicProperties,
final NcmpServiceCmHandle ncmpServiceCmHandle) {
- final Map<String, String> publicPropertiesMap = new LinkedHashMap<>();
- asPropertiesMap(publicProperties, publicPropertiesMap);
- ncmpServiceCmHandle.setPublicProperties(publicPropertiesMap);
+ ncmpServiceCmHandle.setPublicProperties(toPropertiesMap(publicProperties));
}
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/RestServiceUrlTemplateBuilder.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/RestServiceUrlTemplateBuilder.java
new file mode 100644
index 0000000000..c850ca94a0
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/RestServiceUrlTemplateBuilder.java
@@ -0,0 +1,134 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022-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.utils.http;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.util.Strings;
+import org.springframework.web.util.UriComponentsBuilder;
+
+@NoArgsConstructor
+public class RestServiceUrlTemplateBuilder {
+
+ private final UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.newInstance();
+ private static final String FIXED_PATH_SEGMENT = null;
+ private static final String VERSION_SEGMENT = "v1";
+ private final Map<String, String> pathSegments = new LinkedHashMap<>();
+ private final Map<String, String> queryParameters = new LinkedHashMap<>();
+
+ /**
+ * Static factory method to create a new instance of DmiServiceUrlTemplateBuilder.
+ *
+ * @return a new instance of DmiServiceUrlTemplateBuilder
+ */
+ public static RestServiceUrlTemplateBuilder newInstance() {
+ return new RestServiceUrlTemplateBuilder();
+ }
+
+ /**
+ * Add a fixed pathSegment to the URL.
+ *
+ * @param pathSegment the path segment
+ * @return this builder instance
+ */
+ public RestServiceUrlTemplateBuilder fixedPathSegment(final String pathSegment) {
+ pathSegments.put(pathSegment, FIXED_PATH_SEGMENT);
+ return this;
+ }
+
+ /**
+ * Add a variable pathSegment to the URL.
+ * Do NOT add { } braces. the builder will take care of that
+ *
+ * @param pathSegment the name of the variable path segment (with { and }
+ * @param value the value to be insert in teh URL for the given variable path segment
+ * @return this builder instance
+ */
+ public RestServiceUrlTemplateBuilder variablePathSegment(final String pathSegment, final String value) {
+ pathSegments.put(pathSegment, value);
+ return this;
+ }
+
+ /**
+ * Add a query parameter to the URL.
+ * Do NOT encode as the builder wil take care of encoding
+ *
+ * @param queryParameterName the name of the variable
+ * @param queryParameterValue the value of the variable (only Strings are supported).
+ *
+ * @return this builder instance
+ */
+ public RestServiceUrlTemplateBuilder queryParameter(final String queryParameterName,
+ final String queryParameterValue) {
+ if (Strings.isNotBlank(queryParameterValue)) {
+ queryParameters.put(queryParameterName, queryParameterValue);
+ }
+ return this;
+ }
+
+ /**
+ * Constructs a URL template with variables based on the accumulated path segments and query parameters.
+ *
+ * @param serviceBaseUrl the base URL of the service, e.g., "http://dmi-service.com".
+ * @param basePath the base path of the service
+ * @return a UrlTemplateParameters instance containing the complete URL template and URL variables
+ */
+ public UrlTemplateParameters createUrlTemplateParameters(final String serviceBaseUrl, final String basePath) {
+ this.uriComponentsBuilder.pathSegment(basePath).pathSegment(VERSION_SEGMENT);
+ final Map<String, String> urlTemplateVariables = new HashMap<>();
+
+ pathSegments.forEach((pathSegmentName, variablePathValue) -> {
+ if (StringUtils.equals(variablePathValue, FIXED_PATH_SEGMENT)) {
+ this.uriComponentsBuilder.pathSegment(pathSegmentName);
+ } else {
+ this.uriComponentsBuilder.pathSegment("{" + pathSegmentName + "}");
+ urlTemplateVariables.put(pathSegmentName, variablePathValue);
+ }
+ });
+
+ queryParameters.forEach((paramName, paramValue) -> {
+ this.uriComponentsBuilder.queryParam(paramName, "{" + paramName + "}");
+ urlTemplateVariables.put(paramName, paramValue);
+ });
+
+ final String urlTemplate = serviceBaseUrl + this.uriComponentsBuilder.build().toUriString();
+ return new UrlTemplateParameters(urlTemplate, urlTemplateVariables);
+ }
+
+ /**
+ * Constructs a URL for a spring actuator health check based on the given base URL.
+ *
+ * @param serviceBaseUrl the base URL of the service, e.g., "http://dmi-service.com".
+ * @return a {@link UrlTemplateParameters} instance containing the complete URL template and empty URL variables,
+ * suitable for DMI health check.
+ */
+ public UrlTemplateParameters createUrlTemplateParametersForHealthCheck(final String serviceBaseUrl) {
+ this.uriComponentsBuilder.pathSegment("actuator").pathSegment("health");
+
+ final String urlTemplate = serviceBaseUrl + this.uriComponentsBuilder.build().toUriString();
+ return new UrlTemplateParameters(urlTemplate, Collections.emptyMap());
+ }
+
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/UrlTemplateParameters.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/UrlTemplateParameters.java
new file mode 100644
index 0000000000..839af71823
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/UrlTemplateParameters.java
@@ -0,0 +1,30 @@
+/*
+ * ============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.utils.http;
+
+import java.util.Map;
+
+/**
+ * Represents a URL template with associated variables for dynamic substitution.
+ * This record encapsulates a URL template string and a map of variables used for substitution within the template.
+ */
+public record UrlTemplateParameters(String urlTemplate, Map<String, String> urlVariables) {
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/WebClientConfiguration.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/WebClientConfiguration.java
new file mode 100644
index 0000000000..d8e8350345
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/WebClientConfiguration.java
@@ -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.utils.http;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import io.netty.channel.ChannelOption;
+import io.netty.handler.timeout.ReadTimeoutHandler;
+import io.netty.handler.timeout.WriteTimeoutHandler;
+import io.netty.resolver.DefaultAddressResolverGroup;
+import java.time.Duration;
+import java.util.concurrent.TimeUnit;
+import org.onap.cps.ncmp.config.ServiceConfig;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.client.reactive.ReactorClientHttpConnector;
+import org.springframework.web.reactive.function.client.WebClient;
+import reactor.netty.http.client.HttpClient;
+import reactor.netty.resources.ConnectionProvider;
+
+/**
+ * Configures and creates WebClient beans for various rest services such as DMI and Policy Executor.
+ * The configuration utilizes Netty-based HttpClient with custom connection settings, read and write timeouts,
+ * and initializes WebClient with these settings to ensure optimal performance and resource management.
+ */
+public class WebClientConfiguration {
+
+ private static final Duration DEFAULT_RESPONSE_TIMEOUT = Duration.ofSeconds(30);
+
+ protected WebClient configureWebClient(final WebClient.Builder webClientBuilder,
+ final ServiceConfig serviceConfig) {
+ final ConnectionProvider connectionProvider = getConnectionProvider(serviceConfig);
+ final HttpClient httpClient = createHttpClient(serviceConfig, connectionProvider);
+ return buildAndGetWebClient(webClientBuilder, httpClient, serviceConfig.getMaximumInMemorySizeInMegabytes());
+ }
+
+ private static HttpClient createHttpClient(final ServiceConfig serviceConfig,
+ final ConnectionProvider connectionProvider) {
+ return HttpClient.create(connectionProvider)
+ .responseTimeout(DEFAULT_RESPONSE_TIMEOUT)
+ .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, serviceConfig.getConnectionTimeoutInSeconds() * 1000)
+ .doOnConnected(connection -> connection.addHandlerLast(new ReadTimeoutHandler(
+ serviceConfig.getReadTimeoutInSeconds(), TimeUnit.SECONDS)).addHandlerLast(
+ new WriteTimeoutHandler(serviceConfig.getWriteTimeoutInSeconds(), TimeUnit.SECONDS)))
+ .resolver(DefaultAddressResolverGroup.INSTANCE)
+ .compress(true);
+ }
+
+ @SuppressFBWarnings("BC_UNCONFIRMED_CAST_OF_RETURN_VALUE")
+ private static ConnectionProvider getConnectionProvider(final ServiceConfig serviceConfig) {
+ return ConnectionProvider.builder(serviceConfig.getConnectionProviderName())
+ .maxConnections(serviceConfig.getMaximumConnectionsTotal())
+ .pendingAcquireMaxCount(serviceConfig.getPendingAcquireMaxCount())
+ .build();
+ }
+
+ private WebClient buildAndGetWebClient(final WebClient.Builder webClientBuilder, final HttpClient httpClient,
+ final int maximumInMemorySizeInMegabytes) {
+ return webClientBuilder
+ .defaultHeaders(header -> header.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE))
+ .defaultHeaders(header -> header.set(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE))
+ .clientConnector(new ReactorClientHttpConnector(httpClient))
+ .codecs(configurer -> configurer.defaultCodecs()
+ .maxInMemorySize(maximumInMemorySizeInMegabytes * 1024 * 1024)).build();
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/AbstractModelLoader.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/AbstractModelLoader.java
index 4cc8cdaa66..6d51eb48b8 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/AbstractModelLoader.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/AbstractModelLoader.java
@@ -33,13 +33,13 @@ import org.onap.cps.api.CpsAnchorService;
import org.onap.cps.api.CpsDataService;
import org.onap.cps.api.CpsDataspaceService;
import org.onap.cps.api.CpsModuleService;
-import org.onap.cps.ncmp.api.impl.exception.NcmpStartUpException;
+import org.onap.cps.ncmp.exceptions.NcmpStartUpException;
import org.onap.cps.spi.CascadeDeleteAllowed;
import org.onap.cps.spi.exceptions.AlreadyDefinedException;
import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
-import org.springframework.boot.context.event.ApplicationReadyEvent;
+import org.springframework.boot.context.event.ApplicationStartedEvent;
@Slf4j
@RequiredArgsConstructor
@@ -61,12 +61,12 @@ abstract class AbstractModelLoader implements ModelLoader {
long retryTimeMs;
@Override
- public void onApplicationEvent(@NonNull final ApplicationReadyEvent applicationReadyEvent) {
+ public void onApplicationEvent(@NonNull final ApplicationStartedEvent applicationStartedEvent) {
try {
onboardOrUpgradeModel();
} catch (final NcmpStartUpException ncmpStartUpException) {
log.error("Onboarding model for NCMP failed: {} ", ncmpStartUpException.getMessage());
- SpringApplication.exit(applicationReadyEvent.getApplicationContext(), () -> EXIT_CODE_ON_ERROR);
+ SpringApplication.exit(applicationStartedEvent.getApplicationContext(), () -> EXIT_CODE_ON_ERROR);
}
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/CmDataSubscriptionModelLoader.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/CmDataSubscriptionModelLoader.java
index a0b7bd5826..780b240b6c 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/CmDataSubscriptionModelLoader.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/CmDataSubscriptionModelLoader.java
@@ -20,7 +20,7 @@
package org.onap.cps.ncmp.init;
-import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DATASPACE_NAME;
+import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NCMP_DATASPACE_NAME;
import static org.onap.cps.utils.ContentType.JSON;
import java.time.OffsetDateTime;
@@ -29,8 +29,8 @@ import org.onap.cps.api.CpsAnchorService;
import org.onap.cps.api.CpsDataService;
import org.onap.cps.api.CpsDataspaceService;
import org.onap.cps.api.CpsModuleService;
-import org.onap.cps.ncmp.api.impl.exception.NcmpStartUpException;
-import org.onap.cps.ncmp.api.impl.operations.DatastoreType;
+import org.onap.cps.ncmp.api.data.models.DatastoreType;
+import org.onap.cps.ncmp.exceptions.NcmpStartUpException;
import org.onap.cps.spi.exceptions.AlreadyDefinedException;
import org.springframework.stereotype.Service;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/InventoryModelLoader.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/InventoryModelLoader.java
index 7c25953f0d..76d12f290c 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/InventoryModelLoader.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/InventoryModelLoader.java
@@ -20,9 +20,9 @@
package org.onap.cps.ncmp.init;
-import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DATASPACE_NAME;
-import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_ANCHOR;
-import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME;
+import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NCMP_DATASPACE_NAME;
+import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NCMP_DMI_REGISTRY_ANCHOR;
+import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.api.CpsAnchorService;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/ModelLoader.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/ModelLoader.java
index c61bf1c9b1..9832ba3f9e 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/ModelLoader.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/ModelLoader.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2023 Nordix Foundation
+ * Copyright (C) 2023-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.
@@ -21,13 +21,13 @@
package org.onap.cps.ncmp.init;
import lombok.NonNull;
-import org.springframework.boot.context.event.ApplicationReadyEvent;
+import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationListener;
-public interface ModelLoader extends ApplicationListener<ApplicationReadyEvent> {
+public interface ModelLoader extends ApplicationListener<ApplicationStartedEvent> {
@Override
- void onApplicationEvent(@NonNull ApplicationReadyEvent applicationReadyEvent);
+ void onApplicationEvent(@NonNull ApplicationStartedEvent applicationStartedEvent);
void onboardOrUpgradeModel();
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/mapper/CloudEventMapper.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/events/CloudEventMapper.java
index 4120970e52..4462b169e2 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/mapper/CloudEventMapper.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/events/CloudEventMapper.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.events.mapper;
+package org.onap.cps.ncmp.utils.events;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.cloudevents.CloudEvent;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avc/ncmptoclient/AvcEventPublisher.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/events/CmAvcEventPublisher.java
index 7afe606f4f..2a9717cc1a 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avc/ncmptoclient/AvcEventPublisher.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/events/CmAvcEventPublisher.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.events.avc.ncmptoclient;
+package org.onap.cps.ncmp.utils.events;
import io.cloudevents.CloudEvent;
import java.util.Collections;
@@ -26,7 +26,6 @@ import java.util.HashMap;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.onap.cps.events.EventsPublisher;
-import org.onap.cps.ncmp.api.impl.events.NcmpEvent;
import org.onap.cps.ncmp.events.avc.ncmp_to_client.Avc;
import org.onap.cps.ncmp.events.avc.ncmp_to_client.AvcEvent;
import org.onap.cps.ncmp.events.avc.ncmp_to_client.Data;
@@ -35,7 +34,7 @@ import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
-public class AvcEventPublisher {
+public class CmAvcEventPublisher {
private final EventsPublisher<CloudEvent> eventsPublisher;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/NcmpEvent.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/events/NcmpEvent.java
index 248db9805c..8d3190eb00 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/NcmpEvent.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/events/NcmpEvent.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.events;
+package org.onap.cps.ncmp.utils.events;
import io.cloudevents.CloudEvent;
import io.cloudevents.core.builder.CloudEventBuilder;
@@ -27,8 +27,8 @@ import java.util.Map;
import java.util.UUID;
import lombok.Builder;
import org.apache.commons.lang3.StringUtils;
-import org.onap.cps.ncmp.api.impl.utils.EventDateTimeFormatter;
-import org.onap.cps.ncmp.api.impl.utils.context.CpsApplicationContext;
+import org.onap.cps.ncmp.config.CpsApplicationContext;
+import org.onap.cps.ncmp.impl.utils.EventDateTimeFormatter;
import org.onap.cps.utils.JsonObjectMapper;
@Builder
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyQueryService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/events/TopicValidator.java
index 340806b892..07da7f76a0 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyQueryService.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/events/TopicValidator.java
@@ -18,24 +18,30 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api;
+package org.onap.cps.ncmp.utils.events;
-import org.onap.cps.spi.FetchDescendantsOption;
+import java.util.regex.Pattern;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.onap.cps.ncmp.api.exceptions.InvalidTopicException;
-/*
- * Datastore interface for handling cached CPS data query requests.
- */
-public interface NetworkCmProxyQueryService {
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class TopicValidator {
+
+ private static final Pattern TOPIC_NAME_PATTERN = Pattern.compile("^[a-zA-Z0-9]([._-](?![._-])|"
+ + "[a-zA-Z0-9]){0,120}[a-zA-Z0-9]$");
/**
- * Get resource data for operational.
+ * Validate kafka topic name pattern.
*
- * @param cmHandleId cm handle identifier
- * @param cpsPath cps path
- * @Link FetchDescendantsOption fetch descendants option
- * @return {@code Object} resource data
+ * @param topicName name of the topic to be validated
+ *
+ * @throws InvalidTopicException if the topic is not valid
*/
- Object queryResourceDataOperational(String cmHandleId,
- String cpsPath,
- FetchDescendantsOption fetchDescendantsOption);
+ public static void validateTopicName(final String topicName) {
+ if (!TOPIC_NAME_PATTERN.matcher(topicName).matches()) {
+ throw new InvalidTopicException("Topic name " + topicName + " is invalid", "invalid topic");
+ }
+ }
+
}