- 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 <mmarsale@cisco.com>
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;
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;
@Override
public YangStoreService addingService(ServiceReference<SchemaContextProvider> 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)) {
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<YangTextSchemaSource>) sourceProvider));
yangStoreServiceServiceRegistration = context.registerService(YangStoreService.class, yangStoreService, new Hashtable<String, Object>());
configRegistryLookup = new ConfigRegistryLookupThread(yangStoreService);
configRegistryLookup.start();
@Override
public void modifiedService(ServiceReference<SchemaContextProvider> 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<SchemaContextProvider> reference, YangStoreService service) {
+ if(service == null) {
+ return;
+ }
+
LOG.debug("Got removedService(SchemaContextProvider) event");
alreadyStarted.set(false);
configRegistryLookup.interrupt();
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;
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;
new AtomicReference<>(new SoftReference<BindingRuntimeContext>(null));
private final SchemaContextProvider schemaContextProvider;
+ private final SchemaSourceProvider<YangTextSchemaSource> sourceProvider;
private final ExecutorService notificationExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() {
@Override
private final Set<ModuleListener> listeners = Collections.synchronizedSet(new HashSet<ModuleListener>());
- public YangStoreService(final SchemaContextProvider schemaContextProvider) {
+ public YangStoreService(final SchemaContextProvider schemaContextProvider,
+ final SchemaSourceProvider<YangTextSchemaSource> sourceProvider) {
this.schemaContextProvider = schemaContextProvider;
+ this.sourceProvider = sourceProvider;
}
private synchronized YangStoreContext getYangStoreSnapshot() {
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");
}
this.listeners.add(listener);
- listener.onCapabilitiesChanged(context.getModules(), Collections.<Module>emptySet());
+ listener.onCapabilitiesChanged(toCapabilities(context.getModules(), context), Collections.<Capability>emptySet());
return new AutoCloseable() {
@Override
};
}
+ private Set<Capability> toCapabilities(final Set<Module> modules, final YangStoreContext current) {
+ return Sets.newHashSet(Collections2.transform(modules, new Function<Module, Capability>() {
+ @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;
final Set<Module> added = Sets.difference(current.getModules(), previous.getModules());
for (final ModuleListener listener : listeners) {
- listener.onCapabilitiesChanged(added, removed);
+ listener.onCapabilitiesChanged(toCapabilities(added, current), toCapabilities(removed, current));
}
}
}
+
}
}
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;
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;
private final SchemaContext schemaContext;
private final BindingRuntimeContext bindingContextProvider;
+ private final SchemaSourceProvider<YangTextSchemaSource> sourceProvider;
- public YangStoreSnapshot(final SchemaContext resolveSchemaContext, final BindingRuntimeContext bindingContextProvider) {
+ public YangStoreSnapshot(final SchemaContext resolveSchemaContext,
+ final BindingRuntimeContext bindingContextProvider,
+ final SchemaSourceProvider<YangTextSchemaSource> sourceProvider) {
this.bindingContextProvider = bindingContextProvider;
+ this.sourceProvider = sourceProvider;
LOG.trace("Resolved modules:{}", resolveSchemaContext.getModules());
this.schemaContext = resolveSchemaContext;
// JMX generator
@Override
public String getModuleSource(final org.opendaylight.yangtools.yang.model.api.ModuleIdentifier moduleIdentifier) {
- final Optional<String> moduleSource = schemaContext.getModuleSource(moduleIdentifier);
- if(moduleSource.isPresent()) {
- return moduleSource.get();
- } else {
- try {
- return Iterables.find(getModules(), new Predicate<Module>() {
- @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<? extends YangTextSchemaSource, SchemaSourceException> 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);
}
}
BindingContextProvider bindingContextProvider = new BindingContextProvider();
RefreshingSCPModuleInfoRegistry moduleInfoRegistryWrapper = new RefreshingSCPModuleInfoRegistry(
- moduleInfoBackedContext, moduleInfoBackedContext, moduleInfoBackedContext, bindingContextProvider, context);
+ moduleInfoBackedContext, moduleInfoBackedContext, moduleInfoBackedContext, moduleInfoBackedContext, bindingContextProvider, context);
ModuleInfoBundleTracker moduleInfoBundleTracker = new ModuleInfoBundleTracker(moduleInfoRegistryWrapper);
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;
private final ModuleInfoRegistry moduleInfoRegistry;
private final SchemaContextProvider schemaContextProvider;
+ private final SchemaSourceProvider<YangTextSchemaSource> sourceProvider;
private final BindingContextProvider bindingContextProvider;
private final ClassLoadingStrategy classLoadingStrat;
private final ServiceRegistration<SchemaContextProvider> 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<YangTextSchemaSource> 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<String, String>());
+ osgiReg = bundleContext
+ .registerService(SchemaContextProvider.class, schemaContextProvider, new Hashtable<String, String>());
}
private void updateService() {
bindingContextProvider.update(classLoadingStrat, schemaContextProvider);
osgiReg.setProperties(new Hashtable<String, Object>() {{
put(BindingRuntimeContext.class.getName(), bindingContextProvider.getBindingContext());
+ put(SchemaSourceProvider.class.getName(), sourceProvider);
}
}); // send modifiedService event
}
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;
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<YangTextSchemaSource> sourceProvider;
+
+ @Before public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ }
+
@Test
public void testConstructor() throws Exception {
ModuleInfoRegistry reg = mock(ModuleInfoRegistry.class);
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();
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<Module> added, Set<Module> removed);
+ void onCapabilitiesChanged(Set<Capability> added, Set<Capability> removed);
}