Move GlobalBundleScanningSchemaServiceImpl to its own bundle 58/40458/4
authorTom Pantelis <tpanteli@brocade.com>
Thu, 16 Jun 2016 01:04:02 +0000 (21:04 -0400)
committerTom Pantelis <tpanteli@brocade.com>
Mon, 4 Jul 2016 19:38:38 +0000 (19:38 +0000)
Moved the GlobalBundleScanningSchemaServiceImpl and the associated
BundleActivator, SchemaServiceActivator, from sal-dom-broker to a new
bundle sal-schema-service.

A couple reasons for this. One is to break the circular service imports
between sal-dom-broker and sal-distributed-datastore, where
sal-distributed-datastore imports the SchemaService from sal-dom-broker
and sal-dom-broker imports the DOMDataBroker from
sal-distributed-datastore. The result of this was that if the
sal-dom-broker blueprint container was restarted, it would also cause
the sal-distributed-datastore container to restart, which isn't
necessary/desirable.

The other reason is that apps can register a SchemaContextListener as an
OSGi service which is picked up by the
GlobalBundleScanningSchemaServiceImpl. In terms of service usage this
makes sal-dom-broker a dependency of the app bundle so if the app
container restarts, it also restarts sal-dom-broker,
sal-distributed-datastore etc which isn't desirable.

So moving the GlobalBundleScanningSchemaServiceImpl to its own bundle
alleviates both issues.

Change-Id: I75d1009f6bfc1d80a19a61050703a1ca7e049575
Signed-off-by: Tom Pantelis <tpanteli@brocade.com>
12 files changed:
features/mdsal/pom.xml
features/mdsal/src/main/features/features.xml
opendaylight/md-sal/mdsal-artifacts/pom.xml
opendaylight/md-sal/pom.xml
opendaylight/md-sal/sal-distributed-datastore/src/main/resources/org/opendaylight/blueprint/clustered-datastore.xml
opendaylight/md-sal/sal-dom-broker-config/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/DomBrokerImplModule.java
opendaylight/md-sal/sal-dom-broker-config/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/SchemaServiceImplSingletonModule.java
opendaylight/md-sal/sal-dom-broker/pom.xml
opendaylight/md-sal/sal-dom-broker/src/main/resources/org/opendaylight/blueprint/dom-broker.xml
opendaylight/md-sal/sal-schema-service/pom.xml [new file with mode: 0644]
opendaylight/md-sal/sal-schema-service/src/main/java/org/opendaylight/controller/sal/schema/service/impl/GlobalBundleScanningSchemaServiceImpl.java [moved from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/GlobalBundleScanningSchemaServiceImpl.java with 92% similarity]
opendaylight/md-sal/sal-schema-service/src/main/java/org/opendaylight/controller/sal/schema/service/impl/SchemaServiceActivator.java [moved from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/SchemaServiceActivator.java with 72% similarity]

index fa956000a4f8bddf6552c47244c7011cdd3b9de2..c342dd8e28282d0bcb65b9d8ebce946a70960b50 100644 (file)
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal-dom-broker-config</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-schema-service</artifactId>
+    </dependency>
 
     <!-- message-bus -->
     <dependency>
index 94df44bc13204c403735756e58932609909ccb9e..d76c601519ada9203014ad7cb1e2c9b04622f5ee 100644 (file)
@@ -42,7 +42,8 @@
         <!-- FIXME: Bug 4202: Add MD-SAL provided odl-mdsal-dom-broker -->
         <bundle>mvn:org.opendaylight.controller/sal-core-api/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.controller/sal-core-spi/{{VERSION}}</bundle>
-        <bundle start-level="70">mvn:org.opendaylight.controller/sal-broker-impl/{{VERSION}}</bundle>
+        <bundle start-level="70">mvn:org.opendaylight.controller/sal-schema-service/{{VERSION}}</bundle>
+        <bundle>mvn:org.opendaylight.controller/sal-broker-impl/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.controller/sal-binding-api/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.controller/sal-binding-broker-impl/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.controller/sal-binding-util/{{VERSION}}</bundle>
index 5a3b1bf9b0a9c652cffb5c978cb73090d8d63e04..70a13c9aa1d37938f1796b34a74c65fcfb9dc53d 100644 (file)
                 <artifactId>md-sal-config</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>sal-schema-service</artifactId>
+                <version>${project.version}</version>
+            </dependency>
 
             <!-- Test support -->
             <dependency>
index 489ec7bdc3997d636289f288b3010892cc432476..dfdbac05a7aad8b38f58f7bdd20ade4573b96853 100644 (file)
@@ -25,6 +25,7 @@
     <module>sal-dom-api</module>
     <module>sal-dom-broker</module>
     <module>sal-dom-spi</module>
+    <module>sal-schema-service</module>
 
     <!-- Binding Aware -->
     <module>sal-binding-api</module>
index 4fa0af1db84e9f48579a154bab63983e89c43c37..92f6c7a794eeb0b94623ebe8a6573ad49078f0ca 100644 (file)
@@ -10,7 +10,7 @@
     </cm:default-properties>
   </cm:property-placeholder>
 
-  <reference id="schemaService" interface="org.opendaylight.controller.sal.core.api.model.SchemaService" />
+  <odl:static-reference id="schemaService" interface="org.opendaylight.controller.sal.core.api.model.SchemaService" />
 
   <!-- ActorSystemProvider -->
 
index e3d71fb9aaae78ad0f98f9ed1c51bc58dc63fd31..86dcf809c4c87807275650b20b9e13a1026cb966 100644 (file)
@@ -22,7 +22,6 @@ import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
 import org.opendaylight.controller.sal.core.api.BrokerService;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.controller.sal.dom.broker.BrokerImpl;
-import org.opendaylight.controller.sal.dom.broker.GlobalBundleScanningSchemaServiceImpl;
 import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -72,6 +71,9 @@ public final class DomBrokerImplModule extends org.opendaylight.controller.confi
         DOMMountPointService mountService = newTracker(DOMMountPointService.class, closeables).
                 waitForService(WaitingServiceTracker.FIVE_MINUTES);
 
+        SchemaService globalSchemaService = newTracker(SchemaService.class, closeables).
+                waitForService(WaitingServiceTracker.FIVE_MINUTES);
+
         final DOMDataBroker dataBroker = getAsyncDataBrokerDependency();
 
         final ClassToInstanceMap<BrokerService> services = MutableClassToInstanceMap.create();
@@ -79,7 +81,7 @@ public final class DomBrokerImplModule extends org.opendaylight.controller.confi
         services.putInstance(DOMNotificationService.class, domNotificationService);
         services.putInstance(DOMNotificationPublishService.class, domNotificationPublishService);
 
-        final SchemaService schemaService = getSchemaServiceImpl();
+        final SchemaService schemaService = getSchemaServiceImpl(globalSchemaService);
         services.putInstance(SchemaService.class, schemaService);
 
         services.putInstance(DOMDataBroker.class, dataBroker);
@@ -112,12 +114,12 @@ public final class DomBrokerImplModule extends org.opendaylight.controller.confi
         return tracker;
     }
 
-    private SchemaService getSchemaServiceImpl() {
+    private SchemaService getSchemaServiceImpl(SchemaService globalSchemaService) {
         final SchemaService schemaService;
         if(getRootSchemaService() != null) {
             schemaService = getRootSchemaServiceDependency();
         } else {
-            schemaService = GlobalBundleScanningSchemaServiceImpl.getInstance();
+            schemaService = globalSchemaService;
         }
         return schemaService;
     }
index fb4043053beb72443db5a056b52e736d58c8727e..93942957df705cc942c73ab3903d7d437c791e33 100644 (file)
@@ -8,10 +8,9 @@
 package org.opendaylight.controller.config.yang.md.sal.dom.impl;
 
 import com.google.common.util.concurrent.CheckedFuture;
+import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.controller.sal.core.api.model.YangTextSourceProvider;
-import org.opendaylight.controller.sal.dom.broker.GlobalBundleScanningSchemaServiceImpl;
-import org.opendaylight.yangtools.concepts.Delegator;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
@@ -64,57 +63,54 @@ org.opendaylight.controller.config.yang.md.sal.dom.impl.AbstractSchemaServiceImp
     }
 
     @Override
-    public java.lang.AutoCloseable createInstance() {
-        return new GlobalSchemaServiceProxy(GlobalBundleScanningSchemaServiceImpl.getInstance());
-    }
-
-    private static class GlobalSchemaServiceProxy implements AutoCloseable, SchemaService, YangTextSourceProvider,
-            Delegator<SchemaService> {
-        private final GlobalBundleScanningSchemaServiceImpl delegate;
-
-        public GlobalSchemaServiceProxy(GlobalBundleScanningSchemaServiceImpl service) {
-            this.delegate = service;
-        }
-
-        @Override
-        public void close() {
-            // Intentional noop as the life-cycle is controlled via blueprint.
-        }
-
-        @Override
-        public void addModule(final Module arg0) {
-            delegate.addModule(arg0);
-        }
-
-        @Override
-        public SchemaContext getGlobalContext() {
-            return delegate.getGlobalContext();
+    public AutoCloseable createInstance() {
+        final WaitingServiceTracker<SchemaService> schemaServiceTracker =
+                WaitingServiceTracker.create(SchemaService.class, bundleContext);
+        final SchemaService schemaService = schemaServiceTracker.waitForService(WaitingServiceTracker.FIVE_MINUTES);
+
+        final WaitingServiceTracker<YangTextSourceProvider> sourceProviderTracker =
+                WaitingServiceTracker.create(YangTextSourceProvider.class, bundleContext);
+        final YangTextSourceProvider sourceProvider = sourceProviderTracker.waitForService(WaitingServiceTracker.FIVE_MINUTES);
+
+        class GlobalSchemaServiceProxy implements AutoCloseable, SchemaService, YangTextSourceProvider {
+            @Override
+            public void close() {
+                schemaServiceTracker.close();
+                sourceProviderTracker.close();
+            }
+
+            @Override
+            public void addModule(final Module arg0) {
+                schemaService.addModule(arg0);
+            }
+
+            @Override
+            public SchemaContext getGlobalContext() {
+                return schemaService.getGlobalContext();
+            }
+
+            @Override
+            public SchemaContext getSessionContext() {
+                return schemaService.getSessionContext();
+            }
+
+            @Override
+            public ListenerRegistration<SchemaContextListener> registerSchemaContextListener(final SchemaContextListener arg0) {
+                return schemaService.registerSchemaContextListener(arg0);
+            }
+
+            @Override
+            public void removeModule(final Module arg0) {
+                schemaService.removeModule(arg0);
+            }
+
+            @Override
+            public CheckedFuture<? extends YangTextSchemaSource, SchemaSourceException> getSource(
+                    SourceIdentifier sourceIdentifier) {
+                return sourceProvider.getSource(sourceIdentifier);
+            }
         }
 
-        @Override
-        public SchemaContext getSessionContext() {
-            return delegate.getSessionContext();
-        }
-
-        @Override
-        public ListenerRegistration<SchemaContextListener> registerSchemaContextListener(final SchemaContextListener arg0) {
-            return delegate.registerSchemaContextListener(arg0);
-        }
-
-        @Override
-        public void removeModule(final Module arg0) {
-            delegate.removeModule(arg0);
-        }
-
-        @Override
-        public SchemaService getDelegate() {
-            return delegate;
-        }
-
-        @Override
-        public CheckedFuture<? extends YangTextSchemaSource, SchemaSourceException> getSource(
-                SourceIdentifier sourceIdentifier) {
-            return delegate.getSource(sourceIdentifier);
-        }
+        return new GlobalSchemaServiceProxy();
     }
 }
index f806931b1291d6c219d5aa76e3fc488f01fe20a3..fd174633891c2fe949c23db6511b210fd305d7ae 100644 (file)
@@ -82,7 +82,6 @@
         <configuration>
           <instructions>
             <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
-            <Bundle-Activator>org.opendaylight.controller.sal.dom.broker.osgi.SchemaServiceActivator</Bundle-Activator>
             <Export-Package>
                             <!--  Legacy code -->
                             org.opendaylight.controller.sal.dom.broker,
index b7d4d5dd22639766bf26be7b94bc200a40b51338..3cefd47b6c1f5008e19e3b379e70478eb337bd52 100644 (file)
 
   <!-- Schema Service -->
 
-  <bean id="schemaServiceImpl" class="org.opendaylight.controller.sal.dom.broker.GlobalBundleScanningSchemaServiceImpl"
-          factory-method="getInstance" />
-
-  <service ref="schemaServiceImpl">
-    <interfaces>
-      <value>org.opendaylight.controller.sal.core.api.model.SchemaService</value>
-      <value>org.opendaylight.controller.sal.core.api.model.YangTextSourceProvider</value>
-    </interfaces>
-  </service>
+  <odl:static-reference id="schemaService" interface="org.opendaylight.controller.sal.core.api.model.SchemaService"/>
 
   <!-- DOM Notification Service -->
 
@@ -46,7 +38,7 @@
 
   <bean id="domRpcRouter" class="org.opendaylight.controller.md.sal.dom.broker.impl.DOMRpcRouter"
           factory-method="newInstance">
-    <argument ref="schemaServiceImpl"/>
+    <argument ref="schemaService"/>
   </bean>
 
   <service ref="domRpcRouter" odl:type="default">
diff --git a/opendaylight/md-sal/sal-schema-service/pom.xml b/opendaylight/md-sal/sal-schema-service/pom.xml
new file mode 100644 (file)
index 0000000..18fe2a7
--- /dev/null
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>sal-parent</artifactId>
+    <version>1.4.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>sal-schema-service</artifactId>
+  <packaging>bundle</packaging>
+
+  <dependencies>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-core-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-parser-impl</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+            <Bundle-Activator>org.opendaylight.controller.sal.schema.service.impl.SchemaServiceActivator</Bundle-Activator>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
@@ -5,10 +5,9 @@
  * 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;
+package org.opendaylight.controller.sal.schema.service.impl;
 
 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;
@@ -19,7 +18,6 @@ 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;
@@ -48,8 +46,6 @@ 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");
@@ -68,25 +64,10 @@ public class GlobalBundleScanningSchemaServiceImpl implements SchemaContextProvi
 
     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;
     }
@@ -5,30 +5,31 @@
  * 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.osgi;
+package org.opendaylight.controller.sal.schema.service.impl;
 
 import java.util.Hashtable;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
-import org.opendaylight.controller.sal.dom.broker.GlobalBundleScanningSchemaServiceImpl;
+import org.opendaylight.controller.sal.core.api.model.YangTextSourceProvider;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
 
 public class SchemaServiceActivator implements BundleActivator {
-
-
     private ServiceRegistration<SchemaService> schemaServiceReg;
+    private ServiceRegistration<YangTextSourceProvider> schemaSourceReg;
     private GlobalBundleScanningSchemaServiceImpl schemaService;
 
     @Override
     public void start(final BundleContext context) {
         schemaService = GlobalBundleScanningSchemaServiceImpl.createInstance(context);
         schemaServiceReg = context.registerService(SchemaService.class, schemaService, new Hashtable<String,String>());
+        schemaSourceReg = context.registerService(YangTextSourceProvider.class, schemaService, new Hashtable<String,String>());
     }
 
     @Override
-    public void stop(final BundleContext context) throws Exception {
+    public void stop(final BundleContext context) {
         schemaServiceReg.unregister();
+        schemaSourceReg.unregister();
         schemaService.close();
     }
 }