Bug 3350 - Provide override for features detected during handshake 17/21717/1
authorMartin Bobak <mbobak@cisco.com>
Tue, 2 Jun 2015 08:03:51 +0000 (10:03 +0200)
committermichal rehak <mirehak@cisco.com>
Wed, 3 Jun 2015 06:08:24 +0000 (06:08 +0000)
Some devices doesn't provide features considered by OF protocol as
mandatory. We introduce configurable variable that overrides features
check.

Change-Id: I8f7fe9c31f00b785bd19b5f0e79b8162fa7a2a4b
Signed-off-by: Martin Bobak <mbobak@cisco.com>
(cherry picked from commit 4085d17036f47c4b9bcc5113b079309b64fbc390)

openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OpenFlowPluginProvider.java
openflowplugin-controller-config/src/main/resources/initial/42-openflowplugin-new.xml
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/config/openflow/plugin/impl/rev150327/OpenFlowProviderModule.java
openflowplugin-impl/src/main/yang/openflow-plugin-impl.yang

index 83852de9dabad5c4bf8c138db11c6a27dad89ddc..ffbaaabccfa91098796e265c530e474b31730bc1 100644 (file)
@@ -50,4 +50,15 @@ public interface OpenFlowPluginProvider extends AutoCloseable, BindingService {
      */
     void initialize();
 
-}
+    /**
+     * This parameter indicates whether it is mandatory for switch to support OF1.3 features : table, flow, meter,group.
+     * If this is set to true and switch doesn't support these features its connection will be denied.
+     * @param switchFeaturesMandatory
+     */
+    void setSwitchFeaturesMandatory(final boolean switchFeaturesMandatory);
+
+    boolean isSwitchFeaturesMandatory();
+
+
+
+    }
index 4e44ba4cff626054d280697284583df1b7bca521..e6418ad4478d0c1f28f6cfa789f284a01a93cf99 100644 (file)
@@ -83,6 +83,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
                         <name>binding-notification-publish-adapter</name>
                     </notification-publish-adapter>
                     <rpc-requests-quota>20000</rpc-requests-quota>
+                    <switch-features-mandatory>false</switch-features-mandatory>
                 </module>
             </modules>
 
index 469fff3197112d3b39742e922c92437c5c7b2459..30173363c7d3b36eb39b0beb391f28251ab0b769 100644 (file)
@@ -72,6 +72,7 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF
     private DataBroker dataBroker;
     private OfpRole role;
     private Collection<SwitchConnectionProvider> switchConnectionProviders;
+    private boolean switchFeaturesMandatory = false;
 
     public OpenFlowPluginProviderImpl(final long rpcRequestsQuota) {
         Preconditions.checkArgument(rpcRequestsQuota > 0 && rpcRequestsQuota <= Integer.MAX_VALUE, "rpcRequestQuota has to be in range <1,%s>", Integer.MAX_VALUE);
@@ -102,6 +103,14 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF
         });
     }
 
+    public boolean isSwitchFeaturesMandatory() {
+        return switchFeaturesMandatory;
+    }
+
+    public void setSwitchFeaturesMandatory(final boolean switchFeaturesMandatory) {
+        this.switchFeaturesMandatory = switchFeaturesMandatory;
+    }
+
     public static MessageIntelligenceAgency getMessageIntelligenceAgency() {
         return OpenFlowPluginProviderImpl.messageIntelligenceAgency;
     }
@@ -143,7 +152,7 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF
 
         registerMXBean(messageIntelligenceAgency);
 
-        deviceManager = new DeviceManagerImpl(dataBroker, messageIntelligenceAgency);
+        deviceManager = new DeviceManagerImpl(dataBroker, messageIntelligenceAgency, switchFeaturesMandatory);
         statisticsManager = new StatisticsManagerImpl();
         rpcManager = new RpcManagerImpl(rpcProviderRegistry, rpcRequestsQuota);
 
index a2ad5528dc4b3108710b91dc54192580ae9c5bf0..4c776c5d41e020543f2dc94df72e4279f58196f5 100644 (file)
@@ -94,6 +94,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -120,9 +121,11 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable {
 
     private final long barrierNanos = TimeUnit.MILLISECONDS.toNanos(500);
     private final int maxQueueDepth = 25600;
+    private final boolean switchFeaturesMandatory;
 
     public DeviceManagerImpl(@Nonnull final DataBroker dataBroker,
-                             @Nonnull final MessageIntelligenceAgency messageIntelligenceAgency) {
+                             @Nonnull final MessageIntelligenceAgency messageIntelligenceAgency,
+                             final boolean switchFeaturesMandatory) {
         this.dataBroker = Preconditions.checkNotNull(dataBroker);
         hashedWheelTimer = new HashedWheelTimer(TICK_DURATION, TimeUnit.MILLISECONDS, 500);
         /* merge empty nodes to oper DS to predict any problems with missing parent for Node */
@@ -139,8 +142,10 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable {
         }
 
         this.messageIntelligenceAgency = messageIntelligenceAgency;
+        this.switchFeaturesMandatory = switchFeaturesMandatory;
     }
 
+
     @Override
     public void setDeviceInitializationPhaseHandler(final DeviceInitializationPhaseHandler handler) {
         deviceInitPhaseHandler = handler;
@@ -153,14 +158,12 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable {
         try {
             ((DeviceContextImpl) deviceContext).initialSubmitTransaction();
             deviceContext.onPublished();
-        }
-        catch (final Exception e) {
+        } catch (final Exception e) {
             LOG.warn("Node {} can not be add to OPERATIONAL DataStore yet because {} ", deviceContext.getDeviceState().getNodeId(), e.getMessage());
             LOG.trace("Problem with add node {} to OPERATIONAL DataStore", deviceContext.getDeviceState().getNodeId(), e);
             try {
                 deviceContext.close();
-            }
-            catch (final Exception e1) {
+            } catch (final Exception e1) {
                 LOG.warn("Device context close FAIL - " + deviceContext.getDeviceState().getNodeId());
             }
         }
@@ -247,9 +250,7 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable {
         Futures.addCallback(deviceFeaturesFuture, new FutureCallback<List<RpcResult<List<MultipartReply>>>>() {
             @Override
             public void onSuccess(final List<RpcResult<List<MultipartReply>>> result) {
-                deviceContext.getDeviceState().setValid(true);
-                deviceInitPhaseHandler.onDeviceContextLevelUp(deviceContext);
-                LOG.trace("Device context level up called.");
+                deviceCtxLevelUp(deviceContext);
             }
 
             @Override
@@ -261,6 +262,12 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable {
         });
     }
 
+    private void deviceCtxLevelUp(final DeviceContext deviceContext) {
+        deviceContext.getDeviceState().setValid(true);
+        deviceInitPhaseHandler.onDeviceContextLevelUp(deviceContext);
+        LOG.trace("Device context level up called.");
+    }
+
     private static void chainTableTrunkWriteOF10(final DeviceContext deviceContext, final ListenableFuture<List<RpcResult<List<MultipartReply>>>> deviceFeaturesFuture) {
         Futures.addCallback(deviceFeaturesFuture, new FutureCallback<List<RpcResult<List<MultipartReply>>>>() {
             @Override
@@ -294,8 +301,8 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable {
         return Futures.allAsList(Arrays.asList(replyDesc));
     }
 
-    private static ListenableFuture<List<RpcResult<List<MultipartReply>>>> createDeviceFeaturesForOF13(final DeviceContext deviceContext,
-                                                                                                       final DeviceState deviceState) {
+    private ListenableFuture<List<RpcResult<List<MultipartReply>>>> createDeviceFeaturesForOF13(final DeviceContext deviceContext,
+                                                                                                final DeviceState deviceState) {
 
         final ListenableFuture<RpcResult<List<MultipartReply>>> replyDesc = getNodeStaticInfo(MultipartType.OFPMPDESC,
                 deviceContext,
@@ -345,13 +352,19 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable {
                         deviceContext,
                         deviceState.getNodeInstanceIdentifier(),
                         replyPortDescription);
-
-
-                return Futures.allAsList(Arrays.asList(
-                        replyMeterFeature,
-                        replyGroupFeatures,
-//                        replyTableFeatures,
-                        replyPortDescription));
+                if (switchFeaturesMandatory) {
+                    return Futures.allAsList(Arrays.asList(
+                            replyMeterFeature,
+                            replyGroupFeatures,
+                            replyTableFeatures,
+                            replyPortDescription));
+                } else {
+                    return Futures.successfulAsList(Arrays.asList(
+                            replyMeterFeature,
+                            replyGroupFeatures,
+                            replyTableFeatures,
+                            replyPortDescription));
+                }
             }
         });
 
@@ -402,10 +415,12 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable {
             @Override
             public void onFailure(final Throwable t) {
                 LOG.info("Fail response from OutboundQueue for multipart type {}.", type);
-                requestContext.close();
+                final RpcResult<List<MultipartReply>> rpcResult = RpcResultBuilder.<List<MultipartReply>>failed().build();
+                requestContext.setResult(rpcResult);
                 if (MultipartType.OFPMPTABLEFEATURES.equals(type)) {
                     makeEmptyTables(deviceContext, nodeII, deviceContext.getPrimaryConnectionContext().getFeatures().getTables());
                 }
+                requestContext.close();
             }
         });
 
index bde4475ccfa0ef6ea6a8cbbb6ad99eca6aed6324..505f7ee0432f104fe73ba019ca795e76ca3b9485 100644 (file)
@@ -35,8 +35,7 @@ public class OpenFlowProviderModule extends org.opendaylight.yang.gen.v1.urn.ope
         openflowPluginProvider.setRpcProviderRegistry(getRpcRegistryDependency());
         openflowPluginProvider.setNotificationProviderService(getNotificationAdapterDependency());
         openflowPluginProvider.setNotificationPublishService(getNotificationPublishAdapterDependency());
-
-
+        openflowPluginProvider.setSwitchFeaturesMandatory(getSwitchFeaturesMandatory());
         openflowPluginProvider.initialize();
 
         return openflowPluginProvider;
index 1d7e0fd1ccdb4387929c240407b201013b8af7a5..9ce8fafb290d7dc13ad34a096005d3e70c4a9829 100644 (file)
@@ -79,6 +79,10 @@ module openflow-plugin-provider-impl {
                 type uint32;
                 default 500;
             }
+            leaf switch-features-mandatory {
+                type boolean;
+                default false;
+            }
         }
 
     }