diff options
31 files changed, 1276 insertions, 417 deletions
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; @@ -53,28 +54,35 @@ public class CpsRestController implements CpsRestApi { 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<String> 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<String> 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<String>(anchorName, HttpStatus.CREATED); } @Override public ResponseEntity<Object> 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<Object> 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/entities/SchemaSet.java b/cps-ri/src/main/java/org/onap/cps/spi/entities/SchemaSet.java new file mode 100644 index 0000000000..fe67a6089d --- /dev/null +++ b/cps-ri/src/main/java/org/onap/cps/spi/entities/SchemaSet.java @@ -0,0 +1,71 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Pantheon.tech + * ================================================================================ + * 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.entities; + +import java.io.Serializable; +import java.util.Set; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.validation.constraints.NotNull; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +/** + * Entity to store a Schema Set. + */ +@Getter +@Setter +@NoArgsConstructor +@Entity +@Table(name = "schema_set") +public class SchemaSet implements Serializable { + + private static final long serialVersionUID = 6665056955069047269L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @NotNull + @Column + private String name; + + @NotNull + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "dataspace_id", referencedColumnName = "ID") + private Dataspace dataspace; + + @NotNull + @ManyToMany(fetch = FetchType.LAZY) + @JoinTable(name = "schema_set_yang_resources", + joinColumns = @JoinColumn(name = "schema_set_id"), + inverseJoinColumns = @JoinColumn(name = "yang_resource_id")) + private Set<YangResource> yangResources; +} diff --git a/cps-ri/src/main/java/org/onap/cps/spi/entities/YangResource.java b/cps-ri/src/main/java/org/onap/cps/spi/entities/YangResource.java new file mode 100644 index 0000000000..862b7aea64 --- /dev/null +++ b/cps-ri/src/main/java/org/onap/cps/spi/entities/YangResource.java @@ -0,0 +1,63 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Pantheon.tech + * ================================================================================ + * 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.entities; + +import java.io.Serializable; +import java.util.Set; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.ManyToMany; +import javax.persistence.Table; +import javax.validation.constraints.NotNull; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +/** + * Entity to store a Yang files. + */ +@Getter +@Setter +@NoArgsConstructor +@Entity +@Table(name = "yang_resource") +public class YangResource implements Serializable { + + private static final long serialVersionUID = -4496883162142106774L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NotNull + @Column + private String checksum; + + @NotNull + @Column + private String content; + + @ManyToMany(mappedBy = "yangResources") + private Set<SchemaSet> moduleSets; + +} 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 index 82554b3d0a..684750c459 100755..100644 --- 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/CpsModulePersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java new file mode 100644 index 0000000000..52f8034575 --- /dev/null +++ b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java @@ -0,0 +1,111 @@ +/* + * ============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.spi.impl; + +import static org.onap.cps.exceptions.CpsExceptionBuilder.duplicateSchemaSetException; +import static org.onap.cps.exceptions.CpsExceptionBuilder.invalidDataspaceException; + +import com.google.common.collect.ImmutableSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import javax.transaction.Transactional; +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; +import org.onap.cps.spi.repository.DataspaceRepository; +import org.onap.cps.spi.repository.SchemaSetRepository; +import org.onap.cps.spi.repository.YangResourceRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.stereotype.Component; +import org.springframework.util.DigestUtils; + +@Component +public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceService { + + @Autowired + private YangResourceRepository yangResourceRepository; + + @Autowired + private SchemaSetRepository schemaSetRepository; + + @Autowired + private DataspaceRepository dataspaceRepository; + + @Override + public void storeModule(final String namespace, final String moduleContent, final String revision, + final String dataspaceName) { + // TODO this method should be removed as obsolete. + // Modules to be processed within schema sets only. + } + + @Override + @Transactional + public void storeSchemaSet(final String dataspaceName, final String schemaSetName, + final Set<String> yangResourcesAsStrings) { + + final Dataspace dataspace = dataspaceRepository.findByName(dataspaceName) + .orElseThrow(() -> invalidDataspaceException(dataspaceName)); + + final Set<YangResource> yangResources = synchronizeYangResources(yangResourcesAsStrings); + final SchemaSet schemaSet = new SchemaSet(); + schemaSet.setName(schemaSetName); + schemaSet.setDataspace(dataspace); + schemaSet.setYangResources(yangResources); + try { + schemaSetRepository.save(schemaSet); + } catch (final DataIntegrityViolationException e) { + throw duplicateSchemaSetException(dataspaceName, schemaSetName); + } + } + + private Set<YangResource> synchronizeYangResources(final Set<String> yangResourcesAsStrings) { + final Map<String, String> checksumToContentMap = yangResourcesAsStrings.stream() + .collect(Collectors.toMap( + content -> DigestUtils.md5DigestAsHex(content.getBytes()), + content -> content) + ); + + final List<YangResource> existingYangResources = + yangResourceRepository.findAllByChecksumIn(checksumToContentMap.keySet()); + existingYangResources.forEach(yangFile -> checksumToContentMap.remove(yangFile.getChecksum())); + + final List<YangResource> newYangResources = checksumToContentMap.entrySet().stream() + .map(entry -> { + final YangResource yangResource = new YangResource(); + yangResource.setChecksum(entry.getKey()); + yangResource.setContent(entry.getValue()); + return yangResource; + }).collect(Collectors.toList()); + if (!newYangResources.isEmpty()) { + yangResourceRepository.saveAll(newYangResources); + } + + return ImmutableSet.<YangResource>builder() + .addAll(existingYangResources) + .addAll(newYangResources) + .build(); + } + +} 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/ModelPersistenceServiceImpl.java deleted file mode 100755 index 03679b3160..0000000000 --- a/cps-ri/src/main/java/org/onap/cps/spi/impl/ModelPersistenceServiceImpl.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * ============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.spi.impl; - -import org.onap.cps.exceptions.CpsValidationException; -import org.onap.cps.spi.ModelPersistenceService; -import org.onap.cps.spi.entities.Dataspace; -import org.onap.cps.spi.entities.Module; -import org.onap.cps.spi.repository.DataspaceRepository; -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 ModelPersistenceServiceImpl implements ModelPersistenceService { - - @Autowired - private ModuleRepository moduleRepository; - - @Autowired - private DataspaceRepository dataspaceRepository; - - @Override - public void storeModule(final String namespace, final String moduleContent, final String revision, - final String dataspaceName) { - final Dataspace dataspace = new Dataspace(dataspaceName); - if (Boolean.FALSE.equals(dataspaceRepository.existsByName(dataspaceName))) { - dataspaceRepository.save(dataspace); - } - dataspace.setId(dataspaceRepository.getByName(dataspaceName).getId()); - final Module module = new Module(namespace, moduleContent, revision, dataspace); - try { - moduleRepository.save(module); - } catch (final DataIntegrityViolationException ex) { - throw new CpsValidationException("Duplicate Entry", - String.format("Module already exist in dataspace %s.", dataspaceName)); - } - } -} diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/DataspaceRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/DataspaceRepository.java index daf0b716b7..4b649167f3 100755 --- a/cps-ri/src/main/java/org/onap/cps/spi/repository/DataspaceRepository.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/DataspaceRepository.java @@ -21,7 +21,7 @@ package org.onap.cps.spi.repository; import java.util.Optional; import javax.validation.constraints.NotNull; -import org.onap.cps.exceptions.CpsNotFoundException; +import org.onap.cps.exceptions.DataspaceNotFoundException; import org.onap.cps.spi.entities.Dataspace; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @@ -34,6 +34,6 @@ public interface DataspaceRepository extends JpaRepository<Dataspace, Integer> { default Dataspace getByName(@NotNull String name) { return findByName(name).orElseThrow( - () -> new CpsNotFoundException("Not Found", "Dataspace " + name + " does not exist.")); + () -> new DataspaceNotFoundException("Dataspace " + name + " does not exist.")); } }
\ No newline at end of file diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/SchemaSetRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/SchemaSetRepository.java new file mode 100644 index 0000000000..f9746972f3 --- /dev/null +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/SchemaSetRepository.java @@ -0,0 +1,36 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Pantheon.tech + * ================================================================================ + * 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.repository; + +import java.util.List; +import java.util.Optional; +import javax.validation.constraints.NotNull; +import org.onap.cps.spi.entities.Dataspace; +import org.onap.cps.spi.entities.SchemaSet; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface SchemaSetRepository extends JpaRepository<SchemaSet, Integer> { + + List<SchemaSet> findAllByDataspace(@NotNull Dataspace dataspace); + + Optional<SchemaSet> findByDataspaceAndName(@NotNull Dataspace dataspace, @NotNull String name); +} diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java new file mode 100644 index 0000000000..47d3ea32cf --- /dev/null +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java @@ -0,0 +1,34 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Pantheon.tech + * ================================================================================ + * 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.repository; + +import java.util.List; +import java.util.Set; +import javax.validation.constraints.NotNull; +import org.onap.cps.spi.entities.YangResource; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface YangResourceRepository extends JpaRepository<YangResource, Long> { + + List<YangResource> findAllByChecksumIn(@NotNull Set<String> checksum); + +} diff --git a/cps-ri/src/main/resources/schema.sql b/cps-ri/src/main/resources/schema.sql index 3fabc6c9f9..d47f261add 100755 --- a/cps-ri/src/main/resources/schema.sql +++ b/cps-ri/src/main/resources/schema.sql @@ -17,6 +17,30 @@ CREATE TABLE IF NOT EXISTS SCHEMA_NODE ID SERIAL PRIMARY KEY
);
+CREATE TABLE IF NOT EXISTS SCHEMA_SET
+(
+ ID SERIAL PRIMARY KEY,
+ NAME TEXT NOT NULL,
+ DATASPACE_ID BIGINT NOT NULL,
+ UNIQUE (NAME, DATASPACE_ID),
+ CONSTRAINT SCHEMA_SET_DATASPACE FOREIGN KEY (DATASPACE_ID) REFERENCES DATASPACE(ID) ON UPDATE CASCADE ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS YANG_RESOURCE
+(
+ ID SERIAL PRIMARY KEY,
+ CHECKSUM TEXT NOT NULL,
+ CONTENT TEXT NOT NULL,
+ UNIQUE (CHECKSUM)
+);
+
+CREATE TABLE IF NOT EXISTS SCHEMA_SET_YANG_RESOURCES
+(
+ SCHEMA_SET_ID BIGINT NOT NULL,
+ YANG_RESOURCE_ID BIGINT NOT NULL REFERENCES YANG_RESOURCE(ID),
+ CONSTRAINT SCHEMA_SET_RESOURCE FOREIGN KEY (SCHEMA_SET_ID) REFERENCES SCHEMA_SET(ID) ON DELETE CASCADE
+);
+
CREATE TABLE IF NOT EXISTS MODULE
(
ID SERIAL PRIMARY KEY,
@@ -62,4 +86,4 @@ CREATE INDEX IF NOT EXISTS "FKI_RELATION_TYPE_ID_FK" ON RELATION USING CREATE INDEX IF NOT EXISTS "FKI_RELATIONS_FROM_ID_FK" ON RELATION USING BTREE(FROM_FRAGMENT_ID);
CREATE INDEX IF NOT EXISTS "FKI_RELATIONS_TO_ID_FK" ON RELATION USING BTREE(TO_FRAGMENT_ID);
CREATE INDEX IF NOT EXISTS "PERF_MODULE_MODULE_CONTENT" ON MODULE USING BTREE(MODULE_CONTENT);
-CREATE UNIQUE INDEX IF NOT EXISTS "UQ_FRAGMENT_XPATH"ON FRAGMENT USING btree(xpath COLLATE pg_catalog."default" text_pattern_ops, dataspace_id);
\ No newline at end of file +CREATE UNIQUE INDEX IF NOT EXISTS "UQ_FRAGMENT_XPATH"ON FRAGMENT USING btree(xpath COLLATE pg_catalog."default" text_pattern_ops, dataspace_id);
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,42 +20,12 @@ 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. * * @param jsonStructure the JSON structure. @@ -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,23 +20,8 @@ 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; @@ -44,38 +29,8 @@ import org.springframework.stereotype.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<Revision> 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<Revision> 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/exceptions/CpsAdminException.java b/cps-service/src/main/java/org/onap/cps/exceptions/CpsAdminException.java new file mode 100644 index 0000000000..a088913375 --- /dev/null +++ b/cps-service/src/main/java/org/onap/cps/exceptions/CpsAdminException.java @@ -0,0 +1,60 @@ +/* + * ============LICENSE_START======================================================= + * 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.exceptions; + +import lombok.Getter; + +/** + * CPS Admin exception. + */ +public class CpsAdminException extends CpsValidationException { + + private static final long serialVersionUID = 5573438585188332404L; + + /** + * Constructor. + * + * @param cause the cause of the exception + */ + public CpsAdminException(final Throwable cause) { + super(cause.getMessage(), cause); + } + + /** + * Constructor. + * + * @param message the error message + * @param cause the cause of the exception + */ + public CpsAdminException(final String message, final Throwable cause) { + super(message, cause); + } + + /** + * Constructor. + * + * @param message the error message + * @param details the error details + */ + public CpsAdminException(final String message, final String details) { + super(message, details); + this.details = details; + } +} diff --git a/cps-service/src/main/java/org/onap/cps/exceptions/CpsExceptionBuilder.java b/cps-service/src/main/java/org/onap/cps/exceptions/CpsExceptionBuilder.java new file mode 100644 index 0000000000..2acbb92322 --- /dev/null +++ b/cps-service/src/main/java/org/onap/cps/exceptions/CpsExceptionBuilder.java @@ -0,0 +1,94 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Pantheon.tech + * ================================================================================ + * 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.exceptions; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +/** + * Utility class. + * Serves error message consistency for same error cases occurred in different CPS modules. + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class CpsExceptionBuilder { + + private static final String SCHEMA_SET_IS_INVALID = "Schema Set is invalid."; + + /** + * Generates validation error exception for case when requested dataspace is absent. + * + * @param dataspaceName dataspace name + */ + public static CpsException invalidDataspaceException(final String dataspaceName) { + return new CpsValidationException("Dataspace is invalid.", + String.format("Dataspace with name %s does not exist.", dataspaceName)); + } + + /** + * Generates validation error exception for case when requested schema set is absent for existing dataspace. + * + * @param dataspaceName dataspace name + * @param schemaSetName schema set name + */ + public static CpsException invalidSchemaSetException(final String dataspaceName, final String schemaSetName) { + return new CpsValidationException(SCHEMA_SET_IS_INVALID, + String.format("Schema Set with name %s was not found for dataspace %s.", schemaSetName, dataspaceName)); + } + + /** + * Returns validation error exception for case when SchemaSet contains no files. + */ + public static CpsException emptySchemaSetException() { + return new CpsValidationException(SCHEMA_SET_IS_INVALID, "Schema Set has no YANG resources to store"); + } + + /** + * Generates validation error exception for case when SchemaSet with same name already exists in the dataspace. + * + * @param dataspaceName dataspace name + * @param schemaSetName schema set name + */ + public static CpsException duplicateSchemaSetException(final String dataspaceName, final String schemaSetName) { + return new CpsValidationException(SCHEMA_SET_IS_INVALID, + String.format("Schema Set with name %s already exists for dataspace %s.", schemaSetName, dataspaceName)); + } + + /** + * Generates no data found exception for case when requested dataspace is absent. + * + * @param dataspaceName dataspace name + */ + public static CpsException dataspaceNotFoundException(final String dataspaceName) { + return new CpsNotFoundException("Dataspace was not found.", + String.format("Dataspace with name %s does not exist.", dataspaceName)); + } + + /** + * Generates no data found exception for case when requested SchemaSet is absent for existing dataspace. + * + * @param dataspaceName dataspace name + * @param schemaSetName schema set name + */ + public static CpsException schemaSetNotFoundException(final String dataspaceName, final String schemaSetName) { + return new CpsNotFoundException("Schema Set was not found.", + String.format("Schema Set with name %s was not found for dataspace %s.", schemaSetName, dataspaceName)); + } + +} diff --git a/cps-service/src/main/java/org/onap/cps/exceptions/DataspaceNotFoundException.java b/cps-service/src/main/java/org/onap/cps/exceptions/DataspaceNotFoundException.java new file mode 100644 index 0000000000..1b09cdd1eb --- /dev/null +++ b/cps-service/src/main/java/org/onap/cps/exceptions/DataspaceNotFoundException.java @@ -0,0 +1,57 @@ +/* + * ============LICENSE_START======================================================= + * 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.exceptions; + + +/** + * Dataspace Not Found Exception. Indicates the requested data being absent. + */ +public class DataspaceNotFoundException extends CpsAdminException { + + private static final long serialVersionUID = -1852996415384288431L; + + /** + * Constructor. + * + * @param cause the cause of the exception + */ + public DataspaceNotFoundException(final Throwable cause) { + super(cause.getMessage(), cause); + } + + /** + * Constructor. + * + * @param message the error message + * @param cause the cause of the exception + */ + public DataspaceNotFoundException(final String message, final Throwable cause) { + super(message, cause); + } + + /** + * Constructor. + * + * @param details the error details + */ + public DataspaceNotFoundException(final String details) { + super("Dataspace Not Found", details); + } +} 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 index 48dbb0cc25..6709c1fb0b 100755..100644 --- 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 index 3f0b3c1109..20f0122726 100755..100644 --- a/cps-service/src/main/java/org/onap/cps/spi/ModelPersistenceService.java +++ b/cps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java @@ -20,20 +20,36 @@ 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 + * @param namespace module namespace * @param moduleContent module content - * @param revision module revision + * @param revision module revision * @param dataspaceName the name of the dataspace the module is associated with */ + @Deprecated void storeModule(final String namespace, final String moduleContent, final String revision, - final String dataspaceName); + final String dataspaceName); + + + /** + * Stores Schema Set. + * + * @param dataspaceName dataspace name + * @param schemaSetName schema set name + * @param yangResourcesAsStrings the content of YANG resources (files) + */ + void storeSchemaSet(String dataspaceName, String schemaSetName, Set<String> yangResourcesAsStrings); } 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 index a3cbc28c55..a3cbc28c55 100755..100644 --- a/cps-service/src/main/java/org/onap/cps/spi/DataPersistenceService.java +++ b/cps-service/src/main/java/org/onap/cps/spi/DataPersistenceService.java 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 index 576168ae75..cd1c774476 100755..100644 --- 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<String, String> 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<String, Object> leaves; + private Collection<String> 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") + } + +} |