Combine alreadyDefinedException classes
[cps.git] / cps-ncmp-service / src / test / groovy / org / onap / cps / ncmp / init / SubscriptionModelLoaderSpec.groovy
1 /*
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
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  *
17  *  SPDX-License-Identifier: Apache-2.0
18  *  ============LICENSE_END=========================================================
19  */
20
21 package org.onap.cps.ncmp.init
22
23 import ch.qos.logback.classic.Level
24 import ch.qos.logback.classic.Logger
25 import ch.qos.logback.core.read.ListAppender
26 import org.onap.cps.api.CpsAdminService
27 import org.onap.cps.api.CpsDataService
28 import org.onap.cps.api.CpsModuleService
29 import org.onap.cps.ncmp.api.impl.exception.NcmpStartUpException
30 import org.onap.cps.spi.exceptions.AlreadyDefinedException
31 import org.onap.cps.spi.exceptions.DataValidationException
32 import org.onap.cps.spi.exceptions.SchemaSetNotFoundException
33 import org.onap.cps.spi.model.Dataspace
34 import org.springframework.boot.SpringApplication
35 import org.slf4j.LoggerFactory
36 import org.springframework.boot.context.event.ApplicationReadyEvent
37 import org.springframework.context.annotation.AnnotationConfigApplicationContext
38 import spock.lang.Specification
39
40 class SubscriptionModelLoaderSpec extends Specification {
41
42     def mockCpsAdminService = Mock(CpsAdminService)
43     def mockCpsModuleService = Mock(CpsModuleService)
44     def mockCpsDataService = Mock(CpsDataService)
45     def objectUnderTest = new SubscriptionModelLoader(mockCpsAdminService, mockCpsModuleService, mockCpsDataService)
46
47     def sampleYangContentMap = ['subscription.yang':'module subscription { *sample content* }']
48
49     def applicationContext = new AnnotationConfigApplicationContext()
50
51     def applicationReadyEvent = new ApplicationReadyEvent(new SpringApplication(), null, applicationContext, null)
52
53     def yangResourceToContentMap
54     def logger = (Logger) LoggerFactory.getLogger(objectUnderTest.getClass())
55     def loggingListAppender
56
57     void setup() {
58         yangResourceToContentMap = objectUnderTest.createYangResourceToContentMap()
59         logger.setLevel(Level.DEBUG)
60         loggingListAppender = new ListAppender()
61         logger.addAppender(loggingListAppender)
62         loggingListAppender.start()
63         applicationContext.refresh()
64     }
65
66     void cleanup() {
67         ((Logger) LoggerFactory.getLogger(SubscriptionModelLoader.class)).detachAndStopAllAppenders()
68         applicationContext.close()
69     }
70
71     def 'Onboard subscription model successfully via application ready event'() {
72         given: 'dataspace is ready for use'
73             mockCpsAdminService.getDataspace('NCMP-Admin') >> new Dataspace('NCMP-Admin')
74         and:'model loader is enabled'
75             objectUnderTest.subscriptionModelLoaderEnabled = true
76         and: 'maximum attempt count is set'
77             objectUnderTest.maximumAttemptCount = 20
78         and: 'retry time is set'
79             objectUnderTest.retryTimeMs = 100
80         when: 'the application is ready'
81             objectUnderTest.onApplicationEvent(applicationReadyEvent)
82         then: 'the module service to create schema set is called once'
83             1 * mockCpsModuleService.createSchemaSet('NCMP-Admin', 'subscriptions',sampleYangContentMap)
84         and: 'the admin service to create an anchor set is called once'
85             1 * mockCpsAdminService.createAnchor('NCMP-Admin', 'subscriptions', 'AVC-Subscriptions')
86         and: 'the data service to create a top level datanode is called once'
87             1 * mockCpsDataService.saveData('NCMP-Admin', 'AVC-Subscriptions', '{"subscription-registry":{}}', _)
88     }
89
90     def 'No subscription model onboarding when subscription model loader is disabled' () {
91         when: 'model loader is disabled'
92             objectUnderTest.subscriptionModelLoaderEnabled = false
93         and: 'application is ready'
94             objectUnderTest.onApplicationEvent(applicationReadyEvent)
95         and: 'dataspace is ready for use'
96             mockCpsAdminService.getDataspace('NCMP-Admin') >> new Dataspace('NCMP-Admin')
97         then: 'the module service to create schema set was not called'
98             0 * mockCpsModuleService.createSchemaSet(*_)
99         and: 'the admin service to create an anchor set was not called'
100             0 * mockCpsAdminService.createAnchor(*_)
101         and: 'the data service to create a top level datanode was not called'
102             0 * mockCpsDataService.saveData(*_)
103     }
104
105     def 'Onboard subscription model fails as NCMP dataspace does not exist' () {
106         given: 'model loader is enabled'
107             objectUnderTest.subscriptionModelLoaderEnabled = true
108         and: 'maximum attempt count is set'
109             objectUnderTest.maximumAttemptCount = 20
110         and: 'retry time is set'
111             objectUnderTest.retryTimeMs = 100
112         when: 'the application is ready'
113             objectUnderTest.onApplicationEvent(applicationReadyEvent)
114         then: 'the module service to create schema set was not called'
115             0 * mockCpsModuleService.createSchemaSet(*_)
116         and: 'the admin service to create an anchor set was not called'
117             0 * mockCpsAdminService.createAnchor(*_)
118         and: 'the data service to create a top level datanode was not called'
119             0 * mockCpsDataService.saveData(*_)
120         and: 'the log message contains the correct exception message'
121             def logs = loggingListAppender.list.toString()
122             assert logs.contains("Retrieval of NCMP dataspace fails")
123     }
124
125
126     def 'Exception occurred while schema set creation' () {
127         given: 'creating a schema set throws an exception'
128             mockCpsModuleService.createSchemaSet(*_) >>  { throw new DataValidationException(*_) }
129         and: 'model loader is enabled'
130             objectUnderTest.subscriptionModelLoaderEnabled = true
131         and: 'dataspace is ready for use'
132             mockCpsAdminService.getDataspace('NCMP-Admin') >> new Dataspace('NCMP-Admin')
133         when: 'application is ready'
134             objectUnderTest.onApplicationEvent(applicationReadyEvent)
135         then: 'the admin service to create an anchor set was not called'
136             0 * mockCpsAdminService.createAnchor(*_)
137         and: 'the data service to create a top level datanode was not called'
138             0 * mockCpsDataService.saveData(*_)
139     }
140
141     def 'Create schema set from model file'() {
142         when: 'the method to create schema set is called with the following parameters'
143             objectUnderTest.createSchemaSet("myDataspace", "mySchemaSet", yangResourceToContentMap)
144         then: 'yang resource to content map is as expected'
145             assert sampleYangContentMap == yangResourceToContentMap
146         and: 'the module service to create schema set is called once with the correct map'
147             1 * mockCpsModuleService.createSchemaSet(_, _, yangResourceToContentMap)
148     }
149
150     def 'Create schema set fails due to AlreadyDefined exception'() {
151         given: 'creating a schema set throws an exception as it already exists'
152             mockCpsModuleService.createSchemaSet('NCMP-Admin', 'subscriptions', yangResourceToContentMap) >>
153                     { throw AlreadyDefinedException.forSchemaSet('subscriptions', "sampleContextName", null) }
154         when: 'the method to onboard model is called'
155             objectUnderTest.onboardSubscriptionModel(yangResourceToContentMap)
156         then: 'the admin service to create an anchor set is then called once'
157             1 * mockCpsAdminService.createAnchor('NCMP-Admin', 'subscriptions', 'AVC-Subscriptions')
158     }
159
160     def 'Create schema set fails due to any other exception'() {
161         given: 'creating a schema set throws an exception'
162             mockCpsModuleService.createSchemaSet(*_) >> { throw new NcmpStartUpException("Creating schema set failed", "") }
163         when: 'the method to onboard model is called'
164             objectUnderTest.onboardSubscriptionModel(yangResourceToContentMap)
165         then: 'the log message contains the correct exception message'
166             def debugMessage = loggingListAppender.list[0].toString()
167             assert debugMessage.contains("Creating schema set failed")
168         and: 'exception is thrown'
169             thrown(NcmpStartUpException)
170     }
171
172     def 'Create anchor fails due to AlreadyDefined exception'() {
173         given: 'creating anchor throws an exception as it already exists'
174             mockCpsAdminService.createAnchor(*_) >>
175                     { throw AlreadyDefinedException.forSchemaSet('subscriptions', "sampleContextName", null) }
176         when: 'the method to onboard model is called'
177             objectUnderTest.onboardSubscriptionModel(yangResourceToContentMap)
178         then: 'no exception thrown'
179             noExceptionThrown()
180         and: 'the log message contains the correct exception message'
181             def infoMessage = loggingListAppender.list[0].toString()
182             assert infoMessage.contains("already exists")
183     }
184
185     def 'Create anchor fails due to any other exception'() {
186         given: 'creating an anchor failed'
187             mockCpsAdminService.createAnchor(*_) >>
188                     { throw new SchemaSetNotFoundException('NCMP-Admin', 'subscriptions') }
189         when: 'the method to onboard model is called'
190             objectUnderTest.onboardSubscriptionModel(yangResourceToContentMap)
191         then: 'the log message contains the correct exception message'
192             def debugMessage = loggingListAppender.list[0].toString()
193             assert debugMessage.contains("Schema Set not found")
194         and: 'exception is thrown'
195             thrown(NcmpStartUpException)
196     }
197
198     def 'Create top level node fails due to an AlreadyDefined exception'() {
199         given: 'the saving of the node data will throw an Already Defined exception'
200             mockCpsDataService.saveData(*_) >>
201                     { throw AlreadyDefinedException.forDataNodes(['/xpath'], "sampleContextName") }
202         when: 'the method to onboard model is called'
203             objectUnderTest.onboardSubscriptionModel(yangResourceToContentMap)
204         then: 'no exception thrown'
205             noExceptionThrown()
206         and: 'the log message contains the correct exception message'
207             def infoMessage = loggingListAppender.list[0].toString()
208             assert infoMessage.contains("already exists")
209     }
210
211     def 'Create top level node fails due to any other exception'() {
212         given: 'the saving of the node data will throw an exception'
213             mockCpsDataService.saveData(*_) >>
214                 { throw new DataValidationException("Invalid JSON", "JSON Data is invalid") }
215         when: 'the method to onboard model is called'
216             objectUnderTest.onboardSubscriptionModel(yangResourceToContentMap)
217         then: 'the log message contains the correct exception message'
218             def debugMessage = loggingListAppender.list[0].toString()
219             assert debugMessage.contains("Creating data node for subscription model failed: Invalid JSON")
220         and: 'exception is thrown'
221             thrown(NcmpStartUpException)
222     }
223
224     def 'Get file content as string'() {
225         when: 'the method to get yang content is called'
226             objectUnderTest.getFileContentAsString('NonExistingFile')
227         then: 'exception is thrown'
228             thrown(NcmpStartUpException)
229     }
230 }