Fixing minor compilation
[cps.git] / cps-ri / src / test / groovy / org / onap / cps / spi / impl / CpsAdminPersistenceServiceSpec.groovy
1 /*
2  *  ============LICENSE_START=======================================================
3  *  Copyright (C) 2021-2023 Nordix Foundation
4  *  Modifications Copyright (C) 2021 Pantheon.tech
5  *  Modifications Copyright (C) 2022 Bell Canada
6  *  Modifications Copyright (C) 2022 TechMahindra Ltd.
7  *  ================================================================================
8  *  Licensed under the Apache License, Version 2.0 (the "License");
9  *  you may not use this file except in compliance with the License.
10  *  You may obtain a copy of the License at
11  *
12  *        http://www.apache.org/licenses/LICENSE-2.0
13  *
14  *  Unless required by applicable law or agreed to in writing, software
15  *  distributed under the License is distributed on an "AS IS" BASIS,
16  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  *  See the License for the specific language governing permissions and
18  *  limitations under the License.
19  *
20  *  SPDX-License-Identifier: Apache-2.0
21  *  ============LICENSE_END=========================================================
22  */
23
24 package org.onap.cps.spi.impl
25
26 import org.mockito.Mock
27 import org.onap.cps.spi.CpsAdminPersistenceService
28 import org.onap.cps.spi.exceptions.AlreadyDefinedException
29 import org.onap.cps.spi.exceptions.AnchorNotFoundException
30 import org.onap.cps.spi.exceptions.DataspaceInUseException
31 import org.onap.cps.spi.exceptions.DataspaceNotFoundException
32 import org.onap.cps.spi.exceptions.SchemaSetNotFoundException
33 import org.onap.cps.spi.model.Anchor
34 import org.onap.cps.spi.model.Dataspace
35 import org.springframework.beans.factory.annotation.Autowired
36 import org.springframework.test.context.jdbc.Sql
37 import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper
38
39 class CpsAdminPersistenceServiceSpec extends CpsPersistenceSpecBase {
40
41     @Autowired
42     CpsAdminPersistenceService objectUnderTest
43
44     @Mock
45     ObjectMapper objectMapper
46
47     static final String SET_DATA = '/data/anchor.sql'
48     static final String SAMPLE_DATA_FOR_ANCHORS_WITH_MODULES = '/data/anchors-schemaset-modules.sql'
49     static final String DATASPACE_WITH_NO_DATA = 'DATASPACE-002-NO-DATA'
50     static final Integer DELETED_ANCHOR_ID = 3002
51
52     @Sql(CLEAR_DATA)
53     def 'Create and retrieve a new dataspace.'() {
54         when: 'a new dataspace is created'
55             def dataspaceName = 'some-new-dataspace'
56             objectUnderTest.createDataspace(dataspaceName)
57         then: 'that dataspace can be retrieved from the dataspace repository'
58             def dataspaceEntity = dataspaceRepository.findByName(dataspaceName).orElseThrow()
59             dataspaceEntity.id != null
60             dataspaceEntity.name == dataspaceName
61     }
62
63     @Sql([CLEAR_DATA, SET_DATA])
64     def 'Attempt to create a duplicate dataspace.'() {
65         when: 'an attempt is made to create an already existing dataspace'
66             objectUnderTest.createDataspace(DATASPACE_NAME)
67         then: 'an exception that is is already defined is thrown with the correct details'
68             def thrown = thrown(AlreadyDefinedException)
69             thrown.details.contains(DATASPACE_NAME)
70     }
71
72     @Sql([CLEAR_DATA, SET_DATA])
73     def 'Get a dataspace.'() {
74         when: 'dataspace is retrieved'
75             def dataspace = objectUnderTest.getDataspace(DATASPACE_NAME)
76         then: ' the response contains expected dataspace'
77             assert dataspace.getName().equals(DATASPACE_NAME);
78     }
79
80     @Sql([CLEAR_DATA, SET_DATA])
81     def 'Get all dataspaces.'() {
82         when: 'all dataspaces are retrieved'
83             def dataspaces = objectUnderTest.getAllDataspaces()
84         then: 'the response contains expected dataspaces'
85             def expectedDataspaces = Set.of(new Dataspace(name: 'DATASPACE-001'), new Dataspace(name: 'DATASPACE-002-NO-DATA'),
86                      new Dataspace(name: 'DATASPACE-003'))
87             assert dataspaces == expectedDataspaces
88     }
89
90     @Sql([CLEAR_DATA, SET_DATA])
91     def 'Get non existing dataspace.'() {
92         when: 'attempting to retrieve a non-existing dataspace'
93             def dataspace = objectUnderTest.getDataspace('non_existing_dataspace')
94         then: 'an DataspaceNotFoundException is thrown'
95             thrown(DataspaceNotFoundException)
96     }
97
98     @Sql([CLEAR_DATA, SET_DATA])
99     def 'Create and retrieve a new anchor.'() {
100         when: 'a new anchor is created'
101             def newAnchorName = 'my-new-anchor'
102             objectUnderTest.createAnchor(DATASPACE_NAME, SCHEMA_SET_NAME1, newAnchorName)
103         then: 'that anchor can be retrieved'
104             def anchor = objectUnderTest.getAnchor(DATASPACE_NAME, newAnchorName)
105             anchor.name == newAnchorName
106             anchor.dataspaceName == DATASPACE_NAME
107             anchor.schemaSetName == SCHEMA_SET_NAME1
108     }
109
110     @Sql([CLEAR_DATA, SET_DATA])
111     def 'Create anchor error scenario: #scenario.'() {
112         when: 'attempt to create new anchor named #anchorName in dataspace #dataspaceName with #schemaSetName'
113             objectUnderTest.createAnchor(dataspaceName, schemaSetName, anchorName)
114         then: 'an #expectedException is thrown'
115             thrown(expectedException)
116         where: 'the following data is used'
117             scenario                    | dataspaceName  | schemaSetName    | anchorName     || expectedException
118             'dataspace does not exist'  | 'unknown'      | 'not-relevant'   | 'not-relevant' || DataspaceNotFoundException
119             'schema set does not exist' | DATASPACE_NAME | 'unknown'        | 'not-relevant' || SchemaSetNotFoundException
120             'anchor already exists'     | DATASPACE_NAME | SCHEMA_SET_NAME1 | ANCHOR_NAME1   || AlreadyDefinedException
121     }
122
123     @Sql([CLEAR_DATA, SET_DATA])
124     def 'Get anchor error scenario: #scenario.'() {
125         when: 'attempt to get anchor named #anchorName in dataspace #dataspaceName'
126             objectUnderTest.getAnchor(dataspaceName, anchorName)
127         then: 'an #expectedException is thrown'
128             thrown(expectedException)
129         where: 'the following data is used'
130             scenario                   | dataspaceName  | anchorName     || expectedException
131             'dataspace does not exist' | 'unknown'      | 'not-relevant' || DataspaceNotFoundException
132             'anchor does not exists'   | DATASPACE_NAME | 'unknown'      || AnchorNotFoundException
133     }
134
135     @Sql([CLEAR_DATA, SET_DATA])
136     def 'Get all anchors in dataspace #dataspaceName.'() {
137         when: 'all anchors are retrieved from #DATASPACE_NAME'
138             def result = objectUnderTest.getAnchors(dataspaceName)
139         then: 'the expected collection of anchors is returned'
140             result.size() == expectedAnchors.size()
141             result.containsAll(expectedAnchors)
142         where: 'the following data is used'
143             dataspaceName          || expectedAnchors
144             DATASPACE_NAME         || [Anchor.builder().name(ANCHOR_NAME1).schemaSetName(SCHEMA_SET_NAME1).dataspaceName(DATASPACE_NAME).build(),
145                                        Anchor.builder().name(ANCHOR_NAME2).schemaSetName(SCHEMA_SET_NAME2).dataspaceName(DATASPACE_NAME).build(),
146                                        Anchor.builder().name(ANCHOR_NAME3).schemaSetName(SCHEMA_SET_NAME2).dataspaceName(DATASPACE_NAME).build()]
147             DATASPACE_WITH_NO_DATA || []
148     }
149
150     @Sql([CLEAR_DATA, SET_DATA])
151     def 'Get all anchors associated with schemaset in a dataspace.'() {
152         when: 'anchors are retrieved by dataspace and schema-set'
153             def anchors = objectUnderTest.getAnchors(dataspace, schemasetName)
154         then: ' the response contains expected anchors'
155             anchors == expectedAnchors
156         where:
157             scenario     | dataspace       | schemasetName               || expectedAnchors
158             'no-anchors' | 'DATASPACE-003' | 'SCHEMA-SET-002-NO-ANCHORS' || Collections.emptySet()
159             'one-anchor' | 'DATASPACE-001' | 'SCHEMA-SET-001'            || Set.of(new Anchor('ANCHOR-001', 'DATASPACE-001', 'SCHEMA-SET-001'))
160     }
161
162     @Sql([CLEAR_DATA, SET_DATA])
163     def 'Error Handling: Get all anchors associated with schemaset in a dataspace.'() {
164         when: 'anchors are retrieved by dataspace and schema-set'
165             def anchors = objectUnderTest.getAnchors(dataspace, schemasetName)
166         then: ' an expected expception is thrown'
167             thrown(expectedException)
168         where:
169             scenario            | dataspace       | schemasetName               || expectedException
170             'unknown-dataspace' | 'unknown'       | 'SCHEMA-SET-002-NO-ANCHORS' || DataspaceNotFoundException
171             'unknown-schemaset' | 'DATASPACE-001' | 'unknown-schema-set'        || SchemaSetNotFoundException
172     }
173
174     @Sql(CLEAR_DATA)
175     def 'Get all anchors in unknown dataspace.'() {
176         when: 'attempt to get all anchors in an unknown dataspace'
177             objectUnderTest.getAnchors('unknown-dataspace')
178         then: 'an DataspaceNotFoundException is thrown'
179             thrown(DataspaceNotFoundException)
180     }
181
182     @Sql([CLEAR_DATA, SET_DATA])
183     def 'Get all anchors associated with multiple schemasets in a dataspace.'() {
184         when: 'anchors are retrieved by dataspace and schema-sets'
185             def anchors = objectUnderTest.getAnchors('DATASPACE-001', ['SCHEMA-SET-001', 'SCHEMA-SET-002'])
186         then: ' the response contains expected anchors'
187             anchors == Set.of(
188                 new Anchor('ANCHOR-001', 'DATASPACE-001', 'SCHEMA-SET-001'),
189                 new Anchor('ANCHOR-002', 'DATASPACE-001', 'SCHEMA-SET-002'),
190                 new Anchor('ANCHOR-003', 'DATASPACE-001', 'SCHEMA-SET-002'))
191     }
192
193     @Sql([CLEAR_DATA, SET_DATA])
194     def 'Delete anchor'() {
195         when: 'delete anchor action is invoked'
196             objectUnderTest.deleteAnchor(DATASPACE_NAME, ANCHOR_NAME2)
197         then: 'anchor is deleted'
198             assert anchorRepository.findById(DELETED_ANCHOR_ID).isEmpty()
199     }
200
201     @Sql([CLEAR_DATA, SET_DATA])
202     def 'delete anchor error scenario: #scenario'() {
203         when: 'delete anchor attempt is performed'
204             objectUnderTest.deleteAnchor(dataspaceName, anchorName)
205         then: 'an #expectedException is thrown'
206             thrown(expectedException)
207         where: 'the following data is used'
208             scenario                   | dataspaceName  | anchorName     || expectedException
209             'dataspace does not exist' | 'unknown'      | 'not-relevant' || DataspaceNotFoundException
210             'anchor does not exists'   | DATASPACE_NAME | 'unknown'      || AnchorNotFoundException
211     }
212
213     @Sql([CLEAR_DATA, SET_DATA])
214     def 'Delete multiple anchors'() {
215         when: 'delete anchors action is invoked'
216             objectUnderTest.deleteAnchors(DATASPACE_NAME, ['ANCHOR-002', 'ANCHOR-003'])
217         then: 'anchors are deleted'
218             anchorRepository.findById(3002).isEmpty()
219             anchorRepository.findById(3003).isEmpty()
220     }
221
222     @Sql([CLEAR_DATA, SAMPLE_DATA_FOR_ANCHORS_WITH_MODULES])
223     def 'Query anchors that have #scenario.'() {
224         when: 'all anchor are retrieved for the given dataspace name and module names'
225             def anchors = objectUnderTest.queryAnchors(inputDataspaceName, inputModuleNames)
226         then: 'the expected anchors are returned'
227             anchors.size() == expectedAnchors.size()
228             anchors.containsAll(expectedAnchors)
229         where: 'the following data is used'
230             scenario                           | inputDataspaceName  | inputModuleNames                                    || expectedAnchors
231             'one module'                       | 'dataspace-1'       | ['module-name-1']                                   || [buildAnchor('anchor-2', 'dataspace-1', 'schema-set-2'), buildAnchor('anchor-1', 'dataspace-1', 'schema-set-1')]
232             'two modules'                      | 'dataspace-1'       | ['module-name-1', 'module-name-2']                  || [buildAnchor('anchor-2', 'dataspace-1', 'schema-set-2'), buildAnchor('anchor-1', 'dataspace-1', 'schema-set-1')]
233             'no anchors for all three modules' | 'dataspace-1'       | ['module-name-1', 'module-name-2', 'module-name-3'] || []
234             'unknown dataspace'                | 'db-does-not-exist' | ['does-not-matter']                                 || []
235             'unknown module and known module'  | 'dataspace-1'       | ['module-name-1', 'module-does-not-exist']          || []
236     }
237
238     def buildAnchor(def anchorName, def dataspaceName, def SchemaSetName) {
239         return Anchor.builder().name(anchorName).dataspaceName(dataspaceName).schemaSetName(SchemaSetName).build()
240     }
241
242     @Sql([CLEAR_DATA, SET_DATA])
243     def 'Delete dataspace.'() {
244         when: 'delete dataspace action is invoked'
245             objectUnderTest.deleteDataspace(DATASPACE_WITH_NO_DATA)
246         then: 'dataspace is deleted'
247             assert dataspaceRepository.findByName(DATASPACE_WITH_NO_DATA).isEmpty();
248     }
249
250     @Sql([CLEAR_DATA, SET_DATA])
251     def 'Delete dataspace when #scenario.'() {
252         when: 'delete dataspace action is invoked'
253             objectUnderTest.deleteDataspace(dataspaceName)
254         then: 'the correct exception is thrown with the relevant details'
255             def thrownException = thrown(expectedException)
256             thrownException.details.contains(expectedMessageDetails)
257         where: 'the following data is used'
258             scenario                        | dataspaceName   || expectedException          | expectedMessageDetails
259             'dataspace name does not exist' | 'unknown'       || DataspaceNotFoundException | 'unknown does not exist'
260             'dataspace contains an anchor'  | 'DATASPACE-001' || DataspaceInUseException    | 'contains 3 anchor(s)'
261             'dataspace contains schemasets' | 'DATASPACE-003' || DataspaceInUseException    | 'contains 1 schemaset(s)'
262     }
263 }