From a829451766daa29b287faddebd66ae4df8d8baf4 Mon Sep 17 00:00:00 2001 From: Tony Tkacik Date: Tue, 6 Oct 2015 18:19:21 +0200 Subject: [PATCH] ModuleInfoBackedContext uses YangTextSchemaResolver. This removes locking from ModuleInfoBackedContext and improves perforamance characteristic during access from multiple threads. Change-Id: I8c6c3d228fcdb384761185f5347cde284490fbde Signed-off-by: Tony Tkacik --- .../codec/test/ExceptionReportingTest.java | 9 +- .../impl/ModuleInfoBackedContext.java | 89 ++++++++----------- 2 files changed, 40 insertions(+), 58 deletions(-) diff --git a/binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/yangtools/binding/data/codec/test/ExceptionReportingTest.java b/binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/yangtools/binding/data/codec/test/ExceptionReportingTest.java index 12effb52d5..2452ca2f91 100644 --- a/binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/yangtools/binding/data/codec/test/ExceptionReportingTest.java +++ b/binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/yangtools/binding/data/codec/test/ExceptionReportingTest.java @@ -14,6 +14,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.te import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.Top; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelList; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelListKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.yangtools.test.union.rev150121.LowestLevel1; import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator; import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry; import org.opendaylight.yangtools.binding.data.codec.impl.IncorrectNestingException; @@ -33,7 +34,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext; public class ExceptionReportingTest { - private static final BindingNormalizedNodeCodecRegistry EMPTY_SCHEMA_CODEC = codec(); + private static final BindingNormalizedNodeCodecRegistry CODEC_WITHOUT_TOP = codec(LowestLevel1.class); private static final BindingNormalizedNodeCodecRegistry ONLY_TOP_CODEC = codec(Top.class); private static final BindingNormalizedNodeCodecRegistry FULL_CODEC = codec(TreeComplexUsesAugment.class); @@ -50,17 +51,17 @@ public class ExceptionReportingTest { @Test(expected=MissingSchemaException.class) public void testDOMTop() { - EMPTY_SCHEMA_CODEC.fromYangInstanceIdentifier(BI_TOP_PATH); + CODEC_WITHOUT_TOP.fromYangInstanceIdentifier(BI_TOP_PATH); } @Test(expected=MissingSchemaException.class) public void testDOMAugment() { - EMPTY_SCHEMA_CODEC.fromYangInstanceIdentifier(BI_TREE_LEAF_ONLY); + CODEC_WITHOUT_TOP.fromYangInstanceIdentifier(BI_TREE_LEAF_ONLY); } @Test(expected=MissingSchemaForClassException.class) public void testBindingTop() { - EMPTY_SCHEMA_CODEC.toYangInstanceIdentifier(BA_TOP_LEVEL_LIST); + CODEC_WITHOUT_TOP.toYangInstanceIdentifier(BA_TOP_LEVEL_LIST); } @Test(expected=MissingSchemaForClassException.class) diff --git a/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/ModuleInfoBackedContext.java b/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/ModuleInfoBackedContext.java index 289ff4fa8e..5894e329d8 100644 --- a/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/ModuleInfoBackedContext.java +++ b/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/ModuleInfoBackedContext.java @@ -7,16 +7,14 @@ */ package org.opendaylight.yangtools.sal.binding.generator.impl; +import com.google.common.base.MoreObjects.ToStringHelper; import com.google.common.base.Optional; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import com.google.common.io.ByteSource; import com.google.common.util.concurrent.CheckedFuture; import com.google.common.util.concurrent.Futures; import java.io.IOException; import java.io.InputStream; import java.lang.ref.WeakReference; -import java.util.Collection; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.opendaylight.yangtools.concepts.AbstractObjectRegistration; @@ -32,16 +30,15 @@ import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException; import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier; import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider; -import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; -import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; -import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor; -import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline; +import org.opendaylight.yangtools.yang.parser.repo.YangTextSchemaContextResolver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ModuleInfoBackedContext extends GeneratedClassLoadingStrategy implements ModuleInfoRegistry, SchemaContextProvider, SchemaSourceProvider { + private final YangTextSchemaContextResolver ctxResolver = YangTextSchemaContextResolver.create("binding-context"); + private ModuleInfoBackedContext(final ClassLoadingStrategy loadingStrategy) { this.backingLoadingStrategy = loadingStrategy; } @@ -75,52 +72,18 @@ public class ModuleInfoBackedContext extends GeneratedClassLoadingStrategy } Class cls = backingLoadingStrategy.loadClass(fullyQualifiedName); if (BindingReflections.isBindingClass(cls)) { - boolean newModule = resolveModuleInfo(cls); - if (newModule) { - recreateSchemaContext(); - } + resolveModuleInfo(cls); } return cls; } - - private synchronized Optional recreateSchemaContext() { - try { - Collection streams = getAvailableStreams(); - CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR - .newBuild(); - SchemaContext schemaContext = reactor.buildEffective(streams); - return Optional.of(schemaContext); - } catch (IOException | SourceException | ReactorException e) { - LOG.error("Schema was not recreated.", e); - } - return Optional.absent(); - } - // TODO finish schema parsing and expose as SchemaService // Unite with current SchemaService // Implement remove ModuleInfo to update SchemaContext - public synchronized Optional tryToCreateSchemaContext() { - return recreateSchemaContext(); - } - - private Collection getAvailableStreams() throws IOException { - ImmutableSet moduleInfos = ImmutableSet.copyOf(sourceIdentifierToModuleInfo.values()); - - ImmutableList.Builder sourceStreams = ImmutableList. builder(); - for (final YangModuleInfo moduleInfo : moduleInfos) { - sourceStreams.add(new ByteSource() { - - @Override - public InputStream openStream() throws IOException { - return moduleInfo.getModuleSourceStream(); - } - }); - ; - } - return sourceStreams.build(); + public Optional tryToCreateSchemaContext() { + return ctxResolver.getSchemaContext(); } private boolean resolveModuleInfo(final Class cls) { @@ -136,19 +99,39 @@ public class ModuleInfoBackedContext extends GeneratedClassLoadingStrategy SourceIdentifier identifier = sourceIdentifierFrom(moduleInfo); YangModuleInfo previous = sourceIdentifierToModuleInfo.putIfAbsent(identifier, moduleInfo); ClassLoader moduleClassLoader = moduleInfo.getClass().getClassLoader(); - if (previous == null) { - String modulePackageName = moduleInfo.getClass().getPackage().getName(); - packageNameToClassLoader.putIfAbsent(modulePackageName, new WeakReference(moduleClassLoader)); - - for (YangModuleInfo importedInfo : moduleInfo.getImportedModules()) { - resolveModuleInfo(importedInfo); + try { + if (previous == null) { + String modulePackageName = moduleInfo.getClass().getPackage().getName(); + packageNameToClassLoader.putIfAbsent(modulePackageName, + new WeakReference(moduleClassLoader)); + ctxResolver.registerSource(toYangTextSource(identifier, moduleInfo)); + for (YangModuleInfo importedInfo : moduleInfo.getImportedModules()) { + resolveModuleInfo(importedInfo); + } + } else { + return false; } - } else { - return false; + } catch (Exception e) { + LOG.error("Not including {} in YANG sources because of error.", moduleInfo, e); } return true; } + private YangTextSchemaSource toYangTextSource(SourceIdentifier identifier, final YangModuleInfo moduleInfo) { + return new YangTextSchemaSource(identifier) { + + @Override + public InputStream openStream() throws IOException { + return moduleInfo.getModuleSourceStream(); + } + + @Override + protected ToStringHelper addToStringAttributes(ToStringHelper toStringHelper) { + return toStringHelper; + } + }; + } + private static SourceIdentifier sourceIdentifierFrom(final YangModuleInfo moduleInfo) { return SourceIdentifier.create(moduleInfo.getName(), Optional.of(moduleInfo.getRevision())); } @@ -162,9 +145,7 @@ public class ModuleInfoBackedContext extends GeneratedClassLoadingStrategy @Override public ObjectRegistration registerModuleInfo(final YangModuleInfo yangModuleInfo) { YangModuleInfoRegistration registration = new YangModuleInfoRegistration(yangModuleInfo, this); - resolveModuleInfo(yangModuleInfo); - return registration; } -- 2.36.6