diff options
author | Ruslan Kashapov <ruslan.kashapov@pantheon.tech> | 2020-12-10 10:49:59 +0200 |
---|---|---|
committer | Ruslan Kashapov <ruslan.kashapov@pantheon.tech> | 2020-12-24 09:57:48 +0200 |
commit | acfb2078d510f5cec7b6ce57c03ba42663b8f3ee (patch) | |
tree | 0ed0437b534e2d94208c51398afb3dff682e8d12 /cps-service/src/main/java/org | |
parent | 1d9845679de45007db30eee42c105edcffd972fb (diff) |
Create schema set REST API and service level
Issue-ID: CPS-123
Change-Id: Ie6d5fd4755454331415af7b80eaf85925efab395
Signed-off-by: Ruslan Kashapov <ruslan.kashapov@pantheon.tech>
Diffstat (limited to 'cps-service/src/main/java/org')
4 files changed, 76 insertions, 41 deletions
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 index 325893d6fd..e7b02fbad8 100644 --- a/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java +++ b/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java @@ -19,6 +19,8 @@ package org.onap.cps.api; +import java.util.Map; +import org.checkerframework.checker.nullness.qual.NonNull; import org.onap.cps.spi.exceptions.CpsException; import org.opendaylight.yangtools.yang.model.api.SchemaContext; @@ -28,11 +30,15 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext; public interface CpsModuleService { /** - * Store schema context for a yang model. + * Create schema set. * - * @param schemaContext the schema context - * @param dataspaceName the dataspace name - * @throws CpsException if input data already exists. + * @param dataspaceName dataspace name + * @param schemaSetName schema set name + * @param yangResourcesNameToContentMap yang resources (files) as a mep where key is resource name + * and value is content */ - void storeSchemaContext(SchemaContext schemaContext, String dataspaceName); + void createSchemaSet(@NonNull String dataspaceName, @NonNull String schemaSetName, + @NonNull Map<String, String> yangResourcesNameToContentMap); + + } 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 index 2c600b5571..8a437dbdee 100644 --- 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 @@ -20,12 +20,10 @@ package org.onap.cps.api.impl; -import java.util.Optional; +import java.util.Map; import org.onap.cps.api.CpsModuleService; import org.onap.cps.spi.CpsModulePersistenceService; -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.onap.cps.yang.YangTextSchemaSourceSetBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -36,12 +34,12 @@ public class CpsModuleServiceImpl implements CpsModuleService { private CpsModulePersistenceService cpsModulePersistenceService; @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); - } + public void createSchemaSet(final String dataspaceName, final String schemaSetName, + final Map<String, String> yangResourcesNameToContentMap) { + + YangTextSchemaSourceSetBuilder.validate(yangResourcesNameToContentMap); + cpsModulePersistenceService + .storeSchemaSet(dataspaceName, schemaSetName, yangResourcesNameToContentMap); } + } diff --git a/cps-service/src/main/java/org/onap/cps/spi/exceptions/ModelValidationException.java b/cps-service/src/main/java/org/onap/cps/spi/exceptions/ModelValidationException.java index 04a8836aca..b05a3f60eb 100644 --- a/cps-service/src/main/java/org/onap/cps/spi/exceptions/ModelValidationException.java +++ b/cps-service/src/main/java/org/onap/cps/spi/exceptions/ModelValidationException.java @@ -31,6 +31,16 @@ public class ModelValidationException extends CpsException { * * @param message the error message * @param details the error details + */ + public ModelValidationException(final String message, final String details) { + super(message, details); + } + + /** + * Constructor. + * + * @param message the error message + * @param details the error details * @param cause the cause of the exception */ public ModelValidationException(final String message, final String details, final Throwable cause) { diff --git a/cps-service/src/main/java/org/onap/cps/yang/YangTextSchemaSourceSetBuilder.java b/cps-service/src/main/java/org/onap/cps/yang/YangTextSchemaSourceSetBuilder.java index 89eea97f61..6d825445c3 100644 --- a/cps-service/src/main/java/org/onap/cps/yang/YangTextSchemaSourceSetBuilder.java +++ b/cps-service/src/main/java/org/onap/cps/yang/YangTextSchemaSourceSetBuilder.java @@ -24,10 +24,13 @@ import com.google.common.collect.ImmutableMap; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import lombok.NoArgsConstructor; import org.onap.cps.spi.exceptions.CpsException; +import org.onap.cps.spi.exceptions.ModelValidationException; import org.onap.cps.spi.model.ModuleReference; import org.opendaylight.yangtools.yang.common.Revision; import org.opendaylight.yangtools.yang.common.YangNames; @@ -41,13 +44,11 @@ import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangStatementStreamSo import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor; +@NoArgsConstructor public final class YangTextSchemaSourceSetBuilder { private final ImmutableMap.Builder<String, String> yangModelMap = new ImmutableMap.Builder<>(); - public YangTextSchemaSourceSetBuilder() { - } - public YangTextSchemaSourceSetBuilder put(final String fileName, final String content) { this.yangModelMap.put(fileName, content); return this; @@ -58,36 +59,45 @@ public final class YangTextSchemaSourceSetBuilder { return this; } - public YangTextSchemaSourceSet build() throws ReactorException, YangSyntaxErrorException { + public YangTextSchemaSourceSet build() { final SchemaContext schemaContext = generateSchemaContext(yangModelMap.build()); return new YangTextSchemaSourceSetImpl(schemaContext); } - public static YangTextSchemaSourceSet of(final Map<String, String> yangResourceNameToContent) - throws ReactorException, YangSyntaxErrorException { + public static YangTextSchemaSourceSet of(final Map<String, String> yangResourceNameToContent) { return new YangTextSchemaSourceSetBuilder().putAll(yangResourceNameToContent).build(); } + /** + * Validates if SchemaContext can be successfully built from given yang resources. + * + * @param yangResourceNameToContent the yang resources as map where key is name and value is content + * @throws ModelValidationException if validation fails + */ + public static void validate(final Map<String, String> yangResourceNameToContent) { + generateSchemaContext(yangResourceNameToContent); + } + private static class YangTextSchemaSourceSetImpl implements YangTextSchemaSourceSet { private final SchemaContext schemaContext; - public YangTextSchemaSourceSetImpl(final SchemaContext schemaContext) { + private YangTextSchemaSourceSetImpl(final SchemaContext schemaContext) { this.schemaContext = schemaContext; } @Override public List<ModuleReference> getModuleReferences() { return schemaContext.getModules().stream() - .map(YangTextSchemaSourceSetImpl::toModuleReference) - .collect(Collectors.toList()); + .map(YangTextSchemaSourceSetImpl::toModuleReference) + .collect(Collectors.toList()); } private static ModuleReference toModuleReference(final Module module) { return ModuleReference.builder() - .namespace(module.getName()) - .revision(module.getRevision().map(Revision::toString).orElse(null)) - .build(); + .namespace(module.getNamespace().toString()) + .revision(module.getRevision().map(Revision::toString).orElse(null)) + .build(); } @Override @@ -100,38 +110,49 @@ public final class YangTextSchemaSourceSetBuilder { * Parse and validate a string representing a yang model to generate a SchemaContext context. * * @param yangResourceNameToContent is a {@link Map} collection that contains the name of the model represented - * on yangModelContent as key and the yangModelContent as value. + * on yangModelContent as key and the yangModelContent as value. * @return the schema context */ - private SchemaContext generateSchemaContext(final Map<String, String> yangResourceNameToContent) - throws ReactorException, YangSyntaxErrorException { + private static SchemaContext generateSchemaContext(final Map<String, String> yangResourceNameToContent) { final CrossSourceStatementReactor.BuildAction reactor = RFC7950Reactors.defaultReactor().newBuild(); - final List<YangTextSchemaSource> yangTextSchemaSources = forResources(yangResourceNameToContent); - for (final YangTextSchemaSource yangTextSchemaSource : yangTextSchemaSources) { + for (final YangTextSchemaSource yangTextSchemaSource : forResources(yangResourceNameToContent)) { + final String resourceName = yangTextSchemaSource.getIdentifier().getName(); try { reactor.addSource(YangStatementStreamSource.create(yangTextSchemaSource)); } catch (final IOException e) { - throw new CpsException("Failed to read yangTextSchemaSource %s.", - yangTextSchemaSource.getIdentifier().getName(), e); + throw new CpsException("Failed to read yang resource.", + String.format("Exception occurred on reading resource %s.", resourceName), e); + } catch (final YangSyntaxErrorException e) { + throw new ModelValidationException("Yang resource is invalid.", + String.format("Yang syntax validation failed for resource %s.", resourceName), e); } } - return reactor.buildEffective(); + try { + return reactor.buildEffective(); + } catch (final ReactorException e) { + final List<String> resourceNames = yangResourceNameToContent.keySet().stream().collect(Collectors.toList()); + Collections.sort(resourceNames); + throw new ModelValidationException("Invalid schema set.", + String.format("Effective schema context build failed for resources %s.", resourceNames.toString()), + e); + } } - private List<YangTextSchemaSource> forResources(final Map<String, String> yangResourceNameToContent) { + private static List<YangTextSchemaSource> forResources(final Map<String, String> yangResourceNameToContent) { return yangResourceNameToContent.entrySet().stream() - .map(entry -> toYangTextSchemaSource(entry.getKey(), entry.getValue())) - .collect(Collectors.toList()); + .map(entry -> toYangTextSchemaSource(entry.getKey(), entry.getValue())) + .collect(Collectors.toList()); } - private YangTextSchemaSource toYangTextSchemaSource(final String sourceName, final String source) { + private static YangTextSchemaSource toYangTextSchemaSource(final String sourceName, final String source) { final Map.Entry<String, String> sourceNameParsed = YangNames.parseFilename(sourceName); final RevisionSourceIdentifier revisionSourceIdentifier = RevisionSourceIdentifier .create(sourceNameParsed.getKey(), Revision.ofNullable(sourceNameParsed.getValue())); + return new YangTextSchemaSource(revisionSourceIdentifier) { @Override protected MoreObjects.ToStringHelper addToStringAttributes( - final MoreObjects.ToStringHelper toStringHelper) { + final MoreObjects.ToStringHelper toStringHelper) { return toStringHelper; } |