Add blueprint wiring for the helium OpenflowPluginProvider 84/38584/3
authorTom Pantelis <tpanteli@brocade.com>
Mon, 9 May 2016 13:31:58 +0000 (09:31 -0400)
committerAnil Vishnoi <vishnoianil@gmail.com>
Fri, 3 Jun 2016 08:00:38 +0000 (01:00 -0700)
Added a new bundle, openflowplugin-blueprint-config-he, containing the
blueprint XML that instantiates the SwitchConnectionProvider
and OpenflowPluginProvider instances for the helium plugin. It uses
the new SwitchConnectionProviderFactory interface added to the
openflowjava SPI.

This replaces the ConfigurableOpenFlowProviderModule which is now
deprecated but remains for backwards compatibility. The createInstance
method now obtains the OpenflowPluginProvider created via blueprint from
the OSGi registry and returns a proxy instance that delegates to the
actual instance but overrides the close method appropriately.

Patch 3 : Resolved conflict locally

Change-Id: I315444847f5a95d905a5e6adc602445c1101da5b
Signed-off-by: Tom Pantelis <tpanteli@brocade.com>
Signed-off-by: Anil Vishnoi <vishnoianil@gmail.com>
openflowplugin-blueprint-config-he/pom.xml [new file with mode: 0644]
openflowplugin-blueprint-config-he/src/main/resources/org/opendaylight/blueprint/openflowplugin-helium.xml [new file with mode: 0644]
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/OpenflowPluginProvider.java
openflowplugin/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/openflow/common/config/impl/rev140326/ConfigurableOpenFlowProviderModule.java
openflowplugin/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/openflow/common/config/impl/rev140326/ConfigurableOpenFlowProviderModuleFactory.java
openflowplugin/src/main/yang/openflow-plugin-cfg.yang
pom.xml

diff --git a/openflowplugin-blueprint-config-he/pom.xml b/openflowplugin-blueprint-config-he/pom.xml
new file mode 100644 (file)
index 0000000..0e1bf7f
--- /dev/null
@@ -0,0 +1,31 @@
+<?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.openflowplugin</groupId>
+      <artifactId>openflowplugin-parent</artifactId>
+      <version>0.3.0-SNAPSHOT</version>
+      <relativePath>../parent</relativePath>
+    </parent>
+
+    <artifactId>openflowplugin-blueprint-config-he</artifactId>
+    <description>Blueprint configuration for the Helium openflowplugin</description>
+    <packaging>bundle</packaging>
+
+    <build>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.felix</groupId>
+          <artifactId>maven-bundle-plugin</artifactId>
+          <extensions>true</extensions>
+          <configuration>
+            <instructions>
+              <DynamicImport-Package>*</DynamicImport-Package>
+           </instructions>
+         </configuration>
+       </plugin>
+     </plugins>
+   </build>
+</project>
diff --git a/openflowplugin-blueprint-config-he/src/main/resources/org/opendaylight/blueprint/openflowplugin-helium.xml b/openflowplugin-blueprint-config-he/src/main/resources/org/opendaylight/blueprint/openflowplugin-helium.xml
new file mode 100644 (file)
index 0000000..021e38f
--- /dev/null
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+           xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
+        odl:use-default-for-reference-types="true">
+
+  <reference id="switchConnProviderFactory"
+          interface="org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProviderFactory"/>
+
+  <!-- Create OF switch connection provider on port 6633 -->
+  <odl:clustered-app-config id="defaultSwitchConnConfig"
+      binding-class="org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.config.rev160506.SwitchConnectionConfig"
+      list-key-value="openflow-switch-connection-provider-default-impl">
+    <odl:default-config><![CDATA[
+      <switch-connection-config xmlns="urn:opendaylight:params:xml:ns:yang:openflow:switch:connection:config">
+        <instance-name>openflow-switch-connection-provider-default-impl</instance-name>
+        <port>6633</port>
+        <transport-protocol>TCP</transport-protocol>
+      </switch-connection-config>
+    ]]></odl:default-config>
+  </odl:clustered-app-config>
+
+  <bean id="defaultSwitchConnProvider" factory-ref="switchConnProviderFactory" factory-method="newInstance">
+    <argument ref="defaultSwitchConnConfig"/>
+  </bean>
+
+  <service ref="defaultSwitchConnProvider" interface="org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider"
+          odl:type="openflow-switch-connection-provider-default-impl"/>
+
+  <!-- Create OF switch connection provider on port 6653 -->
+  <odl:clustered-app-config id="legacySwitchConnConfig"
+      binding-class="org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.config.rev160506.SwitchConnectionConfig"
+      list-key-value="openflow-switch-connection-provider-legacy-impl">
+    <odl:default-config><![CDATA[
+      <switch-connection-config xmlns="urn:opendaylight:params:xml:ns:yang:openflow:switch:connection:config">
+        <instance-name>openflow-switch-connection-provider-legacy-impl</instance-name>
+        <port>6653</port>
+        <transport-protocol>TCP</transport-protocol>
+      </switch-connection-config>
+    ]]></odl:default-config>
+  </odl:clustered-app-config>
+
+  <bean id="legacySwitchConnProvider" factory-ref="switchConnProviderFactory" factory-method="newInstance">
+    <argument ref="legacySwitchConnConfig"/>
+  </bean>
+
+  <service ref="legacySwitchConnProvider" interface="org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider"
+          odl:type="openflow-switch-connection-provider-legacy-impl"/>
+
+  <!-- Create OpenflowPluginProvider instance -->
+
+  <reference id="dataBroker" interface="org.opendaylight.controller.md.sal.binding.api.DataBroker" odl:type="pingpong"/>
+  <reference id="rpcRegistry" interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry"/>
+  <reference id="notificationService" interface="org.opendaylight.controller.sal.binding.api.NotificationProviderService"/>
+  <reference id="entityOwnershipService" interface="org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService"/>
+
+  <bean id="openflowPluginProvider" class="org.opendaylight.openflowplugin.openflow.md.core.sal.OpenflowPluginProvider"
+          init-method="initialization" destroy-method="close">
+    <property name="dataBroker" ref="dataBroker"/>
+    <property name="rpcRegistry" ref="rpcRegistry"/>
+    <property name="notificationService" ref="notificationService"/>
+    <property name="entityOwnershipService" ref="entityOwnershipService"/>
+    <property name="role" value="NOCHANGE"/>
+    <property name="skipTableFeatures" value="false" />
+    <property name="switchConnectionProviders">
+      <list>
+        <ref component-id="defaultSwitchConnProvider"/>
+        <ref component-id="legacySwitchConnProvider"/>
+      </list>
+    </property>
+  </bean>
+
+  <service ref="openflowPluginProvider" odl:type="openflow-provider-impl">
+    <interfaces>
+      <value>org.opendaylight.openflowplugin.openflow.md.core.sal.OpenflowPluginProvider</value>
+      <value>org.opendaylight.openflowplugin.extension.api.OpenFlowPluginExtensionRegistratorProvider</value>
+    </interfaces>
+  </service>
+
+</blueprint>
\ No newline at end of file
index dac95eb86b21ec91473eea8db875f9a43e37aa0c..58754980b056e55a3ea56f20250fa08864831720 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.openflowplugin.openflow.md.core.sal;
 import com.google.common.annotations.VisibleForTesting;
 import java.util.Collection;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider;
@@ -20,13 +21,12 @@ import org.opendaylight.openflowplugin.extension.api.OpenFlowPluginExtensionRegi
 import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterManager;
 import org.opendaylight.openflowplugin.openflow.md.core.MDController;
 import org.opendaylight.openflowplugin.openflow.md.core.extension.ExtensionConverterManagerImpl;
+import org.opendaylight.openflowplugin.openflow.md.core.role.OfEntityManager;
 import org.opendaylight.openflowplugin.openflow.md.core.session.OFRoleManager;
 import org.opendaylight.openflowplugin.openflow.md.core.session.OFSessionUtil;
-import org.opendaylight.openflowplugin.openflow.md.core.role.OfEntityManager;
 import org.opendaylight.openflowplugin.statistics.MessageSpyCounterImpl;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow.common.config.impl.rev140326.OfpRole;
 import org.opendaylight.yangtools.yang.binding.DataContainer;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -37,6 +37,8 @@ public class OpenflowPluginProvider implements AutoCloseable, OpenFlowPluginExte
 
     private static final Logger LOG = LoggerFactory.getLogger(OpenflowPluginProvider.class);
 
+    private static final boolean SKIP_TABLE_FEATURES = false;
+
     private Collection<SwitchConnectionProvider> switchConnectionProviders;
 
     private MDController mdController;
@@ -48,6 +50,7 @@ public class OpenflowPluginProvider implements AutoCloseable, OpenFlowPluginExte
     private ExtensionConverterManager extensionConverterManager;
 
     private OfpRole role;
+    private Boolean skipTableFeatures;
 
     private OFRoleManager roleManager;
     private OfEntityManager entManager;
@@ -58,6 +61,8 @@ public class OpenflowPluginProvider implements AutoCloseable, OpenFlowPluginExte
 
     private OpenflowPluginConfig openflowPluginConfig;
 
+
+
     /**
      * Initialization of services and msgSpy counter
      */
@@ -65,6 +70,7 @@ public class OpenflowPluginProvider implements AutoCloseable, OpenFlowPluginExte
         messageCountProvider = new MessageSpyCounterImpl();
         extensionConverterManager = new ExtensionConverterManagerImpl();
         roleManager = new OFRoleManager(OFSessionUtil.getSessionManager());
+        openflowPluginConfig = readConfig(skipTableFeatures);
         entManager = new OfEntityManager(entityOwnershipService,getOpenflowPluginConfig());
         entManager.setDataBroker(dataBroker);
         entManager.init();
@@ -95,10 +101,16 @@ public class OpenflowPluginProvider implements AutoCloseable, OpenFlowPluginExte
     @Override
     public void close() {
         LOG.debug("close");
-        mdController.stop();
-        mdController = null;
-        registrationManager.close();
-        registrationManager = null;
+
+        if(mdController != null) {
+            mdController.stop();
+            mdController = null;
+        }
+
+        if(registrationManager != null) {
+            registrationManager.close();
+            registrationManager = null;
+        }
     }
 
     public MessageCountDumper getMessageCountDumper() {
@@ -147,6 +159,20 @@ public class OpenflowPluginProvider implements AutoCloseable, OpenFlowPluginExte
         }
     }
 
+    private OpenflowPluginConfig readConfig(Boolean skipTableFeatures){
+
+        final OpenflowPluginConfig.OpenflowPluginConfigBuilder openflowCfgBuilder = OpenflowPluginConfig.builder();
+
+        if(skipTableFeatures !=null){
+            openflowCfgBuilder.setSkipTableFeatures(skipTableFeatures.booleanValue());
+        } else{
+            LOG.warn("Could not load XML configuration file via ConfigSubsystem! Fallback to default config value(s)");
+            openflowCfgBuilder.setSkipTableFeatures(SKIP_TABLE_FEATURES);
+        }
+
+        return openflowCfgBuilder.build();
+    }
+
     public void setDataBroker(DataBroker dataBroker) {
         this.dataBroker = dataBroker;
     }
@@ -163,8 +189,8 @@ public class OpenflowPluginProvider implements AutoCloseable, OpenFlowPluginExte
         this.entityOwnershipService = entityOwnershipService;
     }
 
-    public void setOpenflowPluginConfig(OpenflowPluginConfig openflowPluginConfig) {
-        this.openflowPluginConfig = openflowPluginConfig;
+    public void setSkipTableFeatures(Boolean skipTableFeatures) {
+        this.skipTableFeatures = skipTableFeatures;
     }
 
     @VisibleForTesting
index 1542d5444bacf717e81ed154717b3f9987528975..3fd3e045f0598fd8dacdf1b3e994475d9b9d6718 100644 (file)
@@ -9,24 +9,30 @@
 */
 package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow.common.config.impl.rev140326;
 
-import com.google.common.base.MoreObjects;
-import javax.management.ObjectName;
-
-import org.opendaylight.openflowplugin.openflow.md.core.sal.OpenflowPluginConfig;
+import java.util.Collection;
+import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider;
+import org.opendaylight.openflowplugin.api.openflow.statistics.MessageCountDumper;
+import org.opendaylight.openflowplugin.extension.api.ExtensionConverterRegistrator;
 import org.opendaylight.openflowplugin.openflow.md.core.sal.OpenflowPluginProvider;
+import org.osgi.framework.BundleContext;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
-*
-*/
+ * @deprecated Replaced by blueprint wiring
+ */
+@Deprecated
 public final class ConfigurableOpenFlowProviderModule extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow.common.config.impl.rev140326.AbstractConfigurableOpenFlowProviderModule {
 
     private static final Logger LOG = LoggerFactory.getLogger(ConfigurableOpenFlowProviderModule.class);
 
-    private OpenflowPluginProvider pluginProvider;
-
-    private static final boolean SKIP_TABLE_FEATURES = false;
+    private BundleContext bundleContext;
 
     /**
      * @param identifier module identifier
@@ -54,58 +60,84 @@ public final class ConfigurableOpenFlowProviderModule extends org.opendaylight.y
     }
 
     @Override
-    public java.lang.AutoCloseable createInstance() {
-        pluginProvider =  new OpenflowPluginProvider();
-        pluginProvider.setDataBroker(getDataBrokerDependency());
-        pluginProvider.setNotificationService(getNotificationServiceDependency());
-        pluginProvider.setRpcRegistry(getRpcRegistryDependency());
-        pluginProvider.setSwitchConnectionProviders(getOpenflowSwitchConnectionProviderDependency());
-        pluginProvider.setEntityOwnershipService(getOwnershipServiceDependency());
-        pluginProvider.setRole(getRole());
-        pluginProvider.setOpenflowPluginConfig(readConfig());
-        pluginProvider.initialization();
-        return pluginProvider;
+    public AutoCloseable createInstance() {
+        // The service is provided via blueprint so wait for and return it here for backwards compatibility.
+        String typeFilter = String.format("(type=%s)", getIdentifier().getInstanceName());
+        final WaitingServiceTracker<OpenflowPluginProvider> tracker = WaitingServiceTracker.create(
+                OpenflowPluginProvider.class, bundleContext, typeFilter);
+        final OpenflowPluginProvider actualService = tracker.waitForService(WaitingServiceTracker.FIVE_MINUTES);
+
+        return new OpenflowPluginProvider() {
+            @Override
+            public void close() {
+                // Don't close the actual service as its life cycle is controlled by blueprint.
+                tracker.close();
+            }
+
+            @Override
+            public void initialization() {
+                actualService.initialization();
+            }
+
+            @Override
+            public void setSwitchConnectionProviders(Collection<SwitchConnectionProvider> switchConnectionProvider) {
+                actualService.setSwitchConnectionProviders(switchConnectionProvider);
+            }
+
+            @Override
+            public MessageCountDumper getMessageCountDumper() {
+                return actualService.getMessageCountDumper();
+            }
+
+            @Override
+            public ExtensionConverterRegistrator getExtensionConverterRegistrator() {
+                return actualService.getExtensionConverterRegistrator();
+            }
+
+            @Override
+            public void setRole(OfpRole role) {
+                actualService.setRole(role);
+            }
+
+            @Override
+            public void setSkipTableFeatures(Boolean skipTableFeatures) {
+                actualService.setSkipTableFeatures(skipTableFeatures);
+            }
+
+            @Override
+            public void fireRoleChange(OfpRole newRole) {
+                actualService.fireRoleChange(newRole);
+            }
+
+            @Override
+            public void setDataBroker(DataBroker dataBroker) {
+                actualService.setDataBroker(dataBroker);
+            }
+
+            @Override
+            public void setNotificationService(NotificationProviderService notificationService) {
+                actualService.setNotificationService(notificationService);
+            }
+
+            @Override
+            public void setRpcRegistry(RpcProviderRegistry rpcRegistry) {
+                actualService.setRpcRegistry(rpcRegistry);
+            }
+
+            @Override
+            public void setEntityOwnershipService(EntityOwnershipService entityOwnershipService) {
+                actualService.setEntityOwnershipService(entityOwnershipService);
+            }
+        };
     }
 
-    @Override
-    public boolean canReuseInstance(
-            AbstractConfigurableOpenFlowProviderModule oldModule) {
-        // we can reuse if only the role field changed
-        boolean noChangeExceptRole = true;
-        noChangeExceptRole &= dependencyResolver.canReuseDependency(
-                getDataBroker(), dataBrokerJmxAttribute);
-        noChangeExceptRole &= dependencyResolver.canReuseDependency(
-                getNotificationService(), notificationServiceJmxAttribute);
-        noChangeExceptRole &= dependencyResolver.canReuseDependency(
-                getRpcRegistry(), rpcRegistryJmxAttribute);
-
-        for (ObjectName ofSwitchProvider : getOpenflowSwitchConnectionProvider()) {
-            noChangeExceptRole &= dependencyResolver.canReuseDependency(
-                    ofSwitchProvider, openflowSwitchConnectionProviderJmxAttribute);
-        }
-        return noChangeExceptRole;
+    public void setBundleContext(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
     }
 
     @Override
-    public AutoCloseable reuseInstance(AutoCloseable oldInstance) {
-        OpenflowPluginProvider recycled = (OpenflowPluginProvider) super.reuseInstance(oldInstance);
-        // change role if different
-        recycled.fireRoleChange(MoreObjects.firstNonNull(getRole(), getRole()));
-
-        return recycled;
+    public boolean canReuseInstance(AbstractConfigurableOpenFlowProviderModule oldModule) {
+        return true;
     }
 
-    private OpenflowPluginConfig readConfig(){
-
-        final OpenflowPluginConfig.OpenflowPluginConfigBuilder openflowCfgBuilder = OpenflowPluginConfig.builder();
-
-        if(getSkipTableFeatures()!=null){
-            openflowCfgBuilder.setSkipTableFeatures(getSkipTableFeatures().booleanValue());
-        } else{
-            LOG.warn("Could not load XML configuration file via ConfigSubsystem! Fallback to default config value(s)");
-            openflowCfgBuilder.setSkipTableFeatures(SKIP_TABLE_FEATURES);
-        }
-
-        return openflowCfgBuilder.build();
-    }
 }
index dfa132202d5aa309c13967e47917d412d73bc21f..77f24c93ded99d08a5bc835d8072e529ae10212e 100644 (file)
@@ -9,11 +9,28 @@
 */
 package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow.common.config.impl.rev140326;
 
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.osgi.framework.BundleContext;
 
 /**
- * the only purpose of this overwritings is to deliver bundleContext from osgi to module
+ * @deprecated Replaced by blueprint wiring
  */
-public class ConfigurableOpenFlowProviderModuleFactory extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow.common.config.impl.rev140326.AbstractConfigurableOpenFlowProviderModuleFactory
-{
-    // nothing to override
+@Deprecated
+public class ConfigurableOpenFlowProviderModuleFactory extends AbstractConfigurableOpenFlowProviderModuleFactory {
+    @Override
+    public ConfigurableOpenFlowProviderModule instantiateModule(String instanceName, DependencyResolver dependencyResolver,
+            ConfigurableOpenFlowProviderModule oldModule, AutoCloseable oldInstance, BundleContext bundleContext) {
+        ConfigurableOpenFlowProviderModule module = super.instantiateModule(instanceName, dependencyResolver, oldModule,
+                oldInstance, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
+
+    @Override
+    public ConfigurableOpenFlowProviderModule instantiateModule(String instanceName, DependencyResolver dependencyResolver,
+            BundleContext bundleContext) {
+        ConfigurableOpenFlowProviderModule module = super.instantiateModule(instanceName, dependencyResolver, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
 }
index 2848c293ca34a812b3a44f9189213a1acc0a3d99..306638f2c1600892163f44af22c5245f720e4826 100644 (file)
@@ -16,5 +16,6 @@ module openflow-provider {
     identity openflow-provider{
         base config:service-type;
         config:java-class "org.opendaylight.openflowplugin.openflow.md.core.sal.OpenflowPluginProvider";
+        config:disable-osgi-service-registration;
     }
 }
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index bfd108b2d85eaf8850f6af41f31bfe5d0d7d0f20..42dc3e43f614286460092942607b8e4d2fed7375 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -31,6 +31,7 @@
       <module>extension</module>
       <module>distribution/karaf</module>
       <module>openflowplugin-controller-config</module>
+      <module>openflowplugin-blueprint-config-he</module>
       <!--
       <module>openflowplugin-it</module>
       -->