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.subscriptions
23 import com.fasterxml.jackson.databind.ObjectMapper
24 import org.onap.cps.api.CpsDataService
25 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelSubscriptionEvent
26 import org.onap.cps.spi.model.DataNodeBuilder
27 import org.onap.cps.utils.JsonObjectMapper
28 import spock.lang.Specification
30 import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NO_TIMESTAMP
32 class SubscriptionPersistenceSpec extends Specification {
34 private static final String SUBSCRIPTION_DATASPACE_NAME = "NCMP-Admin";
35 private static final String SUBSCRIPTION_ANCHOR_NAME = "AVC-Subscriptions";
36 private static final String SUBSCRIPTION_REGISTRY_PARENT = "/subscription-registry";
37 private static final String SUBSCRIPTION_REGISTRY_PREDICATES_XPATH = "/subscription-registry/subscription[@clientID='some-client-id' and @subscriptionName='some-subscription-name']/predicates";
39 def jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
40 def mockCpsDataService = Mock(CpsDataService)
41 def objectUnderTest = new SubscriptionPersistenceImpl(jsonObjectMapper, mockCpsDataService)
43 def predicates = new YangModelSubscriptionEvent.Predicates(datastore: 'some-datastore',
44 targetCmHandles: [new YangModelSubscriptionEvent.TargetCmHandle('cmhandle1'),
45 new YangModelSubscriptionEvent.TargetCmHandle('cmhandle2')])
46 def yangModelSubscriptionEvent = new YangModelSubscriptionEvent(clientId: 'some-client-id',
47 subscriptionName: 'some-subscription-name', tagged: true, topic: 'some-topic', predicates: predicates)
49 def 'save a subscription event as yang model into db for the #scenarios' () {
50 given: 'a blank data node that exist in db'
51 def blankDataNode = new DataNodeBuilder().withDataspace('NCMP-Admin')
52 .withAnchor('AVC-Subscriptions').withXpath('/subscription-registry').build()
53 and: 'cps data service return an empty data node'
54 mockCpsDataService.getDataNodes(*_) >> [blankDataNode]
55 when: 'the yangModelSubscriptionEvent is saved into db'
56 objectUnderTest.saveSubscriptionEvent(yangModelSubscriptionEvent)
57 then: 'the cpsDataService save operation is called with the correct data'
58 1 * mockCpsDataService.saveListElements(SUBSCRIPTION_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME,
59 SUBSCRIPTION_REGISTRY_PARENT,
60 '{"subscription":[{' +
61 '"topic":"some-topic",' +
62 '"predicates":{"datastore":"some-datastore","targetCmHandles":[{"cmHandleId":"cmhandle1","status":"PENDING","details":"Subscription forwarded to dmi plugin"},' +
63 '{"cmHandleId":"cmhandle2","status":"PENDING","details":"Subscription forwarded to dmi plugin"}]},' +
64 '"clientID":"some-client-id","subscriptionName":"some-subscription-name","isTagged":true}]}',
68 def 'add or replace cm handle list element into db' () {
69 given: 'a data node with child node exist in db'
70 def leaves1 = [status:'REJECTED', cmHandleId:'cmhandle1', details:'Cm handle does not exist'] as Map
71 def childDataNode = new DataNodeBuilder().withDataspace('NCMP-Admin')
72 .withAnchor('AVC-Subscriptions').withXpath('/subscription-registry/subscription')
73 .withLeaves(leaves1).build()
74 def engagedDataNode = new DataNodeBuilder().withDataspace('NCMP-Admin')
75 .withAnchor('AVC-Subscriptions').withXpath('/subscription-registry')
76 .withChildDataNodes([childDataNode]).build()
77 and: 'cps data service return data node including a child data node'
78 mockCpsDataService.getDataNodes(*_) >> [engagedDataNode]
79 and: 'cps data service return data node for querying by xpaths'
80 mockCpsDataService.getDataNodesForMultipleXpaths(*_) >> [engagedDataNode]
81 when: 'the yang model subscription event is saved into db'
82 objectUnderTest.saveSubscriptionEvent(yangModelSubscriptionEvent)
83 then: 'the cpsDataService save non-existing cm handle with the correct data'
84 1 * mockCpsDataService.saveListElements(SUBSCRIPTION_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME,
85 SUBSCRIPTION_REGISTRY_PREDICATES_XPATH, '{"targetCmHandles":[{"cmHandleId":"cmhandle2","status":"PENDING","details":"Subscription forwarded to dmi plugin"}]}',
87 and: 'the cpsDataService update existing cm handle with the correct data'
88 1 * mockCpsDataService.updateNodeLeaves(SUBSCRIPTION_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME,
89 SUBSCRIPTION_REGISTRY_PREDICATES_XPATH, '{"targetCmHandles":[{"cmHandleId":"cmhandle1","status":"PENDING","details":"Subscription forwarded to dmi plugin"}]}',