NoContent:
description: No Content
content: {}
+ InternalServerError:
+ description: Internal Server Error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/ErrorMessage"
+ example:
+ status: 500
+ message: Internal Server Error
+ details: Internal Server Error occurred
# ============LICENSE_START=======================================================
# Copyright (C) 2021 Bell Canada
+# Modifications Copyright (C) 2021-2022 Nordix Foundation
# ================================================================================
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
$ref: 'components.yaml#/components/responses/Unauthorized'
403:
$ref: 'components.yaml#/components/responses/Forbidden'
+ 500:
+ $ref: 'components.yaml#/components/responses/InternalServerError'
$ref: 'components.yaml#/components/responses/Unauthorized'
403:
$ref: 'components.yaml#/components/responses/Forbidden'
- 404:
- $ref: 'components.yaml#/components/responses/NotFound'
+ 500:
+ $ref: 'components.yaml#/components/responses/InternalServerError'
resourceDataForPassthroughRunning:
get:
$ref: 'components.yaml#/components/responses/Unauthorized'
403:
$ref: 'components.yaml#/components/responses/Forbidden'
- 404:
- $ref: 'components.yaml#/components/responses/NotFound'
+ 500:
+ $ref: 'components.yaml#/components/responses/InternalServerError'
post:
tags:
- network-cm-proxy
$ref: 'components.yaml#/components/responses/Unauthorized'
403:
$ref: 'components.yaml#/components/responses/Forbidden'
- 404:
- $ref: 'components.yaml#/components/responses/NotFound'
+ 500:
+ $ref: 'components.yaml#/components/responses/InternalServerError'
put:
tags:
$ref: 'components.yaml#/components/responses/Unauthorized'
403:
$ref: 'components.yaml#/components/responses/Forbidden'
- 404:
- $ref: 'components.yaml#/components/responses/NotFound'
+ 500:
+ $ref: 'components.yaml#/components/responses/InternalServerError'
patch:
tags:
$ref: 'components.yaml#/components/responses/Unauthorized'
403:
$ref: 'components.yaml#/components/responses/Forbidden'
- 404:
- $ref: 'components.yaml#/components/responses/NotFound'
+ 500:
+ $ref: 'components.yaml#/components/responses/InternalServerError'
delete:
tags:
$ref: 'components.yaml#/components/responses/Forbidden'
404:
$ref: 'components.yaml#/components/responses/NotFound'
-
+ 500:
+ $ref: 'components.yaml#/components/responses/InternalServerError'
fetchModuleReferencesByCmHandle:
get:
$ref: 'components.yaml#/components/responses/Unauthorized'
403:
$ref: 'components.yaml#/components/responses/Forbidden'
- 404:
- $ref: 'components.yaml#/components/responses/NotFound'
+ 500:
+ $ref: 'components.yaml#/components/responses/InternalServerError'
executeCmHandleSearch:
post:
$ref: 'components.yaml#/components/responses/Unauthorized'
403:
$ref: 'components.yaml#/components/responses/Forbidden'
+ 500:
+ $ref: 'components.yaml#/components/responses/InternalServerError'
package org.onap.cps.ncmp.rest.exceptions;
import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.impl.exception.DmiRequestException;
import org.onap.cps.ncmp.api.impl.exception.NcmpException;
+import org.onap.cps.ncmp.api.impl.exception.ServerNcmpException;
import org.onap.cps.ncmp.rest.controller.NetworkCmProxyController;
import org.onap.cps.ncmp.rest.model.ErrorMessage;
import org.onap.cps.spi.exceptions.CpsException;
return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception);
}
- @ExceptionHandler({NcmpException.class})
- public static ResponseEntity<Object> handleNcmpExceptions(final NcmpException exception) {
+ @ExceptionHandler({ServerNcmpException.class})
+ public static ResponseEntity<Object> handleServerNcmpExceptions(final ServerNcmpException exception) {
return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception);
}
+ @ExceptionHandler({DmiRequestException.class})
+ public static ResponseEntity<Object> handleDmiRequestExceptions(final DmiRequestException exception) {
+ return buildErrorResponse(HttpStatus.BAD_REQUEST, exception);
+ }
+
private static ResponseEntity<Object> buildErrorResponse(final HttpStatus status, final Exception exception) {
if (exception.getCause() != null || !(exception instanceof CpsException)) {
log.error("Exception occurred", exception);
import groovy.json.JsonSlurper
import org.modelmapper.ModelMapper
import org.onap.cps.ncmp.api.NetworkCmProxyDataService
-import org.onap.cps.ncmp.api.impl.exception.NcmpException
+import org.onap.cps.ncmp.api.impl.exception.DmiRequestException
+import org.onap.cps.ncmp.api.impl.exception.ServerNcmpException
import org.onap.cps.spi.exceptions.CpsException
import org.onap.cps.utils.JsonObjectMapper
import org.spockframework.spring.SpringBean
import spock.lang.Shared
import spock.lang.Specification
+import static org.springframework.http.HttpStatus.BAD_REQUEST
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
dataNodeBaseEndpoint = "$basePath/v1"
}
- def 'Get request with generic #scenario exception returns HTTP Status Internal Server Error.'() {
- when: 'generic CPS exception is thrown by the service'
+ def 'Get request with generic #scenario exception returns correct HTTP Status.'() {
+ when: 'an exception is thrown by the service'
setupTestException(exception)
def response = performTestRequest()
- then: 'an HTTP Internal Server Error response is returned with correct message and details'
- assertTestResponse(response, INTERNAL_SERVER_ERROR, errorMessage, expectedErrorDetails)
+ then: 'an HTTP response is returned with correct message and details'
+ assertTestResponse(response, expectedErrorCode, errorMessage, expectedErrorDetails)
where:
- scenario | exception || expectedErrorDetails
- 'CPS' | new CpsException(errorMessage, errorDetails) || errorDetails
- 'NCMP' | new NcmpException(errorMessage, errorDetails) || null
- 'other' | new IllegalStateException(errorMessage) || null
+ scenario | exception || expectedErrorDetails | expectedErrorCode
+ 'CPS' | new CpsException(errorMessage, errorDetails) || errorDetails | INTERNAL_SERVER_ERROR
+ 'NCMP-server' | new ServerNcmpException(errorMessage, errorDetails) || null | INTERNAL_SERVER_ERROR
+ 'NCMP-client' | new DmiRequestException(errorMessage, errorDetails) || null | BAD_REQUEST
+ 'other' | new IllegalStateException(errorMessage) || null | INTERNAL_SERVER_ERROR
}
def setupTestException(exception){
import org.onap.cps.api.CpsDataService;
import org.onap.cps.api.CpsModuleService;
import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
-import org.onap.cps.ncmp.api.impl.exception.NcmpException;
+import org.onap.cps.ncmp.api.impl.exception.ServerNcmpException;
import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations;
import org.onap.cps.ncmp.api.impl.operations.DmiModelOperations;
import org.onap.cps.ncmp.api.impl.operations.DmiOperations;
if (responseEntity.getStatusCode().is2xxSuccessful()) {
return responseEntity.getBody();
} else {
- throw new NcmpException(exceptionMessage,
+ throw new ServerNcmpException(exceptionMessage,
"DMI status code: " + responseEntity.getStatusCodeValue()
+ ", DMI response body: " + responseEntity.getBody());
}
--- /dev/null
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation
+ * ================================================================================
+ * 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.ncmp.api.impl.exception;
+
+/**
+ * Client Based Network CM Proxy exception.
+ */
+public class DmiRequestException extends NcmpException {
+
+ /**
+ * Constructor.
+ *
+ * @param message the error message
+ * @param details the error details
+ */
+ public DmiRequestException(final String message, final String details) {
+ super(message, details);
+ }
+}
--- /dev/null
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation
+ * ================================================================================
+ * 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.ncmp.api.impl.exception;
+
+/**
+ * Server Based Network CM Proxy exception.
+ */
+public class ServerNcmpException extends NcmpException {
+
+ /**
+ * Constructor.
+ *
+ * @param message the error message
+ * @param details the error details
+ */
+ public ServerNcmpException(final String message, final String details) {
+ super(message, details);
+ }
+}
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation
+ * Copyright (C) 2021-2022 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import java.util.List;
import lombok.Getter;
import lombok.Setter;
+import org.onap.cps.ncmp.api.impl.exception.DmiRequestException;
import org.onap.cps.ncmp.api.impl.exception.NcmpException;
/**
}
if (errorMessage != null) {
- throw new NcmpException(errorMessage, "Please supply correct plugin information.");
+ throw new DmiRequestException(errorMessage, "Please supply correct plugin information.");
}
}
import org.onap.cps.api.CpsAdminService
import org.onap.cps.api.CpsDataService
import org.onap.cps.api.CpsModuleService
+import org.onap.cps.ncmp.api.impl.exception.DmiRequestException
import org.onap.cps.ncmp.api.impl.exception.NcmpException
import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations
import org.onap.cps.ncmp.api.impl.operations.DmiModelOperations
dmiPluginRegistration.createdCmHandles = [persistenceCmHandle]
when: 'registration is called with incorrect DMI plugin information'
objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
- then: 'an NcmpException is thrown with correct message details'
- def exceptionThrown = thrown(NcmpException)
+ then: 'a DMI Request Exception is thrown with correct message details'
+ def exceptionThrown = thrown(DmiRequestException.class)
assert exceptionThrown.getMessage().contains(expectedMessageDetails)
and: 'registration is not called'
0 * objectUnderTest.parseAndCreateCmHandlesInDmiRegistrationAndSyncModules(dmiPluginRegistration)
import org.onap.cps.api.CpsAdminService
import org.onap.cps.api.CpsDataService
import org.onap.cps.api.CpsModuleService
-import org.onap.cps.ncmp.api.impl.exception.NcmpException
+import org.onap.cps.ncmp.api.impl.exception.ServerNcmpException
import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations
import org.onap.cps.spi.FetchDescendantsOption
import org.onap.cps.spi.model.DataNode
'testResourceId', CREATE,
'{some-json}', 'application/json')
then: 'exception is thrown'
- def exceptionThrown = thrown(NcmpException.class)
+ def exceptionThrown = thrown(ServerNcmpException.class)
and: 'details contains (not found) error code: 404'
exceptionThrown.details.contains('404')
}
-
def 'Get resource data for pass-through operational from DMI.'() {
given: 'get data node is called'
mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
'testAcceptParam',
'(a=1,b=2)')
then: 'exception is thrown with the expected details'
- def exceptionThrown = thrown(NcmpException.class)
+ def exceptionThrown = thrown(ServerNcmpException.class)
exceptionThrown.details == 'DMI status code: 404, DMI response body: NOK-json'
}
'testAcceptParam',
'(a=1,b=2)')
then: 'exception is thrown'
- def exceptionThrown = thrown(NcmpException.class)
+ def exceptionThrown = thrown(ServerNcmpException.class)
and: 'details contains the original response'
exceptionThrown.details.contains('NOK-json')
}
'testAcceptParam',
'(a=1,b=2)')
then: 'exception is thrown'
- def exceptionThrown = thrown(NcmpException.class)
+ def exceptionThrown = thrown(ServerNcmpException.class)
and: 'details contains the original response'
exceptionThrown.details.contains('NOK-json')
}
'{some-json}',
'application/json')
then: 'an exception is thrown with the expected error message detailsd with correct operation'
- def exceptionThrown = thrown(NcmpException.class)
+ def exceptionThrown = thrown(ServerNcmpException.class)
exceptionThrown.getMessage().contains(expectedResponseMessage)
where:
scenario | givenOperation || expectedResponseMessage
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2020 Nordix Foundation.
- * Modifications Copyright (C) 2020 Bell Canada.
+ * Modifications Copyright (C) 2020-2022 Bell Canada.
* Modifications Copyright (C) 2021 Pantheon.tech
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
import org.onap.cps.spi.CpsAdminPersistenceService;
import org.onap.cps.spi.entities.AnchorEntity;
import org.onap.cps.spi.entities.DataspaceEntity;
+import org.onap.cps.spi.entities.SchemaSetEntity;
import org.onap.cps.spi.entities.YangResourceModuleReference;
import org.onap.cps.spi.exceptions.AlreadyDefinedException;
import org.onap.cps.spi.exceptions.DataspaceInUseException;
final int numberOfAssociatedAnchors = anchorRepository.countByDataspace(dataspaceEntity);
if (numberOfAssociatedAnchors != 0) {
throw new DataspaceInUseException(dataspaceName,
- String.format("Dataspace contains %d anchor(s)", numberOfAssociatedAnchors));
+ String.format("Dataspace contains %d anchor(s)", numberOfAssociatedAnchors));
}
final int numberOfAssociatedSchemaSets = schemaSetRepository.countByDataspace(dataspaceEntity);
if (numberOfAssociatedSchemaSets != 0) {
throw new DataspaceInUseException(dataspaceName,
- String.format("Dataspace contains %d schemaset(s)", numberOfAssociatedSchemaSets));
+ String.format("Dataspace contains %d schemaset(s)", numberOfAssociatedSchemaSets));
}
dataspaceRepository.delete(dataspaceEntity);
}
public Collection<Anchor> getAnchors(final String dataspaceName) {
final var dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
final Collection<AnchorEntity> anchorEntities = anchorRepository.findAllByDataspace(dataspaceEntity);
- return anchorEntities.stream().map(CpsAdminPersistenceServiceImpl::toAnchor).collect(Collectors.toList());
+ return anchorEntities.stream().map(CpsAdminPersistenceServiceImpl::toAnchor).collect(Collectors.toSet());
+ }
+
+ @Override
+ public Collection<Anchor> getAnchors(final String dataspaceName, final String schemaSetName) {
+ final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
+ final SchemaSetEntity schemaSetEntity = schemaSetRepository.getByDataspaceAndName(
+ dataspaceEntity, schemaSetName);
+ return anchorRepository.findAllBySchemaSet(schemaSetEntity)
+ .stream().map(CpsAdminPersistenceServiceImpl::toAnchor)
+ .collect(Collectors.toSet());
}
@Override
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2020 Nordix Foundation
- * Modifications Copyright (C) 2020-2021 Bell Canada.
+ * Modifications Copyright (C) 2020-2022 Bell Canada.
* Modifications Copyright (C) 2021 Pantheon.tech
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.exception.ConstraintViolationException;
-import org.onap.cps.spi.CascadeDeleteAllowed;
import org.onap.cps.spi.CpsAdminPersistenceService;
import org.onap.cps.spi.CpsModulePersistenceService;
-import org.onap.cps.spi.entities.AnchorEntity;
import org.onap.cps.spi.entities.SchemaSetEntity;
import org.onap.cps.spi.entities.YangResourceEntity;
import org.onap.cps.spi.entities.YangResourceModuleReference;
import org.onap.cps.spi.exceptions.AlreadyDefinedException;
import org.onap.cps.spi.exceptions.DuplicatedYangResourceException;
import org.onap.cps.spi.exceptions.ModelValidationException;
-import org.onap.cps.spi.exceptions.SchemaSetInUseException;
import org.onap.cps.spi.model.ModuleReference;
import org.onap.cps.spi.repository.AnchorRepository;
import org.onap.cps.spi.repository.DataspaceRepository;
@Override
@Transactional
- public void deleteSchemaSet(final String dataspaceName, final String schemaSetName,
- final CascadeDeleteAllowed cascadeDeleteAllowed) {
+ public void deleteSchemaSet(final String dataspaceName, final String schemaSetName) {
final var dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
final var schemaSetEntity =
schemaSetRepository.getByDataspaceAndName(dataspaceEntity, schemaSetName);
-
- final Collection<AnchorEntity> anchorEntities = anchorRepository.findAllBySchemaSet(schemaSetEntity);
- if (!anchorEntities.isEmpty()) {
- if (cascadeDeleteAllowed != CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED) {
- throw new SchemaSetInUseException(dataspaceName, schemaSetName);
- }
- fragmentRepository.deleteByAnchorIn(anchorEntities);
- anchorRepository.deleteAll(anchorEntities);
- }
schemaSetRepository.delete(schemaSetEntity);
+ }
+
+ @Override
+ @Transactional
+ public void deleteUnusedYangResourceModules() {
yangResourceRepository.deleteOrphans();
}
/**
* Convert the specified data integrity violation exception into a CPS duplicated Yang resource exception
* if the cause of the error is a yang checksum database constraint violation.
+ *
* @param originalException the original db exception.
* @param yangResourceEntities the collection of Yang resources involved in the db failure.
* @return an optional converted CPS duplicated Yang resource exception. The optional is empty if the original
/**
* Get the name of the yang resource having the specified checksum.
+ *
* @param checksum the checksum. Null is supported.
* @param yangResourceEntities the list of yang resources to search among.
* @return the name found or null if none.
/**
* Get the checksum that caused the constraint violation exception.
+ *
* @param exception the exception having the checksum in error.
* @return the checksum in error or null if not found.
*/
* ============LICENSE_START=======================================================
* Copyright (C) 2021 Nordix Foundation
* Modifications Copyright (C) 2021 Pantheon.tech
+ * Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
static final String SET_DATA = '/data/anchor.sql'
static final String SAMPLE_DATA_FOR_ANCHORS_WITH_MODULES = '/data/anchors-schemaset-modules.sql'
- static final String DATASPACE_WITH_NO_DATA = 'DATASPACE-002'
+ static final String DATASPACE_WITH_NO_DATA = 'DATASPACE-002-NO-DATA'
static final Integer DELETED_ANCHOR_ID = 3001
static final Long DELETED_FRAGMENT_ID = 4001
result.size() == expectedAnchors.size()
result.containsAll(expectedAnchors)
where: 'the following data is used'
- dataspaceName || expectedAnchors
- DATASPACE_NAME || [Anchor.builder().name(ANCHOR_NAME1).schemaSetName(SCHEMA_SET_NAME1).dataspaceName(DATASPACE_NAME).build(),
- Anchor.builder().name(ANCHOR_NAME2).schemaSetName(SCHEMA_SET_NAME2).dataspaceName(DATASPACE_NAME).build()]
+ dataspaceName || expectedAnchors
+ DATASPACE_NAME || [Anchor.builder().name(ANCHOR_NAME1).schemaSetName(SCHEMA_SET_NAME1).dataspaceName(DATASPACE_NAME).build(),
+ Anchor.builder().name(ANCHOR_NAME2).schemaSetName(SCHEMA_SET_NAME2).dataspaceName(DATASPACE_NAME).build()]
DATASPACE_WITH_NO_DATA || []
}
+ @Sql([CLEAR_DATA, SET_DATA])
+ def 'Get all anchors associated with schemaset in a dataspace.'() {
+ when: 'anchors are retrieved by dataspace and schema-set'
+ def anchors = objectUnderTest.getAnchors(dataspace, schemasetName)
+ then: ' the response contains expected anchors'
+ anchors == expectedAnchors
+ where:
+ scenario | dataspace | schemasetName || expectedAnchors
+ 'no-anchors' | 'DATASPACE-003' | 'SCHEMA-SET-002-NO-ANCHORS' || Collections.emptySet()
+ 'one-anchor' | 'DATASPACE-001' | 'SCHEMA-SET-001' || Set.of(new Anchor('ANCHOR-001', 'DATASPACE-001', 'SCHEMA-SET-001'))
+ }
+
+ @Sql([CLEAR_DATA, SET_DATA])
+ def 'Error Handling: Get all anchors associated with schemaset in a dataspace.'() {
+ when: 'anchors are retrieved by dataspace and schema-set'
+ def anchors = objectUnderTest.getAnchors(dataspace, schemasetName)
+ then: ' an expected expception is thrown'
+ thrown(expectedException)
+ where:
+ scenario | dataspace | schemasetName || expectedException
+ 'unknown-dataspace' | 'unknown' | 'SCHEMA-SET-002-NO-ANCHORS' || DataspaceNotFoundException
+ 'unknown-schemaset' | 'DATASPACE-001' | 'unknown-schema-set' || SchemaSetNotFoundException
+ }
+
@Sql(CLEAR_DATA)
def 'Get all anchors in unknown dataspace.'() {
when: 'attempt to get all anchors in an unknown dataspace'
}
@Sql([CLEAR_DATA, SET_DATA])
- def 'delete anchor error scenario: #scenario'(){
+ def 'delete anchor error scenario: #scenario'() {
when: 'delete anchor attempt is performed'
objectUnderTest.deleteAnchor(dataspaceName, anchorName)
then: 'an #expectedException is thrown'
def thrownException = thrown(expectedException)
thrownException.details.contains(expectedMessageDetails)
where: 'the following data is used'
- scenario | dataspaceName || expectedException | expectedMessageDetails
- 'dataspace name does not exist' | 'unknown' || DataspaceNotFoundException | 'unknown does not exist'
- 'dataspace contains an anchor' | 'DATASPACE-001' || DataspaceInUseException | 'contains 2 anchor(s)'
- 'dataspace contains schemasets' | 'DATASPACE-003' || DataspaceInUseException | 'contains 1 schemaset(s)'
+ scenario | dataspaceName || expectedException | expectedMessageDetails
+ 'dataspace name does not exist' | 'unknown' || DataspaceNotFoundException | 'unknown does not exist'
+ 'dataspace contains an anchor' | 'DATASPACE-001' || DataspaceInUseException | 'contains 2 anchor(s)'
+ 'dataspace contains schemasets' | 'DATASPACE-003' || DataspaceInUseException | 'contains 1 schemaset(s)'
}
}
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2021 Nordix Foundation
- * Modifications Copyright (C) 2021 Bell Canada.
+ * Modifications Copyright (C) 2021-2022 Bell Canada.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
}
@Sql([CLEAR_DATA, SET_DATA])
- def 'Delete schema set with cascade delete prohibited but no anchors using it'() {
+ def 'Delete schema set'() {
when: 'a schema set is deleted with cascade-prohibited option'
- objectUnderTest.deleteSchemaSet(DATASPACE_NAME, SCHEMA_SET_NAME_NO_ANCHORS,
- CASCADE_DELETE_PROHIBITED)
+ objectUnderTest.deleteSchemaSet(DATASPACE_NAME, SCHEMA_SET_NAME_NO_ANCHORS)
then: 'the schema set has been deleted'
schemaSetRepository.findByDataspaceAndName(dataspaceEntity, SCHEMA_SET_NAME_NO_ANCHORS).isPresent() == false
- and: 'any orphaned (not used by any schema set anymore) yang resources are deleted'
- def orphanedResourceId = 3100L
- yangResourceRepository.findById(orphanedResourceId).isPresent() == false
- and: 'any shared (still in use by other schema set) yang resources still persists'
- def sharedResourceId = 3003L
- yangResourceRepository.findById(sharedResourceId).isPresent()
- }
-
- @Sql([CLEAR_DATA, SET_DATA])
- def 'Delete schema set with cascade allowed.'() {
- when: 'a schema set is deleted with cascade-allowed option'
- objectUnderTest.deleteSchemaSet(DATASPACE_NAME, SCHEMA_SET_NAME_WITH_ANCHORS_AND_DATA,
- CASCADE_DELETE_ALLOWED)
- then: 'the schema set has been deleted'
- schemaSetRepository
- .findByDataspaceAndName(dataspaceEntity, SCHEMA_SET_NAME_WITH_ANCHORS_AND_DATA).isPresent() == false
- and: 'the associated anchors are removed'
- def associatedAnchorsIds = [ 6001, 6002 ]
- associatedAnchorsIds.each {anchorRepository.findById(it).isPresent() == false }
- and: 'the fragment(s) under those anchors are removed'
- def fragmentUnderAnchor1Id = 7001L
- fragmentRepository.findById(fragmentUnderAnchor1Id).isPresent() == false
- and: 'the shared resources still persist'
- def sharedResourceIds = [ 3003L, 3004L ]
- sharedResourceIds.each {yangResourceRepository.findById(it).isPresent() }
}
@Sql([CLEAR_DATA, SET_DATA])
def 'Delete schema set error scenario: #scenario.'() {
when: 'attempt to delete a schema set where #scenario'
- objectUnderTest.deleteSchemaSet(dataspaceName, schemaSetName, CASCADE_DELETE_PROHIBITED)
+ objectUnderTest.deleteSchemaSet(dataspaceName, schemaSetName)
then: 'an #expectedException is thrown'
thrown(expectedException)
where: 'the following data is used'
scenario | dataspaceName | schemaSetName || expectedException
'dataspace does not exist' | 'unknown' | 'not-relevant' || DataspaceNotFoundException
'schema set does not exists' | DATASPACE_NAME | 'unknown' || SchemaSetNotFoundException
- 'cascade prohibited but schema set in use' | DATASPACE_NAME | SCHEMA_SET_NAME_WITH_ANCHORS_AND_DATA || SchemaSetInUseException
+ }
+
+ @Sql([CLEAR_DATA, SET_DATA])
+ def 'Delete only orphan Yang Resources'() {
+ given: 'a schema set is deleted and and yang resource is not used anymore'
+ objectUnderTest.deleteSchemaSet(DATASPACE_NAME, SCHEMA_SET_NAME_NO_ANCHORS)
+ when: 'orphan yang resources are deleted'
+ objectUnderTest.deleteUnusedYangResourceModules()
+ then: 'any orphaned (not used by any schema set anymore) yang resources are deleted'
+ def orphanedResourceId = 3100L
+ yangResourceRepository.findById(orphanedResourceId).isPresent() == false
+ and: 'any shared (still in use by other schema set) yang resources still persists'
+ def sharedResourceId = 3003L
+ yangResourceRepository.findById(sharedResourceId).isPresent()
}
def assertSchemaSetPersisted(expectedDataspaceName,
============LICENSE_START=======================================================
Copyright (C) 2020 Pantheon.tech
Modifications Copyright (C) 2020 Nordix Foundation.
- Modifications Copyright (C) 2021 Bell Canada.
+ Modifications Copyright (C) 2021-2022 Bell Canada.
================================================================================
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
INSERT INTO DATASPACE (ID, NAME) VALUES
(1001, 'DATASPACE-001'),
- (1002, 'DATASPACE-002'),
+ (1002, 'DATASPACE-002-NO-DATA'),
(1003, 'DATASPACE-003');
INSERT INTO SCHEMA_SET (ID, NAME, DATASPACE_ID) VALUES
(2001, 'SCHEMA-SET-001', 1001),
(2002, 'SCHEMA-SET-002', 1001),
- (2003, 'SCHEMA-SET-002', 1003);
+ (2003, 'SCHEMA-SET-002-NO-ANCHORS', 1003);
INSERT INTO ANCHOR (ID, NAME, DATASPACE_ID, SCHEMA_SET_ID) VALUES
(3001, 'ANCHOR-001', 1001, 2001),
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2020 Nordix Foundation
- * Modifications Copyright (C) 2020 Bell Canada.
+ * Modifications Copyright (C) 2020-2022 Bell Canada.
* Modifications Copyright (C) 2021 Pantheon.tech
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
package org.onap.cps.api;
import java.util.Collection;
-import org.checkerframework.checker.nullness.qual.NonNull;
import org.onap.cps.spi.exceptions.AlreadyDefinedException;
import org.onap.cps.spi.exceptions.CpsException;
import org.onap.cps.spi.model.Anchor;
* @param dataspaceName dataspace name
* @throws AlreadyDefinedException if dataspace with same name already exists
*/
- void createDataspace(@NonNull String dataspaceName);
+ void createDataspace(String dataspaceName);
/**
* Delete dataspace.
*
* @param dataspaceName the name of the dataspace to delete
*/
- void deleteDataspace(@NonNull String dataspaceName);
+ void deleteDataspace(String dataspaceName);
/**
* Create an Anchor.
* @param anchorName anchor name
* @throws CpsException if input data is invalid.
*/
- void createAnchor(@NonNull String dataspaceName, @NonNull String schemaSetName, @NonNull String anchorName);
+ void createAnchor(String dataspaceName, String schemaSetName, String anchorName);
/**
* Read all anchors in the given dataspace.
* @param dataspaceName dataspace name
* @return a collection of anchors
*/
- @NonNull
- Collection<Anchor> getAnchors(@NonNull String dataspaceName);
+ Collection<Anchor> getAnchors(String dataspaceName);
+
+ /**
+ * Read all anchors associated the given schema-set in the given dataspace.
+ *
+ * @param dataspaceName dataspace name
+ * @param schemaSetName schema-set name
+ * @return a collection of anchors
+ */
+ Collection<Anchor> getAnchors(String dataspaceName, String schemaSetName);
/**
* Get an anchor in the given dataspace using the anchor name.
* @param anchorName anchor name
* @return an anchor
*/
- @NonNull
- Anchor getAnchor(@NonNull String dataspaceName, @NonNull String anchorName);
+ Anchor getAnchor(String dataspaceName, String anchorName);
/**
* Delete anchor by name in given dataspace.
* @param dataspaceName dataspace name
* @param anchorName anchor name
*/
- void deleteAnchor(@NonNull String dataspaceName, @NonNull String anchorName);
+ void deleteAnchor(String dataspaceName, String anchorName);
/**
* Query anchor names for the given module names in the provided dataspace.
*
- *
* @param dataspaceName dataspace name
- * @param moduleNames a collection of module names
+ * @param moduleNames a collection of module names
* @return a collection of anchor names in the given dataspace. The schema set for each anchor must include all the
* given module names
*/
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2020 Nordix Foundation
- * Modifications Copyright (C) 2020 Bell Canada.
+ * Modifications Copyright (C) 2020-2022 Bell Canada.
* Modifications Copyright (C) 2021 Pantheon.tech
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
return cpsAdminPersistenceService.getAnchors(dataspaceName);
}
+ @Override
+ public Collection<Anchor> getAnchors(final String dataspaceName, final String schemaSetName) {
+ return cpsAdminPersistenceService.getAnchors(dataspaceName, schemaSetName);
+ }
+
@Override
public Anchor getAnchor(final String dataspaceName, final String anchorName) {
return cpsAdminPersistenceService.getAnchor(dataspaceName, anchorName);
* ============LICENSE_START=======================================================
* Copyright (C) 2020-2021 Nordix Foundation
* Modifications Copyright (C) 2020-2021 Pantheon.tech
+ * Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import java.util.Collection;
import java.util.List;
import java.util.Map;
+import org.onap.cps.api.CpsAdminService;
import org.onap.cps.api.CpsModuleService;
import org.onap.cps.spi.CascadeDeleteAllowed;
import org.onap.cps.spi.CpsModulePersistenceService;
+import org.onap.cps.spi.exceptions.SchemaSetInUseException;
+import org.onap.cps.spi.model.Anchor;
import org.onap.cps.spi.model.ModuleReference;
import org.onap.cps.spi.model.SchemaSet;
import org.onap.cps.yang.YangTextSchemaSourceSetBuilder;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
@Service("CpsModuleServiceImpl")
public class CpsModuleServiceImpl implements CpsModuleService {
- @Autowired
private CpsModulePersistenceService cpsModulePersistenceService;
-
- @Autowired
private YangTextSchemaSourceSetCache yangTextSchemaSourceSetCache;
+ private CpsAdminService cpsAdminService;
+
+ /**
+ * Create an instance of CpsModuleServiceImpl.
+ *
+ * @param cpsModulePersistenceService cpsModulePersistenceService
+ * @param yangTextSchemaSourceSetCache yangTextSchemaSourceSetCache
+ * @param cpsAdminService cpsAdminService
+ */
+ public CpsModuleServiceImpl(final CpsModulePersistenceService cpsModulePersistenceService,
+ final YangTextSchemaSourceSetCache yangTextSchemaSourceSetCache, final CpsAdminService cpsAdminService) {
+ this.cpsModulePersistenceService = cpsModulePersistenceService;
+ this.yangTextSchemaSourceSetCache = yangTextSchemaSourceSetCache;
+ this.cpsAdminService = cpsAdminService;
+ }
@Override
public void createSchemaSet(final String dataspaceName, final String schemaSetName,
@Override
public void createSchemaSetFromModules(final String dataspaceName, final String schemaSetName,
- final Map<String, String> newYangResourcesModuleNameToContentMap,
- final List<ModuleReference> moduleReferences) {
+ final Map<String, String> newYangResourcesModuleNameToContentMap,
+ final List<ModuleReference> moduleReferences) {
cpsModulePersistenceService.storeSchemaSetFromModules(dataspaceName, schemaSetName,
- newYangResourcesModuleNameToContentMap, moduleReferences);
+ newYangResourcesModuleNameToContentMap, moduleReferences);
}
}
@Override
+ @Transactional
public void deleteSchemaSet(final String dataspaceName, final String schemaSetName,
final CascadeDeleteAllowed cascadeDeleteAllowed) {
- cpsModulePersistenceService.deleteSchemaSet(dataspaceName, schemaSetName, cascadeDeleteAllowed);
+ final Collection<Anchor> anchors = cpsAdminService.getAnchors(dataspaceName, schemaSetName);
+ if (!anchors.isEmpty() && isCascadeDeleteProhibited(cascadeDeleteAllowed)) {
+ throw new SchemaSetInUseException(dataspaceName, schemaSetName);
+ }
+ for (final Anchor anchor : anchors) {
+ cpsAdminService.deleteAnchor(dataspaceName, anchor.getName());
+ }
+ cpsModulePersistenceService.deleteSchemaSet(dataspaceName, schemaSetName);
+ cpsModulePersistenceService.deleteUnusedYangResourceModules();
}
@Override
final String anchorName) {
return cpsModulePersistenceService.getYangResourceModuleReferences(dataspaceName, anchorName);
}
+
+ private boolean isCascadeDeleteProhibited(final CascadeDeleteAllowed cascadeDeleteAllowed) {
+ return CascadeDeleteAllowed.CASCADE_DELETE_PROHIBITED == cascadeDeleteAllowed;
+ }
}
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2020 Nordix Foundation.
- * Modifications Copyright (C) 2020 Bell Canada.
+ * Modifications Copyright (C) 2020-2022 Bell Canada.
* Modifications Copyright (C) 2021 Pantheon.tech
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
package org.onap.cps.spi;
import java.util.Collection;
-import org.checkerframework.checker.nullness.qual.NonNull;
import org.onap.cps.spi.exceptions.AlreadyDefinedException;
import org.onap.cps.spi.model.Anchor;
* @param dataspaceName dataspace name
* @throws AlreadyDefinedException if dataspace with same name already exists
*/
- void createDataspace(@NonNull String dataspaceName);
+ void createDataspace(String dataspaceName);
/**
* Delete dataspace.
*
* @param dataspaceName the name of the dataspace to delete
*/
- void deleteDataspace(@NonNull String dataspaceName);
+ void deleteDataspace(String dataspaceName);
/**
* Create an Anchor.
* @param schemaSetName schema set name
* @param anchorName anchor name
*/
- void createAnchor(@NonNull String dataspaceName, @NonNull String schemaSetName, @NonNull String anchorName);
+ void createAnchor(String dataspaceName, String schemaSetName, String anchorName);
+
+ /**
+ * Read all anchors associated the given schema-set in the given dataspace.
+ *
+ * @param dataspaceName dataspace name
+ * @param schemaSetName schema-set name
+ * @return a collection of anchors
+ */
+ Collection<Anchor> getAnchors(String dataspaceName, String schemaSetName);
/**
* Read all anchors in the given a dataspace.
* @param dataspaceName dataspace name
* @return a collection of anchors
*/
- @NonNull
- Collection<Anchor> getAnchors(@NonNull String dataspaceName);
+ Collection<Anchor> getAnchors(String dataspaceName);
/**
* Query anchor names for the given module names in the provided dataspace.
* @param anchorName anchor name
* @return an anchor
*/
- @NonNull
- Anchor getAnchor(@NonNull String dataspaceName, @NonNull String anchorName);
+ Anchor getAnchor(String dataspaceName, String anchorName);
/**
* Delete anchor by name in given dataspace.
* @param dataspaceName dataspace name
* @param anchorName anchor name
*/
- void deleteAnchor(@NonNull String dataspaceName, @NonNull String anchorName);
+ void deleteAnchor(String dataspaceName, String anchorName);
}
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2020 Nordix Foundation
- * Modifications Copyright (C) 2020 Bell Canada.
+ * Modifications Copyright (C) 2020-2022 Bell Canada.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import java.util.Collection;
import java.util.List;
import java.util.Map;
-import org.checkerframework.checker.nullness.qual.NonNull;
-import org.onap.cps.spi.exceptions.DataInUseException;
import org.onap.cps.spi.model.ModuleReference;
/**
* @param schemaSetName schema set name
* @param yangResourcesNameToContentMap YANG resources (files) map where key is a name and value is content
*/
- void storeSchemaSet(@NonNull String dataspaceName, @NonNull String schemaSetName,
- @NonNull Map<String, String> yangResourcesNameToContentMap);
+ void storeSchemaSet(String dataspaceName, String schemaSetName, Map<String, String> yangResourcesNameToContentMap);
/**
* Stores a schema set from new modules and existing modules.
* @param dataspaceName Dataspace name
* @param schemaSetName Schema set name
* @param newYangResourcesModuleNameToContentMap YANG resources map where key is a module name and value is content
- * @param moduleReferences List of YANG resources module references
+ * @param moduleReferences List of YANG resources module references
*/
- void storeSchemaSetFromModules(@NonNull String dataspaceName, @NonNull String schemaSetName,
- @NonNull Map<String, String> newYangResourcesModuleNameToContentMap,
- @NonNull List<ModuleReference> moduleReferences);
+ void storeSchemaSetFromModules(String dataspaceName, String schemaSetName,
+ Map<String, String> newYangResourcesModuleNameToContentMap, List<ModuleReference> moduleReferences);
/**
* Deletes Schema Set.
*
- * @param dataspaceName dataspace name
- * @param schemaSetName schema set name
- * @param cascadeDeleteAllowed indicates the allowance to remove associated anchors and data if exist
- * @throws DataInUseException if cascadeDeleteAllowed is set to CASCADE_DELETE_PROHIBITED and there
- * is associated anchor record exists in database
+ * @param dataspaceName dataspace name
+ * @param schemaSetName schema set name
*/
- void deleteSchemaSet(@NonNull String dataspaceName, @NonNull String schemaSetName,
- @NonNull CascadeDeleteAllowed cascadeDeleteAllowed);
+ void deleteSchemaSet(String dataspaceName, String schemaSetName);
/**
* Returns YANG resources per specific dataspace / schemaSetName.
*
- * @param dataspaceName dataspace name
+ * @param dataspaceName dataspace name
* @param schemaSetName schema set name
* @return YANG resources (files) map where key is a name and value is content
*/
- @NonNull
- Map<String, String> getYangSchemaResources(@NonNull String dataspaceName,
- @NonNull String schemaSetName);
+ Map<String, String> getYangSchemaResources(String dataspaceName, String schemaSetName);
/**
* Returns YANG resources per specific dataspace / anchorName.
*
* @param dataspaceName dataspace name
- * @param anchorName anchor name
+ * @param anchorName anchor name
* @return YANG resources (files) map where key is a name and value is content
*/
- @NonNull
- Map<String, String> getYangSchemaSetResources(@NonNull String dataspaceName,
- @NonNull String anchorName);
+ Map<String, String> getYangSchemaSetResources(String dataspaceName, String anchorName);
/**
* Returns YANG resources module references for the given dataspace name.
* @return a collection of module names and revisions
*/
Collection<ModuleReference> getYangResourceModuleReferences(String dataspaceName, String anchorName);
+
+ /**
+ * Remove unused Yang Resource Modules.
+ */
+ void deleteUnusedYangResourceModules();
}
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2020 Nordix Foundation
- * Modifications Copyright (C) 2020 Bell Canada.
+ * Modifications Copyright (C) 2020-2022 Bell Canada.
* Modifications Copyright (C) 2021 Pantheon.tech
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
objectUnderTest.getAnchors('someDataspace') == anchors
}
+ def 'Retrieve all anchors for schema-set.'() {
+ given: 'that anchor is associated with the dataspace and schemaset'
+ def anchors = [new Anchor()]
+ mockCpsAdminPersistenceService.getAnchors('someDataspace', 'someSchemaSet') >> anchors
+ expect: 'the collection provided by persistence service is returned as result'
+ objectUnderTest.getAnchors('someDataspace', 'someSchemaSet') == anchors
+ }
+
def 'Retrieve anchor for dataspace and provided anchor name.'() {
given: 'that anchor name is associated with the dataspace'
Anchor anchor = new Anchor()
* ============LICENSE_START=======================================================
* Copyright (C) 2020-2021 Nordix Foundation
* Modifications Copyright (C) 2020-2021 Pantheon.tech
- * Modifications Copyright (C) 2020-2021 Bell Canada.
+ * Modifications Copyright (C) 2020-2022 Bell Canada.
* ================================================================================
* 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.api.impl
import org.onap.cps.TestUtils
+import org.onap.cps.api.CpsAdminService
import org.onap.cps.spi.CpsModulePersistenceService
import org.onap.cps.spi.exceptions.ModelValidationException
+import org.onap.cps.spi.exceptions.SchemaSetInUseException
+import org.onap.cps.spi.model.Anchor
import org.onap.cps.spi.model.ExtendedModuleReference
import org.onap.cps.spi.model.ModuleReference
import org.spockframework.spring.SpringBean
import org.springframework.cache.caffeine.CaffeineCacheManager
import org.springframework.test.context.ContextConfiguration
import spock.lang.Specification
-
import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED
import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_PROHIBITED
@SpringBootTest
@EnableCaching
-@ContextConfiguration(classes = [YangTextSchemaSourceSetCache.class, CpsModuleServiceImpl.class])
+@ContextConfiguration(classes = [YangTextSchemaSourceSetCache, CpsModuleServiceImpl])
class CpsModuleServiceImplSpec extends Specification {
@SpringBean
CpsModulePersistenceService mockModuleStoreService = Mock()
+ @SpringBean
+ CpsAdminService mockCpsAdminService = Mock()
+
@SpringBean
CacheManager cacheManager = new CaffeineCacheManager("yangSchema")
1 * mockModuleStoreService.getYangSchemaResources('someDataspace', 'someSchemaSet') >> yangResourcesNameToContentMap
}
- def 'Delete set by name and dataspace with #cascadeDeleteOption.'() {
- when: 'schema set deletion is requested'
- objectUnderTest.deleteSchemaSet(dataspaceName, schemaSetname, cascadeDeleteOption)
- then: 'persistence service method is invoked with same parameters'
- mockModuleStoreService.deleteSchemaSet(dataspaceName, schemaSetname, cascadeDeleteOption)
+ def 'Delete schema-set when cascade is allowed.'() {
+ given: '#numberOfAnchors anchors are associated with schemaset'
+ def associatedAnchors = createAnchors(numberOfAnchors)
+ mockCpsAdminService.getAnchors('my-dataspace', 'my-schemaset') >> associatedAnchors
+ when: 'schema set deletion is requested with cascade allowed'
+ objectUnderTest.deleteSchemaSet('my-dataspace', 'my-schemaset', CASCADE_DELETE_ALLOWED)
+ then: 'anchor deletion is called #numberOfAnchors times'
+ numberOfAnchors * mockCpsAdminService.deleteAnchor('my-dataspace', _)
+ and: 'persistence service method is invoked with same parameters'
+ 1 * mockModuleStoreService.deleteSchemaSet('my-dataspace', 'my-schemaset')
+ and: 'orphan yang resources are deleted'
+ 1 * mockModuleStoreService.deleteUnusedYangResourceModules()
where: 'following parameters are used'
- dataspaceName | schemaSetname | cascadeDeleteOption
- 'dataspace-1' | 'schemas-set-1' | CASCADE_DELETE_ALLOWED
- 'dataspace-2' | 'schemas-set-2' | CASCADE_DELETE_PROHIBITED
+ numberOfAnchors << [0, 3]
+ }
+
+ def 'Delete schema-set when cascade is prohibited.'() {
+ given: 'no anchors are associated with schemaset'
+ mockCpsAdminService.getAnchors('my-dataspace', 'my-schemaset') >> Collections.emptyList()
+ when: 'schema set deletion is requested with cascade allowed'
+ objectUnderTest.deleteSchemaSet('my-dataspace', 'my-schemaset', CASCADE_DELETE_PROHIBITED)
+ then: 'no anchors are deleted'
+ 0 * mockCpsAdminService.deleteAnchor(_, _)
+ and: 'persistence service method is invoked with same parameters'
+ 1 * mockModuleStoreService.deleteSchemaSet('my-dataspace', 'my-schemaset')
+ and: 'orphan yang resources are deleted'
+ 1 * mockModuleStoreService.deleteUnusedYangResourceModules()
+ }
+
+ def 'Delete schema-set when cascade is prohibited and schema-set has anchors.'() {
+ given: '2 anchors are associated with schemaset'
+ mockCpsAdminService.getAnchors('my-dataspace', 'my-schemaset') >> createAnchors(2)
+ when: 'schema set deletion is requested with cascade allowed'
+ objectUnderTest.deleteSchemaSet('my-dataspace', 'my-schemaset', CASCADE_DELETE_PROHIBITED)
+ then: 'Schema-Set in Use exception is thrown'
+ thrown(SchemaSetInUseException)
+ }
+
+ def createAnchors(int anchorCount) {
+ def anchors = []
+ (0..<anchorCount).each { anchors.add(new Anchor("my-anchor-$it", 'my-dataspace', 'my-schemaset')) }
+ return anchors
}
- def 'Get all yang resources module references.'(){
+ def 'Get all yang resources module references.'() {
given: 'an already present module reference'
def moduleReferences = [new ExtendedModuleReference()]
mockModuleStoreService.getYangResourceModuleReferences('someDataspaceName') >> moduleReferences
}
- def 'Get all yang resources module references for the given dataspace name and anchor name.'(){
+ def 'Get all yang resources module references for the given dataspace name and anchor name.'() {
given: 'the module store service service returns a list module references'
def moduleReferences = [new ModuleReference()]
mockModuleStoreService.getYangResourceModuleReferences('someDataspaceName', 'someAnchorName') >> moduleReferences
/*\r
* ============LICENSE_START=======================================================\r
* Copyright (C) 2021 Nordix Foundation.\r
- * Modifications Copyright (C) 2021 Bell Canada.\r
+ * Modifications Copyright (C) 2021-2022 Bell Canada.\r
* Modifications Copyright (C) 2021 Pantheon.tech\r
* ================================================================================\r
* Licensed under the Apache License, Version 2.0 (the "License");\r
\r
package org.onap.cps.api.impl\r
\r
-import java.time.OffsetDateTime\r
import org.onap.cps.TestUtils\r
import org.onap.cps.api.CpsAdminService\r
import org.onap.cps.notification.NotificationService\r
def mockDataStoreService = Mock(CpsDataPersistenceService)\r
def mockCpsAdminService = Mock(CpsAdminService)\r
def mockNotificationService = Mock(NotificationService)\r
- def cpsModuleServiceImpl = new CpsModuleServiceImpl()\r
def cpsDataServiceImpl = new CpsDataServiceImpl()\r
def mockYangTextSchemaSourceSetCache = Mock(YangTextSchemaSourceSetCache)\r
+ def cpsModuleServiceImpl = new CpsModuleServiceImpl(mockModuleStoreService,\r
+ mockYangTextSchemaSourceSetCache,mockCpsAdminService )\r
\r
def dataspaceName = 'someDataspace'\r
def anchorName = 'someAnchor'\r
cpsDataServiceImpl.cpsAdminService = mockCpsAdminService\r
cpsDataServiceImpl.yangTextSchemaSourceSetCache = mockYangTextSchemaSourceSetCache\r
cpsDataServiceImpl.notificationService = mockNotificationService\r
- cpsModuleServiceImpl.yangTextSchemaSourceSetCache = mockYangTextSchemaSourceSetCache\r
- cpsModuleServiceImpl.cpsModulePersistenceService = mockModuleStoreService\r
}\r
\r
def 'E2E model can be parsed by CPS.'() {\r