Wired ClusteredDataStore with Configuration Subsytem
[controller.git] / opendaylight / md-sal / sal-dom-broker / src / main / java / org / opendaylight / controller / sal / dom / broker / SchemaServiceImpl.java
index ba558c51fdd039990a8a7a7e8c5eda4629476c0b..a6c1c508aaa7327b7a008975dd50aa9c3b09ae9a 100644 (file)
@@ -13,6 +13,8 @@ import java.util.zip.Checksum;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 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.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
@@ -20,6 +22,7 @@ import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleEvent;
+import org.osgi.framework.ServiceReference;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
@@ -34,9 +37,13 @@ import com.google.common.collect.Collections2;
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Multimap;
 import com.google.common.collect.Sets;
+
 import static com.google.common.base.Preconditions.*;
 
-public class SchemaServiceImpl implements SchemaService, AutoCloseable {
+public class SchemaServiceImpl implements //
+        SchemaService, //
+        ServiceTrackerCustomizer<SchemaServiceListener, SchemaServiceListener>, //
+        AutoCloseable {
     private static final Logger logger = LoggerFactory.getLogger(SchemaServiceImpl.class);
 
     private ListenerRegistry<SchemaServiceListener> listeners;
@@ -54,6 +61,8 @@ public class SchemaServiceImpl implements SchemaService, AutoCloseable {
     private BundleTracker<Object> bundleTracker;
     private final YangStoreCache cache = new YangStoreCache();
 
+    private ServiceTracker<SchemaServiceListener, SchemaServiceListener> listenerTracker;
+
     public ListenerRegistry<SchemaServiceListener> getListeners() {
         return listeners;
     }
@@ -85,8 +94,10 @@ public class SchemaServiceImpl implements SchemaService, AutoCloseable {
             listeners = new ListenerRegistry<>();
         }
 
+        listenerTracker = new ServiceTracker<>(context, SchemaServiceListener.class, this);
         bundleTracker = new BundleTracker<Object>(context, BundleEvent.RESOLVED | BundleEvent.UNRESOLVED, scanner);
         bundleTracker.open();
+        listenerTracker.open();
     }
 
     public SchemaContext getGlobalContext() {
@@ -121,12 +132,11 @@ public class SchemaServiceImpl implements SchemaService, AutoCloseable {
         throw new UnsupportedOperationException();
     }
 
-    
     @Override
     public ListenerRegistration<SchemaServiceListener> registerSchemaServiceListener(SchemaServiceListener listener) {
         return listeners.register(listener);
     }
-    
+
     @Override
     public void close() throws Exception {
         bundleTracker.close();
@@ -136,7 +146,7 @@ public class SchemaServiceImpl implements SchemaService, AutoCloseable {
 
     private synchronized boolean tryToUpdateState(Collection<URL> changedURLs, Multimap<Bundle, URL> proposedNewState,
             boolean adding) {
-        Preconditions.checkArgument(changedURLs.size() > 0, "No change can occur when no URLs are changed");
+        Preconditions.checkArgument(!changedURLs.isEmpty(), "No change can occur when no URLs are changed");
 
         try {
             // consistent state
@@ -155,8 +165,8 @@ public class SchemaServiceImpl implements SchemaService, AutoCloseable {
         } catch (Exception e) {
             // inconsistent state
             logger.debug(
-                    "SchemaService is falling back on last consistent state containing {}, inconsistent yang files {}, reason {}",
-                    consistentBundlesToYangURLs, inconsistentBundlesToYangURLs, e.toString());
+                    "SchemaService is falling back on last consistent state containing {}, inconsistent yang files {}",
+                    consistentBundlesToYangURLs, inconsistentBundlesToYangURLs, e);
             return false;
         }
     }
@@ -185,11 +195,23 @@ public class SchemaServiceImpl implements SchemaService, AutoCloseable {
 
     private void updateCache(SchemaContext snapshot) {
         cache.cacheYangStore(consistentBundlesToYangURLs, snapshot);
+
+        Object[] services = listenerTracker.getServices();
+        if (services != null) {
+            for (Object rawListener : services) {
+                SchemaServiceListener listener = (SchemaServiceListener) rawListener;
+                try {
+                    listener.onGlobalContextUpdated(snapshot);
+                } catch (Exception e) {
+                    logger.error("Exception occured during invoking listener", e);
+                }
+            }
+        }
         for (ListenerRegistration<SchemaServiceListener> listener : listeners) {
             try {
                 listener.getInstance().onGlobalContextUpdated(snapshot);
             } catch (Exception e) {
-                logger.error("Exception occured during invoking listener",e);
+                logger.error("Exception occured during invoking listener", e);
             }
         }
     }
@@ -202,8 +224,9 @@ public class SchemaServiceImpl implements SchemaService, AutoCloseable {
             // system bundle might have config-api on classpath &&
             // config-api contains yang files =>
             // system bundle might contain yang files from that bundle
-            if (bundle.getBundleId() == 0)
+            if (bundle.getBundleId() == 0) {
                 return bundle;
+            }
 
             Enumeration<URL> enumeration = bundle.findEntries("META-INF/yang", "*.yang", false);
             if (enumeration != null && enumeration.hasMoreElements()) {
@@ -220,6 +243,7 @@ public class SchemaServiceImpl implements SchemaService, AutoCloseable {
                     proposedNewState.putAll(inconsistentBundlesToYangURLs);
                     proposedNewState.putAll(bundle, addedURLs);
                     boolean adding = true;
+
                     if (tryToUpdateState(addedURLs, proposedNewState, adding) == false) {
                         inconsistentBundlesToYangURLs.putAll(bundle, addedURLs);
                     }
@@ -276,6 +300,26 @@ public class SchemaServiceImpl implements SchemaService, AutoCloseable {
             this.cachedUrls = setFromMultimapValues(urls);
             this.cachedContextSnapshot = ctx;
         }
+    }
+
+    @Override
+    public SchemaServiceListener addingService(ServiceReference<SchemaServiceListener> reference) {
+
+        SchemaServiceListener listener = context.getService(reference);
+        SchemaContext _ctxContext = getGlobalContext();
+        if (getContext() != null) {
+            listener.onGlobalContextUpdated(_ctxContext);
+        }
+        return listener;
+    }
 
+    @Override
+    public void modifiedService(ServiceReference<SchemaServiceListener> reference, SchemaServiceListener service) {
+        // NOOP
+    }
+
+    @Override
+    public void removedService(ServiceReference<SchemaServiceListener> reference, SchemaServiceListener service) {
+        context.ungetService(reference);
     }
 }