2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2023 Nordix Foundation
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.cps.ncmp.api.impl.deprecated.subscriptions
23 import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DATASPACE_NAME
24 import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NO_TIMESTAMP
26 import com.fasterxml.jackson.databind.ObjectMapper
27 import org.onap.cps.api.CpsDataService
28 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelSubscriptionEvent
29 import org.onap.cps.spi.model.DataNodeBuilder
30 import org.onap.cps.utils.JsonObjectMapper
31 import org.onap.cps.api.CpsModuleService
32 import org.onap.cps.spi.utils.CpsValidator
33 import spock.lang.Specification
35 class SubscriptionPersistenceSpec extends Specification {
37 private static final String SUBSCRIPTION_ANCHOR_NAME = "AVC-Subscriptions";
38 private static final String SUBSCRIPTION_REGISTRY_PARENT = "/subscription-registry";
39 private static final String SUBSCRIPTION_REGISTRY_PREDICATES_XPATH = "/subscription-registry/subscription[@clientID='some-client-id' and @subscriptionName='some-subscription-name']/predicates";
41 def spiedJsonObjectMapper = Spy(new JsonObjectMapper(new ObjectMapper()))
42 def mockCpsDataService = Mock(CpsDataService)
43 def mockCpsModuleService = Mock(CpsModuleService)
44 def mockCpsValidator = Mock(CpsValidator)
46 def objectUnderTest = new SubscriptionPersistenceImpl(spiedJsonObjectMapper, mockCpsDataService,
47 mockCpsModuleService, mockCpsValidator)
49 def predicates = new YangModelSubscriptionEvent.Predicates(datastore: 'some-datastore',
50 targetCmHandles: [new YangModelSubscriptionEvent.TargetCmHandle('cmhandle1'),
51 new YangModelSubscriptionEvent.TargetCmHandle('cmhandle2')])
52 def yangModelSubscriptionEvent = new YangModelSubscriptionEvent(clientId: 'some-client-id',
53 subscriptionName: 'some-subscription-name', tagged: true, topic: 'some-topic', predicates: predicates)
55 def 'save a subscription event as yang model into db for the #scenarios' () {
56 given: 'a blank data node that exist in db'
57 def blankDataNode = new DataNodeBuilder().withDataspace(NCMP_DATASPACE_NAME)
58 .withAnchor('AVC-Subscriptions').withXpath('/subscription-registry').build()
59 and: 'cps data service return an empty data node'
60 mockCpsDataService.getDataNodes(*_) >> [blankDataNode]
61 when: 'the yangModelSubscriptionEvent is saved into db'
62 objectUnderTest.saveSubscriptionEvent(yangModelSubscriptionEvent)
63 then: 'the cpsDataService save operation is called with the correct data'
64 1 * mockCpsDataService.saveListElements(NCMP_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME,
65 SUBSCRIPTION_REGISTRY_PARENT,
66 '{"subscription":[{' +
67 '"topic":"some-topic",' +
68 '"predicates":{"datastore":"some-datastore","targetCmHandles":[{"cmHandleId":"cmhandle1","status":"PENDING","details":"Subscription forwarded to dmi plugin"},' +
69 '{"cmHandleId":"cmhandle2","status":"PENDING","details":"Subscription forwarded to dmi plugin"}]},' +
70 '"clientID":"some-client-id","subscriptionName":"some-subscription-name","isTagged":true}]}',
74 def 'add or replace cm handle list element into db' () {
75 given: 'a data node with child node exist in db'
76 def leaves1 = [status:'REJECTED', cmHandleId:'cmhandle1', details:'Cm handle does not exist'] as Map
77 def childDataNode = new DataNodeBuilder().withDataspace(NCMP_DATASPACE_NAME)
78 .withAnchor('AVC-Subscriptions').withXpath('/subscription-registry/subscription')
79 .withLeaves(leaves1).build()
80 def engagedDataNode = new DataNodeBuilder().withDataspace(NCMP_DATASPACE_NAME)
81 .withAnchor('AVC-Subscriptions').withXpath('/subscription-registry')
82 .withChildDataNodes([childDataNode]).build()
83 and: 'cps data service return data node including a child data node'
84 mockCpsDataService.getDataNodes(*_) >> [engagedDataNode]
85 and: 'cps data service return data node for querying by xpaths'
86 mockCpsDataService.getDataNodesForMultipleXpaths(*_) >> [engagedDataNode]
87 when: 'the yang model subscription event is saved into db'
88 objectUnderTest.saveSubscriptionEvent(yangModelSubscriptionEvent)
89 then: 'the cpsDataService save non-existing cm handle with the correct data'
90 1 * mockCpsDataService.saveListElements(NCMP_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME,
91 SUBSCRIPTION_REGISTRY_PREDICATES_XPATH, '{"targetCmHandles":[{"cmHandleId":"cmhandle2","status":"PENDING","details":"Subscription forwarded to dmi plugin"}]}',
93 and: 'the cpsDataService update existing cm handle with the correct data'
94 1 * mockCpsDataService.updateNodeLeaves(NCMP_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME,
95 SUBSCRIPTION_REGISTRY_PREDICATES_XPATH, '{"targetCmHandles":[{"cmHandleId":"cmhandle1","status":"PENDING","details":"Subscription forwarded to dmi plugin"}]}',