From: Maros Marsalek Date: Wed, 30 Sep 2015 13:28:23 +0000 (+0200) Subject: BUG-4367: Use SchemaSourceProvider to retrieve sources for yang X-Git-Tag: release/beryllium~252 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=f77ea78c351d1c3604287e8444aae6943f70042f BUG-4367: Use SchemaSourceProvider to retrieve sources for yang - Not using schema context to provide the sources anymore. - Transform the modules into capabilities in YangStoreService instead of requiring the listeners to do so Change-Id: I39a144c7472f7944cca01eeff273058aa2fe7d7a Signed-off-by: Maros Marsalek --- diff --git a/opendaylight/config/config-manager-facade-xml/src/main/java/org/opendaylight/controller/config/facade/xml/osgi/YangStoreActivator.java b/opendaylight/config/config-manager-facade-xml/src/main/java/org/opendaylight/controller/config/facade/xml/osgi/YangStoreActivator.java index 1df85391ab..57ebfb2b10 100644 --- a/opendaylight/config/config-manager-facade-xml/src/main/java/org/opendaylight/controller/config/facade/xml/osgi/YangStoreActivator.java +++ b/opendaylight/config/config-manager-facade-xml/src/main/java/org/opendaylight/controller/config/facade/xml/osgi/YangStoreActivator.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.config.facade.xml.osgi; +import com.google.common.base.Preconditions; import java.lang.management.ManagementFactory; import java.util.Hashtable; import java.util.concurrent.atomic.AtomicBoolean; @@ -16,6 +17,8 @@ import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacadeFactor import org.opendaylight.controller.config.util.ConfigRegistryJMXClient; import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext; import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider; +import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; +import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; @@ -51,6 +54,11 @@ public class YangStoreActivator implements BundleActivator { @Override public YangStoreService addingService(ServiceReference reference) { LOG.debug("Got addingService(SchemaContextProvider) event"); + if(reference.getProperty(SchemaSourceProvider.class.getName()) == null && + reference.getProperty(BindingRuntimeContext.class.getName()) == null) { + LOG.debug("SchemaContextProvider not from config-manager. Ignoring"); + return null; + } // Yang store service should not be registered multiple times if(!alreadyStarted.compareAndSet(false, true)) { @@ -58,7 +66,13 @@ public class YangStoreActivator implements BundleActivator { throw new RuntimeException("Starting yang store service multiple times"); } SchemaContextProvider schemaContextProvider = reference.getBundle().getBundleContext().getService(reference); - final YangStoreService yangStoreService = new YangStoreService(schemaContextProvider); + final Object sourceProvider = Preconditions.checkNotNull( + reference.getProperty(SchemaSourceProvider.class.getName()), "Source provider not found"); + Preconditions.checkArgument(sourceProvider instanceof SchemaSourceProvider); + + // TODO avoid cast + final YangStoreService yangStoreService = new YangStoreService(schemaContextProvider, + ((SchemaSourceProvider) sourceProvider)); yangStoreServiceServiceRegistration = context.registerService(YangStoreService.class, yangStoreService, new Hashtable()); configRegistryLookup = new ConfigRegistryLookupThread(yangStoreService); configRegistryLookup.start(); @@ -67,14 +81,23 @@ public class YangStoreActivator implements BundleActivator { @Override public void modifiedService(ServiceReference reference, YangStoreService service) { + if (service == null) { + return; + } + LOG.debug("Got modifiedService(SchemaContextProvider) event"); - final BindingRuntimeContext runtimeContext = (BindingRuntimeContext) reference.getProperty(BindingRuntimeContext.class.getName()); + final BindingRuntimeContext runtimeContext = (BindingRuntimeContext) reference + .getProperty(BindingRuntimeContext.class.getName()); LOG.debug("BindingRuntimeContext retrieved as {}", runtimeContext); service.refresh(runtimeContext); } @Override public void removedService(ServiceReference reference, YangStoreService service) { + if(service == null) { + return; + } + LOG.debug("Got removedService(SchemaContextProvider) event"); alreadyStarted.set(false); configRegistryLookup.interrupt(); diff --git a/opendaylight/config/config-manager-facade-xml/src/main/java/org/opendaylight/controller/config/facade/xml/osgi/YangStoreService.java b/opendaylight/config/config-manager-facade-xml/src/main/java/org/opendaylight/controller/config/facade/xml/osgi/YangStoreService.java index b6b1869937..ebdfe550da 100644 --- a/opendaylight/config/config-manager-facade-xml/src/main/java/org/opendaylight/controller/config/facade/xml/osgi/YangStoreService.java +++ b/opendaylight/config/config-manager-facade-xml/src/main/java/org/opendaylight/controller/config/facade/xml/osgi/YangStoreService.java @@ -8,6 +8,8 @@ package org.opendaylight.controller.config.facade.xml.osgi; +import com.google.common.base.Function; +import com.google.common.collect.Collections2; import com.google.common.collect.Sets; import java.lang.ref.SoftReference; import java.util.Collections; @@ -18,13 +20,18 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicReference; +import javax.annotation.Nullable; +import org.opendaylight.controller.config.util.capability.Capability; import org.opendaylight.controller.config.util.capability.ModuleListener; +import org.opendaylight.controller.config.util.capability.YangModuleCapability; import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier; import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider; +import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; +import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -59,6 +66,7 @@ public class YangStoreService implements YangStoreContext { new AtomicReference<>(new SoftReference(null)); private final SchemaContextProvider schemaContextProvider; + private final SchemaSourceProvider sourceProvider; private final ExecutorService notificationExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() { @Override @@ -69,8 +77,10 @@ public class YangStoreService implements YangStoreContext { private final Set listeners = Collections.synchronizedSet(new HashSet()); - public YangStoreService(final SchemaContextProvider schemaContextProvider) { + public YangStoreService(final SchemaContextProvider schemaContextProvider, + final SchemaSourceProvider sourceProvider) { this.schemaContextProvider = schemaContextProvider; + this.sourceProvider = sourceProvider; } private synchronized YangStoreContext getYangStoreSnapshot() { @@ -79,7 +89,8 @@ public class YangStoreService implements YangStoreContext { while (ret == null) { // We need to be compute a new value - ret = new YangStoreSnapshot(schemaContextProvider.getSchemaContext(), refBindingContext.get().get()); + // TODO sourceProvider is not a snapshot + ret = new YangStoreSnapshot(schemaContextProvider.getSchemaContext(), refBindingContext.get().get(), sourceProvider); if (!ref.compareAndSet(r, new SoftReference<>(ret))) { LOG.debug("Concurrent refresh detected, recomputing snapshot"); @@ -135,7 +146,7 @@ public class YangStoreService implements YangStoreContext { } this.listeners.add(listener); - listener.onCapabilitiesChanged(context.getModules(), Collections.emptySet()); + listener.onCapabilitiesChanged(toCapabilities(context.getModules(), context), Collections.emptySet()); return new AutoCloseable() { @Override @@ -145,6 +156,14 @@ public class YangStoreService implements YangStoreContext { }; } + private Set toCapabilities(final Set modules, final YangStoreContext current) { + return Sets.newHashSet(Collections2.transform(modules, new Function() { + @Nullable @Override public Capability apply(final Module input) { + return new YangModuleCapability(input, current.getModuleSource(input)); + } + })); + } + private final class CapabilityChangeNotifier implements Runnable { private final YangStoreSnapshot previous; @@ -162,9 +181,10 @@ public class YangStoreService implements YangStoreContext { final Set added = Sets.difference(current.getModules(), previous.getModules()); for (final ModuleListener listener : listeners) { - listener.onCapabilitiesChanged(added, removed); + listener.onCapabilitiesChanged(toCapabilities(added, current), toCapabilities(removed, current)); } } } + } } diff --git a/opendaylight/config/config-manager-facade-xml/src/main/java/org/opendaylight/controller/config/facade/xml/osgi/YangStoreSnapshot.java b/opendaylight/config/config-manager-facade-xml/src/main/java/org/opendaylight/controller/config/facade/xml/osgi/YangStoreSnapshot.java index a5c7ca8cc6..8babb867b2 100644 --- a/opendaylight/config/config-manager-facade-xml/src/main/java/org/opendaylight/controller/config/facade/xml/osgi/YangStoreSnapshot.java +++ b/opendaylight/config/config-manager-facade-xml/src/main/java/org/opendaylight/controller/config/facade/xml/osgi/YangStoreSnapshot.java @@ -8,18 +8,18 @@ package org.opendaylight.controller.config.facade.xml.osgi; -import com.google.common.base.Optional; +import com.google.common.base.Charsets; import com.google.common.base.Preconditions; -import com.google.common.base.Predicate; import com.google.common.collect.BiMap; -import com.google.common.collect.Iterables; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import com.google.common.io.ByteStreams; +import com.google.common.util.concurrent.CheckedFuture; +import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; -import java.util.NoSuchElementException; import java.util.Set; import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; import org.opendaylight.controller.config.yangjmxgenerator.PackageTranslator; @@ -31,7 +31,10 @@ import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; -import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleIdentifierImpl; +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.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,9 +50,13 @@ final class YangStoreSnapshot implements YangStoreContext, EnumResolver { private final SchemaContext schemaContext; private final BindingRuntimeContext bindingContextProvider; + private final SchemaSourceProvider sourceProvider; - public YangStoreSnapshot(final SchemaContext resolveSchemaContext, final BindingRuntimeContext bindingContextProvider) { + public YangStoreSnapshot(final SchemaContext resolveSchemaContext, + final BindingRuntimeContext bindingContextProvider, + final SchemaSourceProvider sourceProvider) { this.bindingContextProvider = bindingContextProvider; + this.sourceProvider = sourceProvider; LOG.trace("Resolved modules:{}", resolveSchemaContext.getModules()); this.schemaContext = resolveSchemaContext; // JMX generator @@ -119,21 +126,18 @@ final class YangStoreSnapshot implements YangStoreContext, EnumResolver { @Override public String getModuleSource(final org.opendaylight.yangtools.yang.model.api.ModuleIdentifier moduleIdentifier) { - final Optional moduleSource = schemaContext.getModuleSource(moduleIdentifier); - if(moduleSource.isPresent()) { - return moduleSource.get(); - } else { - try { - return Iterables.find(getModules(), new Predicate() { - @Override - public boolean apply(final Module input) { - final ModuleIdentifierImpl id = new ModuleIdentifierImpl(input.getName(), Optional.fromNullable(input.getNamespace()), Optional.fromNullable(input.getRevision())); - return id.equals(moduleIdentifier); - } - }).getSource(); - } catch (final NoSuchElementException e) { - throw new IllegalArgumentException("Source for yang module " + moduleIdentifier + " not found", e); - } + final CheckedFuture source = sourceProvider.getSource( + moduleIdentifier.getRevision() == null ? + new SourceIdentifier(moduleIdentifier.getName()) : + new SourceIdentifier(moduleIdentifier.getName(), + QName.formattedRevision(moduleIdentifier.getRevision()))); + + try { + final YangTextSchemaSource yangTextSchemaSource = source.checkedGet(); + return new String(ByteStreams.toByteArray(yangTextSchemaSource.openStream()), Charsets.UTF_8); + } catch (SchemaSourceException | IOException e) { + LOG.warn("Unable to provide source for {}", moduleIdentifier, e); + throw new IllegalArgumentException("Unable to provide source for " + moduleIdentifier, e); } } diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ConfigManagerActivator.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ConfigManagerActivator.java index 128399563a..7966b8983a 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ConfigManagerActivator.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ConfigManagerActivator.java @@ -47,7 +47,7 @@ public class ConfigManagerActivator implements BundleActivator { BindingContextProvider bindingContextProvider = new BindingContextProvider(); RefreshingSCPModuleInfoRegistry moduleInfoRegistryWrapper = new RefreshingSCPModuleInfoRegistry( - moduleInfoBackedContext, moduleInfoBackedContext, moduleInfoBackedContext, bindingContextProvider, context); + moduleInfoBackedContext, moduleInfoBackedContext, moduleInfoBackedContext, moduleInfoBackedContext, bindingContextProvider, context); ModuleInfoBundleTracker moduleInfoBundleTracker = new ModuleInfoBundleTracker(moduleInfoRegistryWrapper); diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/RefreshingSCPModuleInfoRegistry.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/RefreshingSCPModuleInfoRegistry.java index b62e60382c..8bc1a58ccc 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/RefreshingSCPModuleInfoRegistry.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/RefreshingSCPModuleInfoRegistry.java @@ -15,6 +15,8 @@ import org.opendaylight.yangtools.sal.binding.generator.api.ModuleInfoRegistry; import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext; import org.opendaylight.yangtools.yang.binding.YangModuleInfo; import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider; +import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; +import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; @@ -25,24 +27,31 @@ public class RefreshingSCPModuleInfoRegistry implements ModuleInfoRegistry, Auto private final ModuleInfoRegistry moduleInfoRegistry; private final SchemaContextProvider schemaContextProvider; + private final SchemaSourceProvider sourceProvider; private final BindingContextProvider bindingContextProvider; private final ClassLoadingStrategy classLoadingStrat; private final ServiceRegistration osgiReg; public RefreshingSCPModuleInfoRegistry(final ModuleInfoRegistry moduleInfoRegistry, - final SchemaContextProvider schemaContextProvider, final ClassLoadingStrategy classLoadingStrat, final BindingContextProvider bindingContextProvider, final BundleContext bundleContext) { + final SchemaContextProvider schemaContextProvider, final ClassLoadingStrategy classLoadingStrat, + final SchemaSourceProvider sourceProvider, final BindingContextProvider bindingContextProvider, + final BundleContext bundleContext) { + this.moduleInfoRegistry = moduleInfoRegistry; this.schemaContextProvider = schemaContextProvider; this.classLoadingStrat = classLoadingStrat; + this.sourceProvider = sourceProvider; this.bindingContextProvider = bindingContextProvider; - osgiReg = bundleContext.registerService(SchemaContextProvider.class, schemaContextProvider, new Hashtable()); + osgiReg = bundleContext + .registerService(SchemaContextProvider.class, schemaContextProvider, new Hashtable()); } private void updateService() { bindingContextProvider.update(classLoadingStrat, schemaContextProvider); osgiReg.setProperties(new Hashtable() {{ put(BindingRuntimeContext.class.getName(), bindingContextProvider.getBindingContext()); + put(SchemaSourceProvider.class.getName(), sourceProvider); } }); // send modifiedService event } diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/osgi/RefreshingSCPModuleInfoRegistryTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/osgi/RefreshingSCPModuleInfoRegistryTest.java index 00214f6ba7..8613eeba6b 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/osgi/RefreshingSCPModuleInfoRegistryTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/osgi/RefreshingSCPModuleInfoRegistryTest.java @@ -15,8 +15,11 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import java.util.Dictionary; +import org.junit.Before; import org.junit.Test; +import org.mockito.Mock; import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; import org.opendaylight.controller.config.manager.impl.osgi.mapping.BindingContextProvider; import org.opendaylight.controller.config.manager.impl.osgi.mapping.RefreshingSCPModuleInfoRegistry; import org.opendaylight.yangtools.concepts.ObjectRegistration; @@ -25,10 +28,20 @@ import org.opendaylight.yangtools.sal.binding.generator.api.ModuleInfoRegistry; import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext; import org.opendaylight.yangtools.yang.binding.YangModuleInfo; import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider; +import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; +import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; public class RefreshingSCPModuleInfoRegistryTest { + + @Mock + SchemaSourceProvider sourceProvider; + + @Before public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + } + @Test public void testConstructor() throws Exception { ModuleInfoRegistry reg = mock(ModuleInfoRegistry.class); @@ -47,7 +60,7 @@ public class RefreshingSCPModuleInfoRegistryTest { doReturn("B-runtime-context").when(bindingRuntimeContext).toString(); doReturn(bindingRuntimeContext).when(codecRegistryProvider).getBindingContext(); - RefreshingSCPModuleInfoRegistry scpreg = new RefreshingSCPModuleInfoRegistry(reg, prov, classLoadingStrat, codecRegistryProvider, ctxt); + RefreshingSCPModuleInfoRegistry scpreg = new RefreshingSCPModuleInfoRegistry(reg, prov, classLoadingStrat, sourceProvider, codecRegistryProvider, ctxt); doNothing().when(servReg).unregister(); diff --git a/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/capability/ModuleListener.java b/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/capability/ModuleListener.java index eebbe7f01b..f2624c06b1 100644 --- a/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/capability/ModuleListener.java +++ b/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/capability/ModuleListener.java @@ -9,9 +9,8 @@ package org.opendaylight.controller.config.util.capability; import java.util.Set; -import org.opendaylight.yangtools.yang.model.api.Module; public interface ModuleListener { - void onCapabilitiesChanged(Set added, Set removed); + void onCapabilitiesChanged(Set added, Set removed); }