X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-schema-service%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Fschema%2Fservice%2Fimpl%2FGlobalBundleScanningSchemaServiceImpl.java;h=3e55d796c1a0be867fa05f522a78373fe956a614;hp=19232db486755886b0584c0c972e79bbf7aafde6;hb=bfbc7893038987db21ed3ec5970a6de1c2a655de;hpb=6ed4207635b1ac2f4bb9611e82130002602f0d4d diff --git a/opendaylight/md-sal/sal-schema-service/src/main/java/org/opendaylight/controller/sal/schema/service/impl/GlobalBundleScanningSchemaServiceImpl.java b/opendaylight/md-sal/sal-schema-service/src/main/java/org/opendaylight/controller/sal/schema/service/impl/GlobalBundleScanningSchemaServiceImpl.java index 19232db486..3e55d796c1 100644 --- a/opendaylight/md-sal/sal-schema-service/src/main/java/org/opendaylight/controller/sal/schema/service/impl/GlobalBundleScanningSchemaServiceImpl.java +++ b/opendaylight/md-sal/sal-schema-service/src/main/java/org/opendaylight/controller/sal/schema/service/impl/GlobalBundleScanningSchemaServiceImpl.java @@ -7,104 +7,55 @@ */ package org.opendaylight.controller.sal.schema.service.impl; -import static com.google.common.base.Preconditions.checkState; -import com.google.common.base.Optional; import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; import com.google.common.util.concurrent.CheckedFuture; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; -import java.util.List; +import com.google.common.util.concurrent.Futures; +import java.util.HashSet; +import java.util.Set; import javax.annotation.concurrent.GuardedBy; import org.opendaylight.controller.sal.core.api.model.SchemaService; import org.opendaylight.controller.sal.core.api.model.YangTextSourceProvider; +import org.opendaylight.mdsal.dom.api.DOMSchemaService; +import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider; +import org.opendaylight.yangtools.concepts.AbstractListenerRegistration; import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.concepts.Registration; -import org.opendaylight.yangtools.util.ListenerRegistry; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaContextListener; import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider; +import org.opendaylight.yangtools.yang.model.repo.api.MissingSchemaSourceException; 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.parser.repo.YangTextSchemaContextResolver; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.BundleEvent; -import org.osgi.framework.ServiceReference; -import org.osgi.util.tracker.BundleTracker; -import org.osgi.util.tracker.BundleTrackerCustomizer; -import org.osgi.util.tracker.ServiceTracker; -import org.osgi.util.tracker.ServiceTrackerCustomizer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -public class GlobalBundleScanningSchemaServiceImpl implements SchemaContextProvider, SchemaService, ServiceTrackerCustomizer, YangTextSourceProvider, AutoCloseable { - private static final Logger LOG = LoggerFactory.getLogger(GlobalBundleScanningSchemaServiceImpl.class); +@Deprecated +public final class GlobalBundleScanningSchemaServiceImpl implements SchemaContextProvider, SchemaService, + YangTextSourceProvider, AutoCloseable { - @GuardedBy(value = "lock") - private final ListenerRegistry listeners = new ListenerRegistry<>(); - private final YangTextSchemaContextResolver contextResolver = YangTextSchemaContextResolver.create("global-bundle"); - private final BundleScanner scanner = new BundleScanner(); - private final BundleContext context; - - private ServiceTracker listenerTracker; - private BundleTracker> bundleTracker; - private boolean starting = true; - private volatile boolean stopping; + @GuardedBy("lock") + private final Set> listeners = new HashSet<>(); private final Object lock = new Object(); + private final DOMSchemaService schemaService; + private final DOMYangTextSourceProvider yangProvider; - private GlobalBundleScanningSchemaServiceImpl(final BundleContext context) { - this.context = Preconditions.checkNotNull(context); - } - - public static GlobalBundleScanningSchemaServiceImpl createInstance(final BundleContext ctx) { - GlobalBundleScanningSchemaServiceImpl instance = new GlobalBundleScanningSchemaServiceImpl(ctx); - instance.start(); - return instance; + private GlobalBundleScanningSchemaServiceImpl(final DOMSchemaService schemaService) { + this.schemaService = Preconditions.checkNotNull(schemaService); + this.yangProvider = (DOMYangTextSourceProvider) schemaService.getSupportedExtensions() + .get(DOMYangTextSourceProvider.class); } - public BundleContext getContext() { - return context; - } - - private void start() { - checkState(context != null); - LOG.debug("start() starting"); - - listenerTracker = new ServiceTracker<>(context, SchemaContextListener.class, GlobalBundleScanningSchemaServiceImpl.this); - bundleTracker = new BundleTracker<>(context, Bundle.RESOLVED | Bundle.STARTING | - Bundle.STOPPING | Bundle.ACTIVE, scanner); - - synchronized(lock) { - bundleTracker.open(); - - LOG.debug("BundleTracker.open() complete"); - - boolean hasExistingListeners = Iterables.size(listeners.getListeners()) > 0; - if(hasExistingListeners) { - tryToUpdateSchemaContext(); - } - } - - listenerTracker.open(); - starting = false; - - LOG.debug("start() complete"); + public static GlobalBundleScanningSchemaServiceImpl createInstance(final DOMSchemaService schemaService) { + return new GlobalBundleScanningSchemaServiceImpl(schemaService); } @Override public SchemaContext getSchemaContext() { - return getGlobalContext(); + return schemaService.getGlobalContext(); } @Override public SchemaContext getGlobalContext() { - return contextResolver.getSchemaContext().orNull(); + return schemaService.getGlobalContext(); } @Override @@ -123,158 +74,47 @@ public class GlobalBundleScanningSchemaServiceImpl implements SchemaContextProvi } @Override - public ListenerRegistration registerSchemaContextListener(final SchemaContextListener listener) { - synchronized(lock) { - Optional potentialCtx = contextResolver.getSchemaContext(); - if(potentialCtx.isPresent()) { - listener.onGlobalContextUpdated(potentialCtx.get()); - } - return listeners.register(listener); - } - } - - @Override - public void close() { - stopping = true; - if (bundleTracker != null) { - bundleTracker.close(); - } - if (listenerTracker != null) { - listenerTracker.close(); - } - - for (ListenerRegistration l : listeners.getListeners()) { - l.close(); - } - } - - @GuardedBy(value = "lock") - private void notifyListeners(final SchemaContext snapshot) { - Object[] services = listenerTracker.getServices(); - for (ListenerRegistration listener : listeners) { - try { - listener.getInstance().onGlobalContextUpdated(snapshot); - } catch (Exception e) { - LOG.error("Exception occured during invoking listener", e); - } - } - if (services != null) { - for (Object rawListener : services) { - final SchemaContextListener listener = (SchemaContextListener) rawListener; - try { - listener.onGlobalContextUpdated(snapshot); - } catch (Exception e) { - LOG.error("Exception occured during invoking listener {}", listener, e); + public ListenerRegistration registerSchemaContextListener( + final SchemaContextListener listener) { + synchronized (lock) { + final ListenerRegistration reg = schemaService.registerSchemaContextListener( + listener); + + final ListenerRegistration ret = + new AbstractListenerRegistration(listener) { + @Override + protected void removeRegistration() { + synchronized (lock) { + listeners.remove(this); + } + reg.close(); } - } - } - } - - @Override - public CheckedFuture getSource(final SourceIdentifier sourceIdentifier) { - return contextResolver.getSource(sourceIdentifier); - - } + }; - private class BundleScanner implements BundleTrackerCustomizer> { - @Override - public Iterable addingBundle(final Bundle bundle, final BundleEvent event) { - - if (bundle.getBundleId() == 0) { - return Collections.emptyList(); - } - - final Enumeration enumeration = bundle.findEntries("META-INF/yang", "*.yang", false); - if (enumeration == null) { - return Collections.emptyList(); - } - - final List urls = new ArrayList<>(); - while (enumeration.hasMoreElements()) { - final URL u = enumeration.nextElement(); - try { - urls.add(contextResolver.registerSource(u)); - LOG.debug("Registered {}", u); - } catch (Exception e) { - LOG.warn("Failed to register {}, ignoring it", e); - } - } - - if (!urls.isEmpty()) { - LOG.debug("Loaded {} new URLs from bundle {}, attempting to rebuild schema context", - urls.size(), bundle.getSymbolicName()); - tryToUpdateSchemaContext(); - } - - return ImmutableList.copyOf(urls); - } - - @Override - public void modifiedBundle(final Bundle bundle, final BundleEvent event, final Iterable object) { - } - - /** - * If removing YANG files makes yang store inconsistent, method - * {@link #getYangStoreSnapshot()} will throw exception. There is no - * rollback. - */ - - @Override - public void removedBundle(final Bundle bundle, final BundleEvent event, final Iterable urls) { - for (Registration url : urls) { - try { - url.close(); - } catch (Exception e) { - LOG.warn("Failed do unregister URL {}, proceeding", url, e); - } - } - - int numUrls = Iterables.size(urls); - if(numUrls > 0 ) { - if(LOG.isDebugEnabled()) { - LOG.debug("removedBundle: {}, state: {}, # urls: {}", bundle.getSymbolicName(), bundle.getState(), numUrls); - } - - tryToUpdateSchemaContext(); - } + listeners.add(ret); + return ret; } } @Override - public SchemaContextListener addingService(final ServiceReference reference) { - - SchemaContextListener listener = context.getService(reference); - SchemaContext _ctxContext = getGlobalContext(); - if (getContext() != null && _ctxContext != null) { - listener.onGlobalContextUpdated(_ctxContext); - } - return listener; - } - - public void tryToUpdateSchemaContext() { - if (starting || stopping) { - return; - } - - synchronized(lock) { - Optional schema = contextResolver.getSchemaContext(); - if(schema.isPresent()) { - if(LOG.isDebugEnabled()) { - LOG.debug("Got new SchemaContext: # of modules {}", schema.get().getAllModuleIdentifiers().size()); - } - - notifyListeners(schema.get()); + public void close() { + synchronized (lock) { + for (ListenerRegistration l : listeners) { + l.close(); } + listeners.clear(); } } + @SuppressWarnings("unchecked") @Override - public void modifiedService(final ServiceReference reference, final SchemaContextListener service) { - // NOOP - } + public CheckedFuture getSource( + final SourceIdentifier sourceIdentifier) { + if (yangProvider == null) { + return Futures.immediateFailedCheckedFuture(new MissingSchemaSourceException( + "Source provider is not available", sourceIdentifier)); + } - @Override - public void removedService(final ServiceReference reference, final SchemaContextListener service) { - context.ungetService(reference); + return (CheckedFuture) yangProvider.getSource(sourceIdentifier); } }