From: niamhcore Date: Mon, 30 Nov 2020 14:39:28 +0000 (+0000) Subject: Create Common Model objects in SPI X-Git-Tag: 0.0.1~92 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=0cd5910ca2c949bab95ec73591729c4b7230fdd1;p=cps.git Create Common Model objects in SPI Issue-ID: CPS-100 Signed-off-by: niamhcore Change-Id: I8ba54cc5d881d9d5f18b77a54ae28d3dda8412c1 --- diff --git a/cps-rest/src/main/java/org/onap/cps/rest/controller/CpsRestController.java b/cps-rest/src/main/java/org/onap/cps/rest/controller/CpsRestController.java index 549760d2f8..0821dca2b6 100755 --- a/cps-rest/src/main/java/org/onap/cps/rest/controller/CpsRestController.java +++ b/cps-rest/src/main/java/org/onap/cps/rest/controller/CpsRestController.java @@ -29,11 +29,12 @@ import java.io.OutputStream; import javax.validation.Valid; import org.modelmapper.ModelMapper; import org.onap.cps.api.CpService; -import org.onap.cps.api.model.AnchorDetails; +import org.onap.cps.api.CpsAdminService; +import org.onap.cps.api.CpsModuleService; import org.onap.cps.exceptions.CpsException; import org.onap.cps.exceptions.CpsValidationException; import org.onap.cps.rest.api.CpsRestApi; -import org.onap.cps.rest.model.Anchor; +import org.onap.cps.spi.model.Anchor; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -52,29 +53,36 @@ public class CpsRestController implements CpsRestApi { @Autowired private CpService cpService; + @Autowired + private CpsModuleService cpsModuleService; + + @Autowired + private CpsAdminService cpsAdminService; + @Autowired private ModelMapper modelMapper; /** * Create a new anchor. * - * @param anchor the anchor details object. + * @param anchor the anchor details object. * @param dataspaceName the dataspace name. * @return a ResponseEntity with the anchor name. */ @Override - public final ResponseEntity createAnchor(@Valid final Anchor anchor, final String dataspaceName) { - final AnchorDetails anchorDetails = modelMapper.map(anchor, AnchorDetails.class); - anchorDetails.setDataspace(dataspaceName); - final String anchorName = cpService.createAnchor(anchorDetails); + public ResponseEntity createAnchor(final org.onap.cps.rest.model.@Valid Anchor anchor, + final String dataspaceName) { + final Anchor anchorDetails = modelMapper.map(anchor, Anchor.class); + anchorDetails.setDataspaceName(dataspaceName); + final String anchorName = cpsAdminService.createAnchor(anchorDetails); return new ResponseEntity(anchorName, HttpStatus.CREATED); } @Override public ResponseEntity createModules(@Valid final MultipartFile multipartFile, final String dataspaceName) { final File fileToParse = saveToFile(multipartFile); - final SchemaContext schemaContext = cpService.parseAndValidateModel(fileToParse); - cpService.storeSchemaContext(schemaContext, dataspaceName); + final SchemaContext schemaContext = cpsModuleService.parseAndValidateModel(fileToParse); + cpsModuleService.storeSchemaContext(schemaContext, dataspaceName); return new ResponseEntity<>("Resource successfully created", HttpStatus.CREATED); } @@ -105,7 +113,7 @@ public class CpsRestController implements CpsRestApi { @Override public ResponseEntity getModule(final String dataspaceName, @Valid final String namespaceName, - @Valid final String revision) { + @Valid final String revision) { return null; } diff --git a/cps-ri/src/main/java/org/onap/cps/spi/impl/FragmentPersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceImpl.java old mode 100755 new mode 100644 similarity index 80% rename from cps-ri/src/main/java/org/onap/cps/spi/impl/FragmentPersistenceServiceImpl.java rename to cps-ri/src/main/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceImpl.java index 82554b3d0a..684750c459 --- a/cps-ri/src/main/java/org/onap/cps/spi/impl/FragmentPersistenceServiceImpl.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceImpl.java @@ -1,72 +1,73 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2020 Nordix Foundation. All rights reserved. - * ================================================================================ - * 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.spi.impl; - -import org.onap.cps.api.model.AnchorDetails; -import org.onap.cps.exceptions.CpsNotFoundException; -import org.onap.cps.exceptions.CpsValidationException; -import org.onap.cps.spi.FragmentPersistenceService; -import org.onap.cps.spi.entities.Dataspace; -import org.onap.cps.spi.entities.Fragment; -import org.onap.cps.spi.entities.Module; -import org.onap.cps.spi.repository.DataspaceRepository; -import org.onap.cps.spi.repository.FragmentRepository; -import org.onap.cps.spi.repository.ModuleRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.stereotype.Component; - -@Component -public class FragmentPersistenceServiceImpl implements FragmentPersistenceService { - - @Autowired - private DataspaceRepository dataspaceRepository; - - @Autowired - private FragmentRepository fragmentRepository; - - @Autowired - private ModuleRepository moduleRepository; - - @Override - public String createAnchor(final AnchorDetails anchorDetails) { - try { - final Dataspace dataspace = dataspaceRepository.getByName(anchorDetails.getDataspace()); - final Module module = - moduleRepository.getByDataspaceAndNamespaceAndRevision(dataspace, - anchorDetails.getNamespace(), anchorDetails.getRevision()); - - final Fragment fragment = Fragment.builder().xpath(anchorDetails.getAnchorName()) - .anchorName(anchorDetails.getAnchorName()) - .dataspace(dataspace).module(module).build(); - - fragmentRepository.save(fragment); - return anchorDetails.getAnchorName(); - } catch (final CpsNotFoundException ex) { - throw new CpsValidationException("Validation Error", - "Dataspace and/or Module do not exist."); - } catch (final DataIntegrityViolationException ex) { - throw new CpsValidationException("Duplication Error", - String.format("Anchor with name %s already exist in dataspace %s.", - anchorDetails.getAnchorName(), anchorDetails.getDataspace())); - } - } -} +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. All rights reserved. + * ================================================================================ + * 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.spi.impl; + +import org.onap.cps.exceptions.CpsNotFoundException; +import org.onap.cps.exceptions.CpsValidationException; +import org.onap.cps.spi.CpsAdminPersistenceService; +import org.onap.cps.spi.entities.Dataspace; +import org.onap.cps.spi.entities.Fragment; +import org.onap.cps.spi.entities.Module; +import org.onap.cps.spi.model.Anchor; +import org.onap.cps.spi.repository.DataspaceRepository; +import org.onap.cps.spi.repository.FragmentRepository; +import org.onap.cps.spi.repository.ModuleRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.stereotype.Component; + +@Component +public class CpsAdminPersistenceServiceImpl implements CpsAdminPersistenceService { + + @Autowired + private DataspaceRepository dataspaceRepository; + + @Autowired + private FragmentRepository fragmentRepository; + + @Autowired + private ModuleRepository moduleRepository; + + @Override + public String createAnchor(final Anchor anchor) { + final String anchorName = anchor.getAnchorName(); + try { + final Dataspace dataspace = dataspaceRepository.getByName(anchor.getDataspaceName()); + final Module module = + moduleRepository.getByDataspaceAndNamespaceAndRevision(dataspace, + anchor.getNamespace(), anchor.getRevision()); + + final Fragment fragment = Fragment.builder().xpath(anchorName) + .anchorName(anchorName) + .dataspace(dataspace).module(module).build(); + + fragmentRepository.save(fragment); + return anchorName; + } catch (final CpsNotFoundException ex) { + throw new CpsValidationException("Validation Error", + "Dataspace and/or Module do not exist."); + } catch (final DataIntegrityViolationException ex) { + throw new CpsValidationException("Duplication Error", + String.format("Anchor with name %s already exist in dataspace %s.", + anchorName, anchor.getDataspaceName())); + } + } +} diff --git a/cps-ri/src/main/java/org/onap/cps/spi/impl/ModelPersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java old mode 100755 new mode 100644 similarity index 97% rename from cps-ri/src/main/java/org/onap/cps/spi/impl/ModelPersistenceServiceImpl.java rename to cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java index 2207f7940f..52f8034575 --- a/cps-ri/src/main/java/org/onap/cps/spi/impl/ModelPersistenceServiceImpl.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java @@ -29,7 +29,7 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import javax.transaction.Transactional; -import org.onap.cps.spi.ModelPersistenceService; +import org.onap.cps.spi.CpsModulePersistenceService; import org.onap.cps.spi.entities.Dataspace; import org.onap.cps.spi.entities.SchemaSet; import org.onap.cps.spi.entities.YangResource; @@ -42,7 +42,7 @@ import org.springframework.stereotype.Component; import org.springframework.util.DigestUtils; @Component -public class ModelPersistenceServiceImpl implements ModelPersistenceService { +public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceService { @Autowired private YangResourceRepository yangResourceRepository; diff --git a/cps-service/src/main/java/org/onap/cps/api/CpService.java b/cps-service/src/main/java/org/onap/cps/api/CpService.java index 726ca0f28d..29e164d621 100755 --- a/cps-service/src/main/java/org/onap/cps/api/CpService.java +++ b/cps-service/src/main/java/org/onap/cps/api/CpService.java @@ -20,41 +20,11 @@ package org.onap.cps.api; -import java.io.File; -import org.onap.cps.api.model.AnchorDetails; -import org.onap.cps.exceptions.CpsValidationException; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; - /** * Configuration and persistency service interface which holds methods for parsing and storing yang models and data. */ public interface CpService { - /** - * Parse and validate a string representing a yang model to generate a schema context. - * - * @param yangModelContent the input stream - * @return the schema context - */ - SchemaContext parseAndValidateModel(String yangModelContent); - - /** - * Parse and validate a file representing a yang model to generate a schema context. - * - * @param yangModelFile the yang file - * @return the schema context - */ - SchemaContext parseAndValidateModel(File yangModelFile); - - /** - * Store schema context for a yang model. - * - * @param schemaContext the schema context - * @param dataspaceName the dataspace name - * @throws CpsValidationException if input data already exists. - */ - void storeSchemaContext(SchemaContext schemaContext, String dataspaceName); - /** * Store the JSON structure in the database. * @@ -78,12 +48,4 @@ public interface CpService { */ void deleteJsonById(int jsonObjectId); - /** - * Create an anchor using provided anchorDetails object. - * - * @param anchorDetails the anchor details object. - * @return the anchor name. - * @throws CpsValidationException if input data is invalid. - */ - String createAnchor(AnchorDetails anchorDetails); } diff --git a/cps-service/src/main/java/org/onap/cps/api/CpsAdminService.java b/cps-service/src/main/java/org/onap/cps/api/CpsAdminService.java new file mode 100644 index 0000000000..406655e5e2 --- /dev/null +++ b/cps-service/src/main/java/org/onap/cps/api/CpsAdminService.java @@ -0,0 +1,39 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * Modifications Copyright (C) 2020 Bell Canada. All rights reserved. + * ================================================================================ + * 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.api; + +import org.onap.cps.exceptions.CpsValidationException; +import org.onap.cps.spi.model.Anchor; + +/** + * CPS Admin Service. + */ +public interface CpsAdminService { + + /** + * Create an anchor using provided anchorDetails object. + * + * @param anchor the anchor details object. + * @return the anchor name. + * @throws CpsValidationException if input data is invalid. + */ + String createAnchor(Anchor anchor); +} diff --git a/cps-service/src/main/java/org/onap/cps/api/CpsDataService.java b/cps-service/src/main/java/org/onap/cps/api/CpsDataService.java new file mode 100644 index 0000000000..ebeeb9a825 --- /dev/null +++ b/cps-service/src/main/java/org/onap/cps/api/CpsDataService.java @@ -0,0 +1,27 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 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.api; + +/* + * Datastore interface for handling CPS data. + */ +public interface CpsDataService { + +} diff --git a/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java b/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java new file mode 100644 index 0000000000..02553d0741 --- /dev/null +++ b/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java @@ -0,0 +1,55 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 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.api; + +import java.io.File; +import org.onap.cps.exceptions.CpsValidationException; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; + +/** + * Responsible for managing module sets. + */ +public interface CpsModuleService { + + /** + * Parse and validate a string representing a yang model to generate a schema context. + * + * @param yangModelContent the input stream + * @return the schema context + */ + SchemaContext parseAndValidateModel(String yangModelContent); + + /** + * Parse and validate a file representing a yang model to generate a schema context. + * + * @param yangModelFile the yang file + * @return the schema context + */ + SchemaContext parseAndValidateModel(File yangModelFile); + + /** + * Store schema context for a yang model. + * + * @param schemaContext the schema context + * @param dataspaceName the dataspace name + * @throws CpsValidationException if input data already exists. + */ + void storeSchemaContext(SchemaContext schemaContext, String dataspaceName); +} diff --git a/cps-service/src/main/java/org/onap/cps/api/CpsQueryService.java b/cps-service/src/main/java/org/onap/cps/api/CpsQueryService.java new file mode 100644 index 0000000000..a66e084364 --- /dev/null +++ b/cps-service/src/main/java/org/onap/cps/api/CpsQueryService.java @@ -0,0 +1,27 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 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.api; + +/* + * Query interface for handling cps queries. + */ +public interface CpsQueryService { + +} diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java index 3daf9a0d69..3ec08cd733 100755 --- a/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java +++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java @@ -20,62 +20,17 @@ package org.onap.cps.api.impl; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.util.Optional; import org.onap.cps.api.CpService; -import org.onap.cps.api.model.AnchorDetails; -import org.onap.cps.exceptions.CpsException; -import org.onap.cps.exceptions.CpsValidationException; import org.onap.cps.spi.DataPersistenceService; -import org.onap.cps.spi.FragmentPersistenceService; -import org.onap.cps.spi.ModelPersistenceService; -import org.onap.cps.utils.YangUtils; -import org.opendaylight.yangtools.yang.common.Revision; -import org.opendaylight.yangtools.yang.model.api.Module; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; -import org.opendaylight.yangtools.yang.model.parser.api.YangParserException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class CpServiceImpl implements CpService { - @Autowired - private ModelPersistenceService modelPersistenceService; - @Autowired private DataPersistenceService dataPersistenceService; - @Autowired - private FragmentPersistenceService fragmentPersistenceService; - - @Override - public final SchemaContext parseAndValidateModel(final String yangModelContent) { - - try { - final File tempFile = File.createTempFile("yang", ".yang"); - try (BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile))) { - writer.write(yangModelContent); - } - return parseAndValidateModel(tempFile); - } catch (final IOException e) { - throw new CpsException(e); - } - } - - @Override - public final SchemaContext parseAndValidateModel(final File yangModelFile) { - try { - return YangUtils.parseYangModelFile(yangModelFile); - } catch (final YangParserException e) { - throw new CpsValidationException("Yang file validation failed", e.getMessage()); - } catch (final IOException e) { - throw new CpsException(e); - } - } @Override public final Integer storeJsonStructure(final String jsonStructure) { @@ -91,19 +46,4 @@ public class CpServiceImpl implements CpService { public void deleteJsonById(final int jsonObjectId) { dataPersistenceService.deleteJsonById(jsonObjectId); } - - @Override - public final void storeSchemaContext(final SchemaContext schemaContext, final String dataspaceName) { - for (final Module module : schemaContext.getModules()) { - final Optional optionalRevision = module.getRevision(); - final String revisionValue = optionalRevision.map(Object::toString).orElse(null); - modelPersistenceService.storeModule(module.getNamespace().toString(), module.toString(), - revisionValue, dataspaceName); - } - } - - @Override - public String createAnchor(final AnchorDetails anchorDetails) { - return fragmentPersistenceService.createAnchor(anchorDetails); - } } \ No newline at end of file diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java new file mode 100644 index 0000000000..b4deef6785 --- /dev/null +++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java @@ -0,0 +1,39 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * Modifications Copyright (C) 2020 Bell Canada. All rights reserved. + * ================================================================================ + * 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.api.impl; + +import org.onap.cps.api.CpsAdminService; +import org.onap.cps.spi.CpsAdminPersistenceService; +import org.onap.cps.spi.model.Anchor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component("CpsAdminServiceImpl") +public class CpsAdminServiceImpl implements CpsAdminService { + + @Autowired + private CpsAdminPersistenceService cpsAdminPersistenceService; + + @Override + public String createAnchor(final Anchor anchor) { + return cpsAdminPersistenceService.createAnchor(anchor); + } +} diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java new file mode 100644 index 0000000000..87ffdd3d90 --- /dev/null +++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java @@ -0,0 +1,79 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 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.api.impl; + + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Optional; +import org.onap.cps.api.CpsModuleService; +import org.onap.cps.exceptions.CpsException; +import org.onap.cps.exceptions.CpsValidationException; +import org.onap.cps.spi.CpsModulePersistenceService; +import org.onap.cps.utils.YangUtils; +import org.opendaylight.yangtools.yang.common.Revision; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.parser.api.YangParserException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component("CpsModuleServiceImpl") +public class CpsModuleServiceImpl implements CpsModuleService { + + @Autowired + private CpsModulePersistenceService cpsModulePersistenceService; + + @Override + public SchemaContext parseAndValidateModel(final String yangModelContent) { + try { + final File tempFile = File.createTempFile("yang", ".yang"); + try (BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile))) { + writer.write(yangModelContent); + } + return parseAndValidateModel(tempFile); + } catch (final IOException e) { + throw new CpsException(e); + } + } + + @Override + public SchemaContext parseAndValidateModel(final File yangModelFile) { + try { + return YangUtils.parseYangModelFile(yangModelFile); + } catch (final YangParserException e) { + throw new CpsValidationException("Yang file validation failed", e.getMessage()); + } catch (final IOException e) { + throw new CpsException(e); + } + } + + @Override + public void storeSchemaContext(final SchemaContext schemaContext, final String dataspaceName) { + for (final Module module : schemaContext.getModules()) { + final Optional optionalRevision = module.getRevision(); + final String revisionValue = optionalRevision.map(Object::toString).orElse(null); + cpsModulePersistenceService.storeModule(module.getNamespace().toString(), module.toString(), + revisionValue, dataspaceName); + } + } +} diff --git a/cps-service/src/main/java/org/onap/cps/spi/FragmentPersistenceService.java b/cps-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.java old mode 100755 new mode 100644 similarity index 81% rename from cps-service/src/main/java/org/onap/cps/spi/FragmentPersistenceService.java rename to cps-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.java index 48dbb0cc25..6709c1fb0b --- a/cps-service/src/main/java/org/onap/cps/spi/FragmentPersistenceService.java +++ b/cps-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.java @@ -1,34 +1,37 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2020 Nordix Foundation. All rights reserved. - * ================================================================================ - * 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.spi; - -import org.onap.cps.api.model.AnchorDetails; - -public interface FragmentPersistenceService { - - /** - * Create an Anchor. - * - * @param anchorDetails the anchorDetails object. - * @return the anchor name. - */ - String createAnchor(AnchorDetails anchorDetails); -} +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. All rights reserved. + * ================================================================================ + * 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.spi; + +import org.onap.cps.spi.model.Anchor; + +/* + Service for handling CPS admin data. + */ +public interface CpsAdminPersistenceService { + + /** + * Create an Anchor. + * + * @param anchor the anchorDetails object. + * @return the anchor name. + */ + String createAnchor(Anchor anchor); +} diff --git a/cps-service/src/main/java/org/onap/cps/spi/CpsDataPersistenceService.java b/cps-service/src/main/java/org/onap/cps/spi/CpsDataPersistenceService.java new file mode 100644 index 0000000000..12037066de --- /dev/null +++ b/cps-service/src/main/java/org/onap/cps/spi/CpsDataPersistenceService.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. All rights reserved. + * ================================================================================ + * 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.spi; + +/* + Data Store interface that is responsible for handling yang data. + Please follow guidelines in https://gerrit.nordix.org/#/c/onap/ccsdk/features/+/6698/19/cps/interface-proposal/src/main/java/cps/javadoc/spi/DataStoreService.java + when adding methods. + */ +public interface CpsDataPersistenceService { + +} diff --git a/cps-service/src/main/java/org/onap/cps/spi/ModelPersistenceService.java b/cps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java old mode 100755 new mode 100644 similarity index 90% rename from cps-service/src/main/java/org/onap/cps/spi/ModelPersistenceService.java rename to cps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java index 9eed2807cf..20f0122726 --- a/cps-service/src/main/java/org/onap/cps/spi/ModelPersistenceService.java +++ b/cps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java @@ -23,11 +23,14 @@ package org.onap.cps.spi; import java.util.Set; /** - * Defines methods to access and manipulate data using the chosen database solution. + * Service to manage modules. + * */ -public interface ModelPersistenceService { +public interface CpsModulePersistenceService { /** + * TODO + * clean up method to conform with spi proposal - https://jira.onap.org/browse/CPS-103 * Store the module from a yang model in the database. * * @param namespace module namespace diff --git a/cps-service/src/main/java/org/onap/cps/spi/DataPersistenceService.java b/cps-service/src/main/java/org/onap/cps/spi/DataPersistenceService.java old mode 100755 new mode 100644 diff --git a/cps-service/src/main/java/org/onap/cps/api/model/AnchorDetails.java b/cps-service/src/main/java/org/onap/cps/spi/model/Anchor.java old mode 100755 new mode 100644 similarity index 78% rename from cps-service/src/main/java/org/onap/cps/api/model/AnchorDetails.java rename to cps-service/src/main/java/org/onap/cps/spi/model/Anchor.java index 576168ae75..cd1c774476 --- a/cps-service/src/main/java/org/onap/cps/api/model/AnchorDetails.java +++ b/cps-service/src/main/java/org/onap/cps/spi/model/Anchor.java @@ -1,42 +1,43 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2020 Nordix Foundation. All rights reserved. - * ================================================================================ - * 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.api.model; - -import java.io.Serializable; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -@Getter -@Setter -@NoArgsConstructor -public class AnchorDetails implements Serializable { - - private static final long serialVersionUID = 1464791260718603291L; - - private String anchorName; - - private String dataspace; - - private String namespace; - - private String revision; +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. All rights reserved. + * ================================================================================ + * 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.spi.model; + +import java.io.Serializable; +import java.util.Map; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Setter +@Getter +@NoArgsConstructor +public class Anchor implements Serializable { + + // anchor will support both a single module and schema set until CPS-99 is complete + private static final long serialVersionUID = 1464791260718603291L; + private String anchorName; + private String dataspaceName; + private String namespace; + private String revision; + private String moduleSetName; + private Map externalReferences; + private String xpath; } \ No newline at end of file diff --git a/cps-service/src/main/java/org/onap/cps/spi/model/DataNode.java b/cps-service/src/main/java/org/onap/cps/spi/model/DataNode.java new file mode 100644 index 0000000000..5ed45ad6e1 --- /dev/null +++ b/cps-service/src/main/java/org/onap/cps/spi/model/DataNode.java @@ -0,0 +1,41 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. All rights reserved. + * ================================================================================ + * 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.spi.model; + +import java.util.Collection; +import java.util.Map; +import lombok.Builder; +import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Data +@Builder +public class DataNode { + + private String dataspace; + private String moduleSetName; + private ModuleRef moduleRef; + private String xpath; + private Map leaves; + private Collection xpathsChildren; +} diff --git a/cps-service/src/main/java/org/onap/cps/spi/model/ModuleRef.java b/cps-service/src/main/java/org/onap/cps/spi/model/ModuleRef.java new file mode 100644 index 0000000000..1f4e64a949 --- /dev/null +++ b/cps-service/src/main/java/org/onap/cps/spi/model/ModuleRef.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. All rights reserved. + * ================================================================================ + * 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.spi.model; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class ModuleRef { + + private String namespace; + private String revision; +} diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy index 2a3d5cbc5f..873aba78ab 100755 --- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy +++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy @@ -20,24 +20,17 @@ package org.onap.cps.api.impl -import org.onap.cps.TestUtils -import org.onap.cps.api.model.AnchorDetails -import org.onap.cps.exceptions.CpsValidationException + import org.onap.cps.spi.DataPersistenceService -import org.onap.cps.spi.FragmentPersistenceService -import org.opendaylight.yangtools.yang.common.Revision -import org.opendaylight.yangtools.yang.model.api.SchemaContext import spock.lang.Specification class CpServiceImplSpec extends Specification { def mockDataPersistenceService = Mock(DataPersistenceService) - def mockFragmentPersistenceService = Mock(FragmentPersistenceService) def objectUnderTest = new CpServiceImpl() def setup() { objectUnderTest.dataPersistenceService = mockDataPersistenceService - objectUnderTest.fragmentPersistenceService = mockFragmentPersistenceService } def 'Cps Service provides to its client the id assigned by the system when storing a data structure'() { @@ -47,44 +40,6 @@ class CpServiceImplSpec extends Specification { objectUnderTest.storeJsonStructure('') == 123 } - def 'Parse and Validate a Yang Model with a Valid Yang Model'() { - given: 'a yang model (file)' - def yangModel = TestUtils.getResourceFileContent('bookstore.yang') - when: 'a valid model is parsed and validated' - def result = objectUnderTest.parseAndValidateModel(yangModel) - then: 'Verify a schema context for that model is created with the correct identity' - assertModule(result) - } - - def 'Parse and Validate a Yang Model Using a File'() { - given: 'a yang file that contains a yang model' - File file = new File(ClassLoader.getSystemClassLoader().getResource('bookstore.yang').getFile()) - when: 'a model is parsed and validated' - def result = objectUnderTest.parseAndValidateModel(file) - then: 'Verify a schema context for that model is created with the correct identity' - assertModule(result) - - } - - def assertModule(SchemaContext schemaContext){ - def optionalModule = schemaContext.findModule('stores', Revision.of('2020-09-15')) - return schemaContext.modules.size() == 1 && optionalModule.isPresent() - } - - def 'Parse and Validate an Invalid Model'() { - given: 'a yang file that contains a invalid yang model' - File file = new File(ClassLoader.getSystemClassLoader().getResource('invalid.yang').getFile()) - when: 'the model is parsed and validated' - objectUnderTest.parseAndValidateModel(file) - then: 'a CpsValidationException is thrown' - thrown(CpsValidationException) - } - - def 'Store a SchemaContext'() { - expect: 'No exception to be thrown when a valid model (schema) is stored' - objectUnderTest.storeSchemaContext(Stub(SchemaContext.class), "sampleDataspace") - } - def 'Read a JSON object with a valid identifier'(){ given: 'that the data persistence service returns a JSON structure for identifier 1' mockDataPersistenceService.getJsonById(1) >> '{name : hello}' @@ -117,54 +72,4 @@ class CpServiceImplSpec extends Specification { then: 'the same exception is thrown by CPS' thrown(IllegalStateException) } - - def 'Create an anchor with a non-existant dataspace'(){ - given: 'that the dataspace does not exist service throws an exception' - AnchorDetails anchorDetails = new AnchorDetails() - anchorDetails.setDataspace('dummyDataspace') - mockFragmentPersistenceService.createAnchor(anchorDetails) >> {throw new CpsValidationException(_ as String, _ as String)} - when: 'we try to create a anchor with a non-existant dataspace' - objectUnderTest.createAnchor(anchorDetails) - then: 'the same exception is thrown by CPS' - thrown(CpsValidationException) - } - - def 'Create an anchor with invalid dataspace, namespace and revision'(){ - given: 'that the dataspace, namespace and revison combination does not exist service throws an exception' - AnchorDetails anchorDetails = new AnchorDetails() - anchorDetails.setDataspace('dummyDataspace') - anchorDetails.setNamespace('dummyNamespace') - anchorDetails.setRevision('dummyRevision') - mockFragmentPersistenceService.createAnchor(anchorDetails) >> {throw new CpsValidationException(_ as String, _ as String)} - when: 'we try to create a anchor with a non-existant dataspace, namespace and revison combination' - objectUnderTest.createAnchor(anchorDetails) - then: 'the same exception is thrown by CPS' - thrown(CpsValidationException) - } - - def 'Create a duplicate anchor'(){ - given: 'that the anchor already exist service throws an exception' - AnchorDetails anchorDetails = new AnchorDetails() - anchorDetails.setDataspace('dummyDataspace') - anchorDetails.setNamespace('dummyNamespace') - anchorDetails.setRevision('dummyRevision') - anchorDetails.setRevision('dummyAnchorName') - mockFragmentPersistenceService.createAnchor(anchorDetails) >> {throw new CpsValidationException(_ as String, _ as String)} - when: 'we try to create a duplicate anchor' - objectUnderTest.createAnchor(anchorDetails) - then: 'the same exception is thrown by CPS' - thrown(CpsValidationException) - } - - def 'Create an anchor with supplied anchor name, dataspace, namespace and revision'(){ - given: 'that the anchor does not pre-exist service creates an anchor' - AnchorDetails anchorDetails = new AnchorDetails() - anchorDetails.setDataspace('dummyDataspace') - anchorDetails.setNamespace('dummyNamespace') - anchorDetails.setRevision('dummyRevision') - anchorDetails.setRevision('dummyAnchorName') - mockFragmentPersistenceService.createAnchor(anchorDetails) >> 'dummyAnchorName' - expect: 'anchor name is returned by service' - objectUnderTest.createAnchor(anchorDetails) == 'dummyAnchorName' - } } diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminPersistenceServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminPersistenceServiceImplSpec.groovy new file mode 100644 index 0000000000..465badd0c2 --- /dev/null +++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminPersistenceServiceImplSpec.groovy @@ -0,0 +1,86 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * Modifications Copyright (C) 2020 Bell Canada. All rights reserved. + * ================================================================================ + * 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.api.impl + +import org.onap.cps.exceptions.CpsValidationException +import org.onap.cps.spi.CpsAdminPersistenceService +import org.onap.cps.spi.model.Anchor +import spock.lang.Specification + +class CpsAdminPersistenceServiceImplSpec extends Specification { + def mockCpsAdminService = Mock(CpsAdminPersistenceService) + def objectUnderTest = new CpsAdminServiceImpl() + + def setup() { + objectUnderTest.cpsAdminPersistenceService = mockCpsAdminService + } + + def 'Create an anchor with a non-existant dataspace'() { + given: 'that the dataspace does not exist service throws an exception' + Anchor anchor = new Anchor() + anchor.setDataspaceName('dummyDataspace') + mockCpsAdminService.createAnchor(anchor) >> { throw new CpsValidationException(_ as String, _ as String) } + when: 'we try to create a anchor with a non-existant dataspace' + objectUnderTest.createAnchor(anchor) + then: 'the same exception is thrown by CPS' + thrown(CpsValidationException) + } + + def 'Create an anchor with invalid dataspace, namespace and revision'() { + given: 'that the dataspace, namespace and revison combination does not exist service throws an exception' + Anchor anchor = new Anchor() + anchor.setDataspaceName('dummyDataspace') + anchor.setNamespace('dummyNamespace') + anchor.setRevision('dummyRevision') + mockCpsAdminService.createAnchor(anchor) >> { throw new CpsValidationException(_ as String, _ as String) } + when: 'we try to create a anchor with a non-existant dataspace, namespace and revison combination' + objectUnderTest.createAnchor(anchor) + then: 'the same exception is thrown by CPS' + thrown(CpsValidationException) + } + + def 'Create a duplicate anchor'() { + given: 'that the anchor already exist service throws an exception' + Anchor anchor = new Anchor() + anchor.setDataspaceName('dummyDataspace') + anchor.setNamespace('dummyNamespace') + anchor.setRevision('dummyRevision') + anchor.setRevision('dummyAnchorName') + mockCpsAdminService.createAnchor(anchor) >> { throw new CpsValidationException(_ as String, _ as String) } + when: 'we try to create a duplicate anchor' + objectUnderTest.createAnchor(anchor) + then: 'the same exception is thrown by CPS' + thrown(CpsValidationException) + } + + def 'Create an anchor with supplied anchor name, dataspace, namespace and revision'() { + given: 'that the anchor does not pre-exist service creates an anchor' + Anchor anchor = new Anchor() + anchor.setDataspaceName('dummyDataspace') + anchor.setNamespace('dummyNamespace') + anchor.setRevision('dummyRevision') + anchor.setRevision('dummyAnchorName') + mockCpsAdminService.createAnchor(anchor) >> 'dummyAnchorName' + expect: 'anchor name is returned by service' + objectUnderTest.createAnchor(anchor) == 'dummyAnchorName' + } + +} diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModulePersistenceServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModulePersistenceServiceImplSpec.groovy new file mode 100644 index 0000000000..79b981b2a2 --- /dev/null +++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModulePersistenceServiceImplSpec.groovy @@ -0,0 +1,76 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * Modifications Copyright (C) 2020 Bell Canada. All rights reserved. + * ================================================================================ + * 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.api.impl + +import org.onap.cps.TestUtils +import org.onap.cps.exceptions.CpsValidationException +import org.onap.cps.spi.CpsModulePersistenceService +import org.opendaylight.yangtools.yang.common.Revision +import org.opendaylight.yangtools.yang.model.api.SchemaContext +import spock.lang.Specification + +class CpsModulePersistenceServiceImplSpec extends Specification { + def mockModuleStoreService = Mock(CpsModulePersistenceService) + def objectUnderTest = new CpsModuleServiceImpl() + + def setup() { + objectUnderTest.cpsModulePersistenceService = mockModuleStoreService + } + + def 'Parse and Validate a Yang Model with a Valid Yang Model'() { + given: 'a yang model (file)' + def yangModel = TestUtils.getResourceFileContent('bookstore.yang') + when: 'a valid model is parsed and validated' + def result = objectUnderTest.parseAndValidateModel(yangModel) + then: 'Verify a schema context for that model is created with the correct identity' + assertModule(result) + } + + def 'Parse and Validate a Yang Model Using a File'() { + given: 'a yang file that contains a yang model' + File file = new File(ClassLoader.getSystemClassLoader().getResource('bookstore.yang').getFile()) + when: 'a model is parsed and validated' + def result = objectUnderTest.parseAndValidateModel(file) + then: 'Verify a schema context for that model is created with the correct identity' + assertModule(result) + + } + + def assertModule(SchemaContext schemaContext) { + def optionalModule = schemaContext.findModule('stores', Revision.of('2020-09-15')) + return schemaContext.modules.size() == 1 && optionalModule.isPresent() + } + + def 'Parse and Validate an Invalid Model'() { + given: 'a yang file that contains a invalid yang model' + File file = new File(ClassLoader.getSystemClassLoader().getResource('invalid.yang').getFile()) + when: 'the model is parsed and validated' + objectUnderTest.parseAndValidateModel(file) + then: 'a CpsValidationException is thrown' + thrown(CpsValidationException) + } + + def 'Store a SchemaContext'() { + expect: 'No exception to be thrown when a valid model (schema) is stored' + objectUnderTest.storeSchemaContext(Stub(SchemaContext.class), "sampleDataspace") + } + +}