Move GlobalBundleScanningSchemaServiceImpl to its own bundle
[controller.git] / opendaylight / md-sal / sal-dom-broker / src / main / java / org / opendaylight / controller / sal / dom / broker / GlobalBundleScanningSchemaServiceImpl.java
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/GlobalBundleScanningSchemaServiceImpl.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/GlobalBundleScanningSchemaServiceImpl.java
deleted file mode 100644 (file)
index 4ba62e4..0000000
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.dom.broker;
-
-import static com.google.common.base.Preconditions.checkState;
-import com.google.common.annotations.VisibleForTesting;
-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 java.util.concurrent.atomic.AtomicReference;
-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.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.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<SchemaContextListener, SchemaContextListener>, YangTextSourceProvider, AutoCloseable {
-    private static final Logger LOG = LoggerFactory.getLogger(GlobalBundleScanningSchemaServiceImpl.class);
-
-    private static AtomicReference<GlobalBundleScanningSchemaServiceImpl> globalInstance = new AtomicReference<>();
-
-    @GuardedBy(value = "lock")
-    private final ListenerRegistry<SchemaContextListener> listeners = new ListenerRegistry<>();
-    private final YangTextSchemaContextResolver contextResolver = YangTextSchemaContextResolver.create("global-bundle");
-    private final BundleScanner scanner = new BundleScanner();
-    private final BundleContext context;
-
-    private ServiceTracker<SchemaContextListener, SchemaContextListener> listenerTracker;
-    private BundleTracker<Iterable<Registration>> bundleTracker;
-    private boolean starting = true;
-    private volatile boolean stopping;
-    private final Object lock = new Object();
-
-    private GlobalBundleScanningSchemaServiceImpl(final BundleContext context) {
-        this.context = Preconditions.checkNotNull(context);
-    }
-
-    public static GlobalBundleScanningSchemaServiceImpl createInstance(final BundleContext ctx) {
-        GlobalBundleScanningSchemaServiceImpl instance = new GlobalBundleScanningSchemaServiceImpl(ctx);
-        Preconditions.checkState(globalInstance.compareAndSet(null, instance));
-        instance.start();
-        return instance;
-    }
-
-    public static GlobalBundleScanningSchemaServiceImpl getInstance() {
-        GlobalBundleScanningSchemaServiceImpl instance = globalInstance.get();
-        Preconditions.checkState(instance != null, "Global Instance was not instantiated");
-        return instance;
-    }
-
-    @VisibleForTesting
-    public static void destroyInstance() {
-        GlobalBundleScanningSchemaServiceImpl instance = globalInstance.getAndSet(null);
-        if(instance != null) {
-            instance.close();
-        }
-    }
-
-    public BundleContext getContext() {
-        return context;
-    }
-
-    public 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");
-    }
-
-    @Override
-    public SchemaContext getSchemaContext() {
-        return getGlobalContext();
-    }
-
-    @Override
-    public SchemaContext getGlobalContext() {
-        return contextResolver.getSchemaContext().orNull();
-    }
-
-    @Override
-    public void addModule(final Module module) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public SchemaContext getSessionContext() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void removeModule(final Module module) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ListenerRegistration<SchemaContextListener> registerSchemaContextListener(final SchemaContextListener listener) {
-        synchronized(lock) {
-            Optional<SchemaContext> 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<SchemaContextListener> l : listeners.getListeners()) {
-            l.close();
-        }
-    }
-
-    @GuardedBy(value = "lock")
-    private void notifyListeners(final SchemaContext snapshot) {
-        Object[] services = listenerTracker.getServices();
-        for (ListenerRegistration<SchemaContextListener> 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);
-                }
-            }
-        }
-    }
-
-    @Override
-    public CheckedFuture<YangTextSchemaSource, SchemaSourceException> getSource(final SourceIdentifier sourceIdentifier) {
-        return contextResolver.getSource(sourceIdentifier);
-
-    }
-
-    private class BundleScanner implements BundleTrackerCustomizer<Iterable<Registration>> {
-        @Override
-        public Iterable<Registration> addingBundle(final Bundle bundle, final BundleEvent event) {
-
-            if (bundle.getBundleId() == 0) {
-                return Collections.emptyList();
-            }
-
-            final Enumeration<URL> enumeration = bundle.findEntries("META-INF/yang", "*.yang", false);
-            if (enumeration == null) {
-                return Collections.emptyList();
-            }
-
-            final List<Registration> 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<Registration> 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<Registration> 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();
-            }
-        }
-    }
-
-    @Override
-    public SchemaContextListener addingService(final ServiceReference<SchemaContextListener> 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<SchemaContext> schema = contextResolver.getSchemaContext();
-            if(schema.isPresent()) {
-                if(LOG.isDebugEnabled()) {
-                    LOG.debug("Got new SchemaContext: # of modules {}", schema.get().getAllModuleIdentifiers().size());
-                }
-
-                notifyListeners(schema.get());
-            }
-        }
-    }
-
-    @Override
-    public void modifiedService(final ServiceReference<SchemaContextListener> reference, final SchemaContextListener service) {
-        // NOOP
-    }
-
-    @Override
-    public void removedService(final ServiceReference<SchemaContextListener> reference, final SchemaContextListener service) {
-        context.ungetService(reference);
-    }
-}