diff options
author | 2020-12-14 09:49:13 +0100 | |
---|---|---|
committer | 2020-12-16 09:49:26 +0000 | |
commit | 0e9a8a51e51c7f3f90e4eae4b9907558b39818f8 (patch) | |
tree | 0898b160c242963bc4593f080475913d6859d38b /cps-service/src/main/java | |
parent | c040bcb4ae61177b1aa691f059d19c96c6cfff7b (diff) |
Introduce YangTextSchemaSourceSet
Common interface among all layers.
YangTextSchemaSourceSet responsability is to provide all
yang model required information of an YangSchema.
Issue-ID: CPS-21
Signed-off-by: Claudio David Gasparini <claudio.gasparini@pantheon.tech>
Change-Id: I9cba490dec25defbddbb3524c6d6c1535bee63bc
Diffstat (limited to 'cps-service/src/main/java')
3 files changed, 179 insertions, 24 deletions
diff --git a/cps-service/src/main/java/org/onap/cps/utils/YangUtils.java b/cps-service/src/main/java/org/onap/cps/utils/YangUtils.java index 071ff6ad3..a35533c8f 100644 --- a/cps-service/src/main/java/org/onap/cps/utils/YangUtils.java +++ b/cps-service/src/main/java/org/onap/cps/utils/YangUtils.java @@ -19,18 +19,23 @@ package org.onap.cps.utils; +import static com.google.common.base.Preconditions.checkArgument; +import static org.opendaylight.yangtools.yang.common.YangConstants.RFC6020_YANG_FILE_EXTENSION; + +import com.google.common.base.Charsets; +import com.google.common.io.Files; import com.google.gson.stream.JsonReader; import java.io.File; import java.io.IOException; import java.io.StringReader; import java.util.Collection; import java.util.Collections; -import java.util.Iterator; import java.util.List; -import java.util.ServiceLoader; import java.util.logging.Logger; import java.util.stream.Collectors; import org.onap.cps.api.impl.Fragment; +import org.onap.cps.yang.YangTextSchemaSourceSet; +import org.onap.cps.yang.YangTextSchemaSourceSetBuilder; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; @@ -48,44 +53,37 @@ import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeS import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; -import org.opendaylight.yangtools.yang.model.parser.api.YangParser; import org.opendaylight.yangtools.yang.model.parser.api.YangParserException; -import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory; -import org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode; -import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; +import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; public class YangUtils { - - private static final YangParserFactory PARSER_FACTORY; - private static final Logger LOGGER = Logger.getLogger(YangUtils.class.getName()); private YangUtils() { throw new IllegalStateException("Utility class"); } - static { - final Iterator<YangParserFactory> it = ServiceLoader.load(YangParserFactory.class).iterator(); - if (!it.hasNext()) { - throw new IllegalStateException("No YangParserFactory found"); - } - PARSER_FACTORY = it.next(); - } - /** * Parse a file containing yang modules. * - * @param yangModelFile a file containing one or more yang modules. The file has to have a .yang extension. + * @param yangModelFiles list of files containing one or more yang modules. The file has to have a .yang extension. * @return a SchemaContext representing the yang model * @throws IOException when the system as an IO issue * @throws YangParserException when the file does not contain a valid yang structure */ - public static SchemaContext parseYangModelFile(final File yangModelFile) throws IOException, YangParserException { - final YangTextSchemaSource yangTextSchemaSource = YangTextSchemaSource.forFile(yangModelFile); - final YangParser yangParser = PARSER_FACTORY - .createParser(StatementParserMode.DEFAULT_MODE); - yangParser.addSource(yangTextSchemaSource); - return yangParser.buildEffectiveModel(); + @Deprecated + public static YangTextSchemaSourceSet parseYangModelFiles(final List<File> yangModelFiles) + throws IOException, YangParserException, ReactorException { + final YangTextSchemaSourceSetBuilder yangModelsMapBuilder = new YangTextSchemaSourceSetBuilder(); + for (final File file :yangModelFiles) { + final String fileNameWithExtension = file.getName(); + checkArgument(fileNameWithExtension.endsWith(RFC6020_YANG_FILE_EXTENSION), + "Filename %s does not end with '%s'", RFC6020_YANG_FILE_EXTENSION, + fileNameWithExtension); + final String content = Files.asCharSource(file, Charsets.UTF_8).read(); + yangModelsMapBuilder.put(fileNameWithExtension, content); + } + return yangModelsMapBuilder.build(); } /** diff --git a/cps-service/src/main/java/org/onap/cps/yang/YangTextSchemaSourceSet.java b/cps-service/src/main/java/org/onap/cps/yang/YangTextSchemaSourceSet.java new file mode 100644 index 000000000..5c337770d --- /dev/null +++ b/cps-service/src/main/java/org/onap/cps/yang/YangTextSchemaSourceSet.java @@ -0,0 +1,35 @@ +/* + * ============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.yang; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; + +/** + * CPS YangTextSchemaSource. + */ +public interface YangTextSchemaSourceSet { + /** + * Return SchemaContext for given YangSchema. + * @return SchemaContext + */ + @NonNull + SchemaContext getSchemaContext(); +} 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 new file mode 100644 index 000000000..1588c44d9 --- /dev/null +++ b/cps-service/src/main/java/org/onap/cps/yang/YangTextSchemaSourceSetBuilder.java @@ -0,0 +1,122 @@ +/* + * ============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.yang; + +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableMap; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import org.opendaylight.yangtools.yang.common.Revision; +import org.opendaylight.yangtools.yang.common.YangNames; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException; +import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier; +import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; +import org.opendaylight.yangtools.yang.parser.rfc7950.reactor.RFC7950Reactors; +import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangStatementStreamSource; +import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; +import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor; + +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; + } + + public YangTextSchemaSourceSetBuilder putAll(final Map<String, String> yangResourceNameToContent) { + this.yangModelMap.putAll(yangResourceNameToContent); + return this; + } + + public YangTextSchemaSourceSet build() throws ReactorException, IOException, YangSyntaxErrorException { + final SchemaContext schemaContext = generateSchemaContext(yangModelMap.build()); + return new YangTextSchemaSourceSetImpl(schemaContext); + } + + public static YangTextSchemaSourceSet of(final Map<String, String> yangResourceNameToContent) + throws ReactorException, IOException, YangSyntaxErrorException { + return new YangTextSchemaSourceSetBuilder().putAll(yangResourceNameToContent).build(); + } + + private static class YangTextSchemaSourceSetImpl implements YangTextSchemaSourceSet { + + private final SchemaContext schemaContext; + + public YangTextSchemaSourceSetImpl(final SchemaContext schemaContext) { + this.schemaContext = schemaContext; + } + + @Override + public SchemaContext getSchemaContext() { + return schemaContext; + } + } + + /** + * 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. + * @return the schema context + */ + private SchemaContext generateSchemaContext(final Map<String, String> yangResourceNameToContent) + throws IOException, ReactorException, YangSyntaxErrorException { + final CrossSourceStatementReactor.BuildAction reactor = RFC7950Reactors.defaultReactor().newBuild(); + final List<YangTextSchemaSource> yangTextSchemaSources = forResources(yangResourceNameToContent); + for (final YangTextSchemaSource yangTextSchemaSource : yangTextSchemaSources) { + reactor.addSource(YangStatementStreamSource.create(yangTextSchemaSource)); + } + return reactor.buildEffective(); + } + + private List<YangTextSchemaSource> forResources(final Map<String, String> yangResourceNameToContent) { + return yangResourceNameToContent.entrySet().stream() + .map(entry -> toYangTextSchemaSource(entry.getKey(), entry.getValue())) + .collect(Collectors.toList()); + } + + private 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) { + return toStringHelper; + } + + @Override + public InputStream openStream() { + return new ByteArrayInputStream(source.getBytes()); + } + }; + } +} |