Improve property-based configuration 30/53630/16
authorTomas Slusny <tomas.slusny@pantheon.tech>
Tue, 21 Mar 2017 18:17:22 +0000 (19:17 +0100)
committerTomas Slusny <tomas.slusny@pantheon.tech>
Wed, 19 Apr 2017 09:01:26 +0000 (11:01 +0200)
- Add OpenFlowPluginConfigurationService. This service can control
  updating of OpenFlowPlugin configuration (skip-table-features etc.)
  in initialization phase and also on the fly.
- Comment out default settings in org.opendaylight.openflowplugin.cfg
  because with all default values set in that file, we are ignoring
  values specified in openflow-provider-config.yang.
- Add support for missing configuration values from
  openflow-provider-config.yang to OpenFlowPluginConfigurationService
- Remove changeable configuration values that was passed to some
  OpenFlowPlugin class implementations to both constructors and setters
  from constructors to prevent code duplicity and to simplify code a bit

Now, when feature is installed,
default values are taken from openflow-provider-config.yang, then we
check if we have org.opendaylight.openflowplugin.cfg file in karaf/etc/
(blueprint will do this for us) and try to read it as map. Then we will
pass this map to update method, that will iterate over this map and
parse it's keys and values and calls appropriate update methods in
OpenflowPluginProviderImpl based on key
(f.e skip-table-features will call
OpenflowPluginProviderImpl#updateSkipTableFeatures).

When org.opendaylight.openflowplugin.cfg file is changed, we receive
notification about it in form of
OpenFlowPluginConfigurationService#update method call, and we will
repeat same procedure as during initialization (parse map passed as
argument to this method and update configuration).

Resolves: bug 7218

Change-Id: Ida986f7dfffe55a90ddb6f354f0addf56c3c4b90
Signed-off-by: Tomas Slusny <tomas.slusny@pantheon.tech>
23 files changed:
features-aggregator/odl-openflowplugin-southbound/src/main/features/features.xml
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/OFConstants.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OpenFlowPluginConfigurationService.java [new file with mode: 0644]
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OpenFlowPluginProvider.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OpenFlowPluginProviderFactory.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceManager.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/rpc/RpcManager.java
openflowplugin-api/src/main/yang/openflow-provider-config.yang
openflowplugin-blueprint-config/src/main/resources/initial/openflowplugin.cfg
openflowplugin-blueprint-config/src/main/resources/org/opendaylight/blueprint/openflowplugin.xml
openflowplugin-impl/pom.xml
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderFactoryImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/connection/ConnectionManagerImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcManagerImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MdSalRegistrationUtils.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/connection/ConnectionManagerImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/rpc/RpcManagerImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImplTest.java

index 8113d2ce78fae70bd744f102989ea1cd0c614473..54a4797913b008600904b4b2cb5c25449b09506b 100644 (file)
@@ -4,4 +4,4 @@
         <configfile finalname="etc/org.opendaylight.openflowplugin.cfg">mvn:org.opendaylight.openflowplugin/openflowplugin-blueprint-config/${project.version}/cfg/config</configfile>
         <configfile finalname="etc/opendaylight/karaf/42-openflowplugin-Li.xml">mvn:org.opendaylight.openflowplugin/openflowplugin-controller-config/${project.version}/xml/config-Li</configfile>
     </feature>
-</features>
\ No newline at end of file
+</features>
index 3514f9206c92d50d8b355f05b62d6455f55e4db2..7a5a4a2a48512dc08a89535965671cedada1f258 100644 (file)
@@ -73,4 +73,7 @@ public final class OFConstants {
     public static final String APPLICATION_TAG = "OPENFLOW_PLUGIN";
     /** RpcError tag - timeout. */
     public static final String ERROR_TAG_TIMEOUT = "TIMOUT";
+
+    /** Persistent ID of OpenFlowPlugin configuration file */
+    public static final String CONFIG_FILE_ID = "org.opendaylight.openflowplugin";
 }
diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OpenFlowPluginConfigurationService.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OpenFlowPluginConfigurationService.java
new file mode 100644 (file)
index 0000000..23b9865
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.openflowplugin.api.openflow;
+
+import com.google.common.collect.ImmutableMap;
+import java.util.Map;
+import javax.annotation.Nonnull;
+
+/**
+ * Manages OpenFlowPlugin configuration
+ */
+public interface OpenFlowPluginConfigurationService {
+
+    /**
+     * Enum of property keys. All keys from OpenFlowPlugin configuration file are parsed to this enum.
+     * Each enum value represents one working configuration key in format
+     * ENUM.name().toLowerCase().replace('_', '-'), so for example PropertyType.IS_STATISTICS_POLLING_ON
+     * represents 'is-statistics-polling-on' configuration key.
+     */
+    enum PropertyType {
+        /**
+         * Is statistics polling on property type.
+         */
+        IS_STATISTICS_POLLING_ON,
+        /**
+         * Barrier count limit property type.
+         */
+        BARRIER_COUNT_LIMIT,
+        /**
+         * Barrier interval timeout limit property type.
+         */
+        BARRIER_INTERVAL_TIMEOUT_LIMIT,
+        /**
+         * Echo reply timeout property type.
+         */
+        ECHO_REPLY_TIMEOUT,
+        /**
+         * Enable flow removed notification property type.
+         */
+        ENABLE_FLOW_REMOVED_NOTIFICATION,
+        /**
+         * Skip table features property type.
+         */
+        SKIP_TABLE_FEATURES,
+        /**
+         * Basic timer delay property type.
+         */
+        BASIC_TIMER_DELAY,
+        /**
+         * Maximum timer delay property type.
+         */
+        MAXIMUM_TIMER_DELAY,
+        /**
+         * Switch features mandatory property type.
+         */
+        SWITCH_FEATURES_MANDATORY,
+        /**
+         * Is statistics rpc enabled property type.
+         */
+        @Deprecated
+        IS_STATISTICS_RPC_ENABLED,
+        /**
+         * Use single layer serialization property type.
+         */
+        USE_SINGLE_LAYER_SERIALIZATION,
+        /**
+         * Rpc requests quota property type.
+         */
+        RPC_REQUESTS_QUOTA,
+        /**
+         * Global notification quota property type.
+         */
+        GLOBAL_NOTIFICATION_QUOTA,
+        /**
+         * Thread pool min threads property type.
+         */
+        THREAD_POOL_MIN_THREADS,
+        /**
+         * Thread pool max threads property type.
+         */
+        THREAD_POOL_MAX_THREADS,
+        /**
+         * Thread pool timeout property type.
+         */
+        THREAD_POOL_TIMEOUT;
+
+        private static final Map<String, PropertyType> KEY_VALUE_MAP;
+
+        /**
+         * Get property type from property key
+         *
+         * @param key the property key
+         * @return the property type
+         */
+        public static PropertyType forValue(final String key) {
+            return KEY_VALUE_MAP.get(key);
+        }
+
+        static {
+            final PropertyType[] values = values();
+            final ImmutableMap.Builder<String, PropertyType> builder = ImmutableMap.builder();
+
+            for (final PropertyType value : values) {
+                builder.put(value.toString(), value);
+            }
+
+            KEY_VALUE_MAP = builder.build();
+        }
+
+        /**
+         * Converts enum name to property key
+         *
+         * @return the property key
+         */
+        @Override
+        public String toString() {
+            return this.name().toLowerCase().replace('_', '-');
+        }
+
+    }
+
+    /**
+     * Parses key-value pairs of properties read from OpenFlowPlugin configuration file and processes them
+     *
+     * @param properties properties
+     */
+    void update(@Nonnull Map<String,Object> properties);
+
+    /**
+     * Parse and process single property key-value pair
+     *
+     * @see org.opendaylight.openflowplugin.api.openflow.OpenFlowPluginConfigurationService.PropertyType
+     * @param key   property type
+     * @param value property value
+     */
+    void updateProperty(@Nonnull PropertyType key, @Nonnull Object value);
+
+}
index 3fcd3d9db809adf0b673b2bef0ffdcc7e3a07604..5eb41b5a92aab781e6b6fa77c093fc889971d991 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2015, 2017 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,
@@ -8,82 +8,16 @@
 
 package org.opendaylight.openflowplugin.api.openflow;
 
-import java.util.Collection;
-import java.util.Map;
 import org.opendaylight.controller.md.sal.binding.api.BindingService;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
-import org.opendaylight.controller.md.sal.binding.api.NotificationService;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
-import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
-import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
-import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider;
 
 /**
  * Plugin services provider
  */
 public interface OpenFlowPluginProvider extends AutoCloseable, BindingService {
 
-    /**
-     * Method sets openflow java's connection providers.
-     */
-    void setSwitchConnectionProviders(Collection<SwitchConnectionProvider> switchConnectionProvider);
-
-    /**
-     * setter
-     *
-     * @param dataBroker
-     */
-    void setDataBroker(DataBroker dataBroker);
-
-    void setRpcProviderRegistry(RpcProviderRegistry rpcProviderRegistry);
-
-    void setNotificationProviderService(NotificationService notificationProviderService);
-
-    void setNotificationPublishService(NotificationPublishService notificationPublishService);
-
     /**
      * Method initializes all DeviceManager, RpcManager and related contexts.
      */
     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();
-
-    boolean isStatisticsPollingOn();
-
-    void setStatisticsPollingOn(final boolean isStatisticsPollingOn);
-
-    /**
-     * Backward compatibility feature - exposing rpc for statistics polling (result is provided in form of async notification)
-     *
-     * @param isStatisticsRpcEnabled
-     */
-    void setIsStatisticsRpcEnabled(boolean isStatisticsRpcEnabled);
-
-    void setBarrierCountLimit(int barrierCountLimit);
-
-    void setBarrierInterval(long barrierTimeoutLimit);
-
-    void setEchoReplyTimeout(long echoReplyTimeout);
-
-    void setFlowRemovedNotification(boolean isFlowRemovedNotificationOn);
-
-    void update(Map<String,Object> props);
-
-    void setClusteringSingletonServicesProvider(ClusterSingletonServiceProvider singletonServicesProvider);
-    
-    void setSkipTableFeatures(boolean skipTableFeatures);
-
-    void setBasicTimerDelay(long basicTimerDelay);
-
-    void setMaximumTimerDelay(long maximumTimerDelay);
-
-    void setIsUseSingleLayerSerialization(Boolean useSingleLayerSerialization);
 }
index 608537a200f9de5e67de5ed10ff652896285cf97..c1fcaa2ef9b2014f3d8bb22f851845f050e28721 100644 (file)
@@ -16,15 +16,19 @@ import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow.provider.config.rev160510.OpenflowProviderConfig;
+import org.osgi.framework.BundleContext;
 
 /**
  * Factory for creating OpenFlowPluginProvider instances.
  */
 public interface OpenFlowPluginProviderFactory {
-    OpenFlowPluginProvider newInstance(OpenflowProviderConfig providerConfig, DataBroker dataBroker,
-                                       RpcProviderRegistry rpcRegistry, NotificationService notificationService,
+    OpenFlowPluginProvider newInstance(OpenflowProviderConfig providerConfig,
+                                       DataBroker dataBroker,
+                                       RpcProviderRegistry rpcRegistry,
+                                       NotificationService notificationService,
                                        NotificationPublishService notificationPublishService,
                                        EntityOwnershipService entityOwnershipService,
                                        List<SwitchConnectionProvider> switchConnectionProviders,
-                                       ClusterSingletonServiceProvider singletonServiceProvider);
+                                       ClusterSingletonServiceProvider singletonServiceProvider,
+                                       BundleContext bundleContext);
 }
index 93c646d4078cf50b51e3429ab61b9fe210cb2f9d..64cfd864d1aca65c72602fcad1126714aea96e10 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2015, 2017 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,
@@ -9,11 +9,10 @@
 package org.opendaylight.openflowplugin.api.openflow.device;
 
 import com.google.common.util.concurrent.CheckedFuture;
-import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.openflowplugin.api.openflow.OFPManager;
 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
-import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceDisconnectedHandler;
 import org.opendaylight.openflowplugin.api.openflow.translator.TranslatorLibrarian;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
@@ -37,6 +36,10 @@ public interface DeviceManager extends
 
     boolean isFlowRemovedNotificationOn();
 
+    void setGlobalNotificationQuota(long globalNotificationQuota);
+
+    void setSwitchFeaturesMandatory(boolean switchFeaturesMandatory);
+
     void setSkipTableFeatures(boolean skipTableFeatures);
 
     void setBarrierCountLimit(int barrierCountLimit);
@@ -44,17 +47,17 @@ public interface DeviceManager extends
     void setBarrierInterval(long barrierTimeoutLimit);
 
     CheckedFuture<Void, TransactionCommitFailedException> removeDeviceFromOperationalDS(DeviceInfo deviceInfo);
-    
+
     CheckedFuture<Void, TransactionCommitFailedException> removeDeviceFromOperationalDS(final KeyedInstanceIdentifier<Node, NodeKey> ii);
 
     void setUseSingleLayerSerialization(Boolean useSingleLayerSerialization);
 
-    DeviceContext createContext(@CheckForNull final ConnectionContext connectionContext);
+    DeviceContext createContext(@Nonnull final ConnectionContext connectionContext);
 
     long getBarrierIntervalNanos();
 
     int getBarrierCountLimit();
 
-    void sendNodeAddedNotification(@CheckForNull final DeviceInfo deviceInfo);
+    void sendNodeAddedNotification(@Nonnull final DeviceInfo deviceInfo);
 }
 
index a569e1908f7c7b8b3d415ac9a048a23205f810f7..7598ed8a7d957a5882b51a213578c914ee445261 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2015, 2017 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,
@@ -8,7 +8,7 @@
 
 package org.opendaylight.openflowplugin.api.openflow.rpc;
 
-import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
 import org.opendaylight.openflowplugin.api.openflow.OFPManager;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
@@ -20,8 +20,9 @@ public interface RpcManager extends OFPManager {
 
     void setStatisticsRpcEnabled(boolean statisticsRpcEnabled);
 
-    RpcContext createContext(
-            final @CheckForNull DeviceInfo deviceInfo,
-            final @CheckForNull DeviceContext deviceContext);
+    void setRpcRequestQuota(int rpcRequestQuota);
+
+    RpcContext createContext(final @Nonnull DeviceInfo deviceInfo,
+                             final @Nonnull DeviceContext deviceContext);
 
 }
index 95d50b04d60d2c406b40f1b89566846bf5693379..87fe5c2a6e16f9d2569349d2ebcb34d05b1e9d1b 100644 (file)
@@ -25,42 +25,57 @@ module openflow-provider-config {
 
     container openflow-provider-config {
         leaf rpc-requests-quota {
-            type uint32;
+            description "Quota for maximum number of RPC requests";
+            type non-zero-uint16-type;
             default 20000;
         }
 
         leaf switch-features-mandatory {
+            description "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.";
             type boolean;
             default false;
         }
 
         leaf global-notification-quota {
+            description "Global notification quota";
             type uint32;
             default 64000;
         }
 
         leaf is-statistics-polling-on {
+            description "If enabled, periodic statistics gathering will be
+                turned on";
             type boolean;
             default "true";
         }
 
         leaf is-statistics-rpc-enabled {
-            description "Deprecated - exposing backward compatible statistics rpcs providing result in form of async notification";
+            status deprecated;
+            description "Expose backward compatible statistics rpcs providing
+                result in form of async notification. This is deprecated, use direct
+                statistics instead.";
             type boolean;
             default "false";
         }
 
         leaf barrier-interval-timeout-limit {
+            description "Barrier timeout";
             type non-zero-uint32-type;
             default 500;
         }
 
         leaf barrier-count-limit {
+            description "Barrier limit";
             type non-zero-uint16-type;
             default 25600;
         }
 
         leaf echo-reply-timeout {
+            description "How long we should wait for echo reply (value is in
+                milliseconds";
             type non-zero-uint32-type;
             default 2000;
         }
@@ -78,7 +93,8 @@ module openflow-provider-config {
         }
 
         leaf thread-pool-timeout {
-            description "After how much time (in seconds) of inactivity will be threads in pool terminated";
+            description "After how much time (in seconds) of inactivity will be
+                threads in pool terminated";
             type uint32;
             default 60;
         }
@@ -90,29 +106,34 @@ module openflow-provider-config {
         }
 
         leaf skip-table-features {
-            description "Ability to skip pulling and storing of large table features. These features are still
-            available via rpc but if set to true then maintenance in DS will be omitted";
+            description "Ability to skip pulling and storing of large table
+                features. These features are still available via rpc but if set to
+                true then maintenance in DS will be omitted";
             type boolean;
             default "true";
         }
 
         leaf basic-timer-delay {
-            description "initial delay used in polling the statistics, value is in milliseconds";
+            description "Initial delay used in polling the statistics, value is
+                in milliseconds";
             type non-zero-uint32-type;
             default 3000;
         }
 
         leaf maximum-timer-delay {
-            description "maximum timer delay is the wait time to collect next statistics
-            used in polling the statistics, value is in milliseconds";
+            description "Maximum timer delay is the wait time to collect next
+                statistics used in polling the statistics, value is in
+                milliseconds";
             type non-zero-uint32-type;
             default 900000;
         }
 
         leaf use-single-layer-serialization {
-            description "When true, Yang models are serialized and deserialized directly to and from format supported
-            by device, so serialization and deserialization is faster. Otherwise, models are first serialized to
-            Openflow specification models and then to format supported by device, and reversed when deserializing.";
+            description "When true, Yang models are serialized and deserialized
+                directly to and from format supported by device, so serialization
+                and deserialization is faster. Otherwise, models are first
+                serialized to Openflow specification models and then to format
+                supported by device, and reversed when deserializing.";
             type boolean;
             default "true";
         }
index ae46b7d03cd5b9bf3602c88a29188b2417207c3e..0adf815b8aa561f08ca932bbf3a6f5186655e9ee 100644 (file)
@@ -1,42 +1,99 @@
-#All config parameters listed herein
-#require to be configured before switch connection, else requires a switch restart
-#All parameters here will be persisted, however need to change it explicitly for
-#each node of the cluster.
-#Flag to turn flow removed notification on/off.
-#Flow removed notification is turned on by default. Default value true
-enable-flow-removed-notification=true
-#Ability to skip pulling and storing of large table features. These features are still
-#available via rpc but if set to true then maintenance in DS will be omitted
-#Turned off by default. Default value true
-skip-table-features=true
-#Flag exposing backward compatible statistics rpcs providing result in form of async
-#notification.Usage deprecated as of Bo upwards.
-#Turned off by default. Default value false
-is-statistics-rpc-enabled=false
-#Timeout interval in milliseconds between each barrier message.
-#Default value is set to 500 milliseconds
-barrier-interval-timeout-limit=500
-#Maximum outbound queue depth
-#Default value is set to 25600
-barrier-count-limit=25600
-#Echo reply timeout specified on the controller side beyond which the connection is deemed dead
-#Default value is set to 2000 milliseconds
-echo-reply-timeout=2000
-#flag to turn on/off statistics polling
-#can be changed on demand
-#Turned on by default. Default value is true
-is-statistics-polling-on=true
-#Default value of basic-timer-delay is 3000
-#basic timer delay is the initial delay used in polling the statistics, value is in milliseconds
-basic-timer-delay=3000
-#Default value of maximum-timer-delay is 900000
-#maximum timer delay is the wait time to collect next statistics
-#used in polling the statistics, value is in milliseconds
-maximum-timer-delay=900000
-use-single-layer-serialization=true
-#TTL in milliseconds without connection before the context chain shall be dropped
-ttl-before-drop=1000
-#TTL step in milliseconds, if ttl-before-drop equals ttl-step it will be released in first step
-ttl-step=1000
-#if true then context chain will not be dropped, otherwise use ttl-before-drop
-never-drop-contexts-on=false
+# vim:set ft=jproperties:
+################################################################################
+# OpenFlowPlugin configuration file
+#
+# All config parameters listed here require to be configured before switch
+# connection, else requires a switch restart.
+# All parameters here will be persisted, however need to change it explicitly
+# for each node of the cluster.
+################################################################################
+
+#
+# Quota for maximum number of RPC requests
+#
+# rpc-requests-quota=20000
+
+#
+# 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.
+#
+# switch-features-mandatory=false
+
+#
+# Global notification quota
+#
+# global-notification-quota=64000
+
+#
+# If enabled, periodic statistics gathering will be turned on
+#
+# is-statistics-polling-on=true
+
+#
+# Expose backward compatible statistics RPCs providing result in form of
+# asynchronous notification. This is deprecated, use direct statistics instead.
+#
+# is-statistics-rpc-enabled=false
+
+#
+# Barrier timeout
+#
+# barrier-interval-timeout-limit=500
+
+#
+# Barrier limit
+#
+# barrier-count-limit=25600
+
+#
+# How long we should wait for echo reply (value is in milliseconds)
+#
+# echo-reply-timeout=2000
+
+#
+# Minimum (starting) number of threads in thread pool
+#
+# thread-pool-min-threads=1
+
+#
+# Maximum number of threads in thread pool
+#
+# thread-pool-max-threads=32000
+
+#
+# After how much time (in seconds) of inactivity will be threads in pool
+# terminated
+#
+# thread-pool-timeout=60
+
+#
+# Turning on flow removed notification
+#
+# enable-flow-removed-notification=true
+
+#
+# Ability to skip pulling and storing of large table features. These features
+# are still available via rpc but if set to true then maintenance in DS will be
+# omitted
+#
+# skip-table-features=true
+
+#
+# Initial delay used in polling the statistics, value is in milliseconds
+#
+# basic-timer-delay=3000
+
+#
+# Maximum timer delay is the wait time to collect next statistics used in
+# polling the statistics, value is in milliseconds
+#
+# maximum-timer-delay=900000
+
+#
+# When true, Yang models are serialized and deserialized directly to and from
+# format supported by device, so serialization and deserialization is faster.
+# Otherwise, models are first serialized to Openflow specification models and
+# then to format supported by device, and reversed when deserializing.
+#
+# use-single-layer-serialization=true
index d6f0c360d94e6273df7fca7810f9f9ea03cc6f93..58c2916e111e305a8b6c6104be4e6abcc2cb66a9 100644 (file)
@@ -2,53 +2,52 @@
 <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
            xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
            xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
-        odl:use-default-for-reference-types="true">
-
-  <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.md.sal.binding.api.NotificationService"/>
-  <reference id="notificationPublishService" interface="org.opendaylight.controller.md.sal.binding.api.NotificationPublishService"/>
-  <reference id="entityOwnershipService" interface="org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService"/>
-  <reference id="clusterSingletonServiceProvider" interface="org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider"/>
-
-  <reference id="defaultSwitchConnProvider" interface="org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider"
-   odl:type="openflow-switch-connection-provider-default-impl"/>
-
-  <reference id="legacySwitchConnProvider" interface="org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider"
-   odl:type="openflow-switch-connection-provider-legacy-impl"/>
-
-  <!-- Create OpenflowPluginProvider instance -->
-
-  <odl:clustered-app-config id="openflowProviderConfig"
-      binding-class="org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow.provider.config.rev160510.OpenflowProviderConfig"/>
-
-  <reference id="openflowPluginProviderFactory"
-          interface="org.opendaylight.openflowplugin.api.openflow.OpenFlowPluginProviderFactory"/>
-
-  <bean id="openflowPluginProvider" factory-ref="openflowPluginProviderFactory" factory-method="newInstance">
-    <argument ref="openflowProviderConfig"/>
-    <argument ref="dataBroker"/>
-    <argument ref="rpcRegistry"/>
-    <argument ref="notificationService"/>
-    <argument ref="notificationPublishService"/>
-    <argument ref="entityOwnershipService"/>
-    <argument>
-      <list>
-        <ref component-id="defaultSwitchConnProvider"/>
-        <ref component-id="legacySwitchConnProvider"/>
-      </list>
-    </argument>
-    <cm:managed-properties persistent-id="org.opendaylight.openflowplugin"
-                           update-strategy="component-managed"
-                           update-method="update"/>
-    <argument ref="clusterSingletonServiceProvider"/>
-  </bean>
-
-  <service ref="openflowPluginProvider" odl:type="openflow-plugin-provider-impl">
-    <interfaces>
-      <value>org.opendaylight.openflowplugin.api.openflow.OpenFlowPluginProvider</value>
-      <value>org.opendaylight.openflowplugin.extension.api.OpenFlowPluginExtensionRegistratorProvider</value>
-    </interfaces>
-  </service>
-
-</blueprint>
\ No newline at end of file
+           odl:use-default-for-reference-types="true">
+
+    <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.md.sal.binding.api.NotificationService"/>
+    <reference id="notificationPublishService" interface="org.opendaylight.controller.md.sal.binding.api.NotificationPublishService"/>
+    <reference id="entityOwnershipService" interface="org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService"/>
+    <reference id="clusterSingletonServiceProvider" interface="org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider"/>
+
+    <reference id="defaultSwitchConnProvider" interface="org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider"
+               odl:type="openflow-switch-connection-provider-default-impl"/>
+
+    <reference id="legacySwitchConnProvider" interface="org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider"
+               odl:type="openflow-switch-connection-provider-legacy-impl"/>
+
+    <odl:clustered-app-config id="openflowProviderConfig"
+                              binding-class="org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow.provider.config.rev160510.OpenflowProviderConfig"/>
+
+    <reference id="openflowPluginProviderFactory"
+               interface="org.opendaylight.openflowplugin.api.openflow.OpenFlowPluginProviderFactory"/>
+
+    <bean id="openflowPluginProvider" factory-ref="openflowPluginProviderFactory" factory-method="newInstance">
+        <argument ref="openflowProviderConfig"/>
+        <argument ref="dataBroker"/>
+        <argument ref="rpcRegistry"/>
+        <argument ref="notificationService"/>
+        <argument ref="notificationPublishService"/>
+        <argument ref="entityOwnershipService"/>
+        <argument>
+            <list>
+                <ref component-id="defaultSwitchConnProvider"/>
+                <ref component-id="legacySwitchConnProvider"/>
+            </list>
+        </argument>
+        <argument ref="clusterSingletonServiceProvider"/>
+        <argument ref="blueprintBundleContext" />
+        <cm:managed-properties persistent-id="org.opendaylight.openflowplugin"
+                               update-strategy="component-managed"
+                               update-method="update"/>
+    </bean>
+
+    <service ref="openflowPluginProvider" odl:type="openflow-plugin-provider-impl">
+        <interfaces>
+            <value>org.opendaylight.openflowplugin.api.openflow.OpenFlowPluginProvider</value>
+            <value>org.opendaylight.openflowplugin.extension.api.OpenFlowPluginExtensionRegistratorProvider</value>
+        </interfaces>
+    </service>
+
+</blueprint>
index 883ed0479b8012c7cf39db3f687110443543bc95..20556aeec47ce935203ac69357a65f34ccc3ee63 100644 (file)
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-binding-broker-impl</artifactId>
         </dependency>
-
         <dependency>
             <groupId>org.opendaylight.openflowjava</groupId>
             <artifactId>openflow-protocol-api</artifactId>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>
         </dependency>
-
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <artifactId>mockito-core</artifactId>
             <scope>test</scope>
         </dependency>
-
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-log4j12</artifactId>
             <groupId>org.opendaylight.openflowjava</groupId>
             <artifactId>openflow-protocol-impl</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
     </dependencies>
 </project>
 
index dfaa73101eec5127522b578aef0ecb54498067b2..934fb58ca515083fc29383656f7f90d74fcc31e2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Brocade Communications Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2016, 2017 Brocade Communications 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,
@@ -7,7 +7,12 @@
  */
 package org.opendaylight.openflowplugin.impl;
 
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.Optional;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
 import org.opendaylight.controller.md.sal.binding.api.NotificationService;
@@ -15,9 +20,14 @@ import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipS
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider;
+import org.opendaylight.openflowplugin.api.OFConstants;
+import org.opendaylight.openflowplugin.api.openflow.OpenFlowPluginConfigurationService.PropertyType;
 import org.opendaylight.openflowplugin.api.openflow.OpenFlowPluginProvider;
 import org.opendaylight.openflowplugin.api.openflow.OpenFlowPluginProviderFactory;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow.provider.config.rev160510.OpenflowProviderConfig;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -30,69 +40,70 @@ public class OpenFlowPluginProviderFactoryImpl implements OpenFlowPluginProvider
     private static final Logger LOG = LoggerFactory.getLogger(OpenFlowPluginProviderFactoryImpl.class);
 
     @Override
-    public OpenFlowPluginProvider newInstance(OpenflowProviderConfig providerConfig,
-                                              DataBroker dataBroker,
-                                              RpcProviderRegistry rpcRegistry,
-                                              NotificationService notificationService,
-                                              NotificationPublishService notificationPublishService,
-                                              EntityOwnershipService entityOwnershipService,
-                                              List<SwitchConnectionProvider> switchConnectionProviders,
-                                              ClusterSingletonServiceProvider singletonServiceProvider) {
+    public OpenFlowPluginProvider newInstance(final OpenflowProviderConfig providerConfig,
+                                              final DataBroker dataBroker,
+                                              final RpcProviderRegistry rpcRegistry,
+                                              final NotificationService notificationService,
+                                              final NotificationPublishService notificationPublishService,
+                                              final EntityOwnershipService entityOwnershipService,
+                                              final List<SwitchConnectionProvider> switchConnectionProviders,
+                                              final ClusterSingletonServiceProvider singletonServiceProvider,
+                                              final BundleContext bundleContext) {
 
         LOG.info("Initializing new OFP southbound.");
 
-        OpenFlowPluginProvider openflowPluginProvider = new OpenFlowPluginProviderImpl(
-                providerConfig.getRpcRequestsQuota(),
-                providerConfig.getGlobalNotificationQuota(),
-                providerConfig.getThreadPoolMinThreads(),
-                providerConfig.getThreadPoolMaxThreads().getValue(),
-                providerConfig.getThreadPoolTimeout(),
+        final OpenFlowPluginProviderImpl openflowPluginProvider = new OpenFlowPluginProviderImpl(
+                switchConnectionProviders,
+                dataBroker,
+                rpcRegistry,
+                notificationService,
+                notificationPublishService,
+                singletonServiceProvider,
                 entityOwnershipService);
 
-        openflowPluginProvider.setSwitchConnectionProviders(switchConnectionProviders);
-        openflowPluginProvider.setDataBroker(dataBroker);
-        openflowPluginProvider.setRpcProviderRegistry(rpcRegistry);
-        openflowPluginProvider.setNotificationProviderService(notificationService);
-        openflowPluginProvider.setNotificationPublishService(notificationPublishService);
-        openflowPluginProvider.setSwitchFeaturesMandatory(providerConfig.isSwitchFeaturesMandatory());
-        openflowPluginProvider.setFlowRemovedNotification(providerConfig.isEnableFlowRemovedNotification());
-        openflowPluginProvider.setIsStatisticsRpcEnabled(providerConfig.isIsStatisticsRpcEnabled());
-        openflowPluginProvider.setBarrierCountLimit(providerConfig.getBarrierCountLimit().getValue());
-        openflowPluginProvider.setBarrierInterval(providerConfig.getBarrierIntervalTimeoutLimit().getValue());
-        openflowPluginProvider.setEchoReplyTimeout(providerConfig.getEchoReplyTimeout().getValue());
-        openflowPluginProvider.setStatisticsPollingOn(providerConfig.isIsStatisticsPollingOn());
-        openflowPluginProvider.setClusteringSingletonServicesProvider(singletonServiceProvider);
-        openflowPluginProvider.setSkipTableFeatures(providerConfig.isSkipTableFeatures());
-        openflowPluginProvider.setBasicTimerDelay(providerConfig.getBasicTimerDelay().getValue());
-        openflowPluginProvider.setMaximumTimerDelay(providerConfig.getMaximumTimerDelay().getValue());
-        openflowPluginProvider.setIsUseSingleLayerSerialization(providerConfig.isUseSingleLayerSerialization());
+        LOG.info("Loading configuration from YANG file");
+        openflowPluginProvider.updateProperty(PropertyType.RPC_REQUESTS_QUOTA, providerConfig.getRpcRequestsQuota().getValue());
+        openflowPluginProvider.updateProperty(PropertyType.GLOBAL_NOTIFICATION_QUOTA, providerConfig.getGlobalNotificationQuota());
+        openflowPluginProvider.updateProperty(PropertyType.SWITCH_FEATURES_MANDATORY, providerConfig.isSwitchFeaturesMandatory());
+        openflowPluginProvider.updateProperty(PropertyType.ENABLE_FLOW_REMOVED_NOTIFICATION, providerConfig.isEnableFlowRemovedNotification());
+        openflowPluginProvider.updateProperty(PropertyType.IS_STATISTICS_RPC_ENABLED, providerConfig.isIsStatisticsRpcEnabled());
+        openflowPluginProvider.updateProperty(PropertyType.BARRIER_COUNT_LIMIT, providerConfig.getBarrierCountLimit().getValue());
+        openflowPluginProvider.updateProperty(PropertyType.BARRIER_INTERVAL_TIMEOUT_LIMIT, providerConfig.getBarrierIntervalTimeoutLimit().getValue());
+        openflowPluginProvider.updateProperty(PropertyType.ECHO_REPLY_TIMEOUT, providerConfig.getEchoReplyTimeout().getValue());
+        openflowPluginProvider.updateProperty(PropertyType.IS_STATISTICS_POLLING_ON, providerConfig.isIsStatisticsPollingOn());
+        openflowPluginProvider.updateProperty(PropertyType.SKIP_TABLE_FEATURES, providerConfig.isSkipTableFeatures());
+        openflowPluginProvider.updateProperty(PropertyType.BASIC_TIMER_DELAY, providerConfig.getBasicTimerDelay().getValue());
+        openflowPluginProvider.updateProperty(PropertyType.MAXIMUM_TIMER_DELAY, providerConfig.getMaximumTimerDelay().getValue());
+        openflowPluginProvider.updateProperty(PropertyType.USE_SINGLE_LAYER_SERIALIZATION, providerConfig.isUseSingleLayerSerialization());
+        openflowPluginProvider.updateProperty(PropertyType.THREAD_POOL_MIN_THREADS, providerConfig.getThreadPoolMinThreads());
+        openflowPluginProvider.updateProperty(PropertyType.THREAD_POOL_MAX_THREADS, providerConfig.getThreadPoolMaxThreads().getValue());
+        openflowPluginProvider.updateProperty(PropertyType.THREAD_POOL_TIMEOUT, providerConfig.getThreadPoolTimeout());
 
-        openflowPluginProvider.initialize();
+        LOG.info("Loading configuration from properties file");
+        Optional.ofNullable(bundleContext.getServiceReference(ConfigurationAdmin.class.getName())).ifPresent(serviceReference -> {
+            final ConfigurationAdmin configurationAdmin = (ConfigurationAdmin) bundleContext.getService(serviceReference);
+
+            try {
+                final Configuration configuration = configurationAdmin.getConfiguration(OFConstants.CONFIG_FILE_ID);
+
+                Optional.ofNullable(configuration.getProperties()).ifPresent(properties -> {
+                    final Enumeration<String> keys = properties.keys();
+                    final Map<String, Object> mapProperties = new HashMap<>(properties.size());
 
-        LOG.info("Configured values, " +
-                "StatisticsPollingOn:{}, " +
-                "SwitchFeaturesMandatory:{}, " +
-                "BarrierCountLimit:{}, " +
-                "BarrierTimeoutLimit:{}, " +
-                "EchoReplyTimeout:{}, " +
-                "ThreadPoolMinThreads:{}, " +
-                "ThreadPoolMaxThreads:{}, " +
-                "ThreadPoolTimeout:{}, " +
-                "NotificationFlowRemovedOff:{}, " +
-                "BasicTimerDelay:{}, "+
-                "MaximumTimerDelay:{} ",
-                providerConfig.isIsStatisticsPollingOn(),
-                providerConfig.isSwitchFeaturesMandatory(),
-                providerConfig.getBarrierCountLimit().getValue(),
-                providerConfig.getBarrierIntervalTimeoutLimit().getValue(),
-                providerConfig.getEchoReplyTimeout().getValue(),
-                providerConfig.getThreadPoolMinThreads(),
-                providerConfig.getThreadPoolMaxThreads().getValue(),
-                providerConfig.getThreadPoolTimeout(),
-                providerConfig.isEnableFlowRemovedNotification(),
-                providerConfig.getBasicTimerDelay().getValue(),
-                providerConfig.getMaximumTimerDelay().getValue());
+                    while (keys.hasMoreElements()) {
+                        final String key = keys.nextElement();
+                        final Object value = properties.get(key);
+                        mapProperties.put(key, value);
+                    }
 
+                    openflowPluginProvider.update(mapProperties);
+                });
+            } catch (IOException e) {
+                LOG.debug("Failed to load " + OFConstants.CONFIG_FILE_ID + " configuration file", e);
+            }
+        });
+
+        openflowPluginProvider.initialize();
         return openflowPluginProvider;
     }
 }
index d94d9b6a25e620efae1835aa9a6808b1d048a09d..c95bb5d968de18ba883b9d5e3dd4204e6df59db8 100644 (file)
@@ -8,17 +8,19 @@
 
 package org.opendaylight.openflowplugin.impl;
 
-
 import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
+import io.netty.util.HashedWheelTimer;
 import java.lang.management.ManagementFactory;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.SynchronousQueue;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
 import java.util.stream.Collectors;
 import javax.annotation.Nonnull;
 import javax.management.InstanceAlreadyExistsException;
@@ -34,6 +36,7 @@ import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipS
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider;
+import org.opendaylight.openflowplugin.api.openflow.OpenFlowPluginConfigurationService;
 import org.opendaylight.openflowplugin.api.openflow.OpenFlowPluginProvider;
 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionManager;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceManager;
@@ -49,9 +52,9 @@ import org.opendaylight.openflowplugin.impl.connection.ConnectionManagerImpl;
 import org.opendaylight.openflowplugin.impl.device.DeviceManagerImpl;
 import org.opendaylight.openflowplugin.impl.device.initialization.DeviceInitializerProvider;
 import org.opendaylight.openflowplugin.impl.device.initialization.DeviceInitializerProviderFactory;
+import org.opendaylight.openflowplugin.impl.lifecycle.ContextChainHolderImpl;
 import org.opendaylight.openflowplugin.impl.protocol.deserialization.DeserializerInjector;
 import org.opendaylight.openflowplugin.impl.protocol.serialization.SerializerInjector;
-import org.opendaylight.openflowplugin.impl.lifecycle.ContextChainHolderImpl;
 import org.opendaylight.openflowplugin.impl.rpc.RpcManagerImpl;
 import org.opendaylight.openflowplugin.impl.statistics.StatisticsManagerImpl;
 import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.MessageIntelligenceAgencyImpl;
@@ -64,26 +67,25 @@ import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorM
 import org.opendaylight.openflowplugin.openflow.md.core.session.OFSessionUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import io.netty.util.HashedWheelTimer;
 
-public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenFlowPluginExtensionRegistratorProvider {
+public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenFlowPluginConfigurationService, OpenFlowPluginExtensionRegistratorProvider {
 
     private static final Logger LOG = LoggerFactory.getLogger(OpenFlowPluginProviderImpl.class);
     private static final MessageIntelligenceAgency messageIntelligenceAgency = new MessageIntelligenceAgencyImpl();
-    private static final int TICKS_PER_WHEEL = 500;
-    // 0.5 sec.
+    private static final int TICKS_PER_WHEEL = 500; // 0.5 sec.
     private static final long TICK_DURATION = 10;
-    private static final Integer DEFAULT_BARRIER_COUNT = 25600;
-    private static final Long DEFAULT_ECHO_TIMEOUT = 2000L;
-    private static final Long DEFAULT_BARRIER_TIMEOUT = 500L;
     private static final String POOL_NAME = "ofppool";
 
     private final HashedWheelTimer hashedWheelTimer = new HashedWheelTimer(TICK_DURATION, TimeUnit.MILLISECONDS, TICKS_PER_WHEEL);
-
-    private final int rpcRequestsQuota;
-    private final long globalNotificationQuota;
+    private final NotificationService notificationProviderService;
+    private final NotificationPublishService notificationPublishService;
+    private final ExtensionConverterManager extensionConverterManager;
+    private final DataBroker dataBroker;
+    private final Collection<SwitchConnectionProvider> switchConnectionProviders;
+    private final DeviceInitializerProvider deviceInitializerProvider;
     private final ConvertorManager convertorManager;
-    private final ContextChainHolder contextChainHolder;
+    private final ContextChainHolder contextChainHolder;private int rpcRequestsQuota;
+    private long globalNotificationQuota;
     private long barrierInterval;
     private int barrierCountLimit;
     private long echoReplyTimeout;
@@ -92,57 +94,45 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF
     private RpcProviderRegistry rpcProviderRegistry;
     private StatisticsManager statisticsManager;
     private ConnectionManager connectionManager;
-    private NotificationService notificationProviderService;
-    private NotificationPublishService notificationPublishService;
-    private ExtensionConverterManager extensionConverterManager;
-    private DataBroker dataBroker;
-    private Collection<SwitchConnectionProvider> switchConnectionProviders;
-    private boolean switchFeaturesMandatory = false;
-    private boolean isStatisticsPollingOn = true;
+    private boolean switchFeaturesMandatory;
+    private boolean isStatisticsPollingOn;
     private boolean isStatisticsRpcEnabled;
-    private boolean isFlowRemovedNotificationOn = true;
-    private boolean skipTableFeatures = true;
+    private boolean isFlowRemovedNotificationOn;
+    private boolean skipTableFeatures;
     private long basicTimerDelay;
     private long maximumTimerDelay;
-    private boolean useSingleLayerSerialization = false;
-    private final DeviceInitializerProvider deviceInitializerProvider;
-
-    private final ThreadPoolExecutor threadPool;
+    private boolean useSingleLayerSerialization;
+    private ThreadPoolExecutor threadPool;
     private ClusterSingletonServiceProvider singletonServicesProvider;
+    private int threadPoolMinThreads;
+    private int threadPoolMaxThreads;
+    private long threadPoolTimeout;
+    private boolean initialized = false;
 
-    public OpenFlowPluginProviderImpl(final long rpcRequestsQuota,
-                                      final long globalNotificationQuota,
-                                      final int threadPoolMinThreads,
-                                      final int threadPoolMaxThreads,
-                                      final long threadPoolTimeout,
-                                      final EntityOwnershipService entityOwnershipService) {
-        Preconditions.checkArgument(rpcRequestsQuota > 0 && rpcRequestsQuota <= Integer.MAX_VALUE, "rpcRequestQuota has to be in range <1,%s>", Integer.MAX_VALUE);
-        this.rpcRequestsQuota = (int) rpcRequestsQuota;
-        this.globalNotificationQuota = Preconditions.checkNotNull(globalNotificationQuota);
+    public static MessageIntelligenceAgency getMessageIntelligenceAgency() {
+        return messageIntelligenceAgency;
+    }
 
-        // Creates a thread pool that creates new threads as needed, but will reuse previously
-        // constructed threads when they are available.
-        // Threads that have not been used for x seconds are terminated and removed from the cache.
-        threadPool = new ThreadPoolLoggingExecutor(
-                Preconditions.checkNotNull(threadPoolMinThreads),
-                Preconditions.checkNotNull(threadPoolMaxThreads),
-                Preconditions.checkNotNull(threadPoolTimeout), TimeUnit.SECONDS,
-                new SynchronousQueue<>(), POOL_NAME);
-        deviceInitializerProvider = DeviceInitializerProviderFactory.createDefaultProvider();          
+    public OpenFlowPluginProviderImpl(final List<SwitchConnectionProvider> switchConnectionProviders,
+                                      final DataBroker dataBroker,
+                                      final RpcProviderRegistry rpcProviderRegistry,
+                                      final NotificationService notificationProviderService,
+                                      final NotificationPublishService notificationPublishService,
+                                      final ClusterSingletonServiceProvider singletonServiceProvider,
+                                      final EntityOwnershipService entityOwnershipService) {
+        this.switchConnectionProviders = switchConnectionProviders;
+        this.dataBroker = dataBroker;
+        this.rpcProviderRegistry = rpcProviderRegistry;
+        this.notificationProviderService = notificationProviderService;
+        this.notificationPublishService = notificationPublishService;
+        this.singletonServicesProvider = singletonServiceProvider;
         convertorManager = ConvertorManagerFactory.createDefaultManager();
         contextChainHolder = new ContextChainHolderImpl(hashedWheelTimer);
         contextChainHolder.changeEntityOwnershipService(entityOwnershipService);
+        extensionConverterManager = new ExtensionConverterManagerImpl();
+        deviceInitializerProvider = DeviceInitializerProviderFactory.createDefaultProvider();
     }
 
-    @Override
-    public boolean isStatisticsPollingOn() {
-        return isStatisticsPollingOn;
-    }
-
-    @Override
-    public void setStatisticsPollingOn(final boolean isStatisticsPollingOn) {
-        this.isStatisticsPollingOn = isStatisticsPollingOn;
-    }
 
     private void startSwitchConnections() {
         Futures.addCallback(Futures.allAsList(switchConnectionProviders.stream().map(switchConnectionProvider -> {
@@ -168,75 +158,6 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF
         });
     }
 
-    @Override
-    public boolean isSwitchFeaturesMandatory() {
-        return switchFeaturesMandatory;
-    }
-
-    @Override
-    public void setBarrierCountLimit(final int barrierCountLimit) {
-        this.barrierCountLimit = barrierCountLimit;
-    }
-
-    @Override
-    public void setBarrierInterval(final long barrierTimeoutLimit) {
-        this.barrierInterval = barrierTimeoutLimit;
-    }
-
-    @Override
-    public void setEchoReplyTimeout(final long echoReplyTimeout) {
-        this.echoReplyTimeout = echoReplyTimeout;
-    }
-
-    @Override
-    public void setFlowRemovedNotification(boolean isFlowRemovedNotificationOn) {
-        this.isFlowRemovedNotificationOn = isFlowRemovedNotificationOn;
-    }
-
-    @Override
-    public void setClusteringSingletonServicesProvider(ClusterSingletonServiceProvider singletonServicesProvider) {
-        this.singletonServicesProvider = singletonServicesProvider;
-    }
-
-    @Override
-    public void setSkipTableFeatures(final boolean skipTableFeatures){
-        this.skipTableFeatures = skipTableFeatures;
-    }
-
-    @Override
-    public void setBasicTimerDelay(long basicTimerDelay) {
-        this.basicTimerDelay = basicTimerDelay;
-    }
-
-    @Override
-    public void setMaximumTimerDelay(long maximumTimerDelay) {
-        this.maximumTimerDelay = maximumTimerDelay;
-    }
-
-    @Override
-    public void setSwitchFeaturesMandatory(final boolean switchFeaturesMandatory) {
-        this.switchFeaturesMandatory = switchFeaturesMandatory;
-    }
-
-    public static MessageIntelligenceAgency getMessageIntelligenceAgency() {
-        return OpenFlowPluginProviderImpl.messageIntelligenceAgency;
-    }
-
-    @Override
-    public void setSwitchConnectionProviders(final Collection<SwitchConnectionProvider> switchConnectionProviders) {
-        this.switchConnectionProviders = switchConnectionProviders;
-    }
-
-    @Override
-    public void setDataBroker(final DataBroker dataBroker) {
-        this.dataBroker = dataBroker;
-    }
-
-    @Override
-    public void setRpcProviderRegistry(final RpcProviderRegistry rpcProviderRegistry) {
-        this.rpcProviderRegistry = rpcProviderRegistry;
-    }
-
     @Override
     public void initialize() {
         Preconditions.checkNotNull(dataBroker, "missing data broker");
@@ -244,32 +165,51 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF
         Preconditions.checkNotNull(notificationProviderService, "missing notification provider service");
         Preconditions.checkNotNull(singletonServicesProvider, "missing singleton services provider");
 
-        extensionConverterManager = new ExtensionConverterManagerImpl();
         // TODO: copied from OpenFlowPluginProvider (Helium) misusesing the old way of distributing extension converters
         // TODO: rewrite later!
         OFSessionUtil.getSessionManager().setExtensionConverterProvider(extensionConverterManager);
 
-        connectionManager = new ConnectionManagerImpl(echoReplyTimeout, threadPool);
+        // Creates a thread pool that creates new threads as needed, but will reuse previously
+        // constructed threads when they are available.
+        // Threads that have not been used for x seconds are terminated and removed from the cache.
+        threadPool = new ThreadPoolLoggingExecutor(
+                Preconditions.checkNotNull(threadPoolMinThreads),
+                Preconditions.checkNotNull(threadPoolMaxThreads),
+                Preconditions.checkNotNull(threadPoolTimeout),
+                TimeUnit.SECONDS, new SynchronousQueue<>(), POOL_NAME);
+
+        connectionManager = new ConnectionManagerImpl(threadPool);
+        connectionManager.setEchoReplyTimeout(echoReplyTimeout);
 
         registerMXBean(messageIntelligenceAgency);
 
         contextChainHolder.addSingletonServicesProvider(singletonServicesProvider);
 
-        deviceManager = new DeviceManagerImpl(dataBroker,
-                getMessageIntelligenceAgency(), notificationPublishService, hashedWheelTimer, convertorManager, deviceInitializerProvider, globalNotificationQuota,
-                switchFeaturesMandatory,
-                barrierInterval,
-                barrierCountLimit,
-                isFlowRemovedNotificationOn,
-                skipTableFeatures,
-                useSingleLayerSerialization
-        );
+        deviceManager = new DeviceManagerImpl(
+                dataBroker,
+                getMessageIntelligenceAgency(),
+                notificationPublishService,
+                hashedWheelTimer,
+                convertorManager,
+                deviceInitializerProvider);
+
+        deviceManager.setGlobalNotificationQuota(globalNotificationQuota);
+        deviceManager.setSwitchFeaturesMandatory(switchFeaturesMandatory);
+        deviceManager.setBarrierInterval(barrierInterval);
+        deviceManager.setBarrierCountLimit(barrierCountLimit);
+        deviceManager.setFlowRemovedNotificationOn(isFlowRemovedNotificationOn);
+        deviceManager.setSkipTableFeatures(skipTableFeatures);
+        deviceManager.setUseSingleLayerSerialization(useSingleLayerSerialization);
 
         ((ExtensionConverterProviderKeeper) deviceManager).setExtensionConverterProvider(extensionConverterManager);
 
-        rpcManager = new RpcManagerImpl(rpcProviderRegistry, rpcRequestsQuota, extensionConverterManager, convertorManager, notificationPublishService);
-        statisticsManager = new StatisticsManagerImpl(rpcProviderRegistry, isStatisticsPollingOn, hashedWheelTimer,
-                convertorManager,basicTimerDelay,maximumTimerDelay);
+        rpcManager = new RpcManagerImpl(rpcProviderRegistry, extensionConverterManager, convertorManager, notificationPublishService);
+        rpcManager.setRpcRequestQuota(rpcRequestsQuota);
+
+        statisticsManager = new StatisticsManagerImpl(rpcProviderRegistry, hashedWheelTimer, convertorManager);
+        statisticsManager.setBasicTimerDelay(basicTimerDelay);
+        statisticsManager.setMaximumTimerDelay(maximumTimerDelay);
+        statisticsManager.setIsStatisticsPollingOn(isStatisticsPollingOn);
 
         // Device connection handler moved from device manager to context holder
         connectionManager.setDeviceConnectedHandler(contextChainHolder);
@@ -287,103 +227,253 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF
         contextChainHolder.addManager(rpcManager);
 
         startSwitchConnections();
+        initialized = true;
     }
 
-    @Override
-    public void update(Map<String,Object> props) {
-        LOG.debug("Update managed properties = {}", props.toString());
-
-        final boolean containsUseSingleLayer = props.containsKey("use-single-layer-serialization");
-
-        if (containsUseSingleLayer) {
-            final Boolean useSingleLayer = Boolean.valueOf(props.get("use-single-layer-serialization").toString());
-
-            if (useSingleLayer != useSingleLayerSerialization) {
-                useSingleLayerSerialization = useSingleLayer;
-
-                if (useSingleLayer) {
-                    switchConnectionProviders.forEach(switchConnectionProvider -> {
-                        SerializerInjector.injectSerializers(switchConnectionProvider);
-                        DeserializerInjector.injectDeserializers(switchConnectionProvider);
-                    });
-                } else {
-                    switchConnectionProviders.forEach(DeserializerInjector::revertDeserializers);
-                }
-            }
-        }
-
-        if(deviceManager != null) {
-            if (containsUseSingleLayer) {
-                deviceManager.setUseSingleLayerSerialization(Boolean.valueOf(props.get("use-single-layer-serialization").toString()));
-            }
 
-            if (props.containsKey("notification-flow-removed-off")) {
-                deviceManager.setFlowRemovedNotificationOn(Boolean.valueOf(props.get("enable-flow-removed-notification").toString()));
-            }
-            if (props.containsKey("skip-table-features")) {
-                deviceManager.setSkipTableFeatures(Boolean.valueOf(props.get("skip-table-features").toString()));
-            }
-            if (props.containsKey("barrier-count-limit")) {
-                try {
-                    deviceManager.setBarrierCountLimit(Integer.valueOf(props.get("barrier-count-limit").toString()));
-                } catch (NumberFormatException ex) {
-                    deviceManager.setBarrierCountLimit(DEFAULT_BARRIER_COUNT);
-                }
-            }
-            if (props.containsKey("barrier-interval-timeout-limit")){
-                try {
-                    deviceManager.setBarrierInterval(Long.valueOf(props.get("barrier-interval-timeout-limit").toString()));
-                } catch (NumberFormatException ex) {
-                    deviceManager.setBarrierInterval(DEFAULT_BARRIER_TIMEOUT);
-                }
+    @Override
+    public void update(@Nonnull final Map<String, Object> properties) {
+        properties.forEach((key, value) -> {
+            final PropertyType propertyType = PropertyType.forValue(key);
+
+            if (Objects.nonNull(propertyType)) {
+                updateProperty(propertyType, value);
+            } else if (!key.equals("service.pid") && !key.equals("felix.fileinstall.filename")) {
+                LOG.warn("Unsupported configuration property '{}={}'", key, value);
             }
-        }
+        });
+    }
 
-        if (connectionManager != null && props.containsKey("echo-reply-timeout") ){
-            try {
-                connectionManager.setEchoReplyTimeout(Long.valueOf(props.get("echo-reply-timeout").toString()));
-            }catch (NumberFormatException ex){
-                connectionManager.setEchoReplyTimeout(DEFAULT_ECHO_TIMEOUT);
+    private void doPropertyUpdate(final PropertyType propertyType,
+                                  final boolean modifiable,
+                                  final Object origValue,
+                                  final Object newValue,
+                                  final Consumer<Object> successCallback) {
+        if (initialized) {
+            if (Objects.equals(origValue, newValue)) {
+                LOG.debug("{} config parameter is already set to {})", propertyType, origValue);
+                return;
+            } else if (!modifiable) {
+                LOG.warn("{} update ({} -> {}) is not allowed after controller start", propertyType, origValue, newValue);
+                return;
             }
         }
 
-        if(statisticsManager != null && props.containsKey("is-statistics-polling-on")){
-            statisticsManager.setIsStatisticsPollingOn(Boolean.valueOf(props.get("is-statistics-polling-on").toString()));
-        }
-
-        if(statisticsManager != null && props.containsKey("basic-timer-delay")){
-            statisticsManager.setBasicTimerDelay(Long.valueOf(props.get("basic-timer-delay").toString()));
-        }
-
-        if(statisticsManager != null && props.containsKey("maximum-timer-delay")){
-            statisticsManager.setMaximumTimerDelay(Long.valueOf(props.get("maximum-timer-delay").toString()));
-        }
-    }
-
-    private static void registerMXBean(final MessageIntelligenceAgency messageIntelligenceAgency) {
-        final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
-        try {
-            final String pathToMxBean = String.format("%s:type=%s",
-                    MessageIntelligenceAgencyMXBean.class.getPackage().getName(),
-                    MessageIntelligenceAgencyMXBean.class.getSimpleName());
-            final ObjectName name = new ObjectName(pathToMxBean);
-            mbs.registerMBean(messageIntelligenceAgency, name);
-        } catch (MalformedObjectNameException
-                | NotCompliantMBeanException
-                | MBeanRegistrationException
-                | InstanceAlreadyExistsException e) {
-            LOG.warn("Error registering MBean {}", e);
-        }
+        successCallback.accept(newValue);
+        LOG.info("{} config parameter is updated ({} -> {})", propertyType, origValue, newValue);
     }
 
     @Override
-    public void setNotificationProviderService(final NotificationService notificationProviderService) {
-        this.notificationProviderService = notificationProviderService;
-    }
+    public void updateProperty(@Nonnull final PropertyType key, @Nonnull final Object value) {
+        try {
+            final String sValue = value.toString();
+            final Consumer<Object> successCallback;
+            final boolean modifiable;
+            final Object oldValue;
+            final Object newValue;
+
+            switch (key) {
+                case RPC_REQUESTS_QUOTA:
+                    successCallback = (result) -> {
+                        rpcRequestsQuota = (int) result;
+
+                        if (initialized) {
+                            rpcManager.setRpcRequestQuota(rpcRequestsQuota);
+                        }
+                    };
+
+                    oldValue = rpcRequestsQuota;
+                    newValue = Integer.valueOf(sValue);
+                    modifiable = true;
+                    break;
+                case SWITCH_FEATURES_MANDATORY:
+                    successCallback = (result) -> {
+                        switchFeaturesMandatory = (boolean) result;
+
+                        if (initialized) {
+                            deviceManager.setSwitchFeaturesMandatory(switchFeaturesMandatory);
+                        }
+                    };
+
+                    oldValue = switchFeaturesMandatory;
+                    newValue = Boolean.valueOf(sValue);
+                    modifiable = true;
+                    break;
+                case GLOBAL_NOTIFICATION_QUOTA:
+                    successCallback = (result) -> {
+                        globalNotificationQuota = (long) result;
+
+                        if (initialized) {
+                            deviceManager.setGlobalNotificationQuota(globalNotificationQuota);
+                        }
+                    };
+
+                    oldValue = globalNotificationQuota;
+                    newValue = Long.valueOf(sValue);
+                    modifiable = true;
+                    break;
+                case IS_STATISTICS_POLLING_ON:
+                    successCallback = (result) -> {
+                        isStatisticsPollingOn = (boolean) result;
+
+                        if (initialized) {
+                            statisticsManager.setIsStatisticsPollingOn(isStatisticsPollingOn);
+                        }
+                    };
+
+                    oldValue = isStatisticsPollingOn;
+                    newValue = Boolean.valueOf(sValue);
+                    modifiable = true;
+                    break;
+                case IS_STATISTICS_RPC_ENABLED:
+                    successCallback = (result) -> {
+                        isStatisticsRpcEnabled = (boolean) result;
+
+                        if (initialized) {
+                            rpcManager.setStatisticsRpcEnabled(isStatisticsRpcEnabled);
+                        }
+                    };
+
+                    oldValue = isStatisticsRpcEnabled;
+                    newValue = Boolean.valueOf(sValue);
+                    modifiable = true;
+                    break;
+                case BARRIER_INTERVAL_TIMEOUT_LIMIT:
+                    successCallback = (result) -> {
+                        barrierInterval = (long) result;
+
+                        if (initialized) {
+                            deviceManager.setBarrierInterval(barrierInterval);
+                        }
+                    };
+
+                    oldValue = barrierInterval;
+                    newValue = Long.valueOf(sValue);
+                    modifiable = true;
+                    break;
+                case BARRIER_COUNT_LIMIT:
+                    successCallback = (result) -> {
+                        barrierCountLimit = (int) result;
+
+                        if (initialized) {
+                            deviceManager.setBarrierCountLimit(barrierCountLimit);
+                        }
+                    };
+
+                    oldValue = barrierCountLimit;
+                    newValue = Integer.valueOf(sValue);
+                    modifiable = true;
+                    break;
+                case ECHO_REPLY_TIMEOUT:
+                    successCallback = (result) -> {
+                        echoReplyTimeout = (long) result;
+
+                        if (initialized) {
+                            connectionManager.setEchoReplyTimeout(echoReplyTimeout);
+                        }
+                    };
+
+                    oldValue = echoReplyTimeout;
+                    newValue = Long.valueOf(sValue);
+                    modifiable = true;
+                    break;
+                case THREAD_POOL_MIN_THREADS:
+                    successCallback = (result) -> threadPoolMinThreads = (int) result;
+                    oldValue = threadPoolMinThreads;
+                    newValue = Integer.valueOf(sValue);
+                    modifiable = false;
+                    break;
+                case THREAD_POOL_MAX_THREADS:
+                    successCallback = (result) -> threadPoolMaxThreads = (int) result;
+                    oldValue = threadPoolMaxThreads;
+                    newValue = Integer.valueOf(sValue);
+                    modifiable = false;
+                    break;
+                case THREAD_POOL_TIMEOUT:
+                    successCallback = (result) -> threadPoolTimeout = (long) result;
+                    oldValue = threadPoolTimeout;
+                    newValue = Long.valueOf(sValue);
+                    modifiable = false;
+                    break;
+                case ENABLE_FLOW_REMOVED_NOTIFICATION:
+                    successCallback = (result) -> {
+                        isFlowRemovedNotificationOn = (boolean) result;
+
+                        if (initialized) {
+                            deviceManager.setFlowRemovedNotificationOn(isFlowRemovedNotificationOn);
+                        }
+                    };
+
+                    oldValue = isFlowRemovedNotificationOn;
+                    newValue = Boolean.valueOf(sValue);
+                    modifiable = true;
+                    break;
+                case SKIP_TABLE_FEATURES:
+                    successCallback = (result) -> {
+                        skipTableFeatures = (boolean) result;
+
+                        if (initialized) {
+                            deviceManager.setSkipTableFeatures(skipTableFeatures);
+                        }
+                    };
+
+                    oldValue = skipTableFeatures;
+                    newValue = Boolean.valueOf(sValue);
+                    modifiable = true;
+                    break;
+                case BASIC_TIMER_DELAY:
+                    successCallback = (result) -> {
+                        basicTimerDelay = (long) result;
+
+                        if (initialized) {
+                            statisticsManager.setBasicTimerDelay(basicTimerDelay);
+                        }
+                    };
+
+                    oldValue = basicTimerDelay;
+                    newValue = Long.valueOf(sValue);
+                    modifiable = true;
+                    break;
+                case MAXIMUM_TIMER_DELAY:
+                    successCallback = (result) -> {
+                        maximumTimerDelay = (long) result;
+
+                        if (initialized) {
+                            statisticsManager.setMaximumTimerDelay(maximumTimerDelay);
+                        }
+                    };
+
+                    oldValue = maximumTimerDelay;
+                    newValue = Long.valueOf(sValue);
+                    modifiable = true;
+                    break;
+                case USE_SINGLE_LAYER_SERIALIZATION:
+                    successCallback = (result) -> {
+                        useSingleLayerSerialization = (boolean) result;
+
+                        switchConnectionProviders.forEach(switchConnectionProvider -> {
+                            if (useSingleLayerSerialization) {
+                                SerializerInjector.injectSerializers(switchConnectionProvider);
+                                DeserializerInjector.injectDeserializers(switchConnectionProvider);
+                            } else {
+                                DeserializerInjector.revertDeserializers(switchConnectionProvider);
+                            }
+                        });
+                    };
+
+                    oldValue = useSingleLayerSerialization;
+                    newValue = Boolean.valueOf(sValue);
+                    modifiable = true;
+                    break;
+                default:
+                    LOG.warn("Unsupported configuration property '{}={}'", key, sValue);
+                    return;
+            }
 
-    @Override
-    public void setNotificationPublishService(final NotificationPublishService notificationPublishProviderService) {
-        this.notificationPublishService = notificationPublishProviderService;
+            doPropertyUpdate(key, modifiable, oldValue, newValue, successCallback);
+        } catch (final Exception ex) {
+            LOG.warn("Failed to read configuration property '{}={}', error: {}", key, value, ex);
+        }
     }
 
     @Override
@@ -391,13 +481,9 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF
         return extensionConverterManager;
     }
 
-    @Override
-    public void setIsStatisticsRpcEnabled(final boolean isStatisticsRpcEnabled) {
-        this.isStatisticsRpcEnabled = isStatisticsRpcEnabled;
-    }
-
     @Override
     public void close() throws Exception {
+        initialized = false;
         //TODO: consider wrapping each manager into try-catch
         deviceManager.close();
         rpcManager.close();
@@ -407,9 +493,19 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF
         threadPool.shutdown();
     }
 
-    @Override
-    public void setIsUseSingleLayerSerialization(Boolean useSingleLayerSerialization) {
-        this.useSingleLayerSerialization = useSingleLayerSerialization;
+    private static void registerMXBean(final MessageIntelligenceAgency messageIntelligenceAgency) {
+        final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+        try {
+            final String pathToMxBean = String.format("%s:type=%s",
+                    MessageIntelligenceAgencyMXBean.class.getPackage().getName(),
+                    MessageIntelligenceAgencyMXBean.class.getSimpleName());
+            final ObjectName name = new ObjectName(pathToMxBean);
+            mbs.registerMBean(messageIntelligenceAgency, name);
+        } catch (MalformedObjectNameException
+                | NotCompliantMBeanException
+                | MBeanRegistrationException
+                | InstanceAlreadyExistsException e) {
+            LOG.warn("Error registering MBean {}", e);
+        }
     }
-
-}
\ No newline at end of file
+}
index 8e6f3c8e264a7aba1bb2cc0a3cf8bb156da335d9..01877f5807b36f4813f705e6de87a44eb5a1732b 100644 (file)
@@ -39,12 +39,11 @@ public class ConnectionManagerImpl implements ConnectionManager {
     private static final Logger LOG = LoggerFactory.getLogger(ConnectionManagerImpl.class);
     private static final boolean BITMAP_NEGOTIATION_ENABLED = true;
     private DeviceConnectedHandler deviceConnectedHandler;
-    private long echoReplyTimeout;
+    private long echoReplyTimeout = 2000;
     private final ThreadPoolExecutor threadPool;
     private DeviceDisconnectedHandler deviceDisconnectedHandler;
 
-    public ConnectionManagerImpl(long echoReplyTimeout, final ThreadPoolExecutor threadPool) {
-        this.echoReplyTimeout = echoReplyTimeout;
+    public ConnectionManagerImpl(final ThreadPoolExecutor threadPool) {
         this.threadPool = threadPool;
     }
 
@@ -110,6 +109,7 @@ public class ConnectionManagerImpl implements ConnectionManager {
         this.deviceDisconnectedHandler = deviceDisconnectedHandler;
     }
 
+    @Override
     public void setEchoReplyTimeout(long echoReplyTimeout){
         this.echoReplyTimeout = echoReplyTimeout;
     }
index d4d64540f917473f1db09927e9d7c4346c391059..daeea7e31ed95c97a546b9560e0d124bd42ee6fa 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2015, 2017 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,
@@ -13,10 +13,8 @@ import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import io.netty.util.HashedWheelTimer;
 import io.netty.util.internal.ConcurrentSet;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
-import java.util.List;
 import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
@@ -24,8 +22,8 @@ import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
-import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
@@ -65,8 +63,8 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
 
     private static final Logger LOG = LoggerFactory.getLogger(DeviceManagerImpl.class);
 
-    private final long globalNotificationQuota;
-    private final boolean switchFeaturesMandatory;
+    private long globalNotificationQuota;
+    private boolean switchFeaturesMandatory;
     private boolean isFlowRemovedNotificationOn;
     private boolean skipTableFeatures;
     private static final int SPY_RATE = 10;
@@ -91,17 +89,10 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
 
     public DeviceManagerImpl(@Nonnull final DataBroker dataBroker,
                              @Nonnull final MessageSpy messageSpy,
-                             final NotificationPublishService notificationPublishService,
+                             @Nullable final NotificationPublishService notificationPublishService,
                              @Nonnull final HashedWheelTimer hashedWheelTimer,
                              @Nonnull final ConvertorExecutor convertorExecutor,
-                             @Nonnull final DeviceInitializerProvider deviceInitializerProvider,
-                             final long globalNotificationQuota,
-                             final boolean switchFeaturesMandatory,
-                             final long barrierInterval,
-                             final int barrierCountLimit,
-                             final boolean isFlowRemovedNotificationOn,
-                             final boolean skipTableFeatures,
-                             final boolean useSingleLayerSerialization) {
+                             @Nonnull final DeviceInitializerProvider deviceInitializerProvider) {
 
         this.dataBroker = dataBroker;
         this.deviceInitializerProvider = deviceInitializerProvider;
@@ -118,18 +109,11 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
             throw new IllegalStateException(e);
         }
 
-        this.switchFeaturesMandatory = switchFeaturesMandatory;
-        this.globalNotificationQuota = globalNotificationQuota;
-        this.isFlowRemovedNotificationOn = isFlowRemovedNotificationOn;
-        this.skipTableFeatures = skipTableFeatures;
         this.convertorExecutor = convertorExecutor;
         this.hashedWheelTimer = hashedWheelTimer;
-        this.barrierIntervalNanos = TimeUnit.MILLISECONDS.toNanos(barrierInterval);
-        this.barrierCountLimit = barrierCountLimit;
         this.spyPool = new ScheduledThreadPoolExecutor(1);
         this.notificationPublishService = notificationPublishService;
         this.messageSpy = messageSpy;
-        this.useSingleLayerSerialization = useSingleLayerSerialization;
     }
 
     @Override
@@ -181,6 +165,16 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
         return this.isFlowRemovedNotificationOn;
     }
 
+    @Override
+    public void setGlobalNotificationQuota(final long globalNotificationQuota) {
+        this.globalNotificationQuota = globalNotificationQuota;
+    }
+
+    @Override
+    public void setSwitchFeaturesMandatory(final boolean switchFeaturesMandatory) {
+        this.switchFeaturesMandatory = switchFeaturesMandatory;
+    }
+
     @Override
     public void setSkipTableFeatures(boolean skipTableFeaturesValue) {
         skipTableFeatures = skipTableFeaturesValue;
@@ -197,7 +191,7 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
     }
 
     @Override
-    public CheckedFuture<Void, TransactionCommitFailedException> removeDeviceFromOperationalDS(final KeyedInstanceIdentifier<Node, NodeKey> ii) {    
+    public CheckedFuture<Void, TransactionCommitFailedException> removeDeviceFromOperationalDS(final KeyedInstanceIdentifier<Node, NodeKey> ii) {
         final WriteTransaction delWtx = dataBroker.newWriteOnlyTransaction();
         delWtx.delete(LogicalDatastoreType.OPERATIONAL, ii);
         final CheckedFuture<Void, TransactionCommitFailedException> delFuture = delWtx.submit();
@@ -218,7 +212,7 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
 
         return delFuture;
     }
-    
+
     @Override
     public CheckedFuture<Void, TransactionCommitFailedException> removeDeviceFromOperationalDS(final DeviceInfo deviceInfo) {
         return this.removeDeviceFromOperationalDS(deviceInfo.getNodeInstanceIdentifier());
@@ -229,7 +223,7 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
         this.useSingleLayerSerialization = useSingleLayerSerialization;
     }
 
-    public DeviceContext createContext(@CheckForNull final ConnectionContext connectionContext) {
+    public DeviceContext createContext(@Nonnull final ConnectionContext connectionContext) {
 
         LOG.info("ConnectionEvent: Device connected to controller, Device:{}, NodeId:{}",
                 connectionContext.getConnectionAdapter().getRemoteAddress(),
@@ -327,7 +321,7 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
     }
 
     @Override
-    public void sendNodeAddedNotification(@CheckForNull final DeviceInfo deviceInfo) {
+    public void sendNodeAddedNotification(@Nonnull final DeviceInfo deviceInfo) {
         if (!notificationCreateNodeSend.contains(deviceInfo)) {
             notificationCreateNodeSend.add(deviceInfo);
             NodeUpdatedBuilder builder = new NodeUpdatedBuilder();
index 4231e9cd7213ad127e46f951c12f559c65cd23e1..cd74835ec7648139a02cf1d7a1ec8c1ce4570329 100644 (file)
@@ -12,7 +12,7 @@ import com.google.common.collect.Iterators;
 import java.util.Iterator;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
-import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
@@ -28,7 +28,7 @@ public class RpcManagerImpl implements RpcManager {
 
     private static final Logger LOG = LoggerFactory.getLogger(RpcManagerImpl.class);
     private final RpcProviderRegistry rpcProviderRegistry;
-    private final int maxRequestsQuota;
+    private int rpcRequestQuota;
     private final ConcurrentMap<DeviceInfo, RpcContext> contexts = new ConcurrentHashMap<>();
     private boolean isStatisticsRpcEnabled;
     private final ExtensionConverterProvider extensionConverterProvider;
@@ -36,14 +36,11 @@ public class RpcManagerImpl implements RpcManager {
     private final NotificationPublishService notificationPublishService;
 
 
-    public RpcManagerImpl(
-            final RpcProviderRegistry rpcProviderRegistry,
-            final int quotaValue,
-            final ExtensionConverterProvider extensionConverterProvider,
-               final ConvertorExecutor convertorExecutor,
-            final NotificationPublishService notificationPublishService) {
+    public RpcManagerImpl(final RpcProviderRegistry rpcProviderRegistry,
+                          final ExtensionConverterProvider extensionConverterProvider,
+                          final ConvertorExecutor convertorExecutor,
+                          final NotificationPublishService notificationPublishService) {
         this.rpcProviderRegistry = rpcProviderRegistry;
-        this.maxRequestsQuota = quotaValue;
         this.extensionConverterProvider = extensionConverterProvider;
         this.convertorExecutor = convertorExecutor;
         this.notificationPublishService = notificationPublishService;
@@ -74,10 +71,14 @@ public class RpcManagerImpl implements RpcManager {
     }
 
     @Override
-    public RpcContext createContext(final @CheckForNull DeviceInfo deviceInfo, final @CheckForNull DeviceContext deviceContext) {
+    public void setRpcRequestQuota(final int rpcRequestQuota) {
+        this.rpcRequestQuota = rpcRequestQuota;
+    }
+
+    public RpcContext createContext(final @Nonnull DeviceInfo deviceInfo, final @Nonnull DeviceContext deviceContext) {
         return new RpcContextImpl(
                 rpcProviderRegistry,
-                maxRequestsQuota,
+                rpcRequestQuota,
                 deviceContext,
                 extensionConverterProvider,
                 convertorExecutor,
@@ -85,7 +86,6 @@ public class RpcManagerImpl implements RpcManager {
                 this.isStatisticsRpcEnabled);
     }
 
-
     @Override
     public void onDeviceRemoved(final DeviceInfo deviceInfo) {
         contexts.remove(deviceInfo);
index fb91ab57cb1654d3c2df6b4887a5a596d4f5dcae..f55641959fc78b4e960e74666a08ed7c1642ffc4 100644 (file)
@@ -72,19 +72,12 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag
     private final HashedWheelTimer hashedWheelTimer;
 
     public StatisticsManagerImpl(@Nonnull final RpcProviderRegistry rpcProviderRegistry,
-                                 final boolean isStatisticsPollingOn,
                                  final HashedWheelTimer hashedWheelTimer,
-                                 final ConvertorExecutor convertorExecutor,
-                                 final long basicTimerDelay,
-                                 final long maximumTimerDelay) {
-           this.converterExecutor = convertorExecutor;
-        this.controlServiceRegistration = Preconditions.checkNotNull(
-                rpcProviderRegistry.addRpcImplementation(StatisticsManagerControlService.class, this)
-        );
-        this.isStatisticsPollingOn = isStatisticsPollingOn;
-        this.basicTimerDelay = basicTimerDelay;
-        this.currentTimerDelay = basicTimerDelay;
-        this.maximumTimerDelay = maximumTimerDelay;
+                                 final ConvertorExecutor convertorExecutor) {
+        this.converterExecutor = convertorExecutor;
+        this.controlServiceRegistration = Preconditions.checkNotNull(rpcProviderRegistry
+                .addRpcImplementation(StatisticsManagerControlService.class, this));
+
         this.hashedWheelTimer = hashedWheelTimer;
     }
 
@@ -346,6 +339,7 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag
     @Override
     public void setBasicTimerDelay(final long basicTimerDelay) {
         this.basicTimerDelay = basicTimerDelay;
+        this.currentTimerDelay = basicTimerDelay;
     }
 
     @Override
index aa11506cb3be7c4426183927627a183e8c3f3557..317798f22b44809a4e1beeaf4bc94944a3a04ad0 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.openflowplugin.impl.util;
 import com.google.common.base.Preconditions;
 import com.google.common.reflect.TypeToken;
 import java.util.concurrent.atomic.AtomicLong;
-import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
 import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext;
@@ -84,8 +84,8 @@ public class MdSalRegistrationUtils {
      * @param deviceContext - every service needs {@link org.opendaylight.openflowplugin.api.openflow.device.DeviceContext} as input parameter
      * @param convertorExecutor convertor executor
      */
-    public static void registerServices(@CheckForNull final RpcContext rpcContext,
-                                        @CheckForNull final DeviceContext deviceContext,
+    public static void registerServices(@Nonnull final RpcContext rpcContext,
+                                        @Nonnull final DeviceContext deviceContext,
                                         final ExtensionConverterProvider extensionConverterProvider,
                                         final ConvertorExecutor convertorExecutor) {
         Preconditions.checkArgument(rpcContext != null);
index e4553f32204e6aaf5009dff6a5b5bba8adf9146e..1f2d4e9b82b2d46d5c35fe955ea46aec0ffd65bd 100644 (file)
@@ -22,6 +22,7 @@ import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
 import org.opendaylight.controller.md.sal.binding.api.NotificationService;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
@@ -30,6 +31,7 @@ import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider;
+import org.opendaylight.openflowplugin.api.openflow.OpenFlowPluginConfigurationService.PropertyType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.sm.control.rev150812.StatisticsManagerControlService;
 
 @RunWith(MockitoJUnitRunner.class)
@@ -44,6 +46,9 @@ public class OpenFlowPluginProviderImplTest {
     @Mock
     NotificationService notificationService;
 
+    @Mock
+    NotificationPublishService notificationPublishService;
+
     @Mock
     WriteTransaction writeTransaction;
 
@@ -62,7 +67,7 @@ public class OpenFlowPluginProviderImplTest {
     @Mock
     ClusterSingletonServiceProvider clusterSingletonServiceProvider;
 
-    private static final long RPC_REQUESTS_QUOTA = 500;
+    private static final int RPC_REQUESTS_QUOTA = 500;
     private static final long GLOBAL_NOTIFICATION_QUOTA = 131072;
     private static final int THREAD_POOL_MIN_THREADS = 1;
     private static final int THREAD_POOL_MAX_THREADS = 32000;
@@ -79,18 +84,19 @@ public class OpenFlowPluginProviderImplTest {
         when(switchConnectionProvider.startup()).thenReturn(Futures.immediateCheckedFuture(null));
 
         provider = new OpenFlowPluginProviderImpl(
-                RPC_REQUESTS_QUOTA,
-                GLOBAL_NOTIFICATION_QUOTA,
-                THREAD_POOL_MIN_THREADS,
-                THREAD_POOL_MAX_THREADS,
-                THREAD_POOL_TIMEOUT,
+                Lists.newArrayList(switchConnectionProvider),
+                dataBroker,
+                rpcProviderRegistry,
+                notificationService,
+                notificationPublishService,
+                clusterSingletonServiceProvider,
                 entityOwnershipService);
 
-        provider.setDataBroker(dataBroker);
-        provider.setRpcProviderRegistry(rpcProviderRegistry);
-        provider.setNotificationProviderService(notificationService);
-        provider.setSwitchConnectionProviders(Lists.newArrayList(switchConnectionProvider));
-        provider.setClusteringSingletonServicesProvider(clusterSingletonServiceProvider);
+        provider.updateProperty(PropertyType.THREAD_POOL_MIN_THREADS, THREAD_POOL_MIN_THREADS);
+        provider.updateProperty(PropertyType.THREAD_POOL_MAX_THREADS, THREAD_POOL_MAX_THREADS);
+        provider.updateProperty(PropertyType.THREAD_POOL_TIMEOUT, THREAD_POOL_TIMEOUT);
+        provider.updateProperty(PropertyType.RPC_REQUESTS_QUOTA, RPC_REQUESTS_QUOTA);
+        provider.updateProperty(PropertyType.GLOBAL_NOTIFICATION_QUOTA, GLOBAL_NOTIFICATION_QUOTA);
     }
 
     @After
@@ -103,4 +109,4 @@ public class OpenFlowPluginProviderImplTest {
         provider.initialize();
         verify(switchConnectionProvider).startup();
     }
-}
\ No newline at end of file
+}
index 9a4338ea621c0d1b01336bbe72697f051c2f0531..001df46d8d2ba3871af1118f83d4d06154405341 100644 (file)
@@ -9,11 +9,9 @@ package org.opendaylight.openflowplugin.impl.connection;
 
 import com.google.common.util.concurrent.SettableFuture;
 import java.math.BigInteger;
-import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.util.concurrent.SynchronousQueue;
 import java.util.concurrent.TimeUnit;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -71,7 +69,8 @@ public class ConnectionManagerImplTest {
                 60L, TimeUnit.SECONDS,
                 new SynchronousQueue<>(), "ofppool");
 
-        connectionManagerImpl = new ConnectionManagerImpl(ECHO_REPLY_TIMEOUT, threadPool);
+        connectionManagerImpl = new ConnectionManagerImpl(threadPool);
+        connectionManagerImpl.setEchoReplyTimeout(ECHO_REPLY_TIMEOUT);
         connectionManagerImpl.setDeviceConnectedHandler(deviceConnectedHandler);
         final InetSocketAddress deviceAddress = InetSocketAddress.createUnresolved("yahoo", 42);
         Mockito.when(connection.getRemoteAddress()).thenReturn(deviceAddress);
index fb3c0ea012a35fd5c72b2481ce9fc5c53331397e..287740303b07a6ba7c8b3b97227e54e207e0b967 100644 (file)
@@ -95,21 +95,23 @@ public class DeviceManagerImplTest {
 
         when(mockedWriteTransaction.submit()).thenReturn(mockedFuture);
 
-        return new DeviceManagerImpl(
-            mockedDataBroker,
+        final DeviceManagerImpl deviceManager = new DeviceManagerImpl(
+                mockedDataBroker,
                 messageIntelligenceAgency,
                 null,
                 new HashedWheelTimer(),
                 convertorExecutor,
-                DeviceInitializerProviderFactory.createDefaultProvider(),
-                TEST_VALUE_GLOBAL_NOTIFICATION_QUOTA,
-            false,
-            barrierIntervalNanos,
-            barrierCountLimit,
-                true,
-                false,
-            false
-        );
+                DeviceInitializerProviderFactory.createDefaultProvider());
+
+        deviceManager.setBarrierCountLimit(barrierCountLimit);
+        deviceManager.setBarrierInterval(barrierIntervalNanos);
+        deviceManager.setGlobalNotificationQuota(TEST_VALUE_GLOBAL_NOTIFICATION_QUOTA);
+        deviceManager.setSwitchFeaturesMandatory(false);
+        deviceManager.setFlowRemovedNotificationOn(true);
+        deviceManager.setSkipTableFeatures(false);
+        deviceManager.setUseSingleLayerSerialization(false);
+
+        return deviceManager;
     }
 
     @Test
index 912c52c524c8cd5490991dd87674094a9cb460aa..9a5b82cf1890762e5a0681c15fd54514c8a42959 100644 (file)
@@ -86,7 +86,8 @@ public class RpcManagerImplTest {
     @Before
     public void setUp() {
         final NodeKey nodeKey = new NodeKey(nodeId);
-        rpcManager = new RpcManagerImpl(rpcProviderRegistry, QUOTA_VALUE, extensionConverterProvider, convertorExecutor, notificationPublishService);
+        rpcManager = new RpcManagerImpl(rpcProviderRegistry, extensionConverterProvider, convertorExecutor, notificationPublishService);
+        rpcManager.setRpcRequestQuota(QUOTA_VALUE);
 
         GetFeaturesOutput featuresOutput = new GetFeaturesOutputBuilder()
                 .setVersion(OFConstants.OFP_VERSION_1_3)
index 8d15f27b3d882f6a85019d1029624952ed024e26..c7db1430b4a0b82cc53bdd99737c078921df342a 100644 (file)
@@ -12,6 +12,8 @@ import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import com.google.common.util.concurrent.Futures;
+import io.netty.util.HashedWheelTimer;
+import io.netty.util.Timeout;
 import java.lang.reflect.Field;
 import java.math.BigInteger;
 import java.util.Collections;
@@ -64,8 +66,6 @@ import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import io.netty.util.HashedWheelTimer;
-import io.netty.util.Timeout;
 
 
 @RunWith(MockitoJUnitRunner.class)
@@ -152,8 +152,11 @@ public class StatisticsManagerImplTest {
         final ConvertorManager convertorManager = ConvertorManagerFactory.createDefaultManager();
         final long basicTimerDelay = 3000L;
         final long maximumTimerDelay = 900000L;
-        statisticsManager = new StatisticsManagerImpl(rpcProviderRegistry, false, new HashedWheelTimer(),
-                convertorManager, basicTimerDelay, maximumTimerDelay);
+        statisticsManager = new StatisticsManagerImpl(rpcProviderRegistry, new HashedWheelTimer(),
+                convertorManager);
+        statisticsManager.setBasicTimerDelay(basicTimerDelay);
+        statisticsManager.setMaximumTimerDelay(maximumTimerDelay);
+        statisticsManager.setIsStatisticsPollingOn(false);
     }
 
     private static Map<DeviceInfo, StatisticsContext> getContextsMap(final StatisticsManagerImpl statisticsManager)