- remove integration test (notification related) for subscription as it is now invalid
due to development
- modify unit tests with use of new model on onboarding
- onboard new model
- remove old model from repo
Issue-ID: CPS-2890
Change-Id: I47656abb45f8f8c55b1c9d60787510a41dc90f7f
Signed-off-by: emaclee <lee.anjella.macabuhay@est.tech>
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2024 Nordix Foundation
+ * Copyright (C) 2024-2025 OpenInfra Foundation Europe. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
package org.onap.cps.ncmp.init;
import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NCMP_DATASPACE_NAME;
-import static org.onap.cps.utils.ContentType.JSON;
-import java.time.OffsetDateTime;
import lombok.extern.slf4j.Slf4j;
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.api.exceptions.AlreadyDefinedException;
import org.onap.cps.init.AbstractModelLoader;
-import org.onap.cps.ncmp.api.data.models.DatastoreType;
-import org.onap.cps.ncmp.exceptions.NcmpStartUpException;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class CmDataSubscriptionModelLoader extends AbstractModelLoader {
- private static final String MODEL_FILENAME = "cm-data-subscriptions@2024-02-12.yang";
- private static final String SCHEMASET_NAME = "cm-data-subscriptions";
- private static final String ANCHOR_NAME = "cm-data-subscriptions";
- private static final String REGISTRY_DATANODE_NAME = "datastores";
+ private static final String MODEL_FILENAME = "cm-data-job-subscriptions@2025-07-16.yang";
+ private static final String SCHEMASET_NAME = "cm-data-job-subscriptions";
+ private static final String ANCHOR_NAME = "cm-data-job-subscriptions";
+ private static final String REGISTRY_DATANODE_NAME = "dataJob";
public CmDataSubscriptionModelLoader(final CpsDataspaceService cpsDataspaceService,
final CpsModuleService cpsModuleService, final CpsAnchorService cpsAnchorService,
createSchemaSet(NCMP_DATASPACE_NAME, SCHEMASET_NAME, MODEL_FILENAME);
createAnchor(NCMP_DATASPACE_NAME, SCHEMASET_NAME, ANCHOR_NAME);
createTopLevelDataNode(NCMP_DATASPACE_NAME, ANCHOR_NAME, REGISTRY_DATANODE_NAME);
- createDatastore(DatastoreType.PASSTHROUGH_OPERATIONAL.getDatastoreName(),
- DatastoreType.PASSTHROUGH_RUNNING.getDatastoreName());
- }
-
- private void createDatastore(final String... datastoreNames) {
- for (final String datastoreName : datastoreNames) {
- final String nodeData = "{\"datastore\":[{\"name\":\"" + datastoreName + "\",\"cm-handles\":{}}]}";
- try {
- cpsDataService.saveData(NCMP_DATASPACE_NAME, ANCHOR_NAME, "/" + REGISTRY_DATANODE_NAME, nodeData,
- OffsetDateTime.now(), JSON);
- } catch (final AlreadyDefinedException exception) {
- log.info("Creating new child data node '{}' for data node '{}' failed as data node already exists",
- datastoreName, REGISTRY_DATANODE_NAME);
- } catch (final Exception exception) {
- log.error("Creating data node failed: {}", exception.getMessage());
- throw new NcmpStartUpException("Creating data node failed", exception.getMessage());
- }
- }
}
}
+++ /dev/null
-module cm-data-subscriptions {
- yang-version 1.1;
- namespace "org:onap:cps:ncmp";
-
- prefix cmds;
-
- revision "2024-02-12" {
- description
- "First release of cm data (notification) subscriptions model";
- }
-
- container datastores {
-
- list datastore {
- key "name";
-
- leaf name {
- type string;
- }
-
- container cm-handles {
-
- list cm-handle {
- key "id";
-
- leaf id {
- type string;
- }
-
- container filters {
-
- list filter {
- key "xpath";
-
- leaf xpath {
- type string;
- }
-
- leaf-list subscriptionIds {
- type string;
- }
-
- }
- }
- }
- }
- }
- }
-}
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2023-2024 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import org.onap.cps.api.CpsDataService
import org.onap.cps.api.CpsDataspaceService
import org.onap.cps.api.CpsModuleService
-import org.onap.cps.ncmp.exceptions.NcmpStartUpException
-import org.onap.cps.api.exceptions.AlreadyDefinedException
import org.onap.cps.api.model.Dataspace
import org.slf4j.LoggerFactory
import org.springframework.boot.context.event.ApplicationStartedEvent
def loggingListAppender
void setup() {
- expectedYangResourcesToContentMap = objectUnderTest.mapYangResourcesToContent('cm-data-subscriptions@2024-02-12.yang')
+ expectedYangResourcesToContentMap = objectUnderTest.mapYangResourcesToContent('cm-data-job-subscriptions@2025-07-16.yang')
logger.setLevel(Level.DEBUG)
loggingListAppender = new ListAppender()
logger.addAppender(loggingListAppender)
def 'Onboard subscription model via application started event.'() {
given: 'dataspace is ready for use'
mockCpsDataspaceService.getDataspace(NCMP_DATASPACE_NAME) >> new Dataspace('')
- when: 'the application is ready'
+ when: 'the application is started'
objectUnderTest.onApplicationEvent(Mock(ApplicationStartedEvent))
then: 'the module service to create schema set is called once'
- 1 * mockCpsModuleService.createSchemaSet(NCMP_DATASPACE_NAME, 'cm-data-subscriptions', expectedYangResourcesToContentMap)
+ 1 * mockCpsModuleService.createSchemaSet(NCMP_DATASPACE_NAME, 'cm-data-job-subscriptions', expectedYangResourcesToContentMap)
and: 'the admin service to create an anchor set is called once'
- 1 * mockCpsAnchorService.createAnchor(NCMP_DATASPACE_NAME, 'cm-data-subscriptions', 'cm-data-subscriptions')
+ 1 * mockCpsAnchorService.createAnchor(NCMP_DATASPACE_NAME, 'cm-data-job-subscriptions', 'cm-data-job-subscriptions')
and: 'the data service to create a top level datanode is called once'
- 1 * mockCpsDataService.saveData(NCMP_DATASPACE_NAME, 'cm-data-subscriptions', '{"datastores":{}}', _)
- and: 'the data service is called once to create datastore for Passthrough-operational'
- 1 * mockCpsDataService.saveData(NCMP_DATASPACE_NAME, 'cm-data-subscriptions', '/datastores',
- '{"datastore":[{"name":"ncmp-datastore:passthrough-operational","cm-handles":{}}]}', _, _)
- and: 'the data service is called once to create datastore for Passthrough-running'
- 1 * mockCpsDataService.saveData(NCMP_DATASPACE_NAME, 'cm-data-subscriptions', '/datastores',
- '{"datastore":[{"name":"ncmp-datastore:passthrough-running","cm-handles":{}}]}', _, _)
- }
-
- def 'Create node for datastore with already defined exception.'() {
- given: 'the data service throws an Already Defined exception'
- mockCpsDataService.saveData(*_) >> { throw AlreadyDefinedException.forDataNodes([], 'some context') }
- when: 'attempt to create datastore'
- objectUnderTest.createDatastore('some datastore')
- then: 'the exception is ignored i.e. no exception thrown up'
- noExceptionThrown()
- and: 'the exception message is logged'
- def logs = loggingListAppender.list.toString()
- logs.contains("Creating new child data node 'some datastore' for data node 'datastores' failed as data node already exists")
- }
-
- def 'Create node for datastore with any other exception.'() {
- given: 'the data service throws an exception'
- mockCpsDataService.saveData(*_) >> { throw new RuntimeException('test message') }
- when: 'attempt to create datastore'
- objectUnderTest.createDatastore('some datastore')
- then: 'a startup exception with correct message and details is thrown'
- def thrown = thrown(NcmpStartUpException)
- assert thrown.message.contains('Creating data node failed')
- assert thrown.details.contains('test message')
+ 1 * mockCpsDataService.saveData(NCMP_DATASPACE_NAME, 'cm-data-job-subscriptions', '{"dataJob":{}}', _)
}
}
+++ /dev/null
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2024-2025 OpenInfra Foundation Europe. All rights reserved.
- * ================================================================================
- * 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.integration.functional.ncmp.cmnotificationsubscription
-
-import org.onap.cps.integration.base.CpsIntegrationSpecBase
-import org.onap.cps.ncmp.impl.cmnotificationsubscription.utils.CmSubscriptionPersistenceService
-import org.springframework.beans.factory.annotation.Autowired
-
-import static org.onap.cps.ncmp.api.data.models.DatastoreType.PASSTHROUGH_RUNNING
-
-class CmNotificationSubscriptionSpec extends CpsIntegrationSpecBase {
-
- @Autowired
- CmSubscriptionPersistenceService cmSubscriptionPersistenceService
-
- def 'Adding a new cm notification subscription'() {
- given: 'there is no ongoing cm subscription for the following'
- def datastoreType = PASSTHROUGH_RUNNING
- def cmHandleId = 'ch-1'
- def xpath = '/x/y'
- assert cmSubscriptionPersistenceService.
- getOngoingCmSubscriptionIds(datastoreType, cmHandleId, xpath).size() == 0
- when: 'we add a new cm notification subscription'
- cmSubscriptionPersistenceService.addCmSubscription(datastoreType, cmHandleId, xpath,
- 'subId-1')
- then: 'there is an ongoing cm subscription for that CM handle and xpath'
- assert cmSubscriptionPersistenceService.isOngoingCmSubscription(datastoreType, cmHandleId, xpath)
- and: 'only one subscription id is related to now ongoing cm subscription'
- assert cmSubscriptionPersistenceService.getOngoingCmSubscriptionIds(datastoreType, cmHandleId, xpath).size() == 1
- }
-
- def 'Adding a cm notification subscription to the already existing cm handle but non existing xpath'() {
- given: 'an ongoing cm subscription with the following details'
- def datastoreType = PASSTHROUGH_RUNNING
- def cmHandleId = 'ch-1'
- def existingXpath = '/x/y'
- assert cmSubscriptionPersistenceService.isOngoingCmSubscription(datastoreType, cmHandleId, existingXpath)
- and: 'a non existing cm subscription with same datastore name and cm handle but different xpath'
- def nonExistingXpath = '/x2/y2'
- assert !cmSubscriptionPersistenceService.isOngoingCmSubscription(datastoreType, cmHandleId, nonExistingXpath)
- when: 'a new cm notification subscription is made for the existing cm handle and non existing xpath'
- cmSubscriptionPersistenceService.addCmSubscription(datastoreType, cmHandleId, nonExistingXpath,
- 'subId-2')
- then: 'there is an ongoing cm subscription for that CM handle and xpath'
- assert cmSubscriptionPersistenceService.isOngoingCmSubscription(datastoreType, cmHandleId, nonExistingXpath)
- and: 'only one subscription id is related to now ongoing cm subscription'
- assert cmSubscriptionPersistenceService.getOngoingCmSubscriptionIds(datastoreType, cmHandleId, nonExistingXpath).size() == 1
- }
-
- def 'Adding a cm notification subscription to the already existing cm handle and xpath'() {
- given: 'an ongoing cm subscription with the following details'
- def datastoreType = PASSTHROUGH_RUNNING
- def cmHandleId = 'ch-1'
- def xpath = '/x/y'
- when: 'a new cm notification subscription is made for the SAME CM handle and xpath'
- cmSubscriptionPersistenceService.addCmSubscription(datastoreType, cmHandleId, xpath,
- 'subId-3')
- then: 'it is added to the ongoing list of subscription ids'
- def subscriptionIds = cmSubscriptionPersistenceService.getOngoingCmSubscriptionIds(datastoreType, cmHandleId, xpath)
- assert subscriptionIds.size() == 2
- and: 'both subscription ids exists for the CM handle and xpath'
- assert subscriptionIds.contains("subId-1") && subscriptionIds.contains("subId-3")
- }
-
- def 'Removing cm notification subscriber among other subscribers'() {
- given: 'an ongoing cm subscription with the following details'
- def datastoreType = PASSTHROUGH_RUNNING
- def cmHandleId = 'ch-1'
- def xpath = '/x/y'
- and: 'the number of subscribers is as follows'
- def originalNumberOfSubscribers =
- cmSubscriptionPersistenceService.getOngoingCmSubscriptionIds(datastoreType, cmHandleId, xpath).size()
- when: 'a subscriber is removed'
- cmSubscriptionPersistenceService.removeCmSubscription(datastoreType, cmHandleId, xpath, 'subId-3')
- then: 'the number of subscribers is reduced by 1'
- def updatedNumberOfSubscribers = cmSubscriptionPersistenceService.getOngoingCmSubscriptionIds(datastoreType, cmHandleId, xpath).size()
- assert updatedNumberOfSubscribers == originalNumberOfSubscribers - 1
- }
-
- def 'Removing the LAST cm notification subscriber for a given cm handle, datastore and xpath'() {
- given: 'an ongoing cm subscription with the following details'
- def datastoreType = PASSTHROUGH_RUNNING
- def cmHandleId = 'ch-1'
- def xpath = '/x/y'
- and: 'there is only one subscriber'
- assert cmSubscriptionPersistenceService
- .getOngoingCmSubscriptionIds(datastoreType, cmHandleId, xpath).size() == 1
- when: 'only subscriber is removed'
- cmSubscriptionPersistenceService.removeCmSubscription(datastoreType, cmHandleId, xpath, 'subId-1')
- then: 'there are no longer any subscriptions for the cm handle, datastore and xpath'
- assert !cmSubscriptionPersistenceService.isOngoingCmSubscription(datastoreType, cmHandleId, xpath)
- }
-
-}