Merge "BUG:6461 Enhancement to find successfully completed transaction." into stable...
authorAnil Vishnoi <vishnoianil@gmail.com>
Thu, 21 Sep 2017 20:43:30 +0000 (20:43 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 21 Sep 2017 20:43:30 +0000 (20:43 +0000)
182 files changed:
applications/bulk-o-matic/pom.xml
applications/bulk-o-matic/src/main/java/org/opendaylight/openflowplugin/applications/bulk/o/matic/BulkOMaticUtils.java
applications/features/pom.xml
applications/forwardingrules-manager/pom.xml
applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/FlowNodeReconciliation.java
applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/ForwardingRulesManager.java
applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/AbstractListeningCommiter.java
applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/DeviceMastership.java
applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/DeviceMastershipManager.java
applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/FlowNodeReconciliationImpl.java
applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/ForwardingRulesManagerImpl.java
applications/forwardingrules-manager/src/main/resources/org/opendaylight/blueprint/forwardingrules-manager.xml
applications/forwardingrules-manager/src/test/java/org/opendaylight/openflowplugin/applications/frm/impl/DeviceMastershipManagerTest.java
applications/forwardingrules-manager/src/test/java/org/opendaylight/openflowplugin/applications/frm/impl/DeviceMastershipTest.java
applications/forwardingrules-manager/src/test/java/test/mock/FlowListenerTest.java
applications/forwardingrules-manager/src/test/java/test/mock/GroupListenerTest.java
applications/forwardingrules-manager/src/test/java/test/mock/MeterListenerTest.java
applications/forwardingrules-manager/src/test/java/test/mock/NodeListenerTest.java
applications/forwardingrules-manager/src/test/java/test/mock/TableFeaturesListenerTest.java
applications/forwardingrules-sync/pom.xml
applications/inventory-manager/pom.xml
applications/lldp-speaker/pom.xml
applications/notification-supplier/pom.xml
applications/of-switch-config-pusher/pom.xml
applications/pom.xml
applications/statistics-manager/pom.xml
applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/StatRpcMsgManager.java
applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatRpcMsgManagerImpl.java
applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatisticsManagerImpl.java
applications/table-miss-enforcer/pom.xml
applications/table-miss-enforcer/src/main/java/org/opendaylight/openflowplugin/applications/tableMissEnforcer/LLDPPacketPuntEnforcer.java
applications/topology-lldp-discovery/pom.xml
applications/topology-manager/pom.xml
artifacts/pom.xml
distribution/karaf/pom.xml
drop-test-karaf/pom.xml
drop-test/pom.xml
extension/features-he/pom.xml
extension/features/pom.xml
extension/openflowjava-extension-nicira-api/pom.xml
extension/openflowjava-extension-nicira/pom.xml
extension/openflowjava-extension-nicira/src/main/java/org/opendaylight/openflowjava/nx/codec/match/AbstractMatchCodec.java
extension/openflowjava-extension-nicira/src/main/java/org/opendaylight/openflowjava/nx/codec/match/AbstractRegCodec.java
extension/openflowjava-extension-nicira/src/main/yang/nicira-match.yang
extension/openflowplugin-extension-api/pom.xml
extension/openflowplugin-extension-api/src/main/java/org/opendaylight/openflowplugin/extension/api/GroupingLooseResolver.java
extension/openflowplugin-extension-nicira-config/pom.xml
extension/openflowplugin-extension-nicira/pom.xml
extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/NiciraExtensionProvider.java
extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/match/RegConvertor.java
extension/openflowplugin-extension-nicira/src/main/yang/openflowplugin-extension-nicira-match.yang
extension/pom.xml
extension/test-extension/pom.xml
features-he/pom.xml
features/pom.xml
model/model-flow-base/pom.xml
model/model-flow-service/pom.xml
model/model-flow-statistics/pom.xml
model/pom.xml
openflowplugin-api/pom.xml
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/OFConstants.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OFPContext.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/DeviceContext.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceManager.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/lifecycle/LifecycleService.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/AbstractModelDrivenSwitchRegistration.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/ModelDrivenSwitch.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/ModelDrivenSwitchRegistration.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/core/ConnectionConductor.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/core/ErrorHandler.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/core/HandshakeListener.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/core/HandshakeManager.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/core/IMDMessageTranslator.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/core/NotificationEnqueuer.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/core/NotificationQueueWrapper.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/core/SwitchConnectionDistinguisher.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/core/TranslatorKey.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/core/sal/BuildSwitchFeatures.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/core/sal/NotificationComposer.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/core/session/IMessageDispatchService.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/core/session/SessionContext.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/core/session/SessionListener.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/core/session/SessionManager.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/core/session/SwitchSessionKeyOF.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/queue/Enqueuer.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/queue/HarvesterHandle.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/queue/MessageSourcePollRegistrator.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/queue/PopListener.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/queue/QueueItem.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/queue/QueueKeeper.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/queue/QueueProcessor.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/queue/WaterMarkListener.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/util/OpenflowVersion.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/util/PollableQueuesPriorityZipper.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/md/util/PollableQueuesZipper.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/registry/CommonDeviceRegistry.java [new file with mode: 0644]
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/registry/flow/DeviceFlowRegistry.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/registry/flow/FlowDescriptor.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/registry/group/DeviceGroupRegistry.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/registry/meter/DeviceMeterRegistry.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-he/pom.xml
openflowplugin-blueprint-config/pom.xml
openflowplugin-blueprint-config/src/main/resources/initial/openflowplugin.cfg
openflowplugin-blueprint-config/src/main/resources/org/opendaylight/blueprint/openflowplugin.xml
openflowplugin-common/pom.xml
openflowplugin-controller-config/pom.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/connection/listener/HandshakeListenerImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/connection/listener/SystemNotificationsListenerImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/TransactionChainManager.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/lifecycle/LifecycleServiceImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/registry/flow/DeviceFlowRegistryImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/registry/flow/FlowDescriptorFactory.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/registry/flow/FlowRegistryKeyFactory.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/registry/group/DeviceGroupRegistryImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/registry/meter/DeviceMeterRegistryImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcContextImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcManagerImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestOnTheFlyCallback.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalFlowServiceImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalGroupServiceImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalMeterServiceImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsGatheringUtils.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractDirectStatisticsService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/FlowDirectStatisticsService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/AddressNormalizationUtil.java [new file with mode: 0644]
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/DeviceInitializationUtils.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/IntegerIpAddress.java [deleted file]
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MatchComparatorFactory.java [deleted file]
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MatchComparatorHelper.java [deleted file]
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MatchNormalizationUtil.java [new file with mode: 0644]
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MdSalRegistrationUtils.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/SimpleComparator.java [deleted file]
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/connection/listener/HandshakeListenerImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/connection/listener/SystemNotificationsListenerImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/lifecycle/LifecycleServiceImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/registry/flow/DeviceFlowRegistryImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/registry/flow/FlowDescriptorDtoTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/registry/flow/FlowRegistryKeyFactoryTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/registry/group/DeviceGroupRegistryImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/registry/meter/DeviceMeterRegistryImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/rpc/RpcManagerImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestOnTheFlyCallbackTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalFlowServiceImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalGroupServiceImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalMeterServiceImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/ServiceMocking.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsGatheringUtilsTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/FlowDirectStatisticsServiceTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/util/AddressNormalizationUtilTest.java [new file with mode: 0644]
openflowplugin-it/pom.xml
openflowplugin/pom.xml
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/ConnectionConductorImpl.java
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/HandshakeManagerImpl.java
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/common/IpConversionUtil.java
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/util/OpenflowPortsUtil.java
openflowplugin/src/test/java/org/opendaylight/openflowplugin/openflow/md/core/ConnectionConductorImplTest.java
openflowplugin/src/test/java/org/opendaylight/openflowplugin/openflow/md/core/HandshakeManagerImplTest.java
openflowplugin/src/test/java/org/opendaylight/openflowplugin/openflow/md/core/MessageFactoryTest.java
parent/pom.xml
pom.xml
samples/learning-switch/pom.xml
samples/sample-consumer/pom.xml
test-common/pom.xml
test-provider/pom.xml

index abf2dd6ac57b8cb685a5d452bd88b3fc0e407e4b..71eddacaa0db2687854a36325dde0a6d0eb46771 100644 (file)
@@ -6,7 +6,7 @@
     <parent>
         <groupId>org.opendaylight.openflowplugin</groupId>
         <artifactId>applications</artifactId>
-        <version>0.3.3-SNAPSHOT</version>
+        <version>0.3.5-SNAPSHOT</version>
     </parent>
     <groupId>org.opendaylight.openflowplugin.applications</groupId>
     <artifactId>bulk-o-matic</artifactId>
index 37f9899546ca769683ab814a9c20a2b44fca7ef6..8c80b15b03653c6d7c03a5e22f1d4d0e0ccaab3b 100644 (file)
@@ -28,9 +28,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
-public class BulkOMaticUtils {
-
-    private BulkOMaticUtils () { }
+public final class BulkOMaticUtils {
 
     public static final int DEFUALT_STATUS = FlowCounter.OperationStatus.INIT.status();
     public static final int DEFAULT_FLOW_COUNT = 0;
@@ -38,11 +36,14 @@ public class BulkOMaticUtils {
     public static final String DEFAULT_UNITS = "ns";
     public static final String DEVICE_TYPE_PREFIX = "openflow:";
 
+    private BulkOMaticUtils() {
+    }
+
     public static String ipIntToStr (int k) {
-        return new StringBuilder().append(((k >> 24) & 0xFF)).append(".")
-                .append(((k >> 16) & 0xFF)).append(".")
-                .append(((k >> 8) & 0xFF)).append(".")
-                .append((k & 0xFF)).append("/32").toString();
+        return new StringBuilder().append(k >> 24 & 0xFF).append(".")
+                .append(k >> 16 & 0xFF).append(".")
+                .append(k >> 8 & 0xFF).append(".")
+                .append(k & 0xFF).append("/32").toString();
     }
 
     public static Match getMatch(final Integer sourceIp){
@@ -87,7 +88,6 @@ public class BulkOMaticUtils {
                 .augmentation(FlowCapableNode.class)
                 .child(Table.class, new TableKey(tableId))
                 .build();
-
     }
 
     public static InstanceIdentifier<Flow> getFlowId(final InstanceIdentifier<Table> tablePath, final String flowId) {
index d676591f69c9970cdd24d728ffd200e4564e7d61..abef50e4252f525eb9d31ffee95c600fc1f17589 100644 (file)
@@ -4,21 +4,21 @@
   <parent>
     <groupId>org.opendaylight.odlparent</groupId>
     <artifactId>features-parent</artifactId>
-    <version>1.7.3-SNAPSHOT</version>
+    <version>1.7.5-SNAPSHOT</version>
     <relativePath/>
   </parent>
 
   <groupId>org.opendaylight.openflowplugin</groupId>
-  <version>0.3.3-SNAPSHOT</version>
+  <version>0.3.5-SNAPSHOT</version>
   <artifactId>features-flow</artifactId>
   <packaging>jar</packaging>
 
   <properties>
-    <yangtools.version>1.0.3-SNAPSHOT</yangtools.version>
-    <config.version>0.5.3-SNAPSHOT</config.version>
-    <mdsal.version>1.4.3-SNAPSHOT</mdsal.version>
-    <openflowjava.version>0.8.3-SNAPSHOT</openflowjava.version>
-    <lldp.version>0.11.3-SNAPSHOT</lldp.version>
+    <yangtools.version>1.0.5-SNAPSHOT</yangtools.version>
+    <config.version>0.5.5-SNAPSHOT</config.version>
+    <mdsal.version>1.4.5-SNAPSHOT</mdsal.version>
+    <openflowjava.version>0.8.5-SNAPSHOT</openflowjava.version>
+    <lldp.version>0.11.5-SNAPSHOT</lldp.version>
 
     <config.configfile.directory>etc/opendaylight/karaf</config.configfile.directory>
     <config.statistics.manager.configfile>30-statistics-manager.xml</config.statistics.manager.configfile>
index fc4165e15bb28224da765a2e96907ebe4be0dcad..45a25cdfd7d1c1145efdf40d701a33d962e9ac67 100644 (file)
@@ -4,7 +4,7 @@
   <parent>
     <groupId>org.opendaylight.openflowplugin</groupId>
     <artifactId>applications</artifactId>
-    <version>0.3.3-SNAPSHOT</version>
+    <version>0.3.5-SNAPSHOT</version>
   </parent>
   <groupId>org.opendaylight.openflowplugin.applications</groupId>
   <artifactId>forwardingrules-manager</artifactId>
index b15f2ff21f89ce4751969ac64452e4bfa3bbdc2b..52ba4fcdc27be8bfe84b5e2b2b92cc525b0b3555 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2014, 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,52 +8,23 @@
 
 package org.opendaylight.openflowplugin.applications.frm;
 
-import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /**
- * forwardingrules-manager
- * org.opendaylight.openflowplugin.applications.frm
- *
- * FlowNodeReconciliation
- * It represent Reconciliation functionality for every new device.
- * So we have to read all possible pre-configured Flows, Meters and Groups from
- * Config/DS and add all to new device.
- * New device is represented by new {@link org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode}
- * in Operational/DS. So we have to add listener for Wildcarded path in base data change scope.
- *
- * WildCarded InstanceIdentifier:
- * {@code
- *
- * InstanceIdentifier.create(Nodes.class).child(Node.class).augmentation(FlowCapableNode.class)
- *
- * }
+ * Implementation provider of this interface will implement reconciliation functionality for a newly connected node.
+ * Implementation is not enforced to do reconciliation in any specific way, but the higher level intention is to
+ * provide best effort reconciliation of  all the configuration (flow/meter/group) present in configuration data store
+ * for the given node.
  *
  * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- * Created: Aug 26, 2014
  */
-public interface FlowNodeReconciliation extends ClusteredDataTreeChangeListener<FlowCapableNode>, AutoCloseable {
-
-    /**
-     * Method contains Node registration to {@link ForwardingRulesManager} functionality
-     * as a prevention to use a validation check to the Operational/DS for identify
-     * pre-configure transaction and serious device commit in every transaction.
-     *
-     * Second part of functionality is own reconciliation pre-configure
-     * Flows, Meters and Groups.
-     *
-     * @param connectedNode - {@link org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier} to new Node
-     */
-    void flowNodeConnected(InstanceIdentifier<FlowCapableNode> connectedNode);
+public interface FlowNodeReconciliation extends AutoCloseable {
 
     /**
-     * Method contains functionality for registered Node {@link FlowCapableNode} removing
-     * from {@link ForwardingRulesManager}
-     *
-     * @param disconnectedNode - {@link org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier} to removed Node
+     * Reconcile the switch data store configuration on the switch
+     * @param connectedNode Node that need reconciliation
      */
-    void flowNodeDisconnected(InstanceIdentifier<FlowCapableNode> disconnectedNode);
+    void reconcileConfiguration(InstanceIdentifier<FlowCapableNode> connectedNode);
 }
 
index d6916d18e004c9fb080a6fd43f7e994b843a5abc..0dcd3aa17674830a51a07021b36f6d7fb6ab7e47 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2014, 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,
@@ -23,21 +23,15 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /**
- * forwardingrules-manager
- * org.opendaylight.openflowplugin.applications.frm
- *
- * ForwardingRulesManager
- * It represent a central point for whole modul. Implementation
+ * It represent a central point for whole module. Implementation
  * Flow Provider registers the link FlowChangeListener} and it holds all needed
  * services for link FlowChangeListener}.
  *
  * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- * Created: Aug 25, 2014
  */
 public interface ForwardingRulesManager extends AutoCloseable {
 
-    public void start();
+    void start();
 
     /**
      * Method returns information :
@@ -46,7 +40,7 @@ public interface ForwardingRulesManager extends AutoCloseable {
      * @param ident - the key of the node
      * @return boolean - true if device is connected
      */
-    public boolean isNodeActive(InstanceIdentifier<FlowCapableNode> ident);
+    boolean isNodeActive(InstanceIdentifier<FlowCapableNode> ident);
 
     /**
      * Method returns information :
@@ -55,25 +49,7 @@ public interface ForwardingRulesManager extends AutoCloseable {
      * @param ident - the key of the node
      * @return boolean - true if device is present in operational data store
      */
-    public boolean checkNodeInOperationalDataStore(InstanceIdentifier<FlowCapableNode> ident);
-
-    /**
-     * Method add new {@link FlowCapableNode} to active Node Holder.
-     * ActiveNodeHolder prevent unnecessary Operational/DS read for identify
-     * pre-configure and serious Configure/DS transactions.
-     *
-     * @param ident - the key of the node
-     */
-    public void registrateNewNode(InstanceIdentifier<FlowCapableNode> ident);
-
-    /**
-     * Method remove disconnected {@link FlowCapableNode} from active Node
-     * Holder. And all next flows or groups or meters will stay in Config/DS
-     * only.
-     *
-     * @param ident - the key of the node
-     */
-    public void unregistrateNode(InstanceIdentifier<FlowCapableNode> ident);
+    boolean checkNodeInOperationalDataStore(InstanceIdentifier<FlowCapableNode> ident);
 
     /**
      * Method returns generated transaction ID, which is unique for
@@ -81,91 +57,97 @@ public interface ForwardingRulesManager extends AutoCloseable {
      *
      * @return String transactionID for RPC transaction identification
      */
-    public String getNewTransactionId();
+    String getNewTransactionId();
 
     /**
      * Method returns Read Transacion. It is need for Node reconciliation only.
      *
      * @return ReadOnlyTransaction
      */
-    public ReadOnlyTransaction getReadTranaction();
+    ReadOnlyTransaction getReadTranaction();
 
     /**
      * Flow RPC service
      *
      * @return
      */
-    public SalFlowService getSalFlowService();
+    SalFlowService getSalFlowService();
 
     /**
      * Group RPC service
      *
      * @return
      */
-    public SalGroupService getSalGroupService();
+    SalGroupService getSalGroupService();
 
     /**
      * Meter RPC service
      *
      * @return
      */
-    public SalMeterService getSalMeterService();
+    SalMeterService getSalMeterService();
 
     /**
      * Table RPC service
      *
      * @return
      */
-    public SalTableService getSalTableService();
+    SalTableService getSalTableService();
 
     /**
      * Content definition method and prevent code duplicity in Reconcil
      * @return ForwardingRulesCommiter&lt;Flow&gt;
      */
-    public ForwardingRulesCommiter<Flow> getFlowCommiter();
+    ForwardingRulesCommiter<Flow> getFlowCommiter();
 
     /**
      * Content definition method and prevent code duplicity in Reconcil
      * @return ForwardingRulesCommiter&lt;Group&gt;
      */
-    public ForwardingRulesCommiter<Group> getGroupCommiter();
+    ForwardingRulesCommiter<Group> getGroupCommiter();
 
     /**
      * Content definition method and prevent code duplicity
      * @return ForwardingRulesCommiter&lt;Meter&gt;
      */
-    public ForwardingRulesCommiter<Meter> getMeterCommiter();
+    ForwardingRulesCommiter<Meter> getMeterCommiter();
 
     /**
      * Content definition method and prevent code duplicity
      * @return ForwardingRulesCommiter&lt;Table&gt;
      */
-    public ForwardingRulesCommiter<TableFeatures> getTableFeaturesCommiter();
+    ForwardingRulesCommiter<TableFeatures> getTableFeaturesCommiter();
+
+    /**
+     * Check if reconciliation is disabled by user.
+     * @return true if reconciliation is disabled, else false
+     */
+    boolean isReconciliationDisabled();
 
     /**
-     * Content definition method
-     * @return FlowNodeReconciliation
+     * Check if stale marking is enabled for switch reconciliation.
+     * @return true if stale marking is enabled, else false
      */
-    public FlowNodeReconciliation getFlowNodeReconciliation();
+    boolean isStaleMarkingEnabled();
 
     /**
-     * Returns the config-subsystem/fallback configuration of FRM
-     * @return ForwardingRulesManagerConfig
+     * Return number of reconciliation retry are allowed.
+     * @return number of retries.
      */
-    public ForwardingRulesManagerConfig getConfiguration();
+    int getReconciliationRetryCount();
 
     /**
      * Method checks if *this* instance of openflowplugin is owner of
      * the given openflow node.
      * @return True if owner, else false
      */
-    public boolean isNodeOwner(InstanceIdentifier<FlowCapableNode> ident);
+    boolean isNodeOwner(InstanceIdentifier<FlowCapableNode> ident);
 
     /**
      * Content definition method and prevent code duplicity
      * @return FlowNodeConnectorInventoryTranslatorImpl
      */
-    public FlowNodeConnectorInventoryTranslatorImpl getFlowNodeConnectorInventoryTranslatorImpl();
+    FlowNodeConnectorInventoryTranslatorImpl getFlowNodeConnectorInventoryTranslatorImpl();
 
 }
 
index b73e7ba90867a22572f12592b7e7a9b33f4491eb..c3df34644ca33d6038041a80bf482e48c058da94 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2014, 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,
@@ -37,13 +37,13 @@ public abstract class AbstractListeningCommiter <T extends DataObject> implement
     @Override
     public void onDataTreeChanged(Collection<DataTreeModification<T>> changes) {
         Preconditions.checkNotNull(changes, "Changes may not be null!");
+        LOG.trace("Received data changes :{}", changes);
 
         for (DataTreeModification<T> change : changes) {
             final InstanceIdentifier<T> key = change.getRootPath().getRootIdentifier();
             final DataObjectModification<T> mod = change.getRootNode();
             final InstanceIdentifier<FlowCapableNode> nodeIdent =
                     key.firstIdentifierOf(FlowCapableNode.class);
-
             if (preConfigurationCheck(nodeIdent)) {
                 switch (mod.getModificationType()) {
                 case DELETE:
@@ -64,7 +64,7 @@ public abstract class AbstractListeningCommiter <T extends DataObject> implement
                 }
             }
             else{
-                if (provider.getConfiguration().isStaleMarkingEnabled()) {
+                if (provider.isStaleMarkingEnabled()) {
                     LOG.info("Stale-Marking ENABLED and switch {} is NOT connected, storing stale entities",
                             nodeIdent.toString());
                     // Switch is NOT connected
@@ -91,7 +91,7 @@ public abstract class AbstractListeningCommiter <T extends DataObject> implement
     protected abstract InstanceIdentifier<T> getWildCardPath();
 
     private boolean preConfigurationCheck(final InstanceIdentifier<FlowCapableNode> nodeIdent) {
-        Preconditions.checkNotNull(nodeIdent, "FlowCapableNode ident can not be null!");
+        Preconditions.checkNotNull(nodeIdent, "FlowCapableNode identifier can not be null!");
         // In single node cluster, node should be in local cache before we get any flow/group/meter
         // data change event from data store. So first check should pass.
         // In case of 3-node cluster, when shard leader changes, clustering will send blob of data
@@ -99,14 +99,13 @@ public abstract class AbstractListeningCommiter <T extends DataObject> implement
         // should get populated. But to handle a scenario where flow request comes before the blob
         // of config/operational data gets processes, it won't find node in local cache and it will
         // skip the flow/group/meter operational. This requires an addition check, where it reads
-        // node from operational data store and if it's present it calls flowNodeConnected to explictly
+        // node from operational data store and if it's present it calls flowNodeConnected to explicitly
         // trigger the event of new node connected.
 
         if(!provider.isNodeOwner(nodeIdent)) { return false; }
 
         if (!provider.isNodeActive(nodeIdent)) {
             if (provider.checkNodeInOperationalDataStore(nodeIdent)) {
-                provider.getFlowNodeReconciliation().flowNodeConnected(nodeIdent);
                 return true;
             } else {
                 return false;
index 54360a005dee373773f0d9fc2ff5f98da867413a..d53fa6e3144479a51ad7de065a97434f893f2c15 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2016 Pantheon Technologies s.r.o. and others. All rights reserved.
+ * Copyright (c) 2016, 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,
@@ -10,11 +10,18 @@ package org.opendaylight.openflowplugin.applications.frm.impl;
 
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.atomic.AtomicBoolean;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
 import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
+import org.opendaylight.openflowplugin.applications.frm.FlowNodeReconciliation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -25,26 +32,37 @@ public class DeviceMastership implements ClusterSingletonService, AutoCloseable
     private static final Logger LOG = LoggerFactory.getLogger(DeviceMastership.class);
     private final NodeId nodeId;
     private final ServiceGroupIdentifier identifier;
-    private final ClusterSingletonServiceRegistration clusterSingletonServiceRegistration;
-    private boolean deviceMastered;
+    private final ClusterSingletonServiceProvider clusterSingletonServiceProvider;
+    private final FlowNodeReconciliation reconcliationAgent;
+    private final AtomicBoolean deviceMastered = new AtomicBoolean(false);
+    private final AtomicBoolean isDeviceInOperDS = new AtomicBoolean(false);
+    private final InstanceIdentifier<FlowCapableNode> fcnIID;
+    private ClusterSingletonServiceRegistration clusterSingletonServiceRegistration;
 
-    public DeviceMastership(final NodeId nodeId, final ClusterSingletonServiceProvider clusterSingletonService) {
+    public DeviceMastership(final NodeId nodeId,
+                            final ClusterSingletonServiceProvider clusterSingletonService,
+                            final FlowNodeReconciliation reconcliationAgent) {
         this.nodeId = nodeId;
         this.identifier = ServiceGroupIdentifier.create(nodeId.getValue());
-        this.deviceMastered = false;
-        clusterSingletonServiceRegistration = clusterSingletonService.registerClusterSingletonService(this);
+        this.clusterSingletonServiceProvider = clusterSingletonService;
+        this.reconcliationAgent = reconcliationAgent;
+        fcnIID = InstanceIdentifier.create(Nodes.class).child(Node.class, new NodeKey(nodeId)).augmentation
+                (FlowCapableNode.class);
     }
 
     @Override
     public void instantiateServiceInstance() {
-        LOG.debug("FRM started for: {}", nodeId.getValue());
-        deviceMastered = true;
+        LOG.info("FRM started for: {}", nodeId.getValue());
+        deviceMastered.set(true);
+        if(canReconcile()) {
+            reconcliationAgent.reconcileConfiguration(fcnIID);
+        }
     }
 
     @Override
     public ListenableFuture<Void> closeServiceInstance() {
-        LOG.debug("FRM stopped for: {}", nodeId.getValue());
-        deviceMastered = false;
+        LOG.info("FRM stopped for: {}", nodeId.getValue());
+        deviceMastered.set(false);
         return Futures.immediateFuture(null);
     }
 
@@ -65,7 +83,23 @@ public class DeviceMastership implements ClusterSingletonService, AutoCloseable
     }
 
     public boolean isDeviceMastered() {
-        return deviceMastered;
+        return deviceMastered.get();
+    }
+
+    public void setDeviceOperationalStatus(boolean inOperDS) {
+        isDeviceInOperDS.set(inOperDS);
+        if(canReconcile()) {
+            LOG.info("Triggering reconciliation for device {}", nodeId.getValue());
+            reconcliationAgent.reconcileConfiguration(fcnIID);
+        }
     }
 
+    public void registerClusterSingletonService() {
+        LOG.info("Registering FRM as a cluster singleton service listner for service id : {}",getIdentifier());
+        clusterSingletonServiceRegistration = clusterSingletonServiceProvider.registerClusterSingletonService(this);
+    }
+
+    private boolean canReconcile() {
+        return (deviceMastered.get() && isDeviceInOperDS.get());
+    }
 }
index dd7c2721c7093830836384ac065dfaa54a05c881..87c3ba638da6ab04849e63ade189668187063623 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2016 Pantheon Technologies s.r.o. and others. All rights reserved.
+ * Copyright (c) 2016, 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,
 package org.opendaylight.openflowplugin.applications.frm.impl;
 
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
+import org.opendaylight.openflowplugin.applications.frm.FlowNodeReconciliation;
+import org.opendaylight.openflowplugin.common.wait.SimpleTaskRetryLooper;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRemoved;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
  * Manager for clustering service registrations of {@link DeviceMastership}.
  */
-public class DeviceMastershipManager {
+public class DeviceMastershipManager implements ClusteredDataTreeChangeListener<FlowCapableNode>,
+        OpendaylightInventoryListener, AutoCloseable{
     private static final Logger LOG = LoggerFactory.getLogger(DeviceMastershipManager.class);
+    private static final InstanceIdentifier<FlowCapableNode> II_TO_FLOW_CAPABLE_NODE
+            = InstanceIdentifier.builder(Nodes.class)
+            .child(Node.class)
+            .augmentation(FlowCapableNode.class)
+            .build();
+
     private final ClusterSingletonServiceProvider clusterSingletonService;
+    private final ListenerRegistration<?> notifListenerRegistration;
+    private final FlowNodeReconciliation reconcliationAgent;
+    private final DataBroker dataBroker;
     private final ConcurrentHashMap<NodeId, DeviceMastership> deviceMasterships = new ConcurrentHashMap();
+    private final Object lockObj = new Object();
+    private ListenerRegistration<DeviceMastershipManager> listenerRegistration;
+    private Set<InstanceIdentifier<FlowCapableNode>> activeNodes = Collections.emptySet();
 
-    public DeviceMastershipManager(final ClusterSingletonServiceProvider clusterSingletonService) {
+    public DeviceMastershipManager(final ClusterSingletonServiceProvider clusterSingletonService,
+                                   final NotificationProviderService notificationService,
+                                   final FlowNodeReconciliation reconcliationAgent,
+                                   final DataBroker dataBroker) {
         this.clusterSingletonService = clusterSingletonService;
+        this.notifListenerRegistration = notificationService.registerNotificationListener(this);
+        this.reconcliationAgent = reconcliationAgent;
+        this.dataBroker = dataBroker;
+        registerNodeListener();
+    }
+
+    public boolean isDeviceMastered(final NodeId nodeId) {
+        return deviceMasterships.get(nodeId) != null && deviceMasterships.get(nodeId).isDeviceMastered();
+    }
+
+    public boolean isNodeActive(final NodeId nodeId) {
+        final InstanceIdentifier<FlowCapableNode> flowNodeIdentifier = InstanceIdentifier.create(Nodes.class)
+                .child(Node.class, new NodeKey(nodeId)).augmentation(FlowCapableNode.class);
+        return activeNodes.contains(flowNodeIdentifier);
+
+    }
+
+    @VisibleForTesting
+    ConcurrentHashMap<NodeId, DeviceMastership> getDeviceMasterships() {
+        return deviceMasterships;
+    }
+
+    @Override
+    public void onNodeUpdated(NodeUpdated notification) {
+        LOG.debug("NodeUpdate notification received : {}", notification);
+        DeviceMastership membership = deviceMasterships.computeIfAbsent(notification.getId(), device ->
+                new DeviceMastership(notification.getId(), clusterSingletonService, reconcliationAgent));
+        membership.registerClusterSingletonService();
     }
 
-    public void onDeviceConnected(final NodeId nodeId) {
-        LOG.debug("FRM service registered for: {}", nodeId.getValue());
-        final DeviceMastership mastership = new DeviceMastership(nodeId, clusterSingletonService);
-        deviceMasterships.put(nodeId, mastership);
+    @Override
+    public void onNodeConnectorUpdated(NodeConnectorUpdated notification) {
+        //Not published by plugin
     }
 
-    public void onDeviceDisconnected(final NodeId nodeId) {
+    @Override
+    public void onNodeRemoved(NodeRemoved notification) {
+        LOG.debug("NodeRemoved notification received : {}", notification);
+        NodeId nodeId = notification.getNodeRef().getValue().firstKeyOf(Node.class).getId();
         final DeviceMastership mastership = deviceMasterships.remove(nodeId);
         if (mastership != null) {
             mastership.close();
+            LOG.info("Unregistered FRM cluster singleton service for service id : {}", nodeId.getValue());
         }
-        LOG.debug("FRM service unregistered for: {}", nodeId.getValue());
     }
 
-    public boolean isDeviceMastered(final NodeId nodeId) {
-        return deviceMasterships.get(nodeId) != null && deviceMasterships.get(nodeId).isDeviceMastered();
+    @Override
+    public void onNodeConnectorRemoved(NodeConnectorRemoved notification) {
+        //Not published by plugin
     }
 
-    @VisibleForTesting
-    ConcurrentHashMap<NodeId, DeviceMastership> getDeviceMasterships() {
-        return deviceMasterships;
+    @Override
+    public void onDataTreeChanged(@Nonnull Collection<DataTreeModification<FlowCapableNode>> changes) {
+        Preconditions.checkNotNull(changes, "Changes may not be null!");
+
+        for (DataTreeModification<FlowCapableNode> change : changes) {
+            final InstanceIdentifier<FlowCapableNode> key = change.getRootPath().getRootIdentifier();
+            final DataObjectModification<FlowCapableNode> mod = change.getRootNode();
+            final InstanceIdentifier<FlowCapableNode> nodeIdent =
+                    key.firstIdentifierOf(FlowCapableNode.class);
+
+            switch (mod.getModificationType()) {
+                case DELETE:
+                    if (mod.getDataAfter() == null) {
+                        remove(key, mod.getDataBefore(), nodeIdent);
+                    }
+                    break;
+                case SUBTREE_MODIFIED:
+                    //NO-OP since we do not need to reconcile on Node-updated
+                    break;
+                case WRITE:
+                    if (mod.getDataBefore() == null) {
+                        add(key, mod.getDataAfter(), nodeIdent);
+                    }
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unhandled modification type " + mod.getModificationType());
+            }
+        }
+    }
+
+    public void remove(InstanceIdentifier<FlowCapableNode> identifier, FlowCapableNode del,
+                       InstanceIdentifier<FlowCapableNode> nodeIdent) {
+        if(compareInstanceIdentifierTail(identifier,II_TO_FLOW_CAPABLE_NODE)){
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Node removed: {}",nodeIdent.firstKeyOf(Node.class).getId().getValue());
+            }
+
+            if ( ! nodeIdent.isWildcarded()) {
+                if (activeNodes.contains(nodeIdent)) {
+                    synchronized (lockObj) {
+                        if (activeNodes.contains(nodeIdent)) {
+                            Set<InstanceIdentifier<FlowCapableNode>> set =
+                                    Sets.newHashSet(activeNodes);
+                            set.remove(nodeIdent);
+                            activeNodes = Collections.unmodifiableSet(set);
+                            setNodeOperationalStatus(nodeIdent,false);
+                        }
+                    }
+                }
+            }
+
+        }
+    }
+
+    public void add(InstanceIdentifier<FlowCapableNode> identifier, FlowCapableNode add,
+                    InstanceIdentifier<FlowCapableNode> nodeIdent) {
+        if(compareInstanceIdentifierTail(identifier,II_TO_FLOW_CAPABLE_NODE)){
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Node added: {}",nodeIdent.firstKeyOf(Node.class).getId().getValue());
+            }
+
+            if ( ! nodeIdent.isWildcarded()) {
+                if (!activeNodes.contains(nodeIdent)) {
+                    synchronized (lockObj) {
+                        if (!activeNodes.contains(nodeIdent)) {
+                            Set<InstanceIdentifier<FlowCapableNode>> set = Sets.newHashSet(activeNodes);
+                            set.add(nodeIdent);
+                            activeNodes = Collections.unmodifiableSet(set);
+                            setNodeOperationalStatus(nodeIdent,true);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public void close() {
+        if (listenerRegistration != null) {
+            try {
+                listenerRegistration.close();
+            } catch (Exception e) {
+                LOG.warn("Error occurred while closing operational Node listener: {}", e.getMessage());
+                LOG.debug("Error occurred while closing operational Node listener", e);
+            }
+            listenerRegistration = null;
+        }
+        if (notifListenerRegistration != null) {
+            notifListenerRegistration.close();
+        }
+    }
+
+
+    private boolean compareInstanceIdentifierTail(InstanceIdentifier<?> identifier1,
+                                                  InstanceIdentifier<?> identifier2) {
+        return Iterables.getLast(identifier1.getPathArguments()).equals(Iterables.getLast(identifier2.getPathArguments()));
+    }
+
+    private void setNodeOperationalStatus(InstanceIdentifier<FlowCapableNode> nodeIid, boolean status) {
+        NodeId nodeId = nodeIid.firstKeyOf(Node.class).getId();
+        if (nodeId != null ) {
+            if (deviceMasterships.containsKey(nodeId) ) {
+                deviceMasterships.get(nodeId).setDeviceOperationalStatus(status);
+                LOG.debug("Operational status of device {} is set to {}",nodeId, status);
+            }
+        }
+    }
+    private void registerNodeListener(){
+
+        final InstanceIdentifier<FlowCapableNode> flowNodeWildCardIdentifier = InstanceIdentifier.create(Nodes.class)
+                .child(Node.class).augmentation(FlowCapableNode.class);
+
+        final DataTreeIdentifier<FlowCapableNode> treeId =
+                new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, flowNodeWildCardIdentifier);
+
+        try {
+            SimpleTaskRetryLooper looper = new SimpleTaskRetryLooper(ForwardingRulesManagerImpl.STARTUP_LOOP_TICK,
+                    ForwardingRulesManagerImpl.STARTUP_LOOP_MAX_RETRIES);
+
+            listenerRegistration = looper.loopUntilNoException(() ->
+                    dataBroker.registerDataTreeChangeListener(treeId, DeviceMastershipManager.this));
+        } catch (Exception e) {
+            LOG.warn("Data listener registration failed: {}", e.getMessage());
+            LOG.debug("Data listener registration failed ", e);
+            throw new IllegalStateException("Node listener registration failed!", e);
+        }
     }
 }
index 615fc89d2f40da683584b59c5ddd188c31d988d2..c530713c59c3ca7ddfbafcfb19acd8502930c708 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2014, 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,
@@ -12,7 +12,6 @@ package org.opendaylight.openflowplugin.applications.frm.impl;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.FutureCallback;
@@ -23,30 +22,21 @@ import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.ListIterator;
 import java.util.Map;
-import java.util.Map.Entry;
-import java.util.HashMap;
-import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicInteger;
-import javax.annotation.Nonnull;
-
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
-import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
-import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.openflowplugin.applications.frm.FlowNodeReconciliation;
 import org.opendaylight.openflowplugin.applications.frm.ForwardingRulesManager;
-import org.opendaylight.openflowplugin.common.wait.SimpleTaskRetryLooper;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
@@ -72,178 +62,58 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.StaleGroup;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.StaleGroupKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeaturesKey;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-
 /**
- * forwardingrules-manager
- * org.opendaylight.openflowplugin.applications.frm
- *
- * FlowNode Reconciliation Listener
- * Reconciliation for a new FlowNode
+ * Default implementation of {@link ForwardingRulesManager}
  *
  * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- * Created: Jun 13, 2014
  */
 public class FlowNodeReconciliationImpl implements FlowNodeReconciliation {
+     private static final Logger LOG = LoggerFactory.getLogger(FlowNodeReconciliationImpl.class);
 
-    private static final Logger LOG = LoggerFactory.getLogger(FlowNodeReconciliationImpl.class);
-
-    /**
-     * The number of nanoseconds to wait for a single group to be added.
-     */
+    //The number of nanoseconds to wait for a single group to be added.
     private static final long  ADD_GROUP_TIMEOUT = TimeUnit.SECONDS.toNanos(3);
 
-    /**
-     * The maximum number of nanoseconds to wait for completion of add-group
-     * RPCs.
-     */
-    private static final long  MAX_ADD_GROUP_TIMEOUT =
-        TimeUnit.SECONDS.toNanos(20);
-
-    private final DataBroker dataBroker;
-
-    private final ForwardingRulesManager provider;
+     //The maximum number of nanoseconds to wait for completion of add-group RPCs.
+    private static final long  MAX_ADD_GROUP_TIMEOUT = TimeUnit.SECONDS.toNanos(20);
     private static final String SEPARATOR = ":";
-
-    private ListenerRegistration<FlowNodeReconciliationImpl> listenerRegistration;
-
     private static final int THREAD_POOL_SIZE = 4;
-    ExecutorService executor = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
 
-    private static final InstanceIdentifier<FlowCapableNode> II_TO_FLOW_CAPABLE_NODE
-            = InstanceIdentifier.builder(Nodes.class)
-            .child(Node.class)
-            .augmentation(FlowCapableNode.class)
-            .build();
+    private final DataBroker dataBroker;
+    private final ForwardingRulesManager provider;
+    private final ExecutorService executor = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
 
     public FlowNodeReconciliationImpl (final ForwardingRulesManager manager, final DataBroker db) {
         this.provider = Preconditions.checkNotNull(manager, "ForwardingRulesManager can not be null!");
         dataBroker = Preconditions.checkNotNull(db, "DataBroker can not be null!");
-        /* Build Path */
-        final InstanceIdentifier<FlowCapableNode> flowNodeWildCardIdentifier = InstanceIdentifier.create(Nodes.class)
-                .child(Node.class).augmentation(FlowCapableNode.class);
-
-        final DataTreeIdentifier<FlowCapableNode> treeId =
-                new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, flowNodeWildCardIdentifier);
-
-        try {
-        SimpleTaskRetryLooper looper = new SimpleTaskRetryLooper(ForwardingRulesManagerImpl.STARTUP_LOOP_TICK,
-                ForwardingRulesManagerImpl.STARTUP_LOOP_MAX_RETRIES);
-
-            listenerRegistration = looper.loopUntilNoException(new Callable<ListenerRegistration<FlowNodeReconciliationImpl>>() {
-                @Override
-                public ListenerRegistration<FlowNodeReconciliationImpl> call() throws Exception {
-                    return dataBroker.registerDataTreeChangeListener(treeId, FlowNodeReconciliationImpl.this);
-                }
-            });
-        } catch (Exception e) {
-            LOG.warn("data listener registration failed: {}", e.getMessage());
-            LOG.debug("data listener registration failed.. ", e);
-            throw new IllegalStateException("FlowNodeReconciliation startup fail! System needs restart.", e);
-        }
     }
 
     @Override
     public void close() {
-        if (listenerRegistration != null) {
-            try {
-                listenerRegistration.close();
-            } catch (Exception e) {
-                LOG.warn("Error by stop FRM FlowNodeReconilListener: {}", e.getMessage());
-                LOG.debug("Error by stop FRM FlowNodeReconilListener..", e);
-            }
-            listenerRegistration = null;
+        if (executor != null) {
+            executor.shutdownNow();
         }
     }
 
     @Override
-    public void onDataTreeChanged(@Nonnull Collection<DataTreeModification<FlowCapableNode>> changes) {
-        Preconditions.checkNotNull(changes, "Changes may not be null!");
-
-        for (DataTreeModification<FlowCapableNode> change : changes) {
-            final InstanceIdentifier<FlowCapableNode> key = change.getRootPath().getRootIdentifier();
-            final DataObjectModification<FlowCapableNode> mod = change.getRootNode();
-            final InstanceIdentifier<FlowCapableNode> nodeIdent =
-                    key.firstIdentifierOf(FlowCapableNode.class);
-
-            switch (mod.getModificationType()) {
-                case DELETE:
-                    if (mod.getDataAfter() == null) {
-                        remove(key, mod.getDataBefore(), nodeIdent);
-                    }
-                    break;
-                case SUBTREE_MODIFIED:
-                    //NO-OP since we donot need to reconciliate on Node-updated
-                    break;
-                case WRITE:
-                    if (mod.getDataBefore() == null) {
-                        add(key, mod.getDataAfter(), nodeIdent);
-                    }
-                    break;
-                default:
-                    throw new IllegalArgumentException("Unhandled modification type " + mod.getModificationType());
-            }
+    public void reconcileConfiguration(InstanceIdentifier<FlowCapableNode> connectedNode) {
+        if (provider.isReconciliationDisabled()) {
+            LOG.debug("Reconciliation is disabled by user. Skipping reconciliation of node : {}", connectedNode
+                    .firstKeyOf(Node.class));
+            return;
         }
-    }
-
-
-
-    public void remove(InstanceIdentifier<FlowCapableNode> identifier, FlowCapableNode del,
-                       InstanceIdentifier<FlowCapableNode> nodeIdent) {
-        if(compareInstanceIdentifierTail(identifier,II_TO_FLOW_CAPABLE_NODE)){
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("Node removed: {}",nodeIdent.firstKeyOf(Node.class).getId().getValue());
-            }
-
-            if ( ! nodeIdent.isWildcarded()) {
-                flowNodeDisconnected(nodeIdent);
-            }
-
-        }
-    }
-
-    public void add(InstanceIdentifier<FlowCapableNode> identifier, FlowCapableNode add,
-                    InstanceIdentifier<FlowCapableNode> nodeIdent) {
-        if(compareInstanceIdentifierTail(identifier,II_TO_FLOW_CAPABLE_NODE)){
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("Node added: {}",nodeIdent.firstKeyOf(Node.class).getId().getValue());
-            }
-
-            if ( ! nodeIdent.isWildcarded()) {
-                flowNodeConnected(nodeIdent);
-            }
-        }
-    }
-
-    @Override
-    public void flowNodeDisconnected(InstanceIdentifier<FlowCapableNode> disconnectedNode) {
-        provider.unregistrateNode(disconnectedNode);
-    }
-
-    @Override
-    public void flowNodeConnected(InstanceIdentifier<FlowCapableNode> connectedNode) {
-        flowNodeConnected(connectedNode, false);
-    }
-
-    private void flowNodeConnected(InstanceIdentifier<FlowCapableNode> connectedNode, boolean force) {
-        if (force || !provider.isNodeActive(connectedNode)) {
-            provider.registrateNewNode(connectedNode);
-
-            if(!provider.isNodeOwner(connectedNode)) { return; }
-
-            if (provider.getConfiguration().isStaleMarkingEnabled()) {
+        if (provider.isNodeOwner(connectedNode)) {
+            LOG.info("Triggering reconciliation for device {}", connectedNode.firstKeyOf(Node.class));
+            if (provider.isStaleMarkingEnabled()) {
                 LOG.info("Stale-Marking is ENABLED and proceeding with deletion of stale-marked entities on switch {}",
                         connectedNode.toString());
                 reconciliationPreProcess(connectedNode);
@@ -300,7 +170,7 @@ public class FlowNodeReconciliationImpl implements FlowNodeReconciliation {
                 Map<Long, ListenableFuture<?>> groupFutures = new HashMap<>();
 
                 while ((!(toBeInstalledGroups.isEmpty()) || !(suspectedGroups.isEmpty())) &&
-                        (counter <= provider.getConfiguration().getReconciliationRetryCount())) { //also check if the counter has not crossed the threshold
+                        (counter <= provider.getReconciliationRetryCount())) { //also check if the counter has not crossed the threshold
 
                     if (toBeInstalledGroups.isEmpty() && !suspectedGroups.isEmpty()) {
                         LOG.error("These Groups are pointing to node-connectors that are not up yet {}", suspectedGroups.toString());
@@ -385,7 +255,7 @@ public class FlowNodeReconciliationImpl implements FlowNodeReconciliation {
                 if (!toBeInstalledGroups.isEmpty()) {
                     for (Group group : toBeInstalledGroups) {
                         LOG.error("Installing the group {} finally although the port is not up after checking for {} times "
-                                , group.getGroupId().toString(), provider.getConfiguration().getReconciliationRetryCount());
+                                , group.getGroupId().toString(), provider.getReconciliationRetryCount());
                         addGroup(groupFutures, group);
                     }
                 }
@@ -676,13 +546,6 @@ public class FlowNodeReconciliationImpl implements FlowNodeReconciliation {
                 LOG.error("Stale entity removal failed {}", t);
             }
         });
-
-    }
-
-
-    private boolean compareInstanceIdentifierTail(InstanceIdentifier<?> identifier1,
-                                                  InstanceIdentifier<?> identifier2) {
-        return Iterables.getLast(identifier1.getPathArguments()).equals(Iterables.getLast(identifier2.getPathArguments()));
     }
 }
 
index 61665cb59b587510631603ab100d5b7baba88e73..9bfa94363938c9942216c7044c0ba9c51c051447 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2014, 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,
@@ -11,16 +11,15 @@ package org.opendaylight.openflowplugin.applications.frm.impl;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
-import com.google.common.collect.Sets;
 import com.google.common.util.concurrent.CheckedFuture;
-import java.util.Collections;
 import java.util.Objects;
-import java.util.Set;
 import java.util.concurrent.atomic.AtomicLong;
+import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.openflowplugin.applications.frm.FlowNodeReconciliation;
@@ -50,40 +49,46 @@ import org.slf4j.LoggerFactory;
  *
  */
 public class ForwardingRulesManagerImpl implements ForwardingRulesManager {
-
     private static final Logger LOG = LoggerFactory.getLogger(ForwardingRulesManagerImpl.class);
+
     static final int STARTUP_LOOP_TICK = 500;
     static final int STARTUP_LOOP_MAX_RETRIES = 8;
 
     private final AtomicLong txNum = new AtomicLong();
-    private final Object lockObj = new Object();
-    private Set<InstanceIdentifier<FlowCapableNode>> activeNodes = Collections.emptySet();
-
     private final DataBroker dataService;
     private final SalFlowService salFlowService;
     private final SalGroupService salGroupService;
     private final SalMeterService salMeterService;
     private final SalTableService salTableService;
+    private final ForwardingRulesManagerConfig forwardingRulesManagerConfig;
+    private final ClusterSingletonServiceProvider clusterSingletonServiceProvider;
+    private final NotificationProviderService notificationService;
+    private final boolean disableReconciliation;
+    private final boolean staleMarkingEnabled;
+    private final int reconciliationRetryCount;
 
     private ForwardingRulesCommiter<Flow> flowListener;
     private ForwardingRulesCommiter<Group> groupListener;
     private ForwardingRulesCommiter<Meter> meterListener;
     private ForwardingRulesCommiter<TableFeatures> tableListener;
     private FlowNodeReconciliation nodeListener;
-
-    private final ForwardingRulesManagerConfig forwardingRulesManagerConfig;
     private FlowNodeConnectorInventoryTranslatorImpl flowNodeConnectorInventoryTranslatorImpl;
-    private final ClusterSingletonServiceProvider clusterSingletonServiceProvider;
     private DeviceMastershipManager deviceMastershipManager;
 
     public ForwardingRulesManagerImpl(final DataBroker dataBroker,
                                       final RpcConsumerRegistry rpcRegistry,
                                       final ForwardingRulesManagerConfig config,
-                                      final ClusterSingletonServiceProvider clusterSingletonService) {
+                                      final ClusterSingletonServiceProvider clusterSingletonService,
+                                      final NotificationProviderService notificationService,
+                                      final boolean disableReconciliation,
+                                      final boolean staleMarkingEnabled,
+                                      final int reconciliationRetryCount) {
         this.dataService = Preconditions.checkNotNull(dataBroker, "DataBroker can not be null!");
         this.forwardingRulesManagerConfig = Preconditions.checkNotNull(config, "Configuration for FRM cannot be null");
         this.clusterSingletonServiceProvider = Preconditions.checkNotNull(clusterSingletonService,
                 "ClusterSingletonService provider can not be null");
+        this.notificationService = Preconditions.checkNotNull(notificationService, "Notification publisher service is" +
+                " not available");
 
         Preconditions.checkArgument(rpcRegistry != null, "RpcConsumerRegistry can not be null !");
 
@@ -95,18 +100,25 @@ public class ForwardingRulesManagerImpl implements ForwardingRulesManager {
                 "RPC SalMeterService not found.");
         this.salTableService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalTableService.class),
                 "RPC SalTableService not found.");
+
+        this.disableReconciliation = disableReconciliation;
+        this.staleMarkingEnabled = staleMarkingEnabled;
+        this.reconciliationRetryCount = reconciliationRetryCount;
     }
 
     @Override
     public void start() {
-        this.deviceMastershipManager = new DeviceMastershipManager(clusterSingletonServiceProvider);
+        this.nodeListener = new FlowNodeReconciliationImpl(this, dataService);
+        this.deviceMastershipManager = new DeviceMastershipManager(clusterSingletonServiceProvider,
+                notificationService,
+                this.nodeListener,
+                dataService);
+        flowNodeConnectorInventoryTranslatorImpl = new FlowNodeConnectorInventoryTranslatorImpl(this,dataService);
+
         this.flowListener = new FlowForwarder(this, dataService);
         this.groupListener = new GroupForwarder(this, dataService);
         this.meterListener = new MeterForwarder(this, dataService);
         this.tableListener = new TableForwarder(this, dataService);
-        this.nodeListener = new FlowNodeReconciliationImpl(this, dataService);
-        flowNodeConnectorInventoryTranslatorImpl =
-                new FlowNodeConnectorInventoryTranslatorImpl(this,dataService);
         LOG.info("ForwardingRulesManager has started successfully.");
     }
 
@@ -132,6 +144,9 @@ public class ForwardingRulesManagerImpl implements ForwardingRulesManager {
             this.nodeListener.close();
             this.nodeListener = null;
         }
+        if (deviceMastershipManager != null) {
+            deviceMastershipManager.close();
+        }
     }
 
     @Override
@@ -146,7 +161,7 @@ public class ForwardingRulesManagerImpl implements ForwardingRulesManager {
 
     @Override
     public boolean isNodeActive(InstanceIdentifier<FlowCapableNode> ident) {
-        return activeNodes.contains(ident);
+        return deviceMastershipManager.isNodeActive(ident.firstKeyOf(Node.class).getId());
     }
 
     @Override
@@ -172,36 +187,6 @@ public class ForwardingRulesManagerImpl implements ForwardingRulesManager {
         return result;
     }
 
-    @Override
-    public void registrateNewNode(InstanceIdentifier<FlowCapableNode> ident) {
-        if (!activeNodes.contains(ident)) {
-            synchronized (lockObj) {
-                if (!activeNodes.contains(ident)) {
-                    Set<InstanceIdentifier<FlowCapableNode>> set =
-                            Sets.newHashSet(activeNodes);
-                    set.add(ident);
-                    activeNodes = Collections.unmodifiableSet(set);
-                    deviceMastershipManager.onDeviceConnected(ident.firstKeyOf(Node.class).getId());
-                }
-            }
-        }
-    }
-
-    @Override
-    public void unregistrateNode(InstanceIdentifier<FlowCapableNode> ident) {
-        if (activeNodes.contains(ident)) {
-            synchronized (lockObj) {
-                if (activeNodes.contains(ident)) {
-                    Set<InstanceIdentifier<FlowCapableNode>> set =
-                            Sets.newHashSet(activeNodes);
-                    set.remove(ident);
-                    activeNodes = Collections.unmodifiableSet(set);
-                    deviceMastershipManager.onDeviceDisconnected(ident.firstKeyOf(Node.class).getId());
-                }
-            }
-        }
-    }
-
     @Override
     public SalFlowService getSalFlowService() {
         return salFlowService;
@@ -243,13 +228,18 @@ public class ForwardingRulesManagerImpl implements ForwardingRulesManager {
     }
 
     @Override
-    public FlowNodeReconciliation getFlowNodeReconciliation() {
-        return nodeListener;
+    public boolean isReconciliationDisabled() {
+        return this.disableReconciliation;
+    }
+
+    @Override
+    public boolean isStaleMarkingEnabled() {
+        return this.staleMarkingEnabled;
     }
 
     @Override
-    public ForwardingRulesManagerConfig getConfiguration() {
-        return forwardingRulesManagerConfig;
+    public int getReconciliationRetryCount() {
+        return this.reconciliationRetryCount;
     }
 
     @Override
@@ -266,6 +256,5 @@ public class ForwardingRulesManagerImpl implements ForwardingRulesManager {
     public void setDeviceMastershipManager(final DeviceMastershipManager deviceMastershipManager) {
         this.deviceMastershipManager = deviceMastershipManager;
     }
-
 }
 
index b6f154e06524e1cca1ad31685f648da321d310da..34a6dc8f455f03674fa1e5cf9caaaabcbced241f 100644 (file)
@@ -1,20 +1,40 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+           xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
            xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
         odl:use-default-for-reference-types="true">
 
   <reference id="dataBroker" interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"/>
   <reference id="rpcRegistry" interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry"/>
+  <reference id="notificationService" interface="org.opendaylight.controller.sal.binding.api.NotificationProviderService"/>
   <reference id="clusterSingletonService" interface="org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider"/>
 
   <odl:clustered-app-config id="frmConfig"
       binding-class="org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.app.forwardingrules.manager.config.rev160511.ForwardingRulesManagerConfig"/>
 
+  <cm:property-placeholder persistent-id="org.opendaylight.openflowplugin"
+                           placeholder-prefix="${frm-"
+                           update-strategy="none">
+    <cm:default-properties>
+      <!-- Disable switch reconciliation -->
+      <cm:property name="disable-reconciliation" value="false"/>
+      <!-- Enable stale marking for switch reconciliation -->
+      <cm:property name="stale-marking-enabled" value="false"/>
+      <!-- Number of retries for switch reconciliation -->
+      <cm:property name="reconciliation-retry-count" value="5"/>
+    </cm:default-properties>
+  </cm:property-placeholder>
+
   <bean id="frmManager" class="org.opendaylight.openflowplugin.applications.frm.impl.ForwardingRulesManagerImpl"
           init-method="start" destroy-method="close">
     <argument ref="dataBroker"/>
     <argument ref="rpcRegistry"/>
     <argument ref="frmConfig"/>
     <argument ref="clusterSingletonService"/>
+    <argument ref="notificationService"/>
+    <argument value="${frm-disable-reconciliation}"/>
+    <argument value="${frm-stale-marking-enabled}"/>
+    <argument value="${frm-reconciliation-retry-count}"/>
+
   </bean>
 </blueprint>
\ No newline at end of file
index 870eb6be1bb8542eb6ae6965148a15e24769542f..68b63744bb8de4178346f59538d0a58eb9d912e0 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2016 Pantheon Technologies s.r.o. and others. All rights reserved.
+ * Copyright (c) 2016, 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,
@@ -16,10 +16,20 @@ import org.mockito.Matchers;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
+import org.opendaylight.openflowplugin.applications.frm.FlowNodeReconciliation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemovedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /**
  * Test for {@link DeviceMastershipManager}.
@@ -32,10 +42,17 @@ public class DeviceMastershipManagerTest {
     private ClusterSingletonServiceRegistration registration;
     @Mock
     private ClusterSingletonServiceProvider clusterSingletonService;
+    @Mock
+    private NotificationProviderService notificationService;
+    @Mock
+    private FlowNodeReconciliation reconciliationAgent;
+    @Mock
+    private DataBroker dataBroker;
 
     @Before
     public void setUp() throws Exception {
-        deviceMastershipManager = new DeviceMastershipManager(clusterSingletonService);
+        deviceMastershipManager = new DeviceMastershipManager(clusterSingletonService,
+                notificationService, reconciliationAgent, dataBroker);
         Mockito.when(clusterSingletonService.registerClusterSingletonService(Matchers.<ClusterSingletonService>any()))
                 .thenReturn(registration);
     }
@@ -44,22 +61,28 @@ public class DeviceMastershipManagerTest {
     public void testOnDeviceConnectedAndDisconnected() throws Exception {
         // no context
         Assert.assertNull(deviceMastershipManager.getDeviceMasterships().get(NODE_ID));
-        // create context - register
-        deviceMastershipManager.onDeviceConnected(NODE_ID);
+        NodeUpdatedBuilder nodeUpdatedBuilder = new NodeUpdatedBuilder();
+        nodeUpdatedBuilder.setId(NODE_ID);
+        deviceMastershipManager.onNodeUpdated(nodeUpdatedBuilder.build());
         DeviceMastership serviceInstance = deviceMastershipManager.getDeviceMasterships().get(NODE_ID);
         Assert.assertNotNull(serviceInstance);
-        Mockito.verify(clusterSingletonService).registerClusterSingletonService(serviceInstance);
         // destroy context - unregister
-        deviceMastershipManager.onDeviceDisconnected(NODE_ID);
+        Assert.assertNotNull(deviceMastershipManager.getDeviceMasterships().get(NODE_ID));
+        NodeRemovedBuilder nodeRemovedBuilder = new NodeRemovedBuilder();
+        InstanceIdentifier<Node> nodeIId = InstanceIdentifier.create(Nodes.class).
+                child(Node.class, new NodeKey(NODE_ID));
+        nodeRemovedBuilder.setNodeRef(new NodeRef(nodeIId));
+        deviceMastershipManager.onNodeRemoved(nodeRemovedBuilder.build());
         Assert.assertNull(deviceMastershipManager.getDeviceMasterships().get(NODE_ID));
-        Mockito.verify(registration).close();
     }
 
     @Test
     public void testIsDeviceMasteredOrSlaved() {
         // no context
         Assert.assertFalse(deviceMastershipManager.isDeviceMastered(NODE_ID));
-        deviceMastershipManager.onDeviceConnected(NODE_ID);
+        NodeUpdatedBuilder nodeUpdatedBuilder = new NodeUpdatedBuilder();
+        nodeUpdatedBuilder.setId(NODE_ID);
+        deviceMastershipManager.onNodeUpdated(nodeUpdatedBuilder.build());
         // is master
         deviceMastershipManager.getDeviceMasterships().get(NODE_ID).instantiateServiceInstance();
         Assert.assertTrue(deviceMastershipManager.isDeviceMastered(NODE_ID));
index 7beee01f47bb18cf6c7e9d3d3ab15adb6b9a582e..61b4828b111275b8d8f3bf3914f192dc2e6518ed 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2016 Pantheon Technologies s.r.o. and others. All rights reserved.
+ * Copyright (c) 2016, 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,
@@ -16,6 +16,7 @@ import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
+import org.opendaylight.openflowplugin.applications.frm.FlowNodeReconciliation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 
 /**
@@ -29,9 +30,12 @@ public class DeviceMastershipTest {
     @Mock
     private DeviceMastershipManager deviceMastershipManager;
 
+    @Mock
+    private FlowNodeReconciliation reconcliationAgent;
+
     @Before
     public void setUp() throws Exception {
-        deviceMastership = new DeviceMastership(NODE_ID, Mockito.mock(ClusterSingletonServiceProvider.class));
+        deviceMastership = new DeviceMastership(NODE_ID, Mockito.mock(ClusterSingletonServiceProvider.class), reconcliationAgent);
     }
 
     @Test
index acada3752301bb3fb142bcb17a5b23d808f746f4..5246750de9afd6c176b3536549adb85a14f5b350 100644 (file)
@@ -20,6 +20,7 @@ import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.openflowplugin.applications.frm.impl.DeviceMastershipManager;
@@ -63,6 +64,8 @@ public class FlowListenerTest extends FRMTest {
     ClusterSingletonServiceProvider clusterSingletonService;
     @Mock
     DeviceMastershipManager deviceMastershipManager;
+    @Mock
+    private NotificationProviderService notificationService;
 
     @Before
     public void setUp() {
@@ -70,7 +73,8 @@ public class FlowListenerTest extends FRMTest {
                 getDataBroker(),
                 rpcProviderRegistryMock,
                 getConfig(),
-                clusterSingletonService);
+                clusterSingletonService,
+                notificationService, false, false, 5);
         forwardingRulesManager.start();
         // TODO consider tests rewrite (added because of complicated access)
         forwardingRulesManager.setDeviceMastershipManager(deviceMastershipManager);
index e33a88d52aca9eb6ec7ea83342a8d3e3ea84f493..7c990531d340a4bddfa1effa77d693a2b0d77938 100644 (file)
@@ -19,6 +19,7 @@ import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.openflowplugin.applications.frm.impl.DeviceMastershipManager;
@@ -53,6 +54,8 @@ public class GroupListenerTest extends FRMTest {
     ClusterSingletonServiceProvider clusterSingletonService;
     @Mock
     DeviceMastershipManager deviceMastershipManager;
+    @Mock
+    private NotificationProviderService notificationService;
 
     @Before
     public void setUp() {
@@ -60,7 +63,8 @@ public class GroupListenerTest extends FRMTest {
                 getDataBroker(),
                 rpcProviderRegistryMock,
                 getConfig(),
-                clusterSingletonService);
+                clusterSingletonService,
+                notificationService, false, false, 5);
         forwardingRulesManager.start();
         // TODO consider tests rewrite (added because of complicated access)
         forwardingRulesManager.setDeviceMastershipManager(deviceMastershipManager);
index bab64fc88575015472ad3c50cd87936797447373..6fca053ef61ad0963ad6c6863784116a17d5a334 100644 (file)
@@ -19,6 +19,7 @@ import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.openflowplugin.applications.frm.impl.DeviceMastershipManager;
@@ -53,6 +54,8 @@ public class MeterListenerTest extends FRMTest {
     ClusterSingletonServiceProvider clusterSingletonService;
     @Mock
     DeviceMastershipManager deviceMastershipManager;
+    @Mock
+    private NotificationProviderService notificationService;
 
     @Before
     public void setUp() {
@@ -60,7 +63,8 @@ public class MeterListenerTest extends FRMTest {
                 getDataBroker(),
                 rpcProviderRegistryMock,
                 getConfig(),
-                clusterSingletonService);
+                clusterSingletonService,
+                notificationService, false, false, 5);
         forwardingRulesManager.start();
         // TODO consider tests rewrite (added because of complicated access)
         forwardingRulesManager.setDeviceMastershipManager(deviceMastershipManager);
index c0ee47212444c710ad5c9c0b2c717e5df19bca6d..cfae7190217fe69c057187610ce58b7435a220f1 100644 (file)
@@ -16,6 +16,7 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.openflowplugin.applications.frm.impl.ForwardingRulesManagerImpl;
@@ -35,6 +36,8 @@ public class NodeListenerTest extends FRMTest {
     RpcProviderRegistry rpcProviderRegistryMock = new RpcProviderRegistryMock();
     @Mock
     ClusterSingletonServiceProvider clusterSingletonService;
+    @Mock
+    private NotificationProviderService notificationService;
 
     @Before
     public void setUp() {
@@ -42,7 +45,8 @@ public class NodeListenerTest extends FRMTest {
                 getDataBroker(),
                 rpcProviderRegistryMock,
                 getConfig(),
-                clusterSingletonService);
+                clusterSingletonService,
+                notificationService, false ,false ,5);
         forwardingRulesManager.start();
     }
 
index 1dd9697173988dcd40e8888a004701514f5e33b8..52e0b851697eaf02f53dc9dda16945aa999f7127 100644 (file)
@@ -19,6 +19,7 @@ import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.openflowplugin.applications.frm.impl.DeviceMastershipManager;
@@ -48,6 +49,8 @@ public class TableFeaturesListenerTest extends FRMTest {
     ClusterSingletonServiceProvider clusterSingletonService;
     @Mock
     DeviceMastershipManager deviceMastershipManager;
+    @Mock
+    private NotificationProviderService notificationService;
 
     @Before
     public void setUp() {
@@ -55,7 +58,8 @@ public class TableFeaturesListenerTest extends FRMTest {
                 getDataBroker(),
                 rpcProviderRegistryMock,
                 getConfig(),
-                clusterSingletonService);
+                clusterSingletonService,
+                notificationService, false, false , 5);
         forwardingRulesManager.start();
         // TODO consider tests rewrite (added because of complicated access)
         forwardingRulesManager.setDeviceMastershipManager(deviceMastershipManager);
index 2f173eb7459ec07db47c3683b0b8f3d81a753b26..71902fe379468f03e1e2ba9184ce978abccf36ff 100644 (file)
@@ -4,7 +4,7 @@
     <parent>
         <groupId>org.opendaylight.openflowplugin</groupId>
         <artifactId>applications</artifactId>
-        <version>0.3.3-SNAPSHOT</version>
+        <version>0.3.5-SNAPSHOT</version>
     </parent>
     <groupId>org.opendaylight.openflowplugin.applications</groupId>
     <artifactId>forwardingrules-sync</artifactId>
index 25f2b5c9da2e7efc44002c76dd416f087587ef0e..233bc344c6067223c9158437cd8d26aa9779541b 100644 (file)
@@ -4,12 +4,12 @@
   <parent>
     <groupId>org.opendaylight.controller</groupId>
     <artifactId>config-parent</artifactId>
-    <version>0.5.3-SNAPSHOT</version>
+    <version>0.5.5-SNAPSHOT</version>
     <relativePath/>
   </parent>
   <groupId>org.opendaylight.openflowplugin.applications</groupId>
   <artifactId>inventory-manager</artifactId>
-  <version>0.3.3-SNAPSHOT</version>
+  <version>0.3.5-SNAPSHOT</version>
   <packaging>bundle</packaging>
 
   <dependencyManagement>
index fc1828a7871d5828a7f9c285b73e644bbae8ee3a..026c220335b96241cbf28e665e8a9348211ba8af 100644 (file)
@@ -6,7 +6,7 @@
     <parent>
         <groupId>org.opendaylight.openflowplugin</groupId>
         <artifactId>applications</artifactId>
-        <version>0.3.3-SNAPSHOT</version>
+        <version>0.3.5-SNAPSHOT</version>
     </parent>
     <groupId>org.opendaylight.openflowplugin.applications</groupId>
     <artifactId>lldp-speaker</artifactId>
index d55cff2036a699d96282c3d4276a3801e0abbcae..763a0c92f9ba21d07a16532042404dfa61be6d45 100644 (file)
@@ -6,7 +6,7 @@
     <parent>
         <groupId>org.opendaylight.openflowplugin</groupId>
         <artifactId>applications</artifactId>
-        <version>0.3.3-SNAPSHOT</version>
+        <version>0.3.5-SNAPSHOT</version>
     </parent>
     <groupId>org.opendaylight.openflowplugin.applications</groupId>
     <artifactId>notification-supplier</artifactId>
index 23eeb8c5c19bb0e026bf07dc4728b436fcb9d0f9..a690cafaa327b6b7f6bf59ad011b5d470f346dd2 100644 (file)
@@ -6,7 +6,7 @@
     <parent>
         <groupId>org.opendaylight.openflowplugin</groupId>
         <artifactId>applications</artifactId>
-        <version>0.3.3-SNAPSHOT</version>
+        <version>0.3.5-SNAPSHOT</version>
     </parent>
     <groupId>org.opendaylight.openflowplugin.applications</groupId>
     <artifactId>of-switch-config-pusher</artifactId>
index ca680cac7884266161f7ff8a18b5c3dc5dfb062f..61ab4743c869efa1488f476559ed168bfdd08d4a 100644 (file)
@@ -5,7 +5,7 @@
     <parent>
         <groupId>org.opendaylight.openflowplugin</groupId>
         <artifactId>openflowplugin-parent</artifactId>
-        <version>0.3.3-SNAPSHOT</version>
+        <version>0.3.5-SNAPSHOT</version>
         <relativePath>../parent</relativePath>
     </parent>
 
index 09f1455d3ac25cc9a75d02be19ee523f80aac447..072bb3ab6e84f0ff7d68b5b7feb8f65e5456b826 100644 (file)
@@ -4,7 +4,7 @@
   <parent>
     <groupId>org.opendaylight.openflowplugin</groupId>
     <artifactId>applications</artifactId>
-    <version>0.3.3-SNAPSHOT</version>
+    <version>0.3.5-SNAPSHOT</version>
   </parent>
   <groupId>org.opendaylight.openflowplugin.applications</groupId>
   <artifactId>statistics-manager</artifactId>
index d5532a0e337449855b201ffe09b90eb55fab30b2..3ec705086ea86824012f6d98533f0370647c0a66 100644 (file)
@@ -9,7 +9,6 @@
 package org.opendaylight.openflowplugin.applications.statistics.manager;
 
 import java.util.List;
-import java.util.concurrent.Callable;
 import java.util.concurrent.Future;
 
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionAware;
@@ -38,10 +37,7 @@ import com.google.common.util.concurrent.SettableFuture;
  *
  * Created: Aug 29, 2014
  */
-public interface StatRpcMsgManager extends Runnable, AutoCloseable {
-
-    interface RpcJobsQueue extends Callable<Void> {}
-
+public interface StatRpcMsgManager {
     /**
      * Transaction container is definition for Multipart transaction
      * join container for all Multipart msg with same TransactionId
index 4c3f573ccca6cbadbab4e2213cb1daa9e78d8d66..0515ca1d1dd9fd97d23110cc8df5fa845f4c001d 100644 (file)
@@ -11,10 +11,8 @@ package org.opendaylight.openflowplugin.applications.statistics.manager.impl;
 import java.math.BigInteger;
 import java.util.Arrays;
 import java.util.List;
-import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.Future;
-import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementationNotAvailableException;
@@ -88,8 +86,19 @@ public class StatRpcMsgManagerImpl implements StatRpcMsgManager {
 
     private final Cache<String, TransactionCacheContainer<? super TransactionAware>> txCache;
 
+    /**
+     * Cache for futures to be returned by
+     * {@link #isExpectedStatistics(TransactionId, NodeId)}.
+     */
+    private final Cache<String, SettableFuture<Boolean>>  txFutureCache;
+
+    /**
+     * The number of seconds to wait for transaction container to be put into
+     * {@link #txCache}.
+     */
+    private static final long TXCACHE_WAIT_TIMEOUT = 10L;
+
     private static final int MAX_CACHE_SIZE = 10000;
-    private static final int QUEUE_CAPACITY = 5000;
 
     private static final String MSG_TRANS_ID_NOT_NULL = "TransactionId can not be null!";
     private static final String MSG_NODE_ID_NOT_NULL = "NodeId can not be null!";
@@ -107,10 +116,6 @@ public class StatRpcMsgManagerImpl implements StatRpcMsgManager {
     private final OpendaylightFlowTableStatisticsService flowTableStatsService;
     private final OpendaylightQueueStatisticsService queueStatsService;
 
-    private BlockingQueue<RpcJobsQueue> statsRpcJobQueue;
-
-    private volatile boolean finishing = false;
-
     public StatRpcMsgManagerImpl (final StatisticsManager manager,
             final RpcConsumerRegistry rpcRegistry, final long maxNodeForCollector) {
         Preconditions.checkArgument(manager != null, "StatisticManager can not be null!");
@@ -134,46 +139,11 @@ public class StatRpcMsgManagerImpl implements StatRpcMsgManager {
                 rpcRegistry.getRpcService(OpendaylightQueueStatisticsService.class),
                 "OpendaylightQueueStatisticsService can not be null!");
 
-        statsRpcJobQueue = new LinkedBlockingQueue<>(QUEUE_CAPACITY);
         txCache = CacheBuilder.newBuilder().expireAfterWrite((maxNodeForCollector * POSSIBLE_STAT_WAIT_FOR_NOTIFICATION), TimeUnit.SECONDS)
                 .maximumSize(MAX_CACHE_SIZE).build();
-    }
-
-    @Override
-    public void close() {
-        finishing = true;
-        statsRpcJobQueue = null;
-    }
-
-    @Override
-    public void run() {
-         /* Neverending cyle - wait for finishing */
-        while ( ! finishing) {
-            try {
-                statsRpcJobQueue.take().call();
-            }
-            catch (final Exception e) {
-                LOG.warn("Stat Element RPC executor fail!", e);
-            }
-        }
-        // Drain all rpcCall, making sure any blocked threads are unblocked
-        while ( ! statsRpcJobQueue.isEmpty()) {
-            statsRpcJobQueue.poll();
-        }
-    }
-
-    private void addGetAllStatJob(final RpcJobsQueue getAllStatJob) {
-        final boolean success = statsRpcJobQueue.offer(getAllStatJob);
-        if ( ! success) {
-            LOG.warn("Put RPC request getAllStat fail! Queue is full.");
-        }
-    }
-
-    private void addStatJob(final RpcJobsQueue getStatJob) {
-        final boolean success = statsRpcJobQueue.offer(getStatJob);
-        if ( ! success) {
-            LOG.debug("Put RPC request for getStat fail! Queue is full.");
-        }
+        txFutureCache = CacheBuilder.newBuilder().
+            expireAfterWrite(TXCACHE_WAIT_TIMEOUT, TimeUnit.SECONDS).
+            maximumSize(MAX_CACHE_SIZE).build();
     }
 
     @Override
@@ -201,7 +171,7 @@ public class StatRpcMsgManagerImpl implements StatRpcMsgManager {
                     final String cacheKey = buildCacheKey(id, nodeKey.getId());
                     final TransactionCacheContainer<? super TransactionAware> container =
                             new TransactionCacheContainerImpl<>(id, inputObj, nodeKey.getId());
-                    txCache.put(cacheKey, container);
+                    putTransaction(cacheKey, container);
                 }
             }
 
@@ -227,30 +197,61 @@ public class StatRpcMsgManagerImpl implements StatRpcMsgManager {
         return String.valueOf(id.getValue()) + "-" + nodeId.getValue();
     }
 
+    /**
+     * Put the given statistics transaction container into the cache.
+     *
+     * @param key        Key that specifies the given transaction container.
+     * @param container  Transaction container.
+     */
+    private synchronized void putTransaction(
+        String key, TransactionCacheContainer<? super TransactionAware> container) {
+        txCache.put(key, container);
+
+        SettableFuture<Boolean> future = txFutureCache.asMap().remove(key);
+        if (future != null) {
+            // Wake up a thread waiting for this transaction container.
+            future.set(true);
+        }
+    }
+
+    /**
+     * Check to see if the specified transaction container is cached in
+     * {@link #txCache}.
+     *
+     * @param key  Key that specifies the transaction container.
+     * @return  A future that will contain the result.
+     */
+    private synchronized Future<Boolean> isExpectedStatistics(String key) {
+        Future<Boolean> future;
+        TransactionCacheContainer<?> container = txCache.getIfPresent(key);
+        if (container == null) {
+            // Wait for the transaction container to be put into the cache.
+            SettableFuture<Boolean> f = SettableFuture.<Boolean>create();
+            SettableFuture<Boolean> current =
+                txFutureCache.asMap().putIfAbsent(key, f);
+            future = (current == null) ? f : current;
+        } else {
+            future = Futures.immediateFuture(Boolean.TRUE);
+        }
+
+        return future;
+    }
+
     @Override
     public Future<Optional<TransactionCacheContainer<?>>> getTransactionCacheContainer(
             final TransactionId id, final NodeId nodeId) {
         Preconditions.checkArgument(id != null, MSG_TRANS_ID_NOT_NULL);
         Preconditions.checkArgument(nodeId != null, MSG_NODE_ID_NOT_NULL);
 
-        final String key = buildCacheKey(id, nodeId);
-        final SettableFuture<Optional<TransactionCacheContainer<?>>> result = SettableFuture.create();
-
-        final RpcJobsQueue getTransactionCacheContainer = new RpcJobsQueue() {
+        String key = buildCacheKey(id, nodeId);
+        Optional<TransactionCacheContainer<?>> resultContainer =
+            Optional.<TransactionCacheContainer<?>> fromNullable(
+                txCache.asMap().remove(key));
+        if (!resultContainer.isPresent()) {
+            LOG.warn("Transaction cache not found: {}", key);
+        }
 
-            @Override
-            public Void call() throws Exception {
-                final Optional<TransactionCacheContainer<?>> resultContainer =
-                        Optional.<TransactionCacheContainer<?>> fromNullable(txCache.getIfPresent(key));
-                if (resultContainer.isPresent()) {
-                    txCache.invalidate(key);
-                }
-                result.set(resultContainer);
-                return null;
-            }
-        };
-        addStatJob(getTransactionCacheContainer);
-        return result;
+        return Futures.immediateFuture(resultContainer);
     }
 
     @Override
@@ -258,21 +259,8 @@ public class StatRpcMsgManagerImpl implements StatRpcMsgManager {
         Preconditions.checkArgument(id != null, MSG_TRANS_ID_NOT_NULL);
         Preconditions.checkArgument(nodeId != null, MSG_NODE_ID_NOT_NULL);
 
-        final String key = buildCacheKey(id, nodeId);
-        final SettableFuture<Boolean> checkStatId = SettableFuture.create();
-
-        final RpcJobsQueue isExpecedStatistics = new RpcJobsQueue() {
-
-            @Override
-            public Void call() throws Exception {
-                final Optional<TransactionCacheContainer<?>> result =
-                        Optional.<TransactionCacheContainer<?>> fromNullable(txCache.getIfPresent(key));
-                checkStatId.set(Boolean.valueOf(result.isPresent()));
-                return null;
-            }
-        };
-        addStatJob(isExpecedStatistics);
-        return checkStatId;
+        String key = buildCacheKey(id, nodeId);
+        return isExpectedStatistics(key);
     }
 
     @Override
@@ -280,79 +268,54 @@ public class StatRpcMsgManagerImpl implements StatRpcMsgManager {
         Preconditions.checkArgument(notification != null, "TransactionAware can not be null!");
         Preconditions.checkArgument(nodeId != null, MSG_NODE_ID_NOT_NULL);
 
-        final RpcJobsQueue addNotification = new RpcJobsQueue() {
-
-            @Override
-            public Void call() throws Exception {
-                final TransactionId txId = notification.getTransactionId();
-                final String key = buildCacheKey(txId, nodeId);
-                final TransactionCacheContainer<? super TransactionAware> container = (txCache.getIfPresent(key));
-                if (container != null) {
-                    container.addNotif(notification);
-                }
-                return null;
-            }
-        };
-        addStatJob(addNotification);
+        TransactionId txId = notification.getTransactionId();
+        String key = buildCacheKey(txId, nodeId);
+        TransactionCacheContainer<? super TransactionAware> container =
+            txCache.getIfPresent(key);
+        if (container != null) {
+            container.addNotif(notification);
+        } else {
+            LOG.warn("Unable to add notification: {}, {}", key,
+                     notification.getImplementedInterface());
+        }
     }
 
     @Override
     public Future<TransactionId> getAllGroupsStat(final NodeRef nodeRef) {
         Preconditions.checkArgument(nodeRef != null, MSG_NODE_REF_NOT_NULL);
-        final SettableFuture<TransactionId> result = SettableFuture.create();
-        final RpcJobsQueue getAllGroupStat = new RpcJobsQueue() {
-
-            @Override
-            public Void call() throws Exception {
-                final GetAllGroupStatisticsInputBuilder builder =
-                        new GetAllGroupStatisticsInputBuilder();
-                builder.setNode(nodeRef);
-                registrationRpcFutureCallBack(groupStatsService
-                        .getAllGroupStatistics(builder.build()), null, nodeRef, result);
-                return null;
-            }
-        };
-        addGetAllStatJob(getAllGroupStat);
+        SettableFuture<TransactionId> result = SettableFuture.create();
+        GetAllGroupStatisticsInputBuilder builder =
+            new GetAllGroupStatisticsInputBuilder();
+        builder.setNode(nodeRef);
+        registrationRpcFutureCallBack(
+            groupStatsService.getAllGroupStatistics(builder.build()), null,
+            nodeRef, result);
         return result;
     }
 
     @Override
     public Future<TransactionId> getAllMetersStat(final NodeRef nodeRef) {
         Preconditions.checkArgument(nodeRef != null, MSG_NODE_REF_NOT_NULL);
-        final SettableFuture<TransactionId> result = SettableFuture.create();
-        final RpcJobsQueue getAllMeterStat = new RpcJobsQueue() {
-
-            @Override
-            public Void call() throws Exception {
-                final GetAllMeterStatisticsInputBuilder builder =
-                        new GetAllMeterStatisticsInputBuilder();
-                builder.setNode(nodeRef);
-                registrationRpcFutureCallBack(meterStatsService
-                        .getAllMeterStatistics(builder.build()), null, nodeRef, result);
-                return null;
-            }
-        };
-        addGetAllStatJob(getAllMeterStat);
+        SettableFuture<TransactionId> result = SettableFuture.create();
+        GetAllMeterStatisticsInputBuilder builder =
+            new GetAllMeterStatisticsInputBuilder();
+        builder.setNode(nodeRef);
+        registrationRpcFutureCallBack(
+            meterStatsService.getAllMeterStatistics(builder.build()), null,
+            nodeRef, result);
         return result;
     }
 
     @Override
     public Future<TransactionId> getAllFlowsStat(final NodeRef nodeRef) {
         Preconditions.checkArgument(nodeRef != null, MSG_NODE_REF_NOT_NULL);
-        final SettableFuture<TransactionId> result = SettableFuture.create();
-        final RpcJobsQueue getAllFlowStat = new RpcJobsQueue() {
-
-            @Override
-            public Void call() throws Exception {
-                final GetAllFlowsStatisticsFromAllFlowTablesInputBuilder builder =
-                        new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder();
-                builder.setNode(nodeRef);
-                registrationRpcFutureCallBack(flowStatsService
-                        .getAllFlowsStatisticsFromAllFlowTables(builder.build()), null, nodeRef, result);
-                return null;
-            }
-        };
-        addGetAllStatJob(getAllFlowStat);
+        SettableFuture<TransactionId> result = SettableFuture.create();
+        GetAllFlowsStatisticsFromAllFlowTablesInputBuilder builder =
+            new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder();
+        builder.setNode(nodeRef);
+        registrationRpcFutureCallBack(
+            flowStatsService.getAllFlowsStatisticsFromAllFlowTables(builder.build()),
+            null, nodeRef, result);
         return result;
     }
 
@@ -360,159 +323,100 @@ public class StatRpcMsgManagerImpl implements StatRpcMsgManager {
     public void getAggregateFlowStat(final NodeRef nodeRef, final TableId tableId) {
         Preconditions.checkArgument(nodeRef != null, MSG_NODE_REF_NOT_NULL);
         Preconditions.checkArgument(tableId != null, "TableId can not be null!");
-        final RpcJobsQueue getAggregateFlowStat = new RpcJobsQueue() {
-
-            @Override
-            public Void call() throws Exception {
-                final GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder builder =
-                        new GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder();
-                builder.setNode(nodeRef);
-                builder.setTableId(tableId);
-
-                final TableBuilder tbuilder = new TableBuilder();
-                tbuilder.setId(tableId.getValue());
-                tbuilder.setKey(new TableKey(tableId.getValue()));
-                registrationRpcFutureCallBack(flowStatsService
-                        .getAggregateFlowStatisticsFromFlowTableForAllFlows(builder.build()), tbuilder.build(), nodeRef, null);
-                return null;
-            }
-        };
-        addGetAllStatJob(getAggregateFlowStat);
+        GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder builder =
+            new GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder();
+        builder.setNode(nodeRef).setTableId(tableId);
+
+        TableBuilder tbuilder = new TableBuilder().
+            setId(tableId.getValue()).
+            setKey(new TableKey(tableId.getValue()));
+        registrationRpcFutureCallBack(
+            flowStatsService.getAggregateFlowStatisticsFromFlowTableForAllFlows(builder.build()),
+            tbuilder.build(), nodeRef, null);
     }
 
     @Override
     public Future<TransactionId> getAllPortsStat(final NodeRef nodeRef) {
         Preconditions.checkArgument(nodeRef != null, MSG_NODE_REF_NOT_NULL);
-        final SettableFuture<TransactionId> result = SettableFuture.create();
-        final RpcJobsQueue getAllPortsStat = new RpcJobsQueue() {
-
-            @Override
-            public Void call() throws Exception {
-                final GetAllNodeConnectorsStatisticsInputBuilder builder =
-                        new GetAllNodeConnectorsStatisticsInputBuilder();
-                builder.setNode(nodeRef);
-                final Future<RpcResult<GetAllNodeConnectorsStatisticsOutput>> rpc =
-                        portStatsService.getAllNodeConnectorsStatistics(builder.build());
-                registrationRpcFutureCallBack(rpc, null, nodeRef, result);
-                return null;
-            }
-        };
-        addGetAllStatJob(getAllPortsStat);
+        SettableFuture<TransactionId> result = SettableFuture.create();
+        GetAllNodeConnectorsStatisticsInputBuilder builder =
+            new GetAllNodeConnectorsStatisticsInputBuilder();
+        builder.setNode(nodeRef);
+        Future<RpcResult<GetAllNodeConnectorsStatisticsOutput>> rpc =
+            portStatsService.getAllNodeConnectorsStatistics(builder.build());
+        registrationRpcFutureCallBack(rpc, null, nodeRef, result);
         return result;
     }
 
     @Override
     public Future<TransactionId> getAllTablesStat(final NodeRef nodeRef) {
         Preconditions.checkArgument(nodeRef != null, MSG_NODE_REF_NOT_NULL);
-        final SettableFuture<TransactionId> result = SettableFuture.create();
-        final RpcJobsQueue getAllTableStat = new RpcJobsQueue() {
-
-            @Override
-            public Void call() throws Exception {
-                final GetFlowTablesStatisticsInputBuilder builder =
-                        new GetFlowTablesStatisticsInputBuilder();
-                builder.setNode(nodeRef);
-                registrationRpcFutureCallBack(flowTableStatsService
-                        .getFlowTablesStatistics(builder.build()), null, nodeRef, result);
-                return null;
-            }
-        };
-        addGetAllStatJob(getAllTableStat);
+        SettableFuture<TransactionId> result = SettableFuture.create();
+        GetFlowTablesStatisticsInputBuilder builder =
+            new GetFlowTablesStatisticsInputBuilder();
+        builder.setNode(nodeRef);
+        registrationRpcFutureCallBack(
+            flowTableStatsService.getFlowTablesStatistics(builder.build()),
+            null, nodeRef, result);
         return result;
     }
 
     @Override
     public Future<TransactionId>  getAllQueueStat(final NodeRef nodeRef) {
         Preconditions.checkArgument(nodeRef != null, MSG_NODE_REF_NOT_NULL);
-        final SettableFuture<TransactionId> result = SettableFuture.create();
-        final RpcJobsQueue getAllQueueStat = new RpcJobsQueue() {
-
-            @Override
-            public Void call() throws Exception {
-                final GetAllQueuesStatisticsFromAllPortsInputBuilder builder =
-                        new GetAllQueuesStatisticsFromAllPortsInputBuilder();
-                builder.setNode(nodeRef);
-                registrationRpcFutureCallBack(queueStatsService
-                        .getAllQueuesStatisticsFromAllPorts(builder.build()), null, nodeRef, result);
-                return null;
-            }
-        };
-        addGetAllStatJob(getAllQueueStat);
+        SettableFuture<TransactionId> result = SettableFuture.create();
+        GetAllQueuesStatisticsFromAllPortsInputBuilder builder =
+            new GetAllQueuesStatisticsFromAllPortsInputBuilder();
+        builder.setNode(nodeRef);
+        registrationRpcFutureCallBack(
+            queueStatsService.getAllQueuesStatisticsFromAllPorts(builder.build()),
+            null, nodeRef, result);
         return result;
     }
 
     @Override
     public Future<TransactionId> getAllMeterConfigStat(final NodeRef nodeRef) {
         Preconditions.checkArgument(nodeRef != null, MSG_NODE_REF_NOT_NULL);
-        final SettableFuture<TransactionId> result = SettableFuture.create();
-        final RpcJobsQueue qetAllMeterConfStat = new RpcJobsQueue() {
-
-            @Override
-            public Void call() throws Exception {
-                final GetAllMeterConfigStatisticsInputBuilder builder =
-                        new GetAllMeterConfigStatisticsInputBuilder();
-                builder.setNode(nodeRef);
-                registrationRpcFutureCallBack(meterStatsService
-                        .getAllMeterConfigStatistics(builder.build()), null, nodeRef, result);
-                return null;
-            }
-        };
-        addGetAllStatJob(qetAllMeterConfStat);
+        SettableFuture<TransactionId> result = SettableFuture.create();
+        GetAllMeterConfigStatisticsInputBuilder builder =
+            new GetAllMeterConfigStatisticsInputBuilder();
+        builder.setNode(nodeRef);
+        registrationRpcFutureCallBack(
+            meterStatsService.getAllMeterConfigStatistics(builder.build()),
+            null, nodeRef, result);
         return result;
     }
 
     @Override
     public void getGroupFeaturesStat(final NodeRef nodeRef) {
         Preconditions.checkArgument(nodeRef != null, MSG_NODE_REF_NOT_NULL);
-        final RpcJobsQueue getGroupFeaturesStat = new RpcJobsQueue() {
-
-            @Override
-            public Void call() throws Exception {
-                /* RPC input */
-                final GetGroupFeaturesInputBuilder input = new GetGroupFeaturesInputBuilder();
-                input.setNode(nodeRef);
-                registrationRpcFutureCallBack(groupStatsService.getGroupFeatures(input.build()), null, nodeRef, null);
-                return null;
-            }
-        };
-        addStatJob(getGroupFeaturesStat);
+        GetGroupFeaturesInputBuilder input = new GetGroupFeaturesInputBuilder().
+            setNode(nodeRef);
+        registrationRpcFutureCallBack(
+            groupStatsService.getGroupFeatures(input.build()), null, nodeRef,
+            null);
     }
 
     @Override
     public void getMeterFeaturesStat(final NodeRef nodeRef) {
         Preconditions.checkArgument(nodeRef != null, MSG_NODE_REF_NOT_NULL);
-        final RpcJobsQueue getMeterFeaturesStat = new RpcJobsQueue() {
-
-            @Override
-            public Void call() throws Exception {
-                /* RPC input */
-                final GetMeterFeaturesInputBuilder input = new GetMeterFeaturesInputBuilder();
-                input.setNode(nodeRef);
-                registrationRpcFutureCallBack(meterStatsService.getMeterFeatures(input.build()), null, nodeRef, null);
-                return null;
-            }
-        };
-        addStatJob(getMeterFeaturesStat);
+        GetMeterFeaturesInputBuilder input = new GetMeterFeaturesInputBuilder().
+            setNode(nodeRef);
+        registrationRpcFutureCallBack(
+            meterStatsService.getMeterFeatures(input.build()), null, nodeRef,
+            null);
     }
 
     @Override
     public Future<TransactionId> getAllGroupsConfStats(final NodeRef nodeRef) {
         Preconditions.checkArgument(nodeRef != null, MSG_NODE_REF_NOT_NULL);
-        final SettableFuture<TransactionId> result = SettableFuture.create();
-        final RpcJobsQueue getAllGropConfStat = new RpcJobsQueue() {
-
-            @Override
-            public Void call() throws Exception {
-                final GetGroupDescriptionInputBuilder builder =
-                        new GetGroupDescriptionInputBuilder();
-                builder.setNode(nodeRef);
-                registrationRpcFutureCallBack(groupStatsService
-                        .getGroupDescription(builder.build()), null, nodeRef, result);
-
-                return null;
-            }
-        };
-        addGetAllStatJob(getAllGropConfStat);
+        SettableFuture<TransactionId> result = SettableFuture.create();
+        GetGroupDescriptionInputBuilder builder =
+            new GetGroupDescriptionInputBuilder();
+        builder.setNode(nodeRef);
+        registrationRpcFutureCallBack(
+            groupStatsService.getGroupDescription(builder.build()), null,
+            nodeRef, result);
         return result;
     }
 
@@ -556,4 +460,3 @@ public class StatRpcMsgManagerImpl implements StatRpcMsgManager {
         }
     }
 }
-
index afca1d2ed5eeabe95a92a5bb8289146d8560a8a7..3bd0cc2a65303629a6635336c4f3b97143aca98d 100644 (file)
@@ -80,7 +80,6 @@ public class StatisticsManagerImpl implements StatisticsManager, Runnable {
 
 
     private final DataBroker dataBroker;
-   private final ExecutorService statRpcMsgManagerExecutor;
    private final ExecutorService statDataStoreOperationServ;
    private EntityOwnershipService ownershipService;
    private StatRpcMsgManager rpcMsgManager;
@@ -104,7 +103,6 @@ public class StatisticsManagerImpl implements StatisticsManager, Runnable {
        this.dataBroker = Preconditions.checkNotNull(dataBroker, "DataBroker can not be null!");
        ThreadFactory threadFact;
        threadFact = new ThreadFactoryBuilder().setNameFormat("odl-stat-rpc-oper-thread-%d").build();
-       statRpcMsgManagerExecutor = Executors.newSingleThreadExecutor(threadFact);
        threadFact = new ThreadFactoryBuilder().setNameFormat("odl-stat-ds-oper-thread-%d").build();
        statDataStoreOperationServ = Executors.newSingleThreadExecutor(threadFact);
        txChain =  dataBroker.createTransactionChain(this);
@@ -124,7 +122,6 @@ public class StatisticsManagerImpl implements StatisticsManager, Runnable {
        portNotifyCommiter = new StatNotifyCommitPort(this, notifService, nodeRegistrator);
        queueNotifyCommiter = new StatListenCommitQueue(this, dataBroker, notifService, nodeRegistrator);
 
-       statRpcMsgManagerExecutor.execute(rpcMsgManager);
        statDataStoreOperationServ.execute(this);
        LOG.info("Statistics Manager started successfully!");
    }
@@ -153,8 +150,7 @@ public class StatisticsManagerImpl implements StatisticsManager, Runnable {
            }
            statCollectors = null;
        }
-       rpcMsgManager = close(rpcMsgManager);
-       statRpcMsgManagerExecutor.shutdown();
+       rpcMsgManager = null;
        statDataStoreOperationServ.shutdown();
        txChain = close(txChain);
    }
index c024e094b1b2be27e76a20994ebfa26902136668..284865186aabd1c3460ed184bdf9062e5d77c440 100644 (file)
@@ -5,7 +5,7 @@
   <parent>
     <groupId>org.opendaylight.openflowplugin</groupId>
     <artifactId>applications</artifactId>
-    <version>0.3.3-SNAPSHOT</version>
+    <version>0.3.5-SNAPSHOT</version>
   </parent>
   <groupId>org.opendaylight.openflowplugin.applications</groupId>
   <artifactId>table-miss-enforcer</artifactId>
index ac67cd0b061db33d44fe7e9038c8b104db4db236..e9bf815b90757505b0b5b58c0ddec5fa5fc23432 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2014 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,
@@ -14,6 +14,7 @@ import java.util.Collection;
 import java.util.List;
 import java.util.concurrent.Callable;
 import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
@@ -51,7 +52,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.N
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
-public class LLDPPacketPuntEnforcer implements AutoCloseable, DataTreeChangeListener<FlowCapableNode> {
+public class LLDPPacketPuntEnforcer implements AutoCloseable, ClusteredDataTreeChangeListener<FlowCapableNode> {
     private static final long STARTUP_LOOP_TICK = 500L;
     private static final int STARTUP_LOOP_MAX_RETRIES = 8;
     private static final short TABLE_ID = (short) 0;
index dbc029f80443c7c5affb387cf633d2e892d33807..ed243976e93ae155f2f0a8718a29d2f22ad986c7 100644 (file)
@@ -4,12 +4,12 @@
   <parent>
     <groupId>org.opendaylight.controller</groupId>
     <artifactId>config-parent</artifactId>
-    <version>0.5.3-SNAPSHOT</version>
+    <version>0.5.5-SNAPSHOT</version>
     <relativePath/>
   </parent>
   <groupId>org.opendaylight.openflowplugin.applications</groupId>
   <artifactId>topology-lldp-discovery</artifactId>
-  <version>0.3.3-SNAPSHOT</version>
+  <version>0.3.5-SNAPSHOT</version>
   <packaging>bundle</packaging>
 
   <dependencyManagement>
@@ -52,7 +52,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>liblldp</artifactId>
-      <version>0.11.3-SNAPSHOT</version>
+      <version>0.11.5-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.openflowplugin.model</groupId>
index 6256df039faa19bf0e0428bac6b0bab372a6d695..dc82e682c78c2dda825fdddc0fa56e57e6266586 100644 (file)
@@ -4,12 +4,12 @@
   <parent>
     <groupId>org.opendaylight.controller</groupId>
     <artifactId>config-parent</artifactId>
-    <version>0.5.3-SNAPSHOT</version>
+    <version>0.5.5-SNAPSHOT</version>
     <relativePath/>
   </parent>
   <groupId>org.opendaylight.openflowplugin.applications</groupId>
   <artifactId>topology-manager</artifactId>
-  <version>0.3.3-SNAPSHOT</version>
+  <version>0.3.5-SNAPSHOT</version>
   <packaging>bundle</packaging>
 
   <dependencyManagement>
index 5c32b527c2df31f8737fc725dd9ff33ac8a38317..d7ef359f97c9f1bf6248f4d3676dd1bc1e00ef86 100644 (file)
   <parent>
     <groupId>org.opendaylight.odlparent</groupId>
     <artifactId>odlparent-lite</artifactId>
-    <version>1.7.3-SNAPSHOT</version>
+    <version>1.7.5-SNAPSHOT</version>
     <relativePath/>
   </parent>
 
     <groupId>org.opendaylight.openflowplugin</groupId>
     <artifactId>openflowplugin-artifacts</artifactId>
-    <version>0.3.3-SNAPSHOT</version>
+    <version>0.3.5-SNAPSHOT</version>
     <packaging>pom</packaging>
 
     <dependencyManagement>
index abf385c09117b4273e0fd2852361e0219c9554fc..b1886442a1c4d246a59262e6f8f96a13c8888448 100644 (file)
@@ -4,19 +4,19 @@
   <parent>
     <groupId>org.opendaylight.odlparent</groupId>
     <artifactId>karaf-parent</artifactId>
-    <version>1.7.3-SNAPSHOT</version>
+    <version>1.7.5-SNAPSHOT</version>
     <relativePath></relativePath>
   </parent>
   <groupId>org.opendaylight.openflowplugin</groupId>
   <artifactId>openflowplugin-karaf</artifactId>
-  <version>0.3.3-SNAPSHOT</version>
+  <version>0.3.5-SNAPSHOT</version>
   <packaging>pom</packaging>
   <prerequisites>
     <maven>3.0</maven>
   </prerequisites>
 
   <properties>
-    <openflowplugin.version>0.3.3-SNAPSHOT</openflowplugin.version>
+    <openflowplugin.version>0.3.5-SNAPSHOT</openflowplugin.version>
   </properties>
 
   <dependencyManagement>
index 86ba6111707d98e55abcae00056181c082fb1cd1..e46f68b4d7f70a5e53d3e823d407fa10065da3e6 100644 (file)
@@ -4,7 +4,7 @@
     <parent>
         <groupId>org.opendaylight.openflowplugin</groupId>
         <artifactId>openflowplugin-parent</artifactId>
-        <version>0.3.3-SNAPSHOT</version>
+        <version>0.3.5-SNAPSHOT</version>
         <relativePath>../parent</relativePath>
     </parent>
     <artifactId>drop-test-karaf</artifactId>
index 2e79ba7fd7487f832145026dca8f7197ed29eb0e..b1735d33a826226bf73f3f13f5a6f57b740ec214 100644 (file)
@@ -3,7 +3,7 @@
     <parent>
         <groupId>org.opendaylight.openflowplugin</groupId>
         <artifactId>openflowplugin-parent</artifactId>
-        <version>0.3.3-SNAPSHOT</version>
+        <version>0.3.5-SNAPSHOT</version>
         <relativePath>../parent</relativePath>
     </parent>
     <artifactId>drop-test</artifactId>
index f9d744567449041415c658be914e4fe6ce59fd6f..1ec5bd8c79f1a0931a0dae2e54c99764b3517806 100644 (file)
@@ -4,17 +4,17 @@
   <parent>
     <groupId>org.opendaylight.odlparent</groupId>
     <artifactId>features-parent</artifactId>
-    <version>1.7.3-SNAPSHOT</version>
+    <version>1.7.5-SNAPSHOT</version>
     <relativePath/>
   </parent>
   <groupId>org.opendaylight.openflowplugin</groupId>
-  <version>0.3.3-SNAPSHOT</version>
+  <version>0.3.5-SNAPSHOT</version>
   <artifactId>features-openflowplugin-extension-he</artifactId>
 
   <packaging>jar</packaging>
 
   <properties>
-    <openflowplugin.version>0.3.3-SNAPSHOT</openflowplugin.version>
+    <openflowplugin.version>0.3.5-SNAPSHOT</openflowplugin.version>
   </properties>
 
   <dependencyManagement>
index 27b4a9b37daed11e0f96c066c92b9408450345a7..4cb46b7a016b818a7e168665c13ff60e8d456949 100644 (file)
@@ -4,17 +4,17 @@
   <parent>
     <groupId>org.opendaylight.odlparent</groupId>
     <artifactId>features-parent</artifactId>
-    <version>1.7.3-SNAPSHOT</version>
+    <version>1.7.5-SNAPSHOT</version>
     <relativePath/>
   </parent>
   <groupId>org.opendaylight.openflowplugin</groupId>
-  <version>0.3.3-SNAPSHOT</version>
+  <version>0.3.5-SNAPSHOT</version>
   <artifactId>features-openflowplugin-extension</artifactId>
 
   <packaging>jar</packaging>
 
   <properties>
-    <openflowplugin.version>0.3.3-SNAPSHOT</openflowplugin.version>
+    <openflowplugin.version>0.3.5-SNAPSHOT</openflowplugin.version>
   </properties>
 
   <dependencyManagement>
index 20dbd87c009661259d5c7426abec0e6e7adc6317..fa9a69717da270c357eabccc76de83d26f9a34e2 100644 (file)
@@ -6,7 +6,7 @@
     <parent>
         <groupId>org.opendaylight.openflowplugin</groupId>
         <artifactId>openflowplugin-extension-parent</artifactId>
-        <version>0.3.3-SNAPSHOT</version>
+        <version>0.3.5-SNAPSHOT</version>
         <relativePath>../</relativePath>
     </parent>
     <artifactId>openflowjava-extension-nicira-api</artifactId>
index 6828d145c6151ee8236e3d6941eb0d078872b7b4..d856242cfefda5b4d79b5d5c6ee92834ee8d12b4 100644 (file)
@@ -5,7 +5,7 @@
     <parent>
         <groupId>org.opendaylight.openflowplugin</groupId>
         <artifactId>openflowplugin-extension-parent</artifactId>
-        <version>0.3.3-SNAPSHOT</version>
+        <version>0.3.5-SNAPSHOT</version>
         <relativePath>../</relativePath>
     </parent>
     <artifactId>openflowjava-extension-nicira</artifactId>
index 166c2c593625adb27e654437bca852d0cb576d34..8ca8bf52c32e43e89458acdadce82580bc08b2f3 100644 (file)
@@ -20,8 +20,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.matc
 
 public abstract class AbstractMatchCodec implements OFSerializer<MatchEntry>, OFDeserializer<MatchEntry> {
 
-    private NxmHeader headerWithMask;
-    private NxmHeader headerWithoutMask;
+    protected NxmHeader headerWithMask;
+    protected NxmHeader headerWithoutMask;
 
     protected MatchEntryBuilder deserializeHeader(ByteBuf message) {
         MatchEntryBuilder builder = new MatchEntryBuilder();
index 7ff2cc806a17dfec19e090c3c34382d4b504fccb..40997d87569d451c5f6193c49be0ff8d35436cd3 100644 (file)
@@ -25,19 +25,38 @@ public abstract class AbstractRegCodec extends AbstractMatchCodec {
 
     @Override
     public MatchEntry deserialize(ByteBuf message) {
-        MatchEntryBuilder matchEntriesBuilder = deserializeHeader(message);
-        RegCaseValueBuilder caseBuilder = new RegCaseValueBuilder();
-        caseBuilder.setRegValues(new RegValuesBuilder().setValue(message.readUnsignedInt()).build());
-        matchEntriesBuilder.setMatchEntryValue(caseBuilder.build());
-        return matchEntriesBuilder.build();
+        final MatchEntryBuilder matchEntriesBuilder = deserializeHeader(message);
+        final RegValuesBuilder regValuesBuilder = new RegValuesBuilder();
+        regValuesBuilder.setValue(message.readUnsignedInt());
+
+        if (matchEntriesBuilder.isHasMask()) {
+            regValuesBuilder.setMask(message.readUnsignedInt());
+        }
+
+        return matchEntriesBuilder
+            .setMatchEntryValue(new RegCaseValueBuilder()
+                .setRegValues(regValuesBuilder.build())
+                .build())
+            .build();
     }
 
     @Override
     public void serialize(MatchEntry input, ByteBuf outBuffer) {
         serializeHeader(input, outBuffer);
-        RegCaseValue regCase = ((RegCaseValue) input.getMatchEntryValue());
-        Long value = regCase.getRegValues().getValue();
-        outBuffer.writeInt(value.intValue());
+        final RegCaseValue regCase = ((RegCaseValue) input.getMatchEntryValue());
+        outBuffer.writeInt(regCase.getRegValues().getValue().intValue());
+
+        if (input.isHasMask()) {
+            outBuffer.writeInt(regCase.getRegValues().getMask().intValue());
+        }
+    }
+
+    @Override
+    public NxmHeader getHeaderWithHasMask() {
+        if (headerWithMask == null) {
+            headerWithMask = new NxmHeader(getOxmClassCode(), getNxmFieldCode(), true, getValueLength() * 2);
+        }
+        return headerWithMask;
     }
 
     @Override
index ab902d6e29322ad7387ec9cd5adebbae8e2f7e94..e7faa80678c03ec2323a1778bc6f658e00e4dc46 100644 (file)
@@ -148,14 +148,17 @@ module nicira-match {
         base ofoxm:match-field;
     }
 
-
     grouping ofj-nxm-nx-match-reg-grouping {
         container reg-values {
             leaf value {
                 type uint32;
             }
+            leaf mask {
+                type uint32;
+            }
         }
     }
+
     grouping ofj-oxm-of-mpls-label-grouping {
         container mpls-label-values {
              leaf mpls-label {
@@ -171,6 +174,7 @@ module nicira-match {
             }
         }
     }
+
     grouping ofj-nxm-nx-match-arp-sha-grouping {
         container arp-sha-values {
             leaf mac-address {
@@ -178,6 +182,7 @@ module nicira-match {
             }
         }
     }
+
     grouping ofj-nxm-nx-match-arp-tha-grouping {
         container arp-tha-values {
             leaf mac-address {
@@ -185,6 +190,7 @@ module nicira-match {
             }
         }
     }
+
     grouping ofj-nxm-of-match-arp-op-grouping {
         container arp-op-values {
             leaf value {
@@ -192,6 +198,7 @@ module nicira-match {
             }
         }
     }
+
     grouping ofj-nxm-of-match-arp-spa-grouping {
         container arp-spa-values {
             leaf value {
@@ -199,6 +206,7 @@ module nicira-match {
             }
         }
     }
+
     grouping ofj-nxm-of-match-arp-tpa-grouping {
         container arp-tpa-values {
             leaf value {
@@ -206,6 +214,7 @@ module nicira-match {
             }
         }
     }
+
     grouping ofj-nxm-of-in-port-type-grouping {
         container nxm-of-in-port-values {
             leaf value {
@@ -213,6 +222,7 @@ module nicira-match {
             }
         }
     }
+
     grouping ofj-nxm-nx-match-tun-ipv4-dst-grouping {
         container tun-ipv4-dst-values {
             leaf value {
@@ -220,6 +230,7 @@ module nicira-match {
             }
         }
     }
+
     grouping ofj-nxm-nx-match-tun-ipv4-src-grouping {
         container tun-ipv4-src-values {
             leaf value {
@@ -227,6 +238,7 @@ module nicira-match {
             }
         }
     }
+
     grouping ofj-nxm-of-match-eth-src-grouping {
         container eth-src-values {
             leaf mac-address {
@@ -234,6 +246,7 @@ module nicira-match {
             }
         }
     }
+
     grouping ofj-nxm-of-match-eth-dst-grouping {
         container eth-dst-values {
             leaf mac-address {
@@ -241,6 +254,7 @@ module nicira-match {
             }
         }
     }
+
     grouping ofj-nxm-of-match-eth-type-grouping {
         container eth-type-values {
             leaf value {
@@ -276,21 +290,25 @@ module nicira-match {
             uses ofj-nxm-nx-match-nshc-grouping;
         }
     }
+
     grouping ofj-nxm-nx-match-nshc-2-grouping {
         container nshc-2-values {
             uses ofj-nxm-nx-match-nshc-grouping;
         }
     }
+
     grouping ofj-nxm-nx-match-nshc-3-grouping {
         container nshc-3-values {
             uses ofj-nxm-nx-match-nshc-grouping;
         }
     }
+
     grouping ofj-nxm-nx-match-nshc-4-grouping {
         container nshc-4-values {
             uses ofj-nxm-nx-match-nshc-grouping;
         }
     }
+
     grouping ofj-nxm-of-match-tcp-src-grouping {
         container tcp-src-values {
             leaf port {
@@ -301,6 +319,7 @@ module nicira-match {
             }
         }
     }
+
     grouping ofj-nxm-of-match-tcp-dst-grouping {
         container tcp-dst-values {
             leaf port {
@@ -311,7 +330,8 @@ module nicira-match {
             }
         }
     }
-     grouping ofj-nxm-of-match-udp-src-grouping {
+
+    grouping ofj-nxm-of-match-udp-src-grouping {
         container udp-src-values {
             leaf port {
                type inet:port-number;
@@ -321,6 +341,7 @@ module nicira-match {
             }
         }
     }
+
     grouping ofj-nxm-of-match-udp-dst-grouping {
         container udp-dst-values {
             leaf port {
@@ -331,6 +352,7 @@ module nicira-match {
             }
         }
     }
+
     grouping ofj-nxm-nx-match-ct-state-grouping{
          container ct-state-values {
             leaf ct-state {
@@ -341,6 +363,7 @@ module nicira-match {
             }
         }
     }
+
     grouping ofj-nxm-nx-match-ct-zone-grouping{
          container ct-zone-values {
             leaf ct-zone {
@@ -348,6 +371,7 @@ module nicira-match {
             }
         }
     }
+
     grouping ofj-nxm-of-match-ip-dst-grouping {
         container ip-dst-values {
             leaf value {
@@ -355,6 +379,7 @@ module nicira-match {
             }
         }
     }
+
     grouping ofj-nxm-of-match-ip-src-grouping {
         container ip-src-values {
             leaf value {
@@ -362,6 +387,7 @@ module nicira-match {
             }
         }
     }
+
     grouping ofj-nxm-of-match-icmp-type-grouping {
         container icmp-type-values {
             leaf value {
@@ -369,6 +395,7 @@ module nicira-match {
             }
         }
     }
+
     grouping ofj-nxm-nx-match-encap-eth-type-grouping {
         container encap-eth-type-values {
             leaf encap-eth-type {
@@ -376,6 +403,7 @@ module nicira-match {
             }
         }
     }
+
     grouping ofj-nxm-nx-match-encap-eth-src-grouping {
         container encap-eth-src-values {
             leaf mac-address {
@@ -383,6 +411,7 @@ module nicira-match {
             }
         }
     }
+
     grouping ofj-nxm-nx-match-encap-eth-dst-grouping {
         container encap-eth-dst-values {
             leaf mac-address {
@@ -390,6 +419,7 @@ module nicira-match {
             }
         }
     }
+
     grouping ofj-nxm-nx-match-nsh-mdtype-grouping {
         container nsh-mdtype-values {
             leaf value {
@@ -397,6 +427,7 @@ module nicira-match {
             }
         }
     }
+
     grouping ofj-nxm-nx-match-nsh-np-grouping {
         container nsh-np-values {
             leaf value {
@@ -404,6 +435,7 @@ module nicira-match {
             }
         }
     }
+
     grouping ofj-nxm-nx-match-tun-gpe-np-grouping {
         container tun-gpe-np-values {
             leaf value {
@@ -471,7 +503,6 @@ module nicira-match {
         case tun-gpe-np-case-value {
             uses ofj-nxm-nx-match-tun-gpe-np-grouping;
         }
-
         case eth-type-case-value {
             uses ofj-nxm-of-match-eth-type-grouping;
         }
@@ -520,7 +551,6 @@ module nicira-match {
         case icmp-type-case-value {
             uses ofj-nxm-of-match-icmp-type-grouping;
         }
-
     }
 
 }
index 0b11bccbe1c261c5daa743278eedc65f609878e5..0b85293f25baf8dfc6b8a5414d695cbf73ded8e6 100644 (file)
@@ -6,7 +6,7 @@
     <parent>
         <groupId>org.opendaylight.openflowplugin</groupId>
         <artifactId>openflowplugin-extension-parent</artifactId>
-        <version>0.3.3-SNAPSHOT</version>
+        <version>0.3.5-SNAPSHOT</version>
         <relativePath>../</relativePath>
     </parent>
 
index 18480befd8938501ab17d21bf792d14670c12c07..ec57539fb753217f2cd82abb5b6033e77969636d 100644 (file)
@@ -40,6 +40,14 @@ public class GroupingLooseResolver<G> {
         classes = new HashSet<>();
     }
 
+    /**
+     * Get augmentation classes
+     * @return list of augmentation classes
+     */
+    public Set<Class<? extends Augmentation<?>>> getClasses() {
+        return classes;
+    }
+
     /**
      * @param cls equivalent augmentation class
      * @return this for chaining
@@ -69,4 +77,5 @@ public class GroupingLooseResolver<G> {
 
         return Optional.absent();
     }
+
 }
index 1821f32fd1102cb898601a1415c830bce2299d80..d75b732f19dfb76eef7d5dee1378d0036d98ac17 100644 (file)
@@ -5,7 +5,7 @@
     <parent>
       <groupId>org.opendaylight.openflowplugin</groupId>
       <artifactId>openflowplugin-extension-parent</artifactId>
-      <version>0.3.3-SNAPSHOT</version>
+      <version>0.3.5-SNAPSHOT</version>
       <relativePath>../</relativePath>
     </parent>
 
index 9db999292c2aff28f8ec9e75f02c0603f82f3e95..3eaf3937973cb885bcac2d60853a2ac285c99cd3 100644 (file)
@@ -5,7 +5,7 @@
     <parent>
         <groupId>org.opendaylight.openflowplugin</groupId>
         <artifactId>openflowplugin-extension-parent</artifactId>
-        <version>0.3.3-SNAPSHOT</version>
+        <version>0.3.5-SNAPSHOT</version>
         <relativePath>../</relativePath>
     </parent>
 
index 9e12fc614b33ab344d147c2e20d2948d0734b1bf..4e62b5b955cc087414fe3570ac869f27576edc41 100644 (file)
@@ -60,7 +60,6 @@ import org.opendaylight.openflowjava.nx.codec.match.EncapEthTypeCodec;
 import org.opendaylight.openflowjava.nx.codec.match.EncapEthSrcCodec;
 import org.opendaylight.openflowjava.nx.codec.match.EncapEthDstCodec;
 import org.opendaylight.openflowjava.nx.codec.match.NshMdtypeCodec;
-import org.opendaylight.openflowjava.nx.codec.match.NshNpCodec;
 import org.opendaylight.openflowjava.nx.codec.match.TunGpeNpCodec;
 import org.opendaylight.openflowjava.nx.codec.match.UdpSrcCodec;
 import org.opendaylight.openflowjava.nx.codec.match.UdpDstCodec;
@@ -274,47 +273,47 @@ public class NiciraExtensionProvider implements AutoCloseable {
     private ExtensionConverterRegistrator extensionConverterRegistrator;
     private Set<ObjectRegistration<?>> registrations;
 
-    private final static RegConvertor REG_CONVERTOR = new RegConvertor();
-    private final static TunIdConvertor TUN_ID_CONVERTOR = new TunIdConvertor();
-    private final static ArpOpConvertor ARP_OP_CONVERTOR = new ArpOpConvertor();
-    private final static ArpShaConvertor ARP_SHA_CONVERTOR = new ArpShaConvertor();
-    private final static ArpSpaConvertor ARP_SPA_CONVERTOR = new ArpSpaConvertor();
-    private final static ArpTpaConvertor ARP_TPA_CONVERTOR = new ArpTpaConvertor();
-    private final static ArpThaConvertor ARP_THA_CONVERTOR = new ArpThaConvertor();
-    private final static NxmInPortConvertor NXM_IN_PORT_CONVERTOR = new NxmInPortConvertor();
-    private final static EthDstConvertor ETH_DST_CONVERTOR = new EthDstConvertor();
-    private final static EthSrcConvertor ETH_SRC_CONVERTOR = new EthSrcConvertor();
-    private final static RegLoadConvertor REG_LOAD_CONVERTOR = new RegLoadConvertor();
-    private final static RegMoveConvertor REG_MOVE_CONVERTOR = new RegMoveConvertor();
-    private final static OutputRegConvertor OUTPUT_REG_CONVERTOR = new OutputRegConvertor();
-    private final static EthTypeConvertor ETH_TYPE_CONVERTOR = new EthTypeConvertor();
-    private final static ResubmitConvertor RESUBMIT_CONVERTOR = new ResubmitConvertor();
-    private final static FinTimeoutConvertor FIN_TIMEOUT_CONVERTOR = new FinTimeoutConvertor();
-    private final static MultipathConvertor MULTIPATH_CONVERTOR = new MultipathConvertor();
-    private final static PushNshConvertor PUSH_NSH_CONVERTOR = new PushNshConvertor();
-    private final static PopNshConvertor POP_NSH_CONVERTOR = new PopNshConvertor();
-    private final static NspConvertor NSP_CONVERTOR = new NspConvertor();
-    private final static NsiConvertor NSI_CONVERTOR = new NsiConvertor();
-    private final static Nshc1Convertor NSC1_CONVERTOR = new Nshc1Convertor();
-    private final static Nshc2Convertor NSC2_CONVERTOR = new Nshc2Convertor();
-    private final static Nshc3Convertor NSC3_CONVERTOR = new Nshc3Convertor();
-    private final static Nshc4Convertor NSC4_CONVERTOR = new Nshc4Convertor();
-    private final static TunIPv4SrcConvertor TUN_IPV4_SRC_CONVERTOR = new TunIPv4SrcConvertor();
-    private final static TunIPv4DstConvertor TUN_IPV4_DST_CONVERTOR = new TunIPv4DstConvertor();
-    private final static EncapEthTypeConvertor ENCAP_ETH_TYPE_CONVERTOR = new EncapEthTypeConvertor();
-    private final static EncapEthSrcConvertor ENCAP_ETH_SRC_CONVERTOR = new EncapEthSrcConvertor();
-    private final static EncapEthDstConvertor ENCAP_ETH_DST_CONVERTOR = new EncapEthDstConvertor();
-    private final static NshMdtypeConvertor NSH_MDTYPE_CONVERTOR = new NshMdtypeConvertor();
-    private final static NshNpConvertor NSH_NP_CONVERTOR = new NshNpConvertor();
-    private final static TunGpeNpConvertor TUN_GPE_NP_CONVERTOR = new TunGpeNpConvertor();
-    private final static TcpSrcConvertor TCP_SRC_CONVERTOR = new TcpSrcConvertor();
-    private final static TcpDstConvertor TCP_DST_CONVERTOR = new TcpDstConvertor();
-    private final static UdpSrcConvertor UDP_SRC_CONVERTOR = new UdpSrcConvertor();
-    private final static UdpDstConvertor UDP_DST_CONVERTOR = new UdpDstConvertor();
-    private final static ConntrackConvertor CONNTRACK_CONVERTOR = new ConntrackConvertor();
-    private final static LearnConvertor LEARN_CONVERTOR = new LearnConvertor();
-    private final static CtStateConvertor CT_STATE_CONVERTOR = new CtStateConvertor();
-    private final static CtZoneConvertor CT_ZONE_CONVERTOR = new CtZoneConvertor();
+    private static final RegConvertor REG_CONVERTOR = new RegConvertor();
+    private static final TunIdConvertor TUN_ID_CONVERTOR = new TunIdConvertor();
+    private static final ArpOpConvertor ARP_OP_CONVERTOR = new ArpOpConvertor();
+    private static final ArpShaConvertor ARP_SHA_CONVERTOR = new ArpShaConvertor();
+    private static final ArpSpaConvertor ARP_SPA_CONVERTOR = new ArpSpaConvertor();
+    private static final ArpTpaConvertor ARP_TPA_CONVERTOR = new ArpTpaConvertor();
+    private static final ArpThaConvertor ARP_THA_CONVERTOR = new ArpThaConvertor();
+    private static final NxmInPortConvertor NXM_IN_PORT_CONVERTOR = new NxmInPortConvertor();
+    private static final EthDstConvertor ETH_DST_CONVERTOR = new EthDstConvertor();
+    private static final EthSrcConvertor ETH_SRC_CONVERTOR = new EthSrcConvertor();
+    private static final RegLoadConvertor REG_LOAD_CONVERTOR = new RegLoadConvertor();
+    private static final RegMoveConvertor REG_MOVE_CONVERTOR = new RegMoveConvertor();
+    private static final OutputRegConvertor OUTPUT_REG_CONVERTOR = new OutputRegConvertor();
+    private static final EthTypeConvertor ETH_TYPE_CONVERTOR = new EthTypeConvertor();
+    private static final ResubmitConvertor RESUBMIT_CONVERTOR = new ResubmitConvertor();
+    private static final FinTimeoutConvertor FIN_TIMEOUT_CONVERTOR = new FinTimeoutConvertor();
+    private static final MultipathConvertor MULTIPATH_CONVERTOR = new MultipathConvertor();
+    private static final PushNshConvertor PUSH_NSH_CONVERTOR = new PushNshConvertor();
+    private static final PopNshConvertor POP_NSH_CONVERTOR = new PopNshConvertor();
+    private static final NspConvertor NSP_CONVERTOR = new NspConvertor();
+    private static final NsiConvertor NSI_CONVERTOR = new NsiConvertor();
+    private static final Nshc1Convertor NSC1_CONVERTOR = new Nshc1Convertor();
+    private static final Nshc2Convertor NSC2_CONVERTOR = new Nshc2Convertor();
+    private static final Nshc3Convertor NSC3_CONVERTOR = new Nshc3Convertor();
+    private static final Nshc4Convertor NSC4_CONVERTOR = new Nshc4Convertor();
+    private static final TunIPv4SrcConvertor TUN_IPV4_SRC_CONVERTOR = new TunIPv4SrcConvertor();
+    private static final TunIPv4DstConvertor TUN_IPV4_DST_CONVERTOR = new TunIPv4DstConvertor();
+    private static final EncapEthTypeConvertor ENCAP_ETH_TYPE_CONVERTOR = new EncapEthTypeConvertor();
+    private static final EncapEthSrcConvertor ENCAP_ETH_SRC_CONVERTOR = new EncapEthSrcConvertor();
+    private static final EncapEthDstConvertor ENCAP_ETH_DST_CONVERTOR = new EncapEthDstConvertor();
+    private static final NshMdtypeConvertor NSH_MDTYPE_CONVERTOR = new NshMdtypeConvertor();
+    private static final NshNpConvertor NSH_NP_CONVERTOR = new NshNpConvertor();
+    private static final TunGpeNpConvertor TUN_GPE_NP_CONVERTOR = new TunGpeNpConvertor();
+    private static final TcpSrcConvertor TCP_SRC_CONVERTOR = new TcpSrcConvertor();
+    private static final TcpDstConvertor TCP_DST_CONVERTOR = new TcpDstConvertor();
+    private static final UdpSrcConvertor UDP_SRC_CONVERTOR = new UdpSrcConvertor();
+    private static final UdpDstConvertor UDP_DST_CONVERTOR = new UdpDstConvertor();
+    private static final ConntrackConvertor CONNTRACK_CONVERTOR = new ConntrackConvertor();
+    private static final LearnConvertor LEARN_CONVERTOR = new LearnConvertor();
+    private static final CtStateConvertor CT_STATE_CONVERTOR = new CtStateConvertor();
+    private static final CtZoneConvertor CT_ZONE_CONVERTOR = new CtZoneConvertor();
 
     @Override
     public void close() {
@@ -666,5 +665,4 @@ public class NiciraExtensionProvider implements AutoCloseable {
         ActionSerializerKey<?> key = new ActionSerializerKey(EncodeConstants.OF13_VERSION_ID, actionCaseType, null);
         registrations.add(extensionConverterRegistrator.registerActionConvertor(key, actionConvertor));
     }
-
 }
index 1ba11162dbced0c3022b87e7de9cf0549b2947e6..579def71dd84801efe24708cd93ec80a58b95cd5 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.match;
 
 import com.google.common.base.Optional;
+import java.util.Objects;
 import org.opendaylight.openflowjava.nx.NiciraMatchCodecs;
 import org.opendaylight.openflowplugin.extension.api.ConvertorFromOFJava;
 import org.opendaylight.openflowplugin.extension.api.ConvertorToOFJava;
@@ -54,7 +55,7 @@ public class RegConvertor implements ConvertorToOFJava<MatchEntry>, ConvertorFro
 
     /*
      * (non-Javadoc)
-     * 
+     *
      * @see
      * org.opendaylight.openflowplugin.extension.api.ConvertorFromOFJava#convert
      * (org.opendaylight.yangtools.yang.binding.DataContainer,
@@ -77,6 +78,11 @@ public class RegConvertor implements ConvertorToOFJava<MatchEntry>, ConvertorFro
                         .getOxmMatchField());
         RegCaseValue regCaseValue = ((RegCaseValue) input.getMatchEntryValue());
         nxRegBuilder.setValue(regCaseValue.getRegValues().getValue());
+
+        if (input.isHasMask()) {
+            nxRegBuilder.setMask(regCaseValue.getRegValues().getMask());
+        }
+
         return resolveAugmentation(nxRegBuilder.build(), path, resolveRegKey(input.getOxmMatchField()));
     }
 
@@ -130,7 +136,7 @@ public class RegConvertor implements ConvertorToOFJava<MatchEntry>, ConvertorFro
 
     /*
      * (non-Javadoc)
-     * 
+     *
      * @see
      * org.opendaylight.openflowplugin.extension.api.ConvertorToOFJava#convert
      * (org
@@ -144,12 +150,17 @@ public class RegConvertor implements ConvertorToOFJava<MatchEntry>, ConvertorFro
             throw new CodecPreconditionException(extension);
         }
         NxmNxReg nxmNxReg = matchGrouping.get().getNxmNxReg();
-        RegValuesBuilder regValuesBuilder = new RegValuesBuilder().setValue(nxmNxReg.getValue());
+        RegValuesBuilder regValuesBuilder = new RegValuesBuilder()
+            .setValue(nxmNxReg.getValue())
+            .setMask(nxmNxReg.getMask());
+
         RegCaseValueBuilder regCaseValueBuilder = new RegCaseValueBuilder();
         regCaseValueBuilder.setRegValues(regValuesBuilder.build());
         return MatchUtil.createDefaultMatchEntryBuilder(nxmNxReg.getReg(),
                 Nxm1Class.class,
-                regCaseValueBuilder.build()).build();
+                regCaseValueBuilder.build())
+            .setHasMask(Objects.nonNull(nxmNxReg.getMask()))
+            .build();
     }
 
 }
index cd4c5890eaa905c3d0cc3b651db061f3c1151453..199b94d1ba7752759878f6d93a66701890e80940 100644 (file)
@@ -167,6 +167,9 @@ module openflowplugin-extension-nicira-match {
             leaf value {
                 type uint32;
             }
+            leaf mask {
+                type uint32;
+            }
         }
     }
     grouping nxm-nx-tun-id-grouping {
index f3d86ab6a111a0518de1ae3c525ec5e039e87896..052a770383393c3b8724ca7c59a1ce6f67224824 100644 (file)
@@ -6,7 +6,7 @@
     <parent>
         <groupId>org.opendaylight.openflowplugin</groupId>
         <artifactId>openflowplugin-parent</artifactId>
-        <version>0.3.3-SNAPSHOT</version>
+        <version>0.3.5-SNAPSHOT</version>
         <relativePath>../parent</relativePath>
     </parent>
 
index 056750f6288b4a4d4b8990b27976871a6659fef0..30245dda72200da32baeaeec116a5c3e206a3ca7 100644 (file)
@@ -5,7 +5,7 @@
   <parent>
     <groupId>org.opendaylight.openflowplugin</groupId>
     <artifactId>openflowplugin-extension-parent</artifactId>
-    <version>0.3.3-SNAPSHOT</version>
+    <version>0.3.5-SNAPSHOT</version>
     <relativePath>../</relativePath>
   </parent>
   <artifactId>test-extension</artifactId>
index 3e6bd5565a136abe667678a682ee32cc1baa4726..5abcc60b4683c930cfc093b08cad61afb427e5ce 100644 (file)
@@ -5,26 +5,26 @@
     <parent>
         <groupId>org.opendaylight.odlparent</groupId>
         <artifactId>features-parent</artifactId>
-        <version>1.7.3-SNAPSHOT</version>
+        <version>1.7.5-SNAPSHOT</version>
         <relativePath/>
     </parent>
 
     <groupId>org.opendaylight.openflowplugin</groupId>
     <artifactId>features-openflowplugin-he</artifactId>
     <packaging>jar</packaging>
-    <version>0.3.3-SNAPSHOT</version>
+    <version>0.3.5-SNAPSHOT</version>
 
     <properties>
-        <yangtools.version>1.0.3-SNAPSHOT</yangtools.version>
-        <config.version>0.5.3-SNAPSHOT</config.version>
-        <mdsal.version>1.4.3-SNAPSHOT</mdsal.version>
-        <openflowjava.version>0.8.3-SNAPSHOT</openflowjava.version>
-        <openflowplugin.version>0.3.3-SNAPSHOT</openflowplugin.version>
-        <dlux.version>0.4.3-SNAPSHOT</dlux.version>
-        <lldp.version>0.11.3-SNAPSHOT</lldp.version>
+        <yangtools.version>1.0.5-SNAPSHOT</yangtools.version>
+        <config.version>0.5.5-SNAPSHOT</config.version>
+        <mdsal.version>1.4.5-SNAPSHOT</mdsal.version>
+        <openflowjava.version>0.8.5-SNAPSHOT</openflowjava.version>
+        <openflowplugin.version>0.3.5-SNAPSHOT</openflowplugin.version>
+        <dlux.version>0.4.5-SNAPSHOT</dlux.version>
+        <lldp.version>0.11.5-SNAPSHOT</lldp.version>
         <config.configfile.directory>etc/opendaylight/karaf</config.configfile.directory>
-        <restconf.version>1.4.3-SNAPSHOT</restconf.version>
-        <mdsal.model.version>0.9.3-SNAPSHOT</mdsal.model.version>
+        <restconf.version>1.4.5-SNAPSHOT</restconf.version>
+        <mdsal.model.version>0.9.5-SNAPSHOT</mdsal.model.version>
     </properties>
 
     <dependencyManagement>
index c155d0559b34aace0bbb978c0dbc93a358f85224..efcb721bd259d945bc2f161e676edf095a32150b 100644 (file)
@@ -5,26 +5,26 @@
     <parent>
         <groupId>org.opendaylight.odlparent</groupId>
         <artifactId>features-parent</artifactId>
-        <version>1.7.3-SNAPSHOT</version>
+        <version>1.7.5-SNAPSHOT</version>
         <relativePath/>
     </parent>
 
     <groupId>org.opendaylight.openflowplugin</groupId>
     <artifactId>features-openflowplugin</artifactId>
     <packaging>jar</packaging>
-    <version>0.3.3-SNAPSHOT</version>
+    <version>0.3.5-SNAPSHOT</version>
 
     <properties>
-        <yangtools.version>1.0.3-SNAPSHOT</yangtools.version>
-        <config.version>0.5.3-SNAPSHOT</config.version>
-        <mdsal.version>1.4.3-SNAPSHOT</mdsal.version>
-        <openflowjava.version>0.8.3-SNAPSHOT</openflowjava.version>
-        <openflowplugin.version>0.3.3-SNAPSHOT</openflowplugin.version>
-        <dlux.version>0.4.3-SNAPSHOT</dlux.version>
-        <lldp.version>0.11.3-SNAPSHOT</lldp.version>
+        <yangtools.version>1.0.5-SNAPSHOT</yangtools.version>
+        <config.version>0.5.5-SNAPSHOT</config.version>
+        <mdsal.version>1.4.5-SNAPSHOT</mdsal.version>
+        <openflowjava.version>0.8.5-SNAPSHOT</openflowjava.version>
+        <openflowplugin.version>0.3.5-SNAPSHOT</openflowplugin.version>
+        <dlux.version>0.4.5-SNAPSHOT</dlux.version>
+        <lldp.version>0.11.5-SNAPSHOT</lldp.version>
         <config.configfile.directory>etc/opendaylight/karaf</config.configfile.directory>
-        <restconf.version>1.4.3-SNAPSHOT</restconf.version>
-        <mdsal.model.version>0.9.3-SNAPSHOT</mdsal.model.version>
+        <restconf.version>1.4.5-SNAPSHOT</restconf.version>
+        <mdsal.model.version>0.9.5-SNAPSHOT</mdsal.model.version>
     </properties>
 
     <dependencyManagement>
index bea5aa72a3132791e700c5ba1a47ea0102c6c5fb..5aa7ea875e7867cafe29e7d325c5d52fe79525ce 100644 (file)
@@ -6,7 +6,7 @@
   <parent>
     <groupId>org.opendaylight.openflowplugin.model</groupId>
     <artifactId>model-parent</artifactId>
-    <version>0.3.3-SNAPSHOT</version>
+    <version>0.3.5-SNAPSHOT</version>
   </parent>
   <artifactId>model-flow-base</artifactId>
   <packaging>bundle</packaging>
index 97c6e71ac82c61a2e0300db6224954210817bdd6..916faf0fbc1d61acdfbc11bb84f1631c853c6258 100644 (file)
@@ -6,7 +6,7 @@
   <parent>
     <groupId>org.opendaylight.openflowplugin.model</groupId>
     <artifactId>model-parent</artifactId>
-    <version>0.3.3-SNAPSHOT</version>
+    <version>0.3.5-SNAPSHOT</version>
   </parent>
   <artifactId>model-flow-service</artifactId>
   <packaging>bundle</packaging>
index 94e3333c5bc6e584014856e301e15d60a1b20e3d..07f0970a6ef01d1bef5b3fdea788d75d59e2c7d3 100644 (file)
@@ -6,7 +6,7 @@
   <parent>
     <groupId>org.opendaylight.openflowplugin.model</groupId>
     <artifactId>model-parent</artifactId>
-    <version>0.3.3-SNAPSHOT</version>
+    <version>0.3.5-SNAPSHOT</version>
   </parent>
   <artifactId>model-flow-statistics</artifactId>
   <packaging>bundle</packaging>
index cba057e48c9c02ec72f99f25850009116a487599..613cb48d203c5d938194e37b8b4f9813addc1ca6 100644 (file)
@@ -6,7 +6,7 @@
   <parent>
     <groupId>org.opendaylight.openflowplugin</groupId>
     <artifactId>openflowplugin-parent</artifactId>
-    <version>0.3.3-SNAPSHOT</version>
+    <version>0.3.5-SNAPSHOT</version>
     <relativePath>../parent</relativePath>
   </parent>
   <groupId>org.opendaylight.openflowplugin.model</groupId>
index 84c314219440d4af701d771a5c73e1f9fc6a3f10..d1eb5f6e68cd0811df0527df3baeb865afd6e462 100644 (file)
@@ -5,7 +5,7 @@
     <parent>
         <groupId>org.opendaylight.openflowplugin</groupId>
         <artifactId>openflowplugin-parent</artifactId>
-        <version>0.3.3-SNAPSHOT</version>
+        <version>0.3.5-SNAPSHOT</version>
         <relativePath>../parent</relativePath>
     </parent>
 
index e08903b339dcaf44e6903cd82f1f8fb0ab4675d7..78135489de78b2c4c05087b0061426cf4d948bbd 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";
 }
index bd05be9e448d85ffa8275296aec32b61a672943e..5fcd1b9fa70107539f4b3ddb1cf139c37903854a 100644 (file)
@@ -40,9 +40,8 @@ public interface OFPContext extends AutoCloseable, ClusterLifecycleSupervisor, C
     /**
      * About to stop services in cluster not master anymore or going down
      * @return Future most of services need time to be closed
-     * @param connectionInterrupted true if clustering services stopping by device disconnect
      */
-    default ListenableFuture<Void> stopClusterServices(boolean connectionInterrupted) {
+    default ListenableFuture<Void> stopClusterServices() {
         return Futures.immediateFailedFuture(new RejectedExecutionException("Cannot stop abstract services, check implementation of cluster services"));
     }
 
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..b0e6bf7
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * 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,
+        /**
+         * 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 b42c9d1a5dc7c9ab96cda02f4013914e09c5f652..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,79 +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.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);
 }
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 b4e0b098fd496158c3774744a1bf70001d37e9a5..b5aa65fb614fde450934fa9382f2478eb6253f0f 100644 (file)
@@ -145,5 +145,11 @@ public interface DeviceContext extends
      * @return listenable future from sal role service
      */
     ListenableFuture<RpcResult<SetRoleOutput>> makeDeviceSlave();
+
+    void sendNodeAddedNotification();
+
+    void sendNodeRemovedNotification();
+
+    void cleanupDeviceData();
 }
 
index 9698c2551562d7ac968ebe5a50f82dee9e35286d..afd3c7d152543f296a2f1ecea9e22d9d8565e004 100644 (file)
@@ -9,6 +9,7 @@
 package org.opendaylight.openflowplugin.api.openflow.device;
 
 import com.google.common.util.concurrent.CheckedFuture;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.openflowplugin.api.openflow.OFPManager;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceConnectedHandler;
@@ -24,7 +25,8 @@ public interface DeviceManager extends
         OFPManager,
         DeviceConnectedHandler,
         DeviceDisconnectedHandler,
-        TranslatorLibrarian {
+        TranslatorLibrarian,
+        EntityOwnershipListener {
 
     /**
      * invoked after all services injected
@@ -42,5 +44,9 @@ public interface DeviceManager extends
     void setBarrierInterval(long barrierTimeoutLimit);
 
     CheckedFuture<Void, TransactionCommitFailedException> removeDeviceFromOperationalDS(DeviceInfo deviceInfo);
+
+    void setGlobalNotificationQuota(long globalNotificationQuota);
+
+    void setSwitchFeaturesMandatory(boolean switchFeaturesMandatory);
 }
 
index 931aaf0cc14fa79fecffb351706dc57ce3bd7b7f..57608463dbb8f0c45550b9904401b9e153a9681d 100644 (file)
@@ -9,6 +9,9 @@
 package org.opendaylight.openflowplugin.api.openflow.lifecycle;
 
 import javax.annotation.CheckForNull;
+
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.openflowplugin.api.openflow.OFPContext;
index e710c608aa54f47f9260bf3c256367d2c0751c24..2672c08f210bfb1b572029a62f8289be47e2eebc 100644 (file)
@@ -9,8 +9,9 @@ package org.opendaylight.openflowplugin.api.openflow.md;
 
 import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
 
-public abstract class AbstractModelDrivenSwitchRegistration extends AbstractObjectRegistration<ModelDrivenSwitch>
-    implements ModelDrivenSwitchRegistration {
+public abstract class AbstractModelDrivenSwitchRegistration
+        extends AbstractObjectRegistration<ModelDrivenSwitch>
+        implements ModelDrivenSwitchRegistration {
 
     protected AbstractModelDrivenSwitchRegistration(final ModelDrivenSwitch instance) {
         super(instance);
index 90270c6326ffa39317e73571a727e1fb255c3fba..9a3ef94f50fb1967e3a1d9dae4f9139b80097cc0 100644 (file)
@@ -30,7 +30,7 @@ import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /**
- * interface concatenating all md-sal services provided by OF-switch
+ * interface concatenating all md-sal services provided by OF-switch.
  */
 public interface ModelDrivenSwitch
         extends
@@ -42,32 +42,34 @@ public interface ModelDrivenSwitch
         Identifiable<InstanceIdentifier<Node>> {
 
     /**
-     * @param rpcProviderRegistry
+     * Register.
+     * @param rpcProviderRegistry rpc provider
      * @return wrapped list of {service provider + path} registration couples
      */
     ModelDrivenSwitchRegistration register(RpcProviderRegistry rpcProviderRegistry);
 
     /**
+     * Getter.
      * @return id of encapsulated node (served by this impl)
      */
     NodeId getNodeId();
 
     /**
-     * returnes the session context associated with this model-driven switch
+     * returnes the session context associated with this model-driven switch.
      *
      * @return session context object
      */
     SessionContext getSessionContext();
 
     /**
-     * Returns whether this *instance* is entity owner or not
+     * Returns whether this *instance* is entity owner or not.
      * @return true if it's entity owner, else false.
      */
     boolean isEntityOwner();
 
     /**
-     * Set entity ownership satus of this switch in *this* instance
-     * @param isOwner
+     * Set entity ownership satus of this switch in *this* instance.
+     * @param isOwner is owner
      */
     void setEntityOwnership(boolean isOwner);
 
@@ -80,7 +82,6 @@ public interface ModelDrivenSwitch
     /**
      * Method send port/desc multipart request to the switch to fetch the initial details.
      */
-
-    public abstract void requestSwitchDetails();
+    void requestSwitchDetails();
 
 }
index 9da85b390165c2dd710c3059e10fa357e7bb88de..3c159c465c601ec5d2ac6d2678cc30794d2f5dc4 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
index e1ea51f563f2db37dec124dfd9ef0bd2c50fed86..6d517eb73ef90e3ab058827e0133537d48a577f2 100644 (file)
@@ -18,93 +18,94 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yangtools.yang.binding.DataObject;
 
 
-/**
- * @author mirehak
- */
 public interface ConnectionConductor {
 
-    /** distinguished connection states */
-    public enum CONDUCTOR_STATE {
-        /** initial phase of talking to switch */
+    /** distinguished connection states. */
+    @SuppressWarnings({"checkstyle:abbreviationaswordinname", "checkstyle:typename"})
+    enum CONDUCTOR_STATE {
+        /** initial phase of talking to switch. */
         HANDSHAKING,
-        /** standard phase - interacting with switch */
+        /** standard phase - interacting with switch. */
         WORKING,
-        /** connection is idle, waiting for echo reply from switch */
+        /** connection is idle, waiting for echo reply from switch. */
         TIMEOUTING,
-        /** talking to switch is over - resting in pieces */
+        /** talking to switch is over - resting in pieces. */
         RIP
     }
 
-    /** supported version ordered by height (highest version is at the beginning) */
-    List<Short> versionOrder = Lists.newArrayList((short) 0x04, (short) 0x01);
+    /** supported version ordered by height (highest version is at the beginning). */
+    List<Short> VERSION_ORDER = Lists.newArrayList((short) 0x04, (short) 0x01);
 
     /**
-     * initialize wiring around {@link ConnectionAdapter}
+     * initialize wiring around {@link ConnectionAdapter}.
      */
     void init();
 
     /**
-     * @return the negotiated version
+     * return the negotiated version.
      */
     Short getVersion();
 
     /**
-     * @return the state of conductor
+     * return the state of conductor.
      */
     CONDUCTOR_STATE getConductorState();
 
     /**
-     * @param conductorState
+     * Setter.
+     * @param conductorState state
      */
     void setConductorState(CONDUCTOR_STATE conductorState);
 
     /**
-     * terminates owned connection
+     * terminates owned connection.
      * @return future result of disconnect action
      */
     Future<Boolean> disconnect();
 
     /**
-     * assign corresponding {@link SessionContext} to this conductor (to handle disconnect caused by switch)
-     * @param context
+     * assign corresponding {@link SessionContext} to this conductor (to handle disconnect caused by switch).
+     * @param context session context
      */
     void setSessionContext(SessionContext context);
 
     /**
-     * assign corresponding {@link org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher} to this conductor
-     * to handle disconnect caused by switch. This involves auxiliary conductors only.
-     * @param auxiliaryKey
+     * assign corresponding {@link org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher}
+     * to this conductor to handle disconnect caused by switch. This involves auxiliary conductors only.
+     * @param auxiliaryKey key
      */
     void setConnectionCookie(SwitchConnectionDistinguisher auxiliaryKey);
 
     /**
-     * @return the sessionContext
+     * return the sessionContext.
      */
     SessionContext getSessionContext();
 
     /**
-     * @return the auxiliaryKey (null if this is a primary connection)
+     * return the auxiliaryKey (null if this is a primary connection).
      */
     SwitchConnectionDistinguisher getAuxiliaryKey();
 
     /**
-     * @return the connectionAdapter
+     * return the connectionAdapter.
      */
     ConnectionAdapter getConnectionAdapter();
 
     /**
-     * assign global queueKeeper
-     * @param queueKeeper
+     * assign global queueKeeper.
+     * @param queueKeeper keeper
      */
     void setQueueProcessor(QueueProcessor<OfHeader, DataObject> queueKeeper);
 
     /**
+     * Setter.
      * @param errorHandler for internal exception handling
      */
     void setErrorHandler(ErrorHandler errorHandler);
 
     /**
-     * @param conductorId
+     * Setter.
+     * @param conductorId id
      */
     void setId(int conductorId);
 
index 282dfc603cbe662cfda66f0faf275a35ef3e332c..6f930d7cc2a2b47f66e8985eed0964f51446cd07 100644 (file)
@@ -9,16 +9,13 @@ package org.opendaylight.openflowplugin.api.openflow.md.core;
 
 import org.opendaylight.openflowplugin.api.openflow.md.core.session.SessionContext;
 
-/**
- * @author mirehak
- *
- */
 public interface ErrorHandler {
 
     /**
-     * @param e cause
+     * Exception handler.
+     * @param throwable cause
      * @param sessionContext of source
      */
-    void handleException(Throwable e, SessionContext sessionContext);
+    void handleException(Throwable throwable, SessionContext sessionContext);
 
 }
index 5140977e4feadaa388c7f32bd68c134f9a5b5f8d..ae7bfc40849643acdee258e893b31d8a3ba8f840 100644 (file)
@@ -10,13 +10,10 @@ package org.opendaylight.openflowplugin.api.openflow.md.core;
 import org.opendaylight.openflowplugin.api.openflow.connection.HandshakeContext;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
 
-/**
- * @author mirehak
- *
- */
 public interface HandshakeListener {
 
     /**
+     * Handshake successfull.
      * @param featureOutput obtained
      * @param version negotiated
      */
@@ -29,7 +26,8 @@ public interface HandshakeListener {
     void onHandshakeFailure();
 
     /**
-     * @param handshakeContext
+     * Setter.
+     * @param handshakeContext context
      */
     void setHandshakeContext(HandshakeContext handshakeContext);
 }
index 5b7b70ac3606801a651ca442242428cfef659807..80e2af6943b6af589cc9d5bd6af7af820cf476d1 100644 (file)
@@ -9,34 +9,34 @@ package org.opendaylight.openflowplugin.api.openflow.md.core;
 
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessage;
 
-/**
- * @author mirehak
- */
 public interface HandshakeManager {
 
     /**
-     * @return negotiated version
+     * return negotiated version.
      */
     Short getVersion();
 
     /**
+     * Setter.
      * @param errorHandler the errorHandler to set
      */
     void setErrorHandler(ErrorHandler errorHandler);
 
     /**
+     * Setter.
      * @param handshakeListener the handshakeListener to set
      */
     void setHandshakeListener(HandshakeListener handshakeListener);
 
     /**
-     * @param isBitmapNegotiationEnable
+     * should use negotiation bit map.
+     * @param isBitmapNegotiationEnable yes/no
      */
     void setUseVersionBitmap(boolean isBitmapNegotiationEnable);
 
     /**
+     * process current handshake step.
      * @param receivedHello message from device we need to act upon
-     * process current handshake step
      */
     void shake(HelloMessage receivedHello);
 }
index d91014e4943dbbbd3c5f2736e8c9e4a4ae7110bb..d03f20d1c9a2e496d4b6059f47aba231a5c3e39c 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.openflowplugin.api.openflow.md.core;
 import org.opendaylight.openflowplugin.api.openflow.md.core.session.SessionContext;
 
 /**
- * translates between messages
+ * translates between messages.
  * @param <I> source message type (IN)
  * @param <O> result message type (OUT)
  */
@@ -18,14 +18,9 @@ public interface IMDMessageTranslator<I, O> {
 
     /**
      * This method is called in order to translate message to MD-SAL or from MD-SAL.
-     *
-     * @param cookie
-     *            auxiliary connection identifier
-     * @param sc
-     *            The SessionContext which sent the OF message
-     * @param msg
-     *            The OF message
-     *
+     * @param cookie auxiliary connection identifier
+     * @param sc The SessionContext which sent the OF message
+     * @param msg The OF message
      * @return translated message
      */
     O translate(SwitchConnectionDistinguisher cookie, SessionContext sc, I msg);
index f312a41aa38e2e590477e80c7e98488cc1a1f08c..69a83e0e77f6102c0d0c5716b023147ba9acc285 100644 (file)
@@ -1,6 +1,6 @@
-/**
+/*
  * Copyright (c) 2014 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,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
@@ -8,14 +8,13 @@
 package org.opendaylight.openflowplugin.api.openflow.md.core;
 
 /**
- * provider of wrapped notification enqueue
+ * provider of wrapped notification enqueue.
  */
 public interface NotificationEnqueuer {
 
     /**
-     * enqueue given notification into standard message processing queue
-     * 
-     * @param notification
+     * enqueue given notification into standard message processing queue.
+     * @param notification notification
      */
     void enqueueNotification(NotificationQueueWrapper notification);
 
index 81d740fea96c6320730b575e73a45ec83c60489d..6d50a22859dd6276d288dfbe5661749b8036e3a6 100644 (file)
@@ -1,6 +1,6 @@
-/**
+/*
  * Copyright (c) 2014 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,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
@@ -12,24 +12,22 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yangtools.yang.binding.DataContainer;
 import org.opendaylight.yangtools.yang.binding.Notification;
 
-/**
- * 
- */
 public class NotificationQueueWrapper implements OfHeader {
-    
+
     private final Notification notification;
     private final Short version;
     private Long xid = -1L;
 
-    
+
     /**
-     * @param notification
-     * @param version 
+     * Notofication queue wrapper.
+     * @param notification notofication
+     * @param version version
      */
     public NotificationQueueWrapper(final Notification notification, final Short version) {
         Preconditions.checkArgument(notification != null, "wrapped notification must not be null");
         Preconditions.checkArgument(version != null, "message version of wrapped notification must not be null");
-        this.notification = notification; 
+        this.notification = notification;
         this.version = version;
     }
 
@@ -49,13 +47,14 @@ public class NotificationQueueWrapper implements OfHeader {
     }
 
     /**
-     * @return the notification
+     * return the notification.
      */
     public Notification getNotification() {
         return notification;
     }
 
     /**
+     * Setter.
      * @param xid the xid to set
      */
     public void setXid(Long xid) {
index e4e63bc88748e4e2b1573c8396b634b4f399afd5..6537711af99f3545c3b087b8b2f354f902992b58 100644 (file)
@@ -8,12 +8,10 @@
 
 package org.opendaylight.openflowplugin.api.openflow.md.core;
 
-/**
- * @author mirehak
- */
 public interface SwitchConnectionDistinguisher {
 
     /**
+     * Getter.
      * @return encoded switch session identifier
      */
     long getCookie();
index f82da7a017efd3b4b6e6617d72596a42dd093b29..5de9f7b533fd0de5053c621766990ec9ee097e2a 100644 (file)
@@ -7,17 +7,15 @@
  */
 package org.opendaylight.openflowplugin.api.openflow.md.core;
 
-/**
- * @author mirehak
- */
 public class TranslatorKey {
 
-    private int version;
-    private String messageClass;
+    private final int version;
+    private final String messageClass;
 
     /**
-     * @param version
-     * @param messageClass
+     * Constructor.
+     * @param version version
+     * @param messageClass message class
      */
     public TranslatorKey(int version, String messageClass) {
         this.version = version;
@@ -53,10 +51,7 @@ public class TranslatorKey {
         } else if (!messageClass.equals(other.messageClass)) {
             return false;
         }
-        if (version != other.version) {
-            return false;
-        }
-        return true;
+        return version == other.version;
     }
 
 }
index ffb5ccdffafad45b7c05c5abdba067e8cd0452be..c6c7db85b4b4e5c41fd2e5f442384f6fc9121292 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
@@ -11,16 +11,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.fl
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
 
 /**
- * Common interface for SwitchFeatures builders for different OF versions
- *
- * @author jsebin
- *
+ * Common interface for SwitchFeatures builders for different OF versions.
  */
 public interface BuildSwitchFeatures {
 
     /**
-     *
-     * @param features {@link org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput}
+     * Getter.
+     * @param features
+     * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput}
      * @return {@link org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.flow.node.SwitchFeatures}
      */
     SwitchFeatures build(GetFeaturesOutput features);
index 72c7d38a5507560c4c1a2c6f8a63bacac391a52c..f3c92c8e23774bdbcff2aff0a361413ea9be140e 100644 (file)
@@ -1,6 +1,6 @@
-/**
+/*
  * Copyright (c) 2013 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,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
@@ -11,11 +11,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.
 import org.opendaylight.yangtools.yang.binding.Notification;
 
 /**
+ * Notification composer.
  * @param <N> type of notification
  */
 public interface NotificationComposer<N extends Notification> {
-    
+
     /**
+     * Compose.
      * @param xid corresponding OF transaction id
      * @return notification instance
      */
index 5272498d74daaa53943bb4fa2bb1cc48c80f8fbd..8c4ab49d200bd70b115947ec295fa0458fc87880 100644 (file)
@@ -40,17 +40,14 @@ import org.opendaylight.yangtools.yang.common.RpcResult;
 
 /**
  * Message Dispatch Service to send the message to switch.
- *
- * @author AnilGujele
- *
  */
 public interface IMessageDispatchService {
 
-    public static final String CONNECTION_ERROR_MESSAGE = "Session for the cookie is invalid. Reason: "
-    + "the switch has been recently disconnected OR inventory provides outdated information.";
+    String CONNECTION_ERROR_MESSAGE = "Session for the cookie is invalid. Reason: "
+            + "the switch has been recently disconnected OR inventory provides outdated information.";
 
     /**
-     * send barrier message to switch
+     * send barrier message to switch.
      *
      * @param input
      *            - message
@@ -62,7 +59,7 @@ public interface IMessageDispatchService {
     Future<RpcResult<BarrierOutput>> barrier(BarrierInput input, SwitchConnectionDistinguisher cookie);
 
     /**
-     * send experimenter message to switch
+     * send experimenter message to switch.
      *
      * @param input
      *            - message
@@ -74,7 +71,7 @@ public interface IMessageDispatchService {
     Future<RpcResult<java.lang.Void>> experimenter(ExperimenterInput input, SwitchConnectionDistinguisher cookie);
 
     /**
-     * send flow modification message to switch
+     * send flow modification message to switch.
      *
      * @param input
      *            - message
@@ -86,7 +83,7 @@ public interface IMessageDispatchService {
     Future<RpcResult<UpdateFlowOutput>> flowMod(FlowModInput input, SwitchConnectionDistinguisher cookie);
 
     /**
-     * send get async message to switch
+     * send get async message to switch.
      *
      * @param input
      *            - message
@@ -98,7 +95,7 @@ public interface IMessageDispatchService {
     Future<RpcResult<GetAsyncOutput>> getAsync(GetAsyncInput input, SwitchConnectionDistinguisher cookie);
 
     /**
-     * send get config message to switch
+     * send get config message to switch.
      *
      * @param input
      *            - message
@@ -110,7 +107,7 @@ public interface IMessageDispatchService {
     Future<RpcResult<GetConfigOutput>> getConfig(GetConfigInput input, SwitchConnectionDistinguisher cookie);
 
     /**
-     * send get features message to switch
+     * send get features message to switch.
      *
      * @param input
      *            - message
@@ -122,7 +119,7 @@ public interface IMessageDispatchService {
     Future<RpcResult<GetFeaturesOutput>> getFeatures(GetFeaturesInput input, SwitchConnectionDistinguisher cookie);
 
     /**
-     * send get queue config message to switch
+     * send get queue config message to switch.
      *
      * @param input
      *            - message
@@ -135,7 +132,7 @@ public interface IMessageDispatchService {
             SwitchConnectionDistinguisher cookie);
 
     /**
-     * send group modification message to switch
+     * send group modification message to switch.
      *
      * @param input
      *            - message
@@ -147,7 +144,7 @@ public interface IMessageDispatchService {
     Future<RpcResult<UpdateGroupOutput>> groupMod(GroupModInput input, SwitchConnectionDistinguisher cookie);
 
     /**
-     * send meter modification message to switch
+     * send meter modification message to switch.
      *
      * @param input
      *            - message
@@ -159,7 +156,7 @@ public interface IMessageDispatchService {
     Future<RpcResult<UpdateMeterOutput>> meterMod(MeterModInput input, SwitchConnectionDistinguisher cookie);
 
     /**
-     * send multipart request message to switch
+     * send multipart request message to switch.
      *
      * @param input
      *            - multipart request message
@@ -168,10 +165,12 @@ public interface IMessageDispatchService {
      *            any connection
      * @return - the future
      */
-    Future<RpcResult<java.lang.Void>> multipartRequest(MultipartRequestInput input, SwitchConnectionDistinguisher cookie);
+    Future<RpcResult<java.lang.Void>> multipartRequest(
+            MultipartRequestInput input,
+            SwitchConnectionDistinguisher cookie);
 
     /**
-     * send packet out message to switch
+     * send packet out message to switch.
      *
      * @param input
      *            - message
@@ -183,7 +182,7 @@ public interface IMessageDispatchService {
     Future<RpcResult<java.lang.Void>> packetOut(PacketOutInput input, SwitchConnectionDistinguisher cookie);
 
     /**
-     * send port modification message to switch
+     * send port modification message to switch.
      *
      * @param input
      *            - message
@@ -195,7 +194,7 @@ public interface IMessageDispatchService {
     Future<RpcResult<UpdatePortOutput>> portMod(PortModInput input, SwitchConnectionDistinguisher cookie);
 
     /**
-     * send role request message to switch
+     * send role request message to switch.
      *
      * @param input
      *            - message
@@ -207,7 +206,7 @@ public interface IMessageDispatchService {
     Future<RpcResult<RoleRequestOutput>> roleRequest(RoleRequestInput input, SwitchConnectionDistinguisher cookie);
 
     /**
-     * send set async message to switch
+     * send set async message to switch.
      *
      * @param input
      *            - message
@@ -219,7 +218,7 @@ public interface IMessageDispatchService {
     Future<RpcResult<java.lang.Void>> setAsync(SetAsyncInput input, SwitchConnectionDistinguisher cookie);
 
     /**
-     * send set config message to switch
+     * send set config message to switch.
      *
      * @param input
      *            - message
@@ -231,7 +230,7 @@ public interface IMessageDispatchService {
     Future<RpcResult<java.lang.Void>> setConfig(SetConfigInput input, SwitchConnectionDistinguisher cookie);
 
     /**
-     * send table modification message to switch
+     * send table modification message to switch.
      *
      * @param input
      *            - message
index 9de1dd7ad4dab0f7594603b54ed8b5ac5039871b..6413bc9801a2fa361847da689990ff3f8b7a40e9 100644 (file)
@@ -21,22 +21,20 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev13
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortGrouping;
 
-/**
- * @author mirehak
- */
 public interface SessionContext {
 
     /**
-     * @return primary connection wrapper
+     * return primary connection wrapper.
      */
     ConnectionConductor getPrimaryConductor();
 
     /**
-     * @return the features of corresponding switch
+     * return the features of corresponding switch.
      */
     GetFeaturesOutput getFeatures();
 
     /**
+     * Auxiliary connections.
      * @param auxiliaryKey key under which the auxiliary conductor is stored
      * @return list of auxiliary connection wrappers
      */
@@ -44,38 +42,40 @@ public interface SessionContext {
             SwitchConnectionDistinguisher auxiliaryKey);
 
     /**
-     * @return entries of all auxiliary connections wrapped in conductors in this session
+     * return entries of all auxiliary connections wrapped in conductors in this session.
      */
     Set<Entry<SwitchConnectionDistinguisher, ConnectionConductor>> getAuxiliaryConductors();
 
     /**
-     * register new auxiliary connection wrapped in {@link ConnectionConductor}
+     * register new auxiliary connection wrapped in {@link ConnectionConductor}.
      *
-     * @param auxiliaryKey
-     * @param conductor
+     * @param auxiliaryKey key
+     * @param conductor connection conductor
      */
     void addAuxiliaryConductor(SwitchConnectionDistinguisher auxiliaryKey,
                                ConnectionConductor conductor);
 
     /**
-     * @param connectionCookie
+     * Remove conductor.
+     * @param connectionCookie cookie
      * @return removed connectionConductor
      */
     ConnectionConductor removeAuxiliaryConductor(
             SwitchConnectionDistinguisher connectionCookie);
 
     /**
-     * @return true if this session is valid
+     * return true if this session is valid.
      */
     boolean isValid();
 
     /**
+     * Setter.
      * @param valid the valid to set
      */
     void setValid(boolean valid);
 
     /**
-     * @return the sessionKey
+     * return the sessionKey.
      */
     SwitchSessionKeyOF getSessionKey();
 
@@ -120,9 +120,9 @@ public interface SessionContext {
     Boolean getPortBandwidth(Long portNumber);
 
     /**
-     * Returns True if the port is enabled,
+     * Returns True if the port is enabled.
      *
-     * @param portNumber
+     * @param portNumber port number
      * @return True if the port is enabled
      */
     boolean isPortEnabled(long portNumber);
@@ -130,7 +130,7 @@ public interface SessionContext {
     /**
      * Returns True if the port is enabled.
      *
-     * @param port
+     * @param port port
      * @return True if the port is enabled
      */
     boolean isPortEnabled(PortGrouping port);
@@ -145,44 +145,51 @@ public interface SessionContext {
     // TODO:: add listeners here, manager will set them and conductor use them
 
     /**
-     * get message dispatch service to send the message to switch
+     * get message dispatch service to send the message to switch.
      *
      * @return the message service
      */
     IMessageDispatchService getMessageDispatchService();
 
     /**
-     * @return the unique xid for this session
+     * return the unique xid for this session.
+     * @return  xid
      */
     Long getNextXid();
 
     /**
+     * Setter.
      * @param registration provider composite registration
      */
     void setProviderRegistration(ModelDrivenSwitchRegistration registration);
 
     /**
-     * @return provider composite registration
+     * return provider composite registration.
+     * @return ModelDrivenSwitchRegistration
      */
     ModelDrivenSwitchRegistration getProviderRegistration();
 
     /**
-     * @return seed value for random operations
+     * return seed value for random operations.
+     * @return int
      */
     int getSeed();
 
     /**
-     * @return (wrapped) notification enqueue service - {@link NotificationQueueWrapper}
+     * return (wrapped) notification enqueue service - {@link NotificationQueueWrapper}.
+     * @return NotificationEnqueuer
      */
     NotificationEnqueuer getNotificationEnqueuer();
 
     /**
-     * @param roleOnDevice
+     * Setter.
+     * @param roleOnDevice role
      */
     void setRoleOnDevice(ControllerRole roleOnDevice);
 
     /**
-     * @return actual role
+     * return actual role.
+     * @return role
      */
     ControllerRole getRoleOnDevice();
 }
index ea77e9fe4bd80a87495d64c7d7bd792834a212f2..9795a8a669c0a8a1660a238ae164fc13042c0363 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
@@ -10,22 +10,23 @@ package org.opendaylight.openflowplugin.api.openflow.md.core.session;
 import java.util.EventListener;
 
 /**
- * listens on session changes
+ * listens on session changes.
  */
 public interface SessionListener extends EventListener {
 
     /**
-     * fired upon session added
-     * @param sessionKey
-     * @param context
+     * fired upon session added.
+     * @param sessionKey session key
+     * @param context context
      */
     void onSessionAdded(SwitchSessionKeyOF sessionKey, SessionContext context);
 
     /**
-     * fired upon session removed
-     * @param context
+     * fired upon session removed.
+     * @param context context
      */
     void onSessionRemoved(SessionContext context);
+
     void setRole(SessionContext context);
 
 }
index c7685e56ea2ca0fb0b7660dfe025e24989dcbcbd..89456c1b745904b067fe5162debb27ae93e5e38c 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
@@ -26,116 +26,131 @@ import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.DataContainer;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 
-/**
- * @author mirehak
- */
 public interface SessionManager extends AutoCloseable {
 
     /**
-     * @param sessionKey
+     * primary connection.
+     * @param sessionKey session key
      * @return corresponding conductor, holding {@link ConnectionAdapter} to
-     * primary connection
      */
-    public SessionContext getSessionContext(SwitchSessionKeyOF sessionKey);
+    SessionContext getSessionContext(SwitchSessionKeyOF sessionKey);
 
     /**
-     * disconnect all underlying {@link ConnectionAdapter}s and notify listeners
+     * disconnect all underlying {@link ConnectionAdapter}s and notify listeners.
      *
-     * @param sessionKey
+     * @param sessionKey session key
      */
-    public void invalidateSessionContext(SwitchSessionKeyOF sessionKey);
+    void invalidateSessionContext(SwitchSessionKeyOF sessionKey);
 
     /**
-     * register session context
+     * register session context.
      *
-     * @param sessionKey
-     * @param context
+     * @param sessionKey session key
+     * @param context context
      */
-    public void addSessionContext(SwitchSessionKeyOF sessionKey, SessionContext context);
-    public void setRole(SessionContext context);
+    void addSessionContext(SwitchSessionKeyOF sessionKey, SessionContext context);
+
+    void setRole(SessionContext context);
 
     /**
      * disconnect particular auxiliary {@link ConnectionAdapter}, identified by
-     * sessionKey and connectionCookie
+     * sessionKey and connectionCookie.
      *
-     * @param sessionKey
-     * @param connectionCookie
+     * @param sessionKey  session key
+     * @param connectionCookie cookie
      */
-    public void invalidateAuxiliary(SwitchSessionKeyOF sessionKey,
+    void invalidateAuxiliary(SwitchSessionKeyOF sessionKey,
                                     SwitchConnectionDistinguisher connectionCookie);
 
     /**
-     * @param connectionConductor
+     * Invalidate on disconnect.
+     * @param connectionConductor connection conductor.
      */
-    public void invalidateOnDisconnect(ConnectionConductor connectionConductor);
+    void invalidateOnDisconnect(ConnectionConductor connectionConductor);
 
     /**
-     * @param translatorMapping
+     * Setter.
+     * @param translatorMapping translators
      */
-    public void setTranslatorMapping(Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> translatorMapping);
+    void setTranslatorMapping(
+            Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> translatorMapping);
 
     /**
+     * Getter.
      * @return translator mapping
      */
-    public Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> getTranslatorMapping();
+    Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> getTranslatorMapping();
 
     /**
-     * @param notificationProviderService
+     * Setter.
+     * @param notificationProviderService notofication provider
      */
-    public void setNotificationProviderService(NotificationProviderService notificationProviderService);
+    void setNotificationProviderService(NotificationProviderService notificationProviderService);
 
     /**
+     * Getter.
      * @return notificationServiceProvider
      */
-    public DataBroker getDataBroker();
+    DataBroker getDataBroker();
 
     /**
-     * @param dataBroker
+     * Setter.
+     * @param dataBroker databroker
      */
-    public void setDataBroker(DataBroker dataBroker);
+    void setDataBroker(DataBroker dataBroker);
 
     /**
+     * Gatter.
      * @return notificationServiceProvider
      */
-    public NotificationProviderService getNotificationProviderService();
+    NotificationProviderService getNotificationProviderService();
 
     /**
-     * @param listener
+     * Session listener registration.
+     * @param listener listener
      * @return registration
      */
-    public ListenerRegistration<SessionListener> registerSessionListener(SessionListener listener);
+    ListenerRegistration<SessionListener> registerSessionListener(SessionListener listener);
 
     /**
+     * Getter.
      * @return popListener mapping, key=message type; value=collection of listeners
      */
-    public Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> getPopListenerMapping();
+    Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> getPopListenerMapping();
 
     /**
+     * Setter.
      * @param popListenerMapping the popListenerMapping to set
      */
-    void setPopListenerMapping(Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> popListenerMapping);
+    void setPopListenerMapping(
+            Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> popListenerMapping);
 
     /**
-     * @param rpcPoolDelegator
+     * Setter.
+     * @param rpcPoolDelegator rpc pool delegator
      */
     void setRpcPool(ListeningExecutorService rpcPoolDelegator);
 
     /**
+     * Getter.
      * @return the rpcPool instance
      */
     ListeningExecutorService getRpcPool();
 
     /**
-     * @param messageSpy
+     * Setter.
+     * @param messageSpy message spy
      */
     void setMessageSpy(MessageSpy<DataContainer> messageSpy);
 
     /**
+     * Getter.
      * @return the messageSpy
      */
     MessageSpy<DataContainer> getMessageSpy();
 
     /**
+     * Getter.
      * @return collection of current sessions
      */
     Collection<SessionContext> getAllSessions();
index dc50c0edb72e5f5f9e38050f9bab9e053b15d014..2a54db0841ce48c404f2cd795ad67c229a9da7ac 100644 (file)
@@ -10,28 +10,27 @@ package org.opendaylight.openflowplugin.api.openflow.md.core.session;
 
 import java.math.BigInteger;
 
-/**
- * @author mirehak
- */
 public class SwitchSessionKeyOF {
 
     private BigInteger datapathId;
 
     /**
-     * default ctor
+     * default ctor.
      */
     public SwitchSessionKeyOF() {
         // NOOP
     }
-    
+
     /**
+     * Setter.
      * @param datapathId the datapathId to set
      */
     public void setDatapathId(BigInteger datapathId) {
         this.datapathId = datapathId;
     }
-    
+
     /**
+     * Getter.
      * @return the datapathId
      */
     public byte[] getId() {
index faac4ae217f9813b202359aee7a91f6d3e58d91a..38a49d1e2b19cda402e5941b1e43395800061855 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
@@ -10,17 +10,20 @@ package org.opendaylight.openflowplugin.api.openflow.md.queue;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
 
 /**
+ * Enqueuer.
  * @param <I> type of queue items (IN)
  */
 public interface Enqueuer<I> {
 
     /**
+     * item to be enqueued.
      * @param queueItem item to be enqueued
      */
     void enqueueQueueItem(I queueItem);
 
     /**
-     * @param queueItem
+     * for testing and comparing purposes - this strategy blocks netty threads.
+     * @param queueItem item
      * @deprecated for testing and comparing purposes - this strategy blocks netty threads
      */
     @Deprecated
index b9a5955297cd97f7f97d9e6e43d9181e8eb9b981..ec93933d5f94c52ad43014b0a5389aff20cc34dd 100644 (file)
@@ -1,6 +1,6 @@
-/**
+/*
  * Copyright (c) 2014 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,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
@@ -8,12 +8,12 @@
 package org.opendaylight.openflowplugin.api.openflow.md.queue;
 
 /**
- * message harvester simple control
+ * message harvester simple control.
  */
 public interface HarvesterHandle {
 
     /**
-     * wakeup harvester in case it is in phase of starving sleep
+     * wakeup harvester in case it is in phase of starving sleep.
      */
     void ping();
 
index ab668a675d4b421eb30e442627dc4e82d221353e..87a71f3e5f557c231c5c313842a71dbf3676035f 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
@@ -10,29 +10,34 @@ package org.opendaylight.openflowplugin.api.openflow.md.queue;
 import java.util.Collection;
 
 /**
+ * MessageSourcePollRegistrator.
  * @param <I> message wrapping type (IN)
  *
  */
 public interface MessageSourcePollRegistrator<I> {
 
     /**
+     * Message source to read from during processing.
      * @param messageSource to read from during processing
      * @return closeable registration
      */
     AutoCloseable registerMessageSource(I messageSource);
 
     /**
+     * Unregister message source.
      * @param messageSource to be unregistered
      * @return true if successfully unregistered
      */
     boolean unregisterMessageSource(I messageSource);
 
     /**
+     * Getter.
      * @return collection of registered message sources
      */
     Collection<I> getMessageSources();
 
     /**
+     * Getter.
      * @return the harvest handle
      */
     HarvesterHandle getHarvesterHandle();
index e81e24d788234e994fc13bba1c2ebad8b04dc294..da3c4675c6f9458c1e487a1b3b582d0b542d483c 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
@@ -9,15 +9,10 @@ package org.opendaylight.openflowplugin.api.openflow.md.queue;
 
 
 /**
- * @author mirehak
+ * PopListener.
  * @param <T> result type
  *
  */
 public interface PopListener<T> {
-    
-    /**
-     * @param processedMessage
-     */
     void onPop(T processedMessage);
-
 }
index f5c91684e6b54b1960422d2a4639edaeaae867ab..96f3b38e8a3a717bae6062262808390c633ca026 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
@@ -10,21 +10,25 @@ package org.opendaylight.openflowplugin.api.openflow.md.queue;
 import org.opendaylight.openflowplugin.api.openflow.md.core.ConnectionConductor;
 
 /**
+ * Queue item.
  * @param <I> input message type (IN)
  */
 public interface QueueItem<I> {
 
     /**
+     * Getter.
      * @return wrapped message
      */
     I getMessage();
 
     /**
+     * Getter.
      * @return conductor the message arrived to
      */
     ConnectionConductor getConnectionConductor();
 
     /**
+     * Getter.
      * @return queue type associated to this item
      */
     QueueKeeper.QueueType getQueueType();
index 8176a5fab388a667b1eb541d865ddbae273221eb..4fc3ff3a25d0297d4c5b38bb4a83d443bac56f5f 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
@@ -13,7 +13,7 @@ import org.opendaylight.openflowplugin.api.openflow.md.core.ConnectionConductor;
  * This processing mechanism based on queue. Processing consists of 2 steps: translate and publish.
  * Proposed workflow (might slightly deviate in implementations):
  * <ol>
- * <li>messages of input type are pushed in (via {@link QueueKeeper#push(Object, ConnectionConductor, QueueType)} and similar)</li>
+ * <li>messages of input type are pushed in (via {@link QueueKeeper} and similar)</li>
  * <li>ticket (executable task) is build upon each pushed message and enqueued</li>
  * <li>ticket is translated using appropriate translator</li>
  * <li>ticket is dequeued and result is published by appropriate popListener</li>
@@ -23,27 +23,30 @@ import org.opendaylight.openflowplugin.api.openflow.md.core.ConnectionConductor;
  */
 public interface QueueKeeper<I> extends AutoCloseable {
 
-    /** type of message enqueue */
-    public enum QueueType {
-        /** ordered processing */
+    /** type of message enqueue. */
+    enum QueueType {
+        /** ordered processing. */
         DEFAULT,
-        /** unordered processing - bypass fair processing */
-        UNORDERED}
+        /** unordered processing - bypass fair processing. */
+        UNORDERED
+    }
 
     /**
-     * enqueue message for processing
-     * @param message
+     * enqueue message for processing.
+     * @param message message
      * @param conductor source of message
      * @param queueType - {@link QueueType#DEFAULT} if message order matters, {@link QueueType#UNORDERED} otherwise
      */
     void push(I message, ConnectionConductor conductor, QueueType queueType);
 
     /**
-     * @return oldest item from queue - if available and remove it from queue
+     * oldest item from queue - if available and remove it from queue.
+     * @return oldest item from queue
      */
     QueueItem<I> poll();
 
     /**
+     * Setter.
      * @param processingRegistration the processingRegistration to set (in order to provide close method)
      */
     void setPollRegistration(AutoCloseable processingRegistration);
index e1f0e38c4add2e56063e3ecf143a82aa6da21d47..e2dc95e6954635e2e4b54639313042f5f861f8b4 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
@@ -17,7 +17,7 @@ import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
  * This processing mechanism based on queue. Processing consists of 2 steps: translate and publish.
  * Proposed workflow (might slightly deviate in implementations):
  * <ol>
- * <li>messages of input type are pushed in (via {@link QueueKeeper#push(Object, org.opendaylight.openflowplugin.api.openflow.md.core.ConnectionConductor, org.opendaylight.openflowplugin.api.openflow.md.queue.QueueKeeper.QueueType)} and similar)</li>
+ * <li>messages of input type are pushed in (via {@link QueueKeeper and similar})</li>
  * <li>ticket (executable task) is build upon each pushed message and enqueued</li>
  * <li>ticket is translated using appropriate translator</li>
  * <li>ticket is dequeued and result is published by appropriate popListener</li>
@@ -29,11 +29,13 @@ import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
 public interface QueueProcessor<I, O> extends MessageSourcePollRegistrator<QueueKeeper<I>>, Enqueuer<QueueItem<I>> {
 
     /**
+     * translators for message processing.
      * @param translatorMapping translators for message processing
      */
     void setTranslatorMapping(Map<TranslatorKey, Collection<IMDMessageTranslator<I, List<O>>>> translatorMapping);
 
     /**
+     * listeners invoked when processing done.
      * @param popListenersMapping listeners invoked when processing done
      */
     void setPopListenersMapping(Map<Class<? extends O>, Collection<PopListener<O>>> popListenersMapping);
index 77da8f0780ce7086c29924fdc4c474628ed9b06a..5c56516bd6c75fa55ebd6e67974e954a82b879c7 100644 (file)
@@ -11,12 +11,12 @@ package org.opendaylight.openflowplugin.api.openflow.md.queue;
 public interface WaterMarkListener {
 
     /**
-     * When HighWaterMark reached and currently not flooded
+     * When HighWaterMark reached and currently not flooded.
      */
     void onHighWaterMark();
 
     /**
-     * When LowWaterMark reached and currently flooded
+     * When LowWaterMark reached and currently flooded.
      */
     void onLowWaterMark();
 }
index 01c269d11df6b3a3df33935fb39b6c9d5d9c6347..99d7cc8d0043b364fd21ec0cc82fcfd3535df593 100644 (file)
@@ -9,12 +9,10 @@
 package org.opendaylight.openflowplugin.api.openflow.md.util;
 
 /**
- * @deprecated enum in api is not something what we would like to see in case it is evolving
- * TODO: remove class for lithium release
- *
- * List of Openflow versions supported by the plugin
- * Note: If you add a version here, make sure to update org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil as well.
- * Created by kramesha on 5/2/14.
+ * List of Openflow versions supported by the plugin.
+ * Note: If you add a version here,
+ * make sure to update org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil as well.
+ * @deprecated enum in api is not something what we would like to see in case it is evolving.
  */
 public enum OpenflowVersion {
 
@@ -39,6 +37,7 @@ public enum OpenflowVersion {
     }
 
     /**
+     * Getter.
      * @return the version
      */
     public short getVersion() {
index d853236cee42f657854b0d814acf582a3f793220..55ca10a5700592f6206ef4f82b91edbc68c3f410 100644 (file)
@@ -1,6 +1,6 @@
-/**
+/*
  * Copyright (c) 2014 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,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
@@ -16,7 +16,7 @@ import java.util.Queue;
  * still null result, poll will return null. <br>
  * Iterating keeps last position so this polling is supposed to be fairly
  * distributed.
- * 
+ *
  * @param <T> common item type of zipped queues
  */
 public class PollableQueuesPriorityZipper<T> {
@@ -24,25 +24,20 @@ public class PollableQueuesPriorityZipper<T> {
     private Queue<T> prioritizedSource;
     private PollableQueuesZipper<T> zipper;
 
-    /**
-     * default ctor
-     */
     public PollableQueuesPriorityZipper() {
         zipper = new PollableQueuesZipper<>();
     }
 
     /**
-     * Add all member queues before first invocation of
-     * {@link PollableQueuesPriorityZipper#poll()}
-     * 
-     * @param queue
-     *            to be added to group
+     * Add all member queues before first invocation of {@link PollableQueuesPriorityZipper#poll()}.
+     * @param queue to be added to group
      */
     public void addSource(Queue<T> queue) {
         zipper.addSource(queue);
     }
 
     /**
+     * Next common product.
      * @return next common product of polling member groups
      */
     public T poll() {
index 7ba8317607234afd97a10d7b535708e6af437135..c6aca0ef8645f49ef0c9948310277450fb15e36a 100644 (file)
@@ -1,6 +1,6 @@
-/**
+/*
  * Copyright (c) 2014 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,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
@@ -15,27 +15,24 @@ import java.util.Queue;
 
 /**
  * Zipper groups together a list of queues and exposes one poll method. Polling iterates through
- * all groups and returns first not-null result of poll method on each queue. If after polling each 
- * grouped queue for one time there is still null result, poll will return null. 
+ * all groups and returns first not-null result of poll method on each queue. If after polling each
+ * grouped queue for one time there is still null result, poll will return null.
  * <br>
  * Iterating keeps last position so this polling is supposed to be fairly distributed.
- * 
+ *
  * @param <T> common item type of zipped queues
  */
 public class PollableQueuesZipper<T> {
-    
+
     private List<Queue<T>> sources;
     private Iterator<Queue<T>> cursor;
-    
-    /**
-     * default ctor
-     */
+
     public PollableQueuesZipper() {
         sources = new ArrayList<>();
     }
-    
+
     /**
-     * Add all member queues before first invocation of {@link PollableQueuesZipper#poll()}
+     * Add all member queues before first invocation of {@link PollableQueuesZipper#poll()}.
      * @param queue to be added to group
      */
     public void addSource(Queue<T> queue) {
@@ -43,6 +40,7 @@ public class PollableQueuesZipper<T> {
     }
 
     /**
+     * Next common product.
      * @return next common product of polling member groups
      */
     public T poll() {
@@ -50,7 +48,7 @@ public class PollableQueuesZipper<T> {
         if (cursor == null) {
             cursor = Iterators.cycle(sources);
         }
-        
+
         Queue<T> queue;
         for (int i = 0; i < sources.size(); i++) {
             queue = cursor.next();
@@ -59,7 +57,7 @@ public class PollableQueuesZipper<T> {
                 break;
             }
         }
-        
+
         return item;
     }
 }
diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/registry/CommonDeviceRegistry.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/registry/CommonDeviceRegistry.java
new file mode 100644 (file)
index 0000000..a5c019d
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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.registry;
+
+import java.util.function.Consumer;
+
+public interface CommonDeviceRegistry<KEY> extends AutoCloseable {
+
+    /**
+     * Store KEY in device registry.
+     * @param key device registry key
+     */
+    void store(KEY key);
+
+    /**
+     * Add mark for specified KEY.
+     * @param key device registry key
+     */
+    void addMark(KEY key);
+
+    /**
+     * Process marked keys.
+     */
+    void processMarks();
+
+    /**
+     * Iterate over all keys in device registry.
+     * @param consumer key consumer
+     */
+    void forEach(Consumer<KEY> consumer);
+
+    /**
+     * Get device registry size.
+     * @return device registry size
+     */
+    int size();
+
+    @Override
+    void close();
+
+}
index e43433f4fb5692f4cbf0f94f4c630fd0b27bb3d3..6dbd7094737a2431e916084732066000fc06cc1e 100644 (file)
@@ -12,30 +12,22 @@ package org.opendaylight.openflowplugin.api.openflow.registry.flow;
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.ListenableFuture;
 import java.util.List;
-import java.util.Map;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.openflowplugin.api.openflow.registry.CommonDeviceRegistry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
 
 /**
  * Registry for mapping composite-key of flow ({@link FlowRegistryKey}) from device view
  * to flow descriptor ({@link FlowDescriptor}) as the identifier of the same flow in data store.
  */
-public interface DeviceFlowRegistry extends AutoCloseable {
+public interface DeviceFlowRegistry extends CommonDeviceRegistry<FlowRegistryKey> {
 
     ListenableFuture<List<Optional<FlowCapableNode>>> fill();
 
-    FlowDescriptor retrieveIdForFlow(FlowRegistryKey flowRegistryKey);
+    void storeDescriptor(@Nonnull FlowRegistryKey flowRegistryKey, @Nonnull FlowDescriptor flowDescriptor);
 
-    void store(FlowRegistryKey flowRegistryKey, FlowDescriptor flowDescriptor);
+    @Nullable
+    FlowDescriptor retrieveDescriptor(@Nonnull FlowRegistryKey flowRegistryKey);
 
-    FlowId storeIfNecessary(FlowRegistryKey flowRegistryKey);
-
-    void removeDescriptor(FlowRegistryKey flowRegistryKey);
-
-    void update(FlowRegistryKey newFlowRegistryKey,FlowDescriptor flowDescriptor);
-
-    Map<FlowRegistryKey, FlowDescriptor> getAllFlowDescriptors();
-
-    @Override
-    void close();
-}
\ No newline at end of file
+}
index dd9cff527f31dcbeeaff76816b661cfe6c6eaf3a..24fcc945d1f0ef4f7c712b89bb5758f47518ee37 100644 (file)
@@ -11,12 +11,10 @@ package org.opendaylight.openflowplugin.api.openflow.registry.flow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
 
-/**
- * Created by Martin Bobak &lt;mbobak@cisco.com&gt; on 9.4.2015.
- */
 public interface FlowDescriptor {
 
     FlowId getFlowId();
 
     TableKey getTableKey();
+
 }
index 05eb9f6d0da4ae00a698fc71f39cc0a3978897f5..7414f70f4d81e997387f59de51b88ed9dc34052d 100644 (file)
@@ -8,22 +8,9 @@
 
 package org.opendaylight.openflowplugin.api.openflow.registry.group;
 
-import java.util.List;
+import org.opendaylight.openflowplugin.api.openflow.registry.CommonDeviceRegistry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
 
-/**
- * Created by Martin Bobak &lt;mbobak@cisco.com&gt; on 15.4.2015.
- */
-public interface DeviceGroupRegistry extends AutoCloseable {
-
-    void store(GroupId groupId);
-
-    void markToBeremoved(GroupId groupId);
-
-    void removeMarked();
-
-    List<GroupId> getAllGroupIds();
+public interface DeviceGroupRegistry extends CommonDeviceRegistry<GroupId> {
 
-    @Override
-    void close();
 }
index 12540cb086c75c48e02e5baa75cff3883a6b150d..25b5bb9bb70328e9e901938e0dc5fd9dd49cdd4a 100644 (file)
@@ -8,23 +8,9 @@
 
 package org.opendaylight.openflowplugin.api.openflow.registry.meter;
 
-import java.util.List;
+import org.opendaylight.openflowplugin.api.openflow.registry.CommonDeviceRegistry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId;
 
-/**
- * Created by Martin Bobak &lt;mbobak@cisco.com&gt; on 15.4.2015.
- */
-public interface DeviceMeterRegistry extends AutoCloseable {
-
-    void store(MeterId meterId);
-
-    void markToBeremoved(MeterId meterId);
-
-    void removeMarked();
-
-    List<MeterId> getAllMeterIds();
-
-    @Override
-    void close();
+public interface DeviceMeterRegistry extends CommonDeviceRegistry<MeterId> {
 
 }
index 505e8eb3535ac29fb0df4a5c7227c274f324f5db..5340eca322eb82b5b8a25f9c6421c8b88e609448 100644 (file)
@@ -10,14 +10,16 @@ package org.opendaylight.openflowplugin.api.openflow.rpc;
 
 import org.opendaylight.openflowplugin.api.openflow.OFPManager;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
-import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceInitializationPhaseHandler;
 
 /**
  * The RPC Manager will maintain an RPC Context for each online switch. RPC context for device is created when
- * {@link DeviceInitializationPhaseHandler#onDeviceContextLevelUp(DeviceInfo, org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleService)}
+ * {@link org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceInitializationPhaseHandler#onDeviceContextLevelUp(DeviceInfo, org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleService)}
  * is called.
  */
 public interface RpcManager extends OFPManager {
 
     void setStatisticsRpcEnabled(boolean statisticsRpcEnabled);
+
+    void setRpcRequestQuota(int rpcRequestQuota);
+
 }
index d9497d7811b9e03f02af4b47263cec3f4f04b4de..9989436383feffc2127cd2ce11643b59aa4df40c 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,21 +106,24 @@ 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;
         }
index cc23c97307eba1d6443532f8c661cba83d62820b..c86993afdc6ba608fc323d47dbbf43b9e1453fc1 100644 (file)
@@ -6,7 +6,7 @@
     <parent>
       <groupId>org.opendaylight.openflowplugin</groupId>
       <artifactId>openflowplugin-parent</artifactId>
-      <version>0.3.3-SNAPSHOT</version>
+      <version>0.3.5-SNAPSHOT</version>
       <relativePath>../parent</relativePath>
     </parent>
 
index af80f42db48862ada9e63e11086df9bbc7066469..094c2bfcfa3f0f89b13bd01a8c82fc2b683e98da 100644 (file)
@@ -6,7 +6,7 @@
     <parent>
       <groupId>org.opendaylight.openflowplugin</groupId>
       <artifactId>openflowplugin-parent</artifactId>
-      <version>0.3.3-SNAPSHOT</version>
+      <version>0.3.5-SNAPSHOT</version>
       <relativePath>../parent</relativePath>
     </parent>
 
index bcf40e7dcfa52a347e595ae46bc3ffa6cf63caa4..141cb63086c215523f8519ee17498d7056cddf65 100644 (file)
-#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
+# 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
+
+
+
+#############################################################################
+#                                                                           #
+#            Forwarding Rule Manager Application Configuration              #
+#                                                                           #
+#############################################################################
+
+# Disable the default switch reconciliation mechanism
+# disable-reconciliation=false
+
+# Enable stale marking for switch reconciliation. Once user enable this feature
+# forwarding rule manager will keep track of any change to the config data store
+# while the switch is disconnected from controller. Once switch reconnect to the
+# controller it will apply those changes to the switch and do the reconciliation
+# of other configuration as well.
+# NOTE: This option will be effective only if disable_reconciliation=false.
+# stale-marking-enabled=false
+
+# Number of time forwarding rules manager should retry to reconcile any specific
+# configuration.
+# reconciliation-retry-count=5
\ No newline at end of file
index bd72c349c703fd9cb8d86699d3f5239ee4d35890..a8cf7e4e19c7c5f4604700d8be50a883a36ac2f5 100644 (file)
   <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>
+    <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>
index ffbde466a3b159ab21b3ced2f8b1c50aebe8f493..8099b9584dd5feb43ccce877d115f87c9f033fdd 100644 (file)
@@ -4,7 +4,7 @@
     <parent>
         <groupId>org.opendaylight.openflowplugin</groupId>
         <artifactId>openflowplugin-parent</artifactId>
-        <version>0.3.3-SNAPSHOT</version>
+        <version>0.3.5-SNAPSHOT</version>
         <relativePath>../parent</relativePath>
     </parent>
 
index 57cdacf7d4b5e02b01d75ef7b6fe1be1cf754d32..88f0434eebcffb019c9e3f1bd8107cb634b0504d 100644 (file)
@@ -13,7 +13,7 @@
     <parent>
       <groupId>org.opendaylight.openflowplugin</groupId>
       <artifactId>openflowplugin-parent</artifactId>
-      <version>0.3.3-SNAPSHOT</version>
+      <version>0.3.5-SNAPSHOT</version>
       <relativePath>../parent</relativePath>
     </parent>
 
index 51a7e0c9ee82da2a3bc2453ffd241033a9b3a8e8..4c1324ce29c186a10886cf1676339080add18648 100644 (file)
@@ -4,7 +4,7 @@
     <parent>
         <groupId>org.opendaylight.openflowplugin</groupId>
         <artifactId>openflowplugin-parent</artifactId>
-        <version>0.3.3-SNAPSHOT</version>
+        <version>0.3.5-SNAPSHOT</version>
         <relativePath>../parent</relativePath>
     </parent>
 
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-common-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
     </dependencies>
 </project>
 
index bc770118636e9759ac67ec2a909aef052e702b41..afaecbda5166433b0290beda8e9b671520ac3bb0 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,67 +40,69 @@ 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());
+        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.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 08ccb34e2399e42eb3d6044dd6dae7cee41ed52d..5559ff307e527e698eba0b5724eb718fc4c7837c 100644 (file)
@@ -8,19 +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 com.google.common.util.concurrent.ListenableFuture;
+import io.netty.util.HashedWheelTimer;
 import java.lang.management.ManagementFactory;
 import java.util.ArrayList;
-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 javax.annotation.Nonnull;
 import javax.management.InstanceAlreadyExistsException;
 import javax.management.MBeanRegistrationException;
@@ -31,9 +31,11 @@ import javax.management.ObjectName;
 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;
+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;
@@ -58,24 +60,26 @@ 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 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 ConvertorManager convertorManager;
+    private final List<SwitchConnectionProvider> switchConnectionProviders;
+    private final DataBroker dataBroker;
+    private final NotificationPublishService notificationPublishService;
+    private final NotificationService notificationProviderService;
+    private final EntityOwnershipService entityOwnershipService;
+    private int rpcRequestsQuota;
+    private long globalNotificationQuota;
     private long barrierInterval;
     private int barrierCountLimit;
     private long echoReplyTimeout;
@@ -84,51 +88,43 @@ 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 final ThreadPoolExecutor threadPool;
     private ClusterSingletonServiceProvider singletonServicesProvider;
+    private ExtensionConverterManager extensionConverterManager;
+    private int threadPoolMinThreads;
+    private int threadPoolMaxThreads;
+    private long threadPoolTimeout;
+    private boolean initialized = false;
+    private ThreadPoolLoggingExecutor threadPool;
 
-    public OpenFlowPluginProviderImpl(final long rpcRequestsQuota,
-                                      final long globalNotificationQuota,
-                                      final int threadPoolMinThreads,
-                                      final int threadPoolMaxThreads,
-                                      final long threadPoolTimeout) {
-        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);
-
-        // 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<>(), "ofppool");
-        convertorManager = ConvertorManagerFactory.createDefaultManager();
+    public static MessageIntelligenceAgency getMessageIntelligenceAgency() {
+        return messageIntelligenceAgency;
     }
 
-    @Override
-    public boolean isStatisticsPollingOn() {
-        return isStatisticsPollingOn;
+    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;
+        this.entityOwnershipService = entityOwnershipService;
+        convertorManager = ConvertorManagerFactory.createDefaultManager();
+        extensionConverterManager = new ExtensionConverterManagerImpl();
     }
 
-    @Override
-    public void setStatisticsPollingOn(final boolean isStatisticsPollingOn) {
-        this.isStatisticsPollingOn = isStatisticsPollingOn;
-    }
 
     private void startSwitchConnections() {
         final List<ListenableFuture<Boolean>> starterChain = new ArrayList<>(switchConnectionProviders.size());
@@ -153,75 +149,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 = this.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");
@@ -229,33 +156,48 @@ 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);
 
         deviceManager = new DeviceManagerImpl(dataBroker,
-                globalNotificationQuota,
-                switchFeaturesMandatory,
-                barrierInterval,
-                barrierCountLimit,
                 getMessageIntelligenceAgency(),
-                isFlowRemovedNotificationOn,
                 singletonServicesProvider,
-                notificationPublishService,
+                entityOwnershipService,
                 hashedWheelTimer,
                 convertorManager,
-                skipTableFeatures);
+                notificationPublishService);
+
+        deviceManager.setGlobalNotificationQuota(globalNotificationQuota);
+        deviceManager.setSwitchFeaturesMandatory(switchFeaturesMandatory);
+        deviceManager.setBarrierInterval(barrierInterval);
+        deviceManager.setBarrierCountLimit(barrierCountLimit);
+        deviceManager.setFlowRemovedNotificationOn(isFlowRemovedNotificationOn);
+        deviceManager.setSkipTableFeatures(skipTableFeatures);
 
         ((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);
 
         /* Initialization Phase ordering - OFP Device Context suite */
         // CM -> DM -> SM -> RPC -> Role -> DM
@@ -275,60 +217,251 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF
         deviceManager.initialize();
 
         startSwitchConnections();
+        initialized = true;
     }
 
     @Override
-    public void update(Map<String,Object> props) {
-        LOG.debug("Update managed properties = {}", props.toString());
-
-        if(deviceManager != null) {
-            if (props.containsKey("notification-flow-removed-off")) {
-                deviceManager.setFlowRemovedNotificationOn(Boolean.valueOf(props.get("enable-flow-removed-notification").toString()));
+    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 (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);
-                }
+        });
+    }
+
+    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(rpcManager != null && props.containsKey("is-statistics-rpc-enabled")){
-            rpcManager.setStatisticsRpcEnabled(Boolean.valueOf((props.get("is-statistics-rpc-enabled").toString())));
-        }
+        successCallback.accept(newValue);
+        LOG.info("{} config parameter is updated ({} -> {})", propertyType, origValue, newValue);
+    }
 
-        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);
+    @Override
+    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;
+                default:
+                    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()));
+            doPropertyUpdate(key, modifiable, oldValue, newValue, successCallback);
+        } catch (final Exception ex) {
+            LOG.warn("Failed to read configuration property '{}={}', error: {}", key, value, ex);
         }
+    }
 
-        if(statisticsManager != null && props.containsKey("maximum-timer-delay")){
-            statisticsManager.setMaximumTimerDelay(Long.valueOf(props.get("maximum-timer-delay").toString()));
-        }
+    @Override
+    public ExtensionConverterRegistrator getExtensionConverterRegistrator() {
+        return extensionConverterManager;
     }
 
+    @Override
+    public void close() throws Exception {
+        initialized = false;
+        //TODO: consider wrapping each manager into try-catch
+        deviceManager.close();
+        rpcManager.close();
+        statisticsManager.close();
+
+        // Manually shutdown all remaining running threads in pool
+        threadPool.shutdown();
+    }
 
     private static void registerMXBean(final MessageIntelligenceAgency messageIntelligenceAgency) {
         final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
@@ -345,35 +478,4 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF
             LOG.warn("Error registering MBean {}", e);
         }
     }
-
-    @Override
-    public void setNotificationProviderService(final NotificationService notificationProviderService) {
-        this.notificationProviderService = notificationProviderService;
-    }
-
-    @Override
-    public void setNotificationPublishService(final NotificationPublishService notificationPublishProviderService) {
-        this.notificationPublishService = notificationPublishProviderService;
-    }
-
-    @Override
-    public ExtensionConverterRegistrator getExtensionConverterRegistrator() {
-        return extensionConverterManager;
-    }
-
-    @Override
-    public void setIsStatisticsRpcEnabled(final boolean isStatisticsRpcEnabled) {
-        this.isStatisticsRpcEnabled = isStatisticsRpcEnabled;
-    }
-
-    @Override
-    public void close() throws Exception {
-        //TODO: consider wrapping each manager into try-catch
-        deviceManager.close();
-        rpcManager.close();
-        statisticsManager.close();
-
-        // Manually shutdown all remaining running threads in pool
-        threadPool.shutdown();
-    }
-}
\ No newline at end of file
+}
index f9bc7d4c603a947656a1a0c22a958ccb956ee534..584e032244927447d645104d726e46c9cef6af15 100644 (file)
@@ -41,7 +41,7 @@ public class ConnectionManagerImpl implements ConnectionManager {
     private long echoReplyTimeout;
     private final ThreadPoolExecutor threadPool;
 
-    public ConnectionManagerImpl(long echoReplyTimeout, final ThreadPoolExecutor threadPool) {
+    public ConnectionManagerImpl(final ThreadPoolExecutor threadPool) {
         this.echoReplyTimeout = echoReplyTimeout;
         this.threadPool = threadPool;
     }
@@ -82,8 +82,8 @@ public class ConnectionManagerImpl implements ConnectionManager {
     private HandshakeManager createHandshakeManager(final ConnectionAdapter connectionAdapter,
                                                     final HandshakeListener handshakeListener) {
         HandshakeManagerImpl handshakeManager = new HandshakeManagerImpl(connectionAdapter,
-                ConnectionConductor.versionOrder.get(0),
-                ConnectionConductor.versionOrder);
+                ConnectionConductor.VERSION_ORDER.get(0),
+                ConnectionConductor.VERSION_ORDER);
         handshakeManager.setUseVersionBitmap(BITMAP_NEGOTIATION_ENABLED);
         handshakeManager.setHandshakeListener(handshakeListener);
         handshakeManager.setErrorHandler(new ErrorHandlerSimpleImpl());
@@ -102,6 +102,7 @@ public class ConnectionManagerImpl implements ConnectionManager {
         this.deviceConnectedHandler = deviceConnectedHandler;
     }
 
+    @Override
     public void setEchoReplyTimeout(long echoReplyTimeout){
         this.echoReplyTimeout = echoReplyTimeout;
     }
index 696743f31a744ffa8f3a8576457affd239d35dfd..afac7ac95836b01fb6609b4683dd28cb1b665902 100644 (file)
@@ -69,18 +69,18 @@ public class HandshakeListenerImpl implements HandshakeListener {
             @Override
             public void onSuccess(@Nullable final RpcResult<BarrierOutput> result) {
                 if (LOG.isDebugEnabled()) {
-                    LOG.debug("succeeded by getting sweep barrier after post-handshake for device {}", connectionContext.getNodeId().getValue());
+                    LOG.debug("succeeded by getting sweep barrier after post-handshake for device {}", connectionContext.getDeviceInfo().getLOGValue());
                 }
                 try {
                     ConnectionStatus connectionStatusResult = deviceConnectedHandler.deviceConnected(connectionContext);
                     if (!ConnectionStatus.MAY_CONTINUE.equals(connectionStatusResult)) {
                         connectionContext.closeConnection(true);
                     }
-                    SessionStatistics.countEvent(connectionContext.getNodeId().toString(),
+                    SessionStatistics.countEvent(connectionContext.getDeviceInfo().getLOGValue(),
                             SessionStatistics.ConnectionStatus.CONNECTION_CREATED);
                 } catch (final Exception e) {
-                    LOG.error("ConnectionContext initial processing failed: ", e);
-                    SessionStatistics.countEvent(connectionContext.getNodeId().toString(),
+                    LOG.error("ConnectionContext initial processing failed for device {}", connectionContext.getDeviceInfo().getLOGValue(), e);
+                    SessionStatistics.countEvent(connectionContext.getDeviceInfo().getLOGValue(),
                             SessionStatistics.ConnectionStatus.CONNECTION_DISCONNECTED_BY_OFP);
                     connectionContext.closeConnection(true);
                 }
@@ -88,7 +88,7 @@ public class HandshakeListenerImpl implements HandshakeListener {
 
             @Override
             public void onFailure(final Throwable t) {
-                LOG.error("failed to get sweep barrier after post-handshake for device {}", connectionContext.getNodeId());
+                LOG.error("failed to get sweep barrier after post-handshake for device {}", connectionContext.getDeviceInfo().getLOGValue(), t);
                 connectionContext.closeConnection(false);
             }
         };
index 1d5263a8a7af15d1f55d1f09f7425ea4fde43bcf..b32e259842e66c00412892602cea93b6af563778 100644 (file)
@@ -33,8 +33,10 @@ import org.slf4j.LoggerFactory;
  */
 public class SystemNotificationsListenerImpl implements SystemNotificationsListener {
 
-    private final ConnectionContext connectionContext;
     private static final Logger LOG = LoggerFactory.getLogger(SystemNotificationsListenerImpl.class);
+    private static final long ECHO_XID = 0L;
+
+    private final ConnectionContext connectionContext;
     @VisibleForTesting
     static final long MAX_ECHO_REPLY_TIMEOUT = 2000;
     private final long echoReplyTimeout;
@@ -71,14 +73,14 @@ public class SystemNotificationsListenerImpl implements SystemNotificationsListe
             connectionContext.changeStateToTimeouting();
             EchoInputBuilder builder = new EchoInputBuilder();
             builder.setVersion(features.getVersion());
-            Xid xid = new Xid(0L);
+            Xid xid = new Xid(ECHO_XID);
             builder.setXid(xid.getValue());
 
             Future<RpcResult<EchoOutput>> echoReplyFuture = connectionContext.getConnectionAdapter().echo(builder.build());
 
             try {
                 RpcResult<EchoOutput> echoReplyValue = echoReplyFuture.get(echoReplyTimeout, TimeUnit.MILLISECONDS);
-                if (echoReplyValue.isSuccessful()) {
+                if (echoReplyValue.isSuccessful() && echoReplyValue.getResult().getXid() == ECHO_XID) {
                     connectionContext.changeStateToWorking();
                     shouldBeDisconnected = false;
                 } else {
index 302deb93e5c1a720630427708f71f5c79d4a84f9..59192333f07ffbb1e97e1aabf99bac57557f0d53 100644 (file)
@@ -12,6 +12,7 @@ import com.google.common.base.Function;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Verify;
 import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.JdkFutureAdapters;
@@ -19,17 +20,6 @@ import com.google.common.util.concurrent.ListenableFuture;
 import io.netty.util.HashedWheelTimer;
 import io.netty.util.Timeout;
 import io.netty.util.TimerTask;
-import java.math.BigInteger;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-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.ReadOnlyTransaction;
@@ -86,6 +76,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.ta
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemovedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdatedBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
@@ -117,6 +109,16 @@ import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
 public class DeviceContextImpl implements DeviceContext, ExtensionConverterProviderKeeper {
 
     private static final Logger LOG = LoggerFactory.getLogger(DeviceContextImpl.class);
@@ -164,6 +166,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
     private volatile CONTEXT_STATE state;
     private ClusterInitializationPhaseHandler clusterInitializationPhaseHandler;
     private final DeviceManager myManager;
+    private Boolean isAddNotificationSent = false;
 
     DeviceContextImpl(
             @Nonnull final ConnectionContext primaryConnectionContext,
@@ -327,9 +330,9 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
         final ItemLifecycleListener itemLifecycleListener = flowLifeCycleKeeper.getItemLifecycleListener();
         if (itemLifecycleListener != null) {
             //2. create registry key
-            final FlowRegistryKey flowRegKey = FlowRegistryKeyFactory.create(flowRemovedNotification);
+            final FlowRegistryKey flowRegKey = FlowRegistryKeyFactory.create(getDeviceInfo().getVersion(), flowRemovedNotification);
             //3. lookup flowId
-            final FlowDescriptor flowDescriptor = deviceFlowRegistry.retrieveIdForFlow(flowRegKey);
+            final FlowDescriptor flowDescriptor = deviceFlowRegistry.retrieveDescriptor(flowRegKey);
             //4. if flowId present:
             if (flowDescriptor != null) {
                 // a) construct flow path
@@ -346,6 +349,28 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
         }
     }
 
+    @Override
+    public void sendNodeAddedNotification() {
+        if (!isAddNotificationSent) {
+            isAddNotificationSent = true;
+            NodeUpdatedBuilder builder = new NodeUpdatedBuilder();
+            builder.setId(getDeviceInfo().getNodeId());
+            builder.setNodeRef(new NodeRef(getDeviceInfo().getNodeInstanceIdentifier()));
+            LOG.debug("Publishing node added notification for {}", builder.build());
+            notificationPublishService.offerNotification(builder.build());
+        }
+    }
+
+    @Override
+    public void sendNodeRemovedNotification() {
+        NodeRemovedBuilder builder = new NodeRemovedBuilder();
+        builder.setNodeRef(new NodeRef(getDeviceInfo().getNodeInstanceIdentifier()));
+        LOG.debug("Publishing node removed notification for {}", builder.build());
+        if (notificationPublishService != null) {
+          notificationPublishService.offerNotification(builder.build());
+        }
+    }
+
     @Override
     public void processPortStatusMessage(final PortStatusMessage portStatus) {
         messageSpy.spyMessage(portStatus.getImplementedInterface(), MessageSpy.STATISTIC_GROUP.FROM_SWITCH_PUBLISHED_SUCCESS);
@@ -614,51 +639,25 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
     }
 
     @Override
-    public ListenableFuture<Void> stopClusterServices(boolean connectionInterrupted) {
+    public ListenableFuture<Void> stopClusterServices() {
         final ListenableFuture<Void> deactivateTxManagerFuture = initialized
                 ? transactionChainManager.deactivateTransactionManager()
                 : Futures.immediateFuture(null);
 
+        final boolean connectionInterrupted =
+                this.getPrimaryConnectionContext()
+                        .getConnectionState()
+                        .equals(ConnectionContext.CONNECTION_STATE.RIP);
         if (!connectionInterrupted) {
-            final ListenableFuture<Void> makeSlaveFuture = Futures.transform(makeDeviceSlave(), new Function<RpcResult<SetRoleOutput>, Void>() {
-                @Nullable
-                @Override
-                public Void apply(@Nullable RpcResult<SetRoleOutput> setRoleOutputRpcResult) {
-                    return null;
-                }
-            });
-
-            Futures.addCallback(makeSlaveFuture, new FutureCallback<Void>() {
-                @Override
-                public void onSuccess(@Nullable Void aVoid) {
-                    if (LOG.isDebugEnabled()) {
-                        LOG.debug("Role SLAVE was successfully propagated on device, node {}", deviceInfo.getLOGValue());
-                    }
-                }
-
-                @Override
-                public void onFailure(final Throwable throwable) {
-                    LOG.warn("Was not able to set role SLAVE to device on node {} ", deviceInfo.getLOGValue());
-                    LOG.trace("Error occurred on device role setting, probably connection loss: ", throwable);
-                }
-            });
-
-            return Futures.transform(deactivateTxManagerFuture, new AsyncFunction<Void, Void>() {
-                @Override
-                public ListenableFuture<Void> apply(Void aVoid) throws Exception {
-                    // Add fallback to remove device from operational DS if setting slave fails
-                    return Futures.withFallback(makeSlaveFuture, t ->
-                            myManager.removeDeviceFromOperationalDS(deviceInfo));
-                }
-            });
-        } else {
-            return Futures.transform(deactivateTxManagerFuture, new AsyncFunction<Void, Void>() {
-                @Override
-                public ListenableFuture<Void> apply(Void aVoid) throws Exception {
-                    return myManager.removeDeviceFromOperationalDS(deviceInfo);
-                }
-            });
+            LOG.info("This controller instance is now acting as a non-owner for node {}", deviceInfo.getLOGValue());
         }
+
+        return deactivateTxManagerFuture;
+    }
+
+    @Override
+    public void cleanupDeviceData() {
+        myManager.removeDeviceFromOperationalDS(deviceInfo);
     }
 
     @Override
@@ -680,6 +679,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
         } else {
             this.state = CONTEXT_STATE.TERMINATION;
         }
+        sendNodeRemovedNotification();
     }
 
     @Override
@@ -745,7 +745,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
                 LOG.debug("Transaction chain manager for node {} created", deviceInfo.getLOGValue());
             }
             this.transactionChainManager = new TransactionChainManager(dataBroker, deviceInfo);
-            this.deviceFlowRegistry = new DeviceFlowRegistryImpl(dataBroker, deviceInfo.getNodeInstanceIdentifier());
+            this.deviceFlowRegistry = new DeviceFlowRegistryImpl(deviceInfo.getVersion(), dataBroker, deviceInfo.getNodeInstanceIdentifier());
             this.deviceGroupRegistry = new DeviceGroupRegistryImpl();
             this.deviceMeterRegistry = new DeviceMeterRegistryImpl();
             this.initialized = true;
@@ -803,6 +803,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
             if (LOG.isDebugEnabled()) {
                 LOG.debug("Role MASTER was successfully set on device, node {}", deviceInfo.getLOGValue());
             }
+            sendNodeAddedNotification();
         }
 
         @Override
index d88cb1c359489f4ceb7f40a977c29bd5411f1c0f..0f3d5f3ef1d866fa449e0f43df9d0ab5bdf70758 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.openflowplugin.impl.device;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
+import com.google.common.base.Verify;
 import com.google.common.collect.Iterators;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.FutureCallback;
@@ -16,6 +17,7 @@ import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import io.netty.util.HashedWheelTimer;
 import io.netty.util.TimerTask;
+import java.math.BigInteger;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.Objects;
@@ -31,6 +33,9 @@ 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;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
@@ -54,13 +59,18 @@ import org.opendaylight.openflowplugin.impl.connection.OutboundQueueProviderImpl
 import org.opendaylight.openflowplugin.impl.device.listener.OpenflowProtocolListenerFullImpl;
 import org.opendaylight.openflowplugin.impl.lifecycle.LifecycleServiceImpl;
 import org.opendaylight.openflowplugin.impl.services.SalRoleServiceImpl;
+import org.opendaylight.openflowplugin.impl.util.DeviceStateUtil;
 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleOutput;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -70,9 +80,11 @@ import org.slf4j.LoggerFactory;
 public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProviderKeeper {
 
     private static final Logger LOG = LoggerFactory.getLogger(DeviceManagerImpl.class);
+    private static final String SERVICE_ENTITY_TYPE = "org.opendaylight.mdsal.ServiceEntityType";
 
-    private final long globalNotificationQuota;
-    private final boolean switchFeaturesMandatory;
+    private long globalNotificationQuota;
+    private boolean switchFeaturesMandatory;
+    private final EntityOwnershipListenerRegistration eosListenerRegistration;
     private boolean isFlowRemovedNotificationOn;
     private boolean skipTableFeatures;
     private static final int SPY_RATE = 10;
@@ -84,6 +96,7 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
     private DeviceTerminationPhaseHandler deviceTerminPhaseHandler;
 
     private final ConcurrentMap<DeviceInfo, DeviceContext> deviceContexts = new ConcurrentHashMap<>();
+    private final ConcurrentMap<DeviceInfo, DeviceContext> removeddeviceContexts = new ConcurrentHashMap<>();
     private final ConcurrentMap<DeviceInfo, LifecycleService> lifecycleServices = new ConcurrentHashMap<>();
 
     private long barrierIntervalNanos;
@@ -92,24 +105,31 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
     private ExtensionConverterProvider extensionConverterProvider;
     private ScheduledThreadPoolExecutor spyPool;
     private final ClusterSingletonServiceProvider singletonServiceProvider;
+    private final EntityOwnershipService entityOwnershipService;
     private final NotificationPublishService notificationPublishService;
     private final MessageSpy messageSpy;
     private final HashedWheelTimer hashedWheelTimer;
 
     public DeviceManagerImpl(@Nonnull final DataBroker dataBroker,
-                             final long globalNotificationQuota,
-                             final boolean switchFeaturesMandatory,
-                             final long barrierInterval,
-                             final int barrierCountLimit,
                              final MessageSpy messageSpy,
-                             final boolean isFlowRemovedNotificationOn,
                              final ClusterSingletonServiceProvider singletonServiceProvider,
-                             final NotificationPublishService notificationPublishService,
+                             final EntityOwnershipService entityOwnershipService,
                              final HashedWheelTimer hashedWheelTimer,
                              final ConvertorExecutor convertorExecutor,
-                             final boolean skipTableFeatures) {
+                             final NotificationPublishService notificationPublishService) {
+
 
         this.dataBroker = dataBroker;
+        this.entityOwnershipService = entityOwnershipService;
+        this.convertorExecutor = convertorExecutor;
+        this.hashedWheelTimer = hashedWheelTimer;
+        this.spyPool = new ScheduledThreadPoolExecutor(1);
+        this.singletonServiceProvider = singletonServiceProvider;
+        this.notificationPublishService = notificationPublishService;
+        this.messageSpy = messageSpy;
+
+        this.eosListenerRegistration = Verify.verifyNotNull(entityOwnershipService.registerListener
+                (SERVICE_ENTITY_TYPE, this));
 
         /* merge empty nodes to oper DS to predict any problems with missing parent for Node */
         final WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
@@ -122,19 +142,6 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
             LOG.error("Creation of node failed.", e);
             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.singletonServiceProvider = singletonServiceProvider;
-        this.notificationPublishService = notificationPublishService;
-        this.messageSpy = messageSpy;
     }
 
 
@@ -163,14 +170,24 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
          * in {@link org.opendaylight.openflowplugin.impl.connection.org.opendaylight.openflowplugin.impl.connection.HandshakeContextImpl}
          * If context already exist we are in state closing process (connection flapping) and we should not propagate connection close
          */
-         if (deviceContexts.containsKey(deviceInfo)) {
-             DeviceContext deviceContext = deviceContexts.get(deviceInfo);
-             LOG.warn("Node {} already connected disconnecting device. Rejecting connection", deviceInfo.getLOGValue());
-             if (!deviceContext.getState().equals(OFPContext.CONTEXT_STATE.TERMINATION)) {
+         DeviceContext current = deviceContexts.get(deviceInfo);
+         if (current != null) {
+             LOG.warn("New connection received from the already connected Node {}. Disconnecting both the connection " +
+                      "to add the switch back gracefully.", deviceInfo.getLOGValue());
+             if (!current.getState().equals(OFPContext.CONTEXT_STATE.TERMINATION)) {
                  LOG.warn("Node {} context state not in TERMINATION state.",
                          connectionContext.getDeviceInfo().getLOGValue());
+                 //Lets disconnect the existing connection as well and ask switch to connect fresh.
+                 //This will re-add the node properly
+                 current.getPrimaryConnectionContext().closeConnection(true);
                  return ConnectionStatus.ALREADY_CONNECTED;
              } else {
+                 // Device context already exist with a terminated connection. Reject the connection to receive fresh
+                 // connection and properly add the device.
+                 LOG.debug("Old connection from {} is terminated but still exist in device context." +
+                         "Rejecting new connection and cleaning up the old connection.", deviceInfo.getLOGValue());
+                 deviceContexts.remove(deviceInfo);
+                 current.getPrimaryConnectionContext().closeConnection(true);
                  return ConnectionStatus.CLOSING;
              }
          }
@@ -254,6 +271,15 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
         Optional.ofNullable(spyPool).ifPresent(ScheduledThreadPoolExecutor::shutdownNow);
         spyPool = null;
 
+        if (Objects.nonNull(eosListenerRegistration)) {
+            try {
+                LOG.debug("Closing entity ownership listener");
+                eosListenerRegistration.close();
+            } catch (Exception e) {
+                LOG.debug("Failed to close entity ownership listener registration with exception",e);
+            }
+        }
+
     }
 
     @Override
@@ -293,6 +319,19 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
             return;
         }
 
+        if (connectionContext.getFeatures() != null
+                && connectionContext.getFeatures().getAuxiliaryId() != null
+                && connectionContext.getFeatures().getAuxiliaryId() > 0
+                && deviceCtx.getAuxiliaryConnectionContexts(new BigInteger(String.valueOf(
+                connectionContext.getFeatures().getAuxiliaryId().intValue()))) != null) {
+
+            LOG.debug("Node {} disconnected, but not primary connection.", connectionContext.getDeviceInfo().getLOGValue());
+            // Connection is not PrimaryConnection so try to remove from Auxiliary Connections
+            deviceCtx.removeAuxiliaryConnectionContext(connectionContext);
+            // If this is not primary connection, we should not continue disabling everything
+            return;
+        }
+
         if (deviceCtx.getState().equals(OFPContext.CONTEXT_STATE.TERMINATION)) {
             LOG.info("Device context for node {} is already is termination state, waiting for close all context", deviceInfo.getLOGValue());
             return;
@@ -300,12 +339,6 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
 
         deviceCtx.close();
 
-        if (!connectionContext.equals(deviceCtx.getPrimaryConnectionContext())) {
-            LOG.debug("Node {} disconnected, but not primary connection.", connectionContext.getDeviceInfo().getLOGValue());
-            // Connection is not PrimaryConnection so try to remove from Auxiliary Connections
-            deviceCtx.removeAuxiliaryConnectionContext(connectionContext);
-        }
-
         // TODO: Auxiliary connections supported ?
         // Device is disconnected and so we need to close TxManager
         final ListenableFuture<Void> future = deviceCtx.shuttingDownDataStoreTransactions();
@@ -368,28 +401,44 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
 
     @Override
     public CheckedFuture<Void, TransactionCommitFailedException> removeDeviceFromOperationalDS(final DeviceInfo deviceInfo) {
+        return removeDeviceFromOperationalDS(deviceInfo.getNodeInstanceIdentifier(), deviceInfo.getLOGValue());
+    }
+
+    @Override
+    public void setGlobalNotificationQuota(final long globalNotificationQuota) {
+        this.globalNotificationQuota = globalNotificationQuota;
+    }
+
+    @Override
+    public void setSwitchFeaturesMandatory(final boolean switchFeaturesMandatory) {
+        this.switchFeaturesMandatory = switchFeaturesMandatory;
+    }
+
+    private CheckedFuture<Void, TransactionCommitFailedException> removeDeviceFromOperationalDS(
+            final KeyedInstanceIdentifier<Node, NodeKey> nodeIid, final String nodeName) {
+        Preconditions.checkNotNull(nodeIid, "Node IID must not be null");
+
         final WriteTransaction delWtx = dataBroker.newWriteOnlyTransaction();
-        delWtx.delete(LogicalDatastoreType.OPERATIONAL, deviceInfo.getNodeInstanceIdentifier());
+        delWtx.delete(LogicalDatastoreType.OPERATIONAL, nodeIid);
         final CheckedFuture<Void, TransactionCommitFailedException> delFuture = delWtx.submit();
 
         Futures.addCallback(delFuture, new FutureCallback<Void>() {
             @Override
             public void onSuccess(final Void result) {
                 if (LOG.isDebugEnabled()) {
-                    LOG.debug("Delete Node {} was successful", deviceInfo.getLOGValue());
+                    LOG.debug("Delete Node {} was successful", nodeName);
                 }
             }
 
             @Override
             public void onFailure(@Nonnull final Throwable t) {
-                LOG.warn("Delete node {} failed with exception {}", deviceInfo.getLOGValue(), t);
+                LOG.warn("Delete node {} failed with exception {}", nodeName, t);
             }
         });
 
         return delFuture;
     }
 
-
     private void addCallbackToDeviceInitializeToSlave(final DeviceInfo deviceInfo, final DeviceContext deviceContext, final LifecycleService lifecycleService) {
         Futures.addCallback(deviceContext.makeDeviceSlave(), new FutureCallback<RpcResult<SetRoleOutput>>() {
             @Override
@@ -397,6 +446,7 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
                 if (LOG.isDebugEnabled()) {
                     LOG.debug("Role SLAVE was successfully propagated on device, node {}", deviceInfo.getLOGValue());
                 }
+                deviceContext.sendNodeAddedNotification();
             }
 
             @Override
@@ -426,10 +476,38 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
     }
 
     public void onDeviceRemoved(DeviceInfo deviceInfo) {
-        deviceContexts.remove(deviceInfo);
+        DeviceContext deviceContext = deviceContexts.remove(deviceInfo);
+        removeddeviceContexts.putIfAbsent(deviceInfo, deviceContext);
         LOG.debug("Device context removed for node {}", deviceInfo.getLOGValue());
 
         lifecycleServices.remove(deviceInfo);
         LOG.debug("Lifecycle service removed for node {}", deviceInfo.getLOGValue());
     }
+
+    @Override
+    public void ownershipChanged(EntityOwnershipChange entityOwnershipChange) {
+        if (!entityOwnershipChange.hasOwner()) {
+            final YangInstanceIdentifier yii = entityOwnershipChange.getEntity().getId();
+            final YangInstanceIdentifier.NodeIdentifierWithPredicates niiwp =
+                    (YangInstanceIdentifier.NodeIdentifierWithPredicates) yii.getLastPathArgument();
+            String entityName =  niiwp.getKeyValues().values().iterator().next().toString();
+            LOG.info("Entity ownership changed for device : {} : {}", entityName, entityOwnershipChange);
+
+            if (entityName != null ){
+                if (!removeddeviceContexts.isEmpty()) {
+                    for (DeviceInfo device : removeddeviceContexts.keySet()) {
+                        if (device.getNodeId().getValue().equals(entityName)) {
+                            LOG.info("Cleaning up operational data of the node : {}", entityName);
+                            // No owner present for the entity, clean up the data and remove it from
+                            // removed context.
+                            removeddeviceContexts.remove(device).cleanupDeviceData();
+                            return;
+                        }
+                    }
+                }
+                removeDeviceFromOperationalDS(DeviceStateUtil.createNodeInstanceIdentifier(new NodeId(entityName)),
+                        entityName);
+            }
+        }
+    }
 }
index da4bdae04e427d42efd4ab7eebbf44e3b0b27e7d..aded9b26d9ee3d76f6222f9ae172934ddf872885 100644 (file)
@@ -64,7 +64,7 @@ class TransactionChainManager implements TransactionChainListener, AutoCloseable
     @GuardedBy("txLock")
     private ListenableFuture<Void> lastSubmittedFuture;
 
-    private boolean initCommit;
+    private volatile boolean initCommit;
 
     @GuardedBy("txLock")
     private TransactionChainManagerStatus transactionChainManagerStatus = TransactionChainManagerStatus.SLEEPING;
@@ -73,7 +73,6 @@ class TransactionChainManager implements TransactionChainListener, AutoCloseable
                             @Nonnull final DeviceInfo deviceInfo) {
         this.dataBroker = dataBroker;
         this.nodeId = deviceInfo.getNodeInstanceIdentifier().getKey().getId().getValue();
-        this.transactionChainManagerStatus = TransactionChainManagerStatus.SLEEPING;
         this.lastSubmittedFuture = Futures.immediateFuture(null);
     }
 
@@ -103,7 +102,7 @@ class TransactionChainManager implements TransactionChainListener, AutoCloseable
             LOG.debug("activateTransactionManager for node {} transaction submit is set to {}", this.nodeId, submitIsEnabled);
         }
         synchronized (txLock) {
-            if (TransactionChainManagerStatus.SLEEPING.equals(transactionChainManagerStatus)) {
+            if (TransactionChainManagerStatus.SLEEPING == transactionChainManagerStatus) {
                 Preconditions.checkState(txChainFactory == null, "TxChainFactory survive last close.");
                 Preconditions.checkState(wTx == null, "We have some unexpected WriteTransaction.");
                 this.transactionChainManagerStatus = TransactionChainManagerStatus.WORKING;
@@ -126,7 +125,7 @@ class TransactionChainManager implements TransactionChainListener, AutoCloseable
         }
         final ListenableFuture<Void> future;
         synchronized (txLock) {
-            if (TransactionChainManagerStatus.WORKING.equals(transactionChainManagerStatus)) {
+            if (TransactionChainManagerStatus.WORKING == transactionChainManagerStatus) {
                 transactionChainManagerStatus = TransactionChainManagerStatus.SLEEPING;
                 future = txChainShuttingDown();
                 Preconditions.checkState(wTx == null, "We have some unexpected WriteTransaction.");
@@ -168,15 +167,16 @@ class TransactionChainManager implements TransactionChainListener, AutoCloseable
                 }
                 return true;
             }
-            Preconditions.checkState(TransactionChainManagerStatus.WORKING.equals(transactionChainManagerStatus),
+            Preconditions.checkState(TransactionChainManagerStatus.WORKING == transactionChainManagerStatus,
                     "we have here Uncompleted Transaction for node {} and we are not MASTER", this.nodeId);
             final CheckedFuture<Void, TransactionCommitFailedException> submitFuture = wTx.submit();
+            lastSubmittedFuture = submitFuture;
+            wTx = null;
+
             Futures.addCallback(submitFuture, new FutureCallback<Void>() {
                 @Override
                 public void onSuccess(final Void result) {
-                    if (initCommit) {
-                        initCommit = false;
-                    }
+                    initCommit = false;
                 }
 
                 @Override
@@ -192,27 +192,24 @@ class TransactionChainManager implements TransactionChainListener, AutoCloseable
                         }
                     }
                     if (initCommit) {
-                        wTx = null;
                         Optional.ofNullable(lifecycleService).ifPresent(LifecycleService::closeConnection);
                     }
                 }
             });
-            lastSubmittedFuture = submitFuture;
-            wTx = null;
         }
         return true;
     }
 
     <T extends DataObject> void addDeleteOperationTotTxChain(final LogicalDatastoreType store,
                                                              final InstanceIdentifier<T> path){
-        final WriteTransaction writeTx = getTransactionSafely();
-        if (Objects.nonNull(writeTx)) {
-            writeTx.delete(store, path);
-        } else {
-            if (LOG.isDebugEnabled()) {
+        synchronized (txLock) {
+            ensureTransaction();
+            if (wTx == null) {
                 LOG.debug("WriteTx is null for node {}. Delete {} was not realized.", this.nodeId, path);
+                throw new TransactionChainClosedException(CANNOT_WRITE_INTO_TRANSACTION);
             }
-            throw new TransactionChainClosedException(CANNOT_WRITE_INTO_TRANSACTION);
+
+            wTx.delete(store, path);
         }
     }
 
@@ -220,23 +217,26 @@ class TransactionChainManager implements TransactionChainListener, AutoCloseable
                                                    final InstanceIdentifier<T> path,
                                                    final T data,
                                                    final boolean createParents){
-        final WriteTransaction writeTx = getTransactionSafely();
-        if (Objects.nonNull(writeTx)) {
-            writeTx.put(store, path, data, createParents);
-        } else {
-            if (LOG.isDebugEnabled()) {
+        synchronized (txLock) {
+            ensureTransaction();
+            if (wTx == null) {
                 LOG.debug("WriteTx is null for node {}. Write data for {} was not realized.", this.nodeId, path);
+                throw new TransactionChainClosedException(CANNOT_WRITE_INTO_TRANSACTION);
             }
-            throw new TransactionChainClosedException(CANNOT_WRITE_INTO_TRANSACTION);
+
+            wTx.put(store, path, data, createParents);
         }
     }
 
     @Override
     public void onTransactionChainFailed(final TransactionChain<?, ?> chain,
                                          final AsyncTransaction<?, ?> transaction, final Throwable cause) {
-        if (transactionChainManagerStatus.equals(TransactionChainManagerStatus.WORKING)) {
-            LOG.warn("Transaction chain failed, recreating chain due to ", cause);
-            recreateTxChain();
+        synchronized (txLock) {
+            if (TransactionChainManagerStatus.WORKING == transactionChainManagerStatus) {
+                LOG.warn("Transaction chain failed, recreating chain due to ", cause);
+                createTxChain();
+                wTx = null;
+            }
         }
     }
 
@@ -245,21 +245,13 @@ class TransactionChainManager implements TransactionChainListener, AutoCloseable
         // NOOP
     }
 
-    private void recreateTxChain() {
-        synchronized (txLock) {
-            createTxChain();
-            wTx = null;
-        }
-    }
-
+    @GuardedBy("txLock")
     @Nullable
-    private WriteTransaction getTransactionSafely() {
-            synchronized (txLock) {
-                if (wTx == null && TransactionChainManagerStatus.WORKING.equals(transactionChainManagerStatus)) {
-                    Optional.ofNullable(txChainFactory).ifPresent(bindingTransactionChain -> wTx = txChainFactory.newWriteOnlyTransaction());
-                }
-            }
-        return wTx;
+    private void ensureTransaction() {
+        if (wTx == null && TransactionChainManagerStatus.WORKING == transactionChainManagerStatus
+            && txChainFactory != null) {
+                wTx = txChainFactory.newWriteOnlyTransaction();
+        }
     }
 
     @VisibleForTesting
@@ -274,12 +266,10 @@ class TransactionChainManager implements TransactionChainListener, AutoCloseable
         if (LOG.isDebugEnabled()) {
             LOG.debug("TxManager is going SHUTTING_DOWN for node {}", this.nodeId);
         }
-        ListenableFuture<Void> future;
         synchronized (txLock) {
             this.transactionChainManagerStatus = TransactionChainManagerStatus.SHUTTING_DOWN;
-            future = txChainShuttingDown();
+            return txChainShuttingDown();
         }
-        return future;
     }
 
     @GuardedBy("txLock")
index 7522fe54b08f6c1d8339a449e3d4cb2b3dbe3e95..c4ac4c7d6335e8b4f8d3f01010b5ad18e56fc1aa 100644 (file)
@@ -18,6 +18,7 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Objects;
 import javax.annotation.Nullable;
+
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
 import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
@@ -35,15 +36,15 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class LifecycleServiceImpl implements LifecycleService {
-
     private static final Logger LOG = LoggerFactory.getLogger(LifecycleServiceImpl.class);
+
+    private final List<DeviceRemovedHandler> deviceRemovedHandlers = new ArrayList<>();
+    private volatile CONTEXT_STATE state = CONTEXT_STATE.INITIALIZATION;
     private DeviceContext deviceContext;
     private RpcContext rpcContext;
     private StatisticsContext statContext;
     private ClusterSingletonServiceRegistration registration;
     private ClusterInitializationPhaseHandler clusterInitializationPhaseHandler;
-    private final List<DeviceRemovedHandler> deviceRemovedHandlers = new ArrayList<>();
-    private volatile CONTEXT_STATE state = CONTEXT_STATE.INITIALIZATION;
 
 
     @Override
@@ -57,17 +58,12 @@ public class LifecycleServiceImpl implements LifecycleService {
 
     @Override
     public ListenableFuture<Void> closeServiceInstance() {
-        final boolean connectionInterrupted =
-                this.deviceContext
-                        .getPrimaryConnectionContext()
-                        .getConnectionState()
-                        .equals(ConnectionContext.CONNECTION_STATE.RIP);
 
         // Chain all jobs that will stop our services
         final List<ListenableFuture<Void>> futureList = new ArrayList<>();
-        futureList.add(statContext.stopClusterServices(connectionInterrupted));
-        futureList.add(rpcContext.stopClusterServices(connectionInterrupted));
-        futureList.add(deviceContext.stopClusterServices(connectionInterrupted));
+        futureList.add(statContext.stopClusterServices());
+        futureList.add(rpcContext.stopClusterServices());
+        futureList.add(deviceContext.stopClusterServices());
 
         return Futures.transform(Futures.successfulAsList(futureList), new Function<List<Void>, Void>() {
             @Nullable
@@ -114,10 +110,10 @@ public class LifecycleServiceImpl implements LifecycleService {
             // If we are still registered and we are not already closing, then close the registration
             if (Objects.nonNull(registration)) {
                 try {
-                    LOG.debug("Closing clustering MASTER services for node {}", getDeviceInfo().getLOGValue());
+                    LOG.debug("Closing clustering singleton services for node {}", getDeviceInfo().getLOGValue());
                     registration.close();
                 } catch (Exception e) {
-                    LOG.debug("Failed to close clustering MASTER services for node {} with exception: ",
+                    LOG.debug("Failed to close clustering singleton services for node {} with exception: ",
                             getDeviceInfo().getLOGValue(), e);
                 }
             }
@@ -126,7 +122,7 @@ public class LifecycleServiceImpl implements LifecycleService {
 
     @Override
     public void registerService(final ClusterSingletonServiceProvider singletonServiceProvider) {
-        LOG.debug("Registered clustering MASTER services for node {}", getDeviceInfo().getLOGValue());
+        LOG.debug("Registered clustering singleton services for node {}", getDeviceInfo().getLOGValue());
 
         // lifecycle service -> device context -> statistics context -> rpc context -> role context -> lifecycle service
         this.clusterInitializationPhaseHandler = deviceContext;
@@ -139,7 +135,7 @@ public class LifecycleServiceImpl implements LifecycleService {
         // Register cluster singleton service
         try {
             this.registration = Verify.verifyNotNull(singletonServiceProvider.registerClusterSingletonService(this));
-            LOG.info("Registered clustering MASTER services for node {}", getDeviceInfo().getLOGValue());
+            LOG.info("Registered clustering singleton services for node {}", getDeviceInfo().getLOGValue());
         } catch (Exception e) {
             LOG.warn("Failed to register cluster singleton service for node {}, with exception: {}", getDeviceInfo(), e);
             closeConnection();
index 01f7178e2f3cb656f92dd08ec4d3e0c55ab64a0d..5009323f93c76aa89aef1a84634578c7d5cdaa3b 100644 (file)
@@ -18,13 +18,14 @@ import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Consumer;
+import javax.annotation.Nonnull;
+import javax.annotation.concurrent.ThreadSafe;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
@@ -42,6 +43,7 @@ import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+@ThreadSafe
 public class DeviceFlowRegistryImpl implements DeviceFlowRegistry {
     private static final Logger LOG = LoggerFactory.getLogger(DeviceFlowRegistryImpl.class);
     private static final String ALIEN_SYSTEM_FLOW_ID = "#UF$TABLE*";
@@ -51,40 +53,40 @@ public class DeviceFlowRegistryImpl implements DeviceFlowRegistry {
     private final DataBroker dataBroker;
     private final KeyedInstanceIdentifier<Node, NodeKey> instanceIdentifier;
     private final List<ListenableFuture<List<Optional<FlowCapableNode>>>> lastFillFutures = new ArrayList<>();
+    private final Consumer<Flow> flowConsumer;
 
-    // Specifies what to do with flow read from datastore
-    private final Consumer<Flow> flowConsumer = flow -> {
-        // Create flow registry key from flow
-        final FlowRegistryKey key = FlowRegistryKeyFactory.create(flow);
-
-        // Now, we will update the registry, but we will also try to prevent duplicate entries
-        if (!flowRegistry.containsKey(key)) {
-            LOG.trace("Found flow with table ID : {} and flow ID : {}", flow.getTableId(), flow.getId().getValue());
-            final FlowDescriptor descriptor = FlowDescriptorFactory.create(flow.getTableId(), flow.getId());
-            store(key, descriptor);
-        }
-    };
-
-    public DeviceFlowRegistryImpl(final DataBroker dataBroker, final KeyedInstanceIdentifier<Node, NodeKey> instanceIdentifier) {
+    public DeviceFlowRegistryImpl(final short version, final DataBroker dataBroker, final KeyedInstanceIdentifier<Node, NodeKey> instanceIdentifier) {
         this.dataBroker = dataBroker;
         this.instanceIdentifier = instanceIdentifier;
+
+        // Specifies what to do with flow read from data store
+        flowConsumer = flow -> {
+            final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(version, flow);
+
+            if (!flowRegistry.containsKey(flowRegistryKey)) {
+                // Now, we will update the registry
+                storeDescriptor(flowRegistryKey, FlowDescriptorFactory.create(flow.getTableId(), flow.getId()));
+            }
+        };
     }
 
     @Override
     public ListenableFuture<List<Optional<FlowCapableNode>>> fill() {
-        LOG.debug("Filling flow registry with flows for node: {}", instanceIdentifier.getKey().getId().getValue());
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Filling flow registry with flows for node: {}", instanceIdentifier.getKey().getId().getValue());
+        }
 
         // Prepare path for read transaction
         // TODO: Read only Tables, and not entire FlowCapableNode (fix Yang model)
         final InstanceIdentifier<FlowCapableNode> path = instanceIdentifier.augmentation(FlowCapableNode.class);
 
         // First, try to fill registry with flows from DS/Configuration
-        CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> configFuture = fillFromDatastore(LogicalDatastoreType.CONFIGURATION, path);
+        final CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> configFuture = fillFromDatastore(LogicalDatastoreType.CONFIGURATION, path);
 
         // Now, try to fill registry with flows from DS/Operational
         // in case of cluster fail over, when clients are not using DS/Configuration
         // for adding flows, but only RPCs
-        CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> operationalFuture = fillFromDatastore(LogicalDatastoreType.OPERATIONAL, path);
+        final CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> operationalFuture = fillFromDatastore(LogicalDatastoreType.OPERATIONAL, path);
 
         // And at last, chain and return futures created above.
         // Also, cache this future, so call to DeviceFlowRegistry.close() will be able
@@ -143,84 +145,89 @@ public class DeviceFlowRegistryImpl implements DeviceFlowRegistry {
     }
 
     @Override
-    public FlowDescriptor retrieveIdForFlow(final FlowRegistryKey flowRegistryKey) {
-        LOG.trace("Retrieving flow descriptor for flow hash : {}", flowRegistryKey.hashCode());
-        FlowDescriptor flowDescriptor = flowRegistry.get(flowRegistryKey);
-        // Get FlowDescriptor from flow registry
-        if(flowDescriptor == null){
-            if (LOG.isTraceEnabled()) {
-                LOG.trace("Failed to retrieve flow descriptor for flow hash : {}, trying with custom equals method", flowRegistryKey.hashCode());
-            }
-            for(Map.Entry<FlowRegistryKey, FlowDescriptor> fd : flowRegistry.entrySet()) {
-                if (fd.getKey().equals(flowRegistryKey)) {
-                    flowDescriptor = fd.getValue();
-                    break;
-                }
-            }
+    public FlowDescriptor retrieveDescriptor(@Nonnull final FlowRegistryKey flowRegistryKey) {
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Retrieving flow descriptor for flow hash : {}", flowRegistryKey.hashCode());
         }
-        return flowDescriptor;
+
+        return flowRegistry.get(flowRegistryKey);
     }
 
     @Override
-    public void store(final FlowRegistryKey flowRegistryKey, final FlowDescriptor flowDescriptor) {
+    public void storeDescriptor(@Nonnull final FlowRegistryKey flowRegistryKey,
+                                @Nonnull final FlowDescriptor flowDescriptor) {
         try {
-          LOG.trace("Storing flowDescriptor with table ID : {} and flow ID : {} for flow hash : {}",
-                    flowDescriptor.getTableKey().getId(), flowDescriptor.getFlowId().getValue(), flowRegistryKey.hashCode());
-          flowRegistry.put(flowRegistryKey, flowDescriptor);
+            if (LOG.isTraceEnabled()) {
+                LOG.trace("Storing flowDescriptor with table ID : {} and flow ID : {} for flow hash : {}",
+                        flowDescriptor.getTableKey().getId(), flowDescriptor.getFlowId().getValue(), flowRegistryKey.hashCode());
+            }
+
+            flowRegistry.put(flowRegistryKey, flowDescriptor);
         } catch (IllegalArgumentException ex) {
-          LOG.warn("Flow with flowId {} already exists in table {}", flowDescriptor.getFlowId().getValue(),
-                    flowDescriptor.getTableKey().getId());
-          final FlowId newFlowId = createAlienFlowId(flowDescriptor.getTableKey().getId());
-          final FlowDescriptor newFlowDescriptor = FlowDescriptorFactory.
-            create(flowDescriptor.getTableKey().getId(), newFlowId);
-          flowRegistry.put(flowRegistryKey, newFlowDescriptor);
+            if (LOG.isWarnEnabled()) {
+                LOG.warn("Flow with flow ID {} already exists in table {}, generating alien flow ID", flowDescriptor.getFlowId().getValue(),
+                        flowDescriptor.getTableKey().getId());
+            }
+
+            // We are trying to store new flow to flow registry, but we already have different flow with same flow ID
+            // stored in registry, so we need to create alien ID for this new flow here.
+            flowRegistry.put(
+                    flowRegistryKey,
+                    FlowDescriptorFactory.create(
+                            flowDescriptor.getTableKey().getId(),
+                            createAlienFlowId(flowDescriptor.getTableKey().getId())));
         }
     }
 
     @Override
-    public void update(final FlowRegistryKey newFlowRegistryKey, final FlowDescriptor flowDescriptor) {
-        LOG.trace("Updating the entry with hash: {}", newFlowRegistryKey.hashCode());
-        flowRegistry.forcePut(newFlowRegistryKey, flowDescriptor);
+    public void store(final FlowRegistryKey flowRegistryKey) {
+        if (Objects.isNull(retrieveDescriptor(flowRegistryKey))) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Flow descriptor for flow hash : {} not found, generating alien flow ID", flowRegistryKey.hashCode());
+            }
+
+            // We do not found flow in flow registry, that means it do not have any ID already assigned, so we need
+            // to generate new alien flow ID here.
+            storeDescriptor(
+                    flowRegistryKey,
+                    FlowDescriptorFactory.create(
+                            flowRegistryKey.getTableId(),
+                            createAlienFlowId(flowRegistryKey.getTableId())));
+        }
     }
 
     @Override
-    public FlowId storeIfNecessary(final FlowRegistryKey flowRegistryKey) {
-        LOG.trace("Trying to retrieve flow ID for flow hash : {}", flowRegistryKey.hashCode());
-
-        // First, try to get FlowDescriptor from flow registry
-        FlowDescriptor flowDescriptor = retrieveIdForFlow(flowRegistryKey);
-
-        // We was not able to retrieve FlowDescriptor, so we will at least try to generate it
-        if (flowDescriptor == null) {
-            LOG.trace("Flow descriptor for flow hash : {} not found, generating alien flow ID", flowRegistryKey.hashCode());
-            final short tableId = flowRegistryKey.getTableId();
-            final FlowId alienFlowId = createAlienFlowId(tableId);
-            flowDescriptor = FlowDescriptorFactory.create(tableId, alienFlowId);
-
-            // Finally we got flowDescriptor, so now we will store it to registry,
-            // so next time we won't need to generate it again
-            store(flowRegistryKey, flowDescriptor);
+    public void addMark(final FlowRegistryKey flowRegistryKey) {
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Removing flow descriptor for flow hash : {}", flowRegistryKey.hashCode());
         }
 
-        return flowDescriptor.getFlowId();
+        flowRegistry.remove(flowRegistryKey);
     }
 
     @Override
-    public void removeDescriptor(final FlowRegistryKey flowRegistryKey) {
-        LOG.trace("Removing flow descriptor for flow hash : {}", flowRegistryKey.hashCode());
-        flowRegistry.remove(flowRegistryKey);
+    public void processMarks() {
+        // Do nothing
     }
 
     @Override
-    public Map<FlowRegistryKey, FlowDescriptor> getAllFlowDescriptors() {
-        return Collections.unmodifiableMap(flowRegistry);
+    public void forEach(final Consumer<FlowRegistryKey> consumer) {
+        synchronized (flowRegistry) {
+            flowRegistry.keySet().forEach(consumer);
+        }
+    }
+
+    @Override
+    public int size() {
+        return flowRegistry.size();
     }
 
     @Override
     public void close() {
         final Iterator<ListenableFuture<List<Optional<FlowCapableNode>>>> iterator = lastFillFutures.iterator();
 
-        while(iterator.hasNext()) {
+        // We need to force interrupt and clear all running futures that are trying to read flow IDs from data store
+        while (iterator.hasNext()) {
             final ListenableFuture<List<Optional<FlowCapableNode>>> next = iterator.next();
             boolean success = next.cancel(true);
             LOG.trace("Cancelling filling flow registry with flows job {} with result: {}", next, success);
@@ -233,6 +240,12 @@ public class DeviceFlowRegistryImpl implements DeviceFlowRegistry {
     @VisibleForTesting
     static FlowId createAlienFlowId(final short tableId) {
         final String alienId = ALIEN_SYSTEM_FLOW_ID + tableId + '-' + UNACCOUNTED_FLOWS_COUNTER.incrementAndGet();
+        LOG.debug("Created alien flow id {} for table id {}", alienId, tableId);
         return new FlowId(alienId);
     }
-}
\ No newline at end of file
+
+    @VisibleForTesting
+    Map<FlowRegistryKey, FlowDescriptor> getAllFlowDescriptors() {
+        return flowRegistry;
+    }
+}
index 68ad18ee5e6fe2fafba2cece66dbe0db8899bd4d..2638aaeee237c3479e2fa7ef64859fe8c2534fac 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.openflowplugin.impl.registry.flow;
 
 import com.google.common.base.Objects;
 import com.google.common.base.Preconditions;
+import javax.annotation.Nonnull;
 import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowDescriptor;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
@@ -19,13 +20,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.ta
  * Created by Martin Bobak &lt;mbobak@cisco.com&gt; on 9.4.2015.
  */
 public class FlowDescriptorFactory {
+
     private FlowDescriptorFactory() {
         // Hide implicit constructor
     }
 
-    public static FlowDescriptor create(final short tableId, final FlowId fLowId) {
-        final TableKey tableKey = new TableKey(tableId);
-        return new FlowDescriptorDto(tableKey, fLowId);
+    @Nonnull
+    public static FlowDescriptor create(final short tableId, @Nonnull final FlowId flowId) {
+        return new FlowDescriptorDto(
+                new TableKey(tableId),
+                Preconditions.checkNotNull(flowId));
     }
 
     private static final class FlowDescriptorDto implements FlowDescriptor {
@@ -33,9 +37,7 @@ public class FlowDescriptorFactory {
         private final FlowId flowId;
         private final TableKey tableKey;
 
-        private FlowDescriptorDto(final TableKey tableKey, final FlowId flowId) {
-            Preconditions.checkNotNull(tableKey);
-            Preconditions.checkNotNull(flowId);
+        private FlowDescriptorDto(@Nonnull final TableKey tableKey, @Nonnull final FlowId flowId) {
             this.flowId = flowId;
             this.tableKey = tableKey;
         }
@@ -64,4 +66,5 @@ public class FlowDescriptorFactory {
             return tableKey;
         }
     }
+
 }
\ No newline at end of file
index 889e30a2c21f606852e154ce7ca14394973ee74b..8febbd1f9fa463be67e73568bbd29dd65ffc0dc1 100644 (file)
@@ -11,24 +11,27 @@ package org.opendaylight.openflowplugin.impl.registry.flow;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Preconditions;
 import java.math.BigInteger;
+import javax.annotation.Nonnull;
 import org.opendaylight.openflowplugin.api.OFConstants;
 import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey;
-import org.opendaylight.openflowplugin.impl.util.MatchComparatorFactory;
+import org.opendaylight.openflowplugin.impl.util.MatchNormalizationUtil;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
 
-/**
- * Created by Martin Bobak &lt;mbobak@cisco.com&gt; on 8.4.2015.
- */
 public class FlowRegistryKeyFactory {
 
     private FlowRegistryKeyFactory() {
         // Hide implicit constructor
     }
 
-    public static FlowRegistryKey create(final Flow flow) {
-        return new FlowRegistryKeyDto(flow);
+    @Nonnull
+    public static FlowRegistryKey create(final short version, @Nonnull final Flow flow) {
+        //TODO: mandatory flow input values (or default values) should be specified via yang model
+        final short tableId = Preconditions.checkNotNull(flow.getTableId(), "flow tableId must not be null");
+        final int priority = MoreObjects.firstNonNull(flow.getPriority(), OFConstants.DEFAULT_FLOW_PRIORITY);
+        final BigInteger cookie = MoreObjects.firstNonNull(flow.getCookie(), OFConstants.DEFAULT_FLOW_COOKIE).getValue();
+        final Match match = MatchNormalizationUtil.normalizeMatch(MoreObjects.firstNonNull(flow.getMatch(), OFConstants.EMPTY_MATCH), version);
+        return new FlowRegistryKeyDto(tableId, priority, cookie, match);
     }
 
     private static final class FlowRegistryKeyDto implements FlowRegistryKey {
@@ -37,12 +40,14 @@ public class FlowRegistryKeyFactory {
         private final BigInteger cookie;
         private final Match match;
 
-        private FlowRegistryKeyDto(final Flow flow) {
-            //TODO: mandatory flow input values (or default values) should be specified via yang model
-            tableId = Preconditions.checkNotNull(flow.getTableId(), "flow tableId must not be null");
-            priority = MoreObjects.firstNonNull(flow.getPriority(), OFConstants.DEFAULT_FLOW_PRIORITY);
-            match = MoreObjects.firstNonNull(flow.getMatch(), OFConstants.EMPTY_MATCH);
-            cookie = MoreObjects.firstNonNull(flow.getCookie(), OFConstants.DEFAULT_FLOW_COOKIE).getValue();
+        private FlowRegistryKeyDto(final short tableId,
+                                   final int priority,
+                                   @Nonnull final BigInteger cookie,
+                                   @Nonnull final Match match) {
+            this.tableId = tableId;
+            this.priority = priority;
+            this.cookie = cookie;
+            this.match = match;
         }
 
         @Override
@@ -60,7 +65,7 @@ public class FlowRegistryKeyFactory {
             return getPriority() == that.getPriority() &&
                     getTableId() == that.getTableId() &&
                     getCookie().equals(that.getCookie()) &&
-                    MatchComparatorFactory.createMatch().areObjectsEqual(getMatch(), that.getMatch());
+                    getMatch().equals(that.getMatch());
         }
 
         @Override
@@ -92,4 +97,5 @@ public class FlowRegistryKeyFactory {
             return match;
         }
     }
+
 }
index 1698929974f1474a0c248be6a816618aa15ded7f..a3da37b9dfd5e131638cebfd668be06bfefd1c89 100644 (file)
@@ -8,49 +8,57 @@
 
 package org.opendaylight.openflowplugin.impl.registry.group;
 
+import com.google.common.annotations.VisibleForTesting;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
+import java.util.function.Consumer;
+import javax.annotation.concurrent.ThreadSafe;
 import org.opendaylight.openflowplugin.api.openflow.registry.group.DeviceGroupRegistry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
 
-/**
- * Created by Martin Bobak &lt;mbobak@cisco.com&gt; on 15.4.2015.
- */
+@ThreadSafe
 public class DeviceGroupRegistryImpl implements DeviceGroupRegistry {
 
-    private final List<GroupId> groupIdList = new ArrayList<>();
-    private final List<GroupId> marks = new ArrayList<>();
+    private final List<GroupId> groupIds = Collections.synchronizedList(new ArrayList<>());
+    private final List<GroupId> marks = Collections.synchronizedList(new ArrayList<>());
 
     @Override
     public void store(final GroupId groupId) {
-        groupIdList.add(groupId);
+        groupIds.add(groupId);
     }
 
     @Override
-    public void markToBeremoved(final GroupId groupId) {
+    public void addMark(final GroupId groupId) {
         marks.add(groupId);
     }
 
     @Override
-    public void removeMarked() {
-        synchronized (groupIdList) {
-            groupIdList.removeAll(marks);
-        }
+    public void processMarks() {
+        groupIds.removeAll(marks);
         marks.clear();
     }
 
     @Override
-    public List<GroupId> getAllGroupIds() {
-        return groupIdList;
+    public void forEach(final Consumer<GroupId> consumer) {
+        synchronized (groupIds) {
+            groupIds.forEach(consumer);
+        }
+    }
+
+    @Override
+    public int size() {
+        return groupIds.size();
     }
 
     @Override
     public void close() {
-        synchronized (groupIdList) {
-            groupIdList.clear();
-        }
-        synchronized (marks) {
-            marks.clear();
-        }
+        groupIds.clear();
+        marks.clear();
+    }
+
+    @VisibleForTesting
+    List<GroupId> getAllGroupIds() {
+        return groupIds;
     }
 }
index c5e2192a530ee2bbe7889788e76051596f6c2761..c6623080aa7f5180595e119542eaa548b16d4db4 100644 (file)
@@ -8,18 +8,20 @@
 
 package org.opendaylight.openflowplugin.impl.registry.meter;
 
+import com.google.common.annotations.VisibleForTesting;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
+import java.util.function.Consumer;
+import javax.annotation.concurrent.ThreadSafe;
 import org.opendaylight.openflowplugin.api.openflow.registry.meter.DeviceMeterRegistry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId;
 
-/**
- * Created by Martin Bobak &lt;mbobak@cisco.com&gt; on 15.4.2015.
- */
+@ThreadSafe
 public class DeviceMeterRegistryImpl implements DeviceMeterRegistry {
 
-    private final List<MeterId> meterIds = new ArrayList<>();
-    private final List<MeterId> marks = new ArrayList<>();
+    private final List<MeterId> meterIds = Collections.synchronizedList(new ArrayList<>());
+    private final List<MeterId> marks = Collections.synchronizedList(new ArrayList<>());
 
     @Override
     public void store(final MeterId meterId) {
@@ -27,32 +29,36 @@ public class DeviceMeterRegistryImpl implements DeviceMeterRegistry {
     }
 
     @Override
-    public void markToBeremoved(final MeterId meterId) {
+    public void addMark(final MeterId meterId) {
         marks.add(meterId);
     }
 
     @Override
-    public void removeMarked() {
+    public void processMarks() {
+        meterIds.removeAll(marks);
+        marks.clear();
+    }
+
+    @Override
+    public void forEach(final Consumer<MeterId> consumer) {
         synchronized (meterIds) {
-            meterIds.removeAll(marks);
-        }
-        synchronized (marks) {
-            marks.clear();
+            meterIds.forEach(consumer);
         }
     }
 
     @Override
-    public List<MeterId> getAllMeterIds() {
-        return meterIds;
+    public int size() {
+        return meterIds.size();
     }
 
     @Override
     public void close() {
-        synchronized (meterIds) {
-            meterIds.clear();
-        }
-        synchronized (marks) {
-            marks.clear();
-        }
+        meterIds.clear();
+        marks.clear();
+    }
+
+    @VisibleForTesting
+    List<MeterId> getAllMeterIds() {
+        return meterIds;
     }
 }
index 6953784a3f72f6825f29a1d696bc874e480c44d9..f794d850511c98509dc4e8a5f36c8305038b79bb 100644 (file)
@@ -115,7 +115,7 @@ class RpcContextImpl implements RpcContext {
             }
         } else {
             try {
-                stopClusterServices(true).get();
+                stopClusterServices().get();
             } catch (Exception e) {
                 LOG.debug("Failed to close RpcContext for node {} with exception: ", getDeviceInfo().getLOGValue(), e);
             }
@@ -188,7 +188,7 @@ class RpcContextImpl implements RpcContext {
     }
 
     @Override
-    public ListenableFuture<Void> stopClusterServices(boolean connectionInterrupted) {
+    public ListenableFuture<Void> stopClusterServices() {
         if (CONTEXT_STATE.TERMINATION.equals(getState())) {
             return Futures.immediateCancelledFuture();
         }
index f8cf02e33129af88bb267e8b06a786a3ab6aafc8..9d51e9d7755acf543e828b154ccabdc75e4ff14b 100644 (file)
@@ -36,7 +36,7 @@ public class RpcManagerImpl implements RpcManager {
     private final RpcProviderRegistry rpcProviderRegistry;
     private DeviceInitializationPhaseHandler deviceInitPhaseHandler;
     private DeviceTerminationPhaseHandler deviceTerminationPhaseHandler;
-    private final int maxRequestsQuota;
+    private int maxRequestsQuota;
     private final ConcurrentMap<DeviceInfo, RpcContext> contexts = new ConcurrentHashMap<>();
     private boolean isStatisticsRpcEnabled;
     private final ExtensionConverterProvider extensionConverterProvider;
@@ -46,12 +46,10 @@ public class RpcManagerImpl implements RpcManager {
 
     public RpcManagerImpl(
             final RpcProviderRegistry rpcProviderRegistry,
-            final int quotaValue,
             final ExtensionConverterProvider extensionConverterProvider,
                final ConvertorExecutor convertorExecutor,
             final NotificationPublishService notificationPublishService) {
         this.rpcProviderRegistry = rpcProviderRegistry;
-        maxRequestsQuota = quotaValue;
         this.extensionConverterProvider = extensionConverterProvider;
         this.convertorExecutor = convertorExecutor;
         this.notificationPublishService = notificationPublishService;
@@ -78,6 +76,13 @@ public class RpcManagerImpl implements RpcManager {
                 convertorExecutor,
                 notificationPublishService);
 
+        // Clean up any old context present
+        RpcContext staleContext = contexts.remove(deviceInfo);
+        if (staleContext != null){
+            LOG.warn("Previous rpc context for node {} was not closed, closing the context.", deviceInfo);
+            staleContext.close();
+        }
+
         Verify.verify(contexts.putIfAbsent(deviceInfo, rpcContext) == null, "RpcCtx still not closed for node {}", deviceInfo.getNodeId());
         lifecycleService.setRpcContext(rpcContext);
         lifecycleService.registerDeviceRemovedHandler(this);
@@ -122,6 +127,11 @@ public class RpcManagerImpl implements RpcManager {
         isStatisticsRpcEnabled = statisticsRpcEnabled;
     }
 
+    @Override
+    public void setRpcRequestQuota(final int rpcRequestQuota) {
+        this.maxRequestsQuota = rpcRequestQuota;
+    }
+
     @Override
     public void onDeviceRemoved(DeviceInfo deviceInfo) {
         contexts.remove(deviceInfo);
index da8d74275dd45956d9b493e303366984211b7320..a516bccc7f72cd1e6f23ce3b8c9183ba4fc73c07 100644 (file)
@@ -112,6 +112,7 @@ final class MultipartRequestOnTheFlyCallback extends AbstractRequestCallback<Lis
             StatisticsGatheringUtils.writeFlowStatistics(allMultipartData, deviceInfo, registry, txFacade);
             if (!multipartReply.getFlags().isOFPMPFREQMORE()) {
                 endCollecting();
+                registry.processMarks();
             }
         }
     }
index 5f032a70435daedf563c3690e012d9ca0d7e507f..a18385e7b3ce4062c59122da622e68c01fec6c2c 100644 (file)
@@ -75,7 +75,7 @@ public class SalFlowServiceImpl implements SalFlowService, ItemLifeCycleSource {
 
     @Override
     public Future<RpcResult<AddFlowOutput>> addFlow(final AddFlowInput input) {
-        final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(input);
+        final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(deviceContext.getDeviceInfo().getVersion(), input);
         final ListenableFuture<RpcResult<AddFlowOutput>> future =
                 flowAdd.processFlowModInputBuilders(flowAdd.toFlowModInputs(input));
         Futures.addCallback(future, new AddFlowCallback(input, flowRegistryKey));
@@ -144,10 +144,10 @@ public class SalFlowServiceImpl implements SalFlowService, ItemLifeCycleSource {
                 if (Objects.nonNull(input.getFlowRef())) {
                     final FlowId flowId = input.getFlowRef().getValue().firstKeyOf(Flow.class, FlowKey.class).getId();
                     flowDescriptor = FlowDescriptorFactory.create(input.getTableId(), flowId);
-                    deviceContext.getDeviceFlowRegistry().store(flowRegistryKey, flowDescriptor);
+                    deviceContext.getDeviceFlowRegistry().storeDescriptor(flowRegistryKey, flowDescriptor);
                 } else {
-                    final FlowId flowId = deviceContext.getDeviceFlowRegistry().storeIfNecessary(flowRegistryKey);
-                    flowDescriptor = FlowDescriptorFactory.create(input.getTableId(), flowId);
+                    deviceContext.getDeviceFlowRegistry().store(flowRegistryKey);
+                    flowDescriptor = deviceContext.getDeviceFlowRegistry().retrieveDescriptor(flowRegistryKey);
                 }
 
                 if (LOG.isDebugEnabled()) {
@@ -187,12 +187,12 @@ public class SalFlowServiceImpl implements SalFlowService, ItemLifeCycleSource {
                 if (LOG.isDebugEnabled()) {
                     LOG.debug("Flow remove finished without error for flow={}", input);
                 }
-                FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(input);
-                deviceContext.getDeviceFlowRegistry().removeDescriptor(flowRegistryKey);
+                FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(deviceContext.getDeviceInfo().getVersion(), input);
+                deviceContext.getDeviceFlowRegistry().addMark(flowRegistryKey);
 
                 if (itemLifecycleListener != null) {
-                    final FlowDescriptor flowDescriptor =
-                            deviceContext.getDeviceFlowRegistry().retrieveIdForFlow(flowRegistryKey);
+                    final FlowDescriptor flowDescriptor = deviceContext.getDeviceFlowRegistry().retrieveDescriptor(flowRegistryKey);
+
                     if (flowDescriptor != null) {
                         KeyedInstanceIdentifier<Flow, FlowKey> flowPath = createFlowPath(flowDescriptor,
                                 deviceContext.getDeviceInfo().getNodeInstanceIdentifier());
@@ -226,18 +226,27 @@ public class SalFlowServiceImpl implements SalFlowService, ItemLifeCycleSource {
 
             final UpdatedFlow updated = input.getUpdatedFlow();
             final OriginalFlow original = input.getOriginalFlow();
-            final FlowRegistryKey origFlowRegistryKey = FlowRegistryKeyFactory.create(original);
-            final FlowRegistryKey updatedFlowRegistryKey = FlowRegistryKeyFactory.create(updated);
-            final FlowDescriptor origFlowDescriptor = deviceFlowRegistry.retrieveIdForFlow(origFlowRegistryKey);
+            final FlowRegistryKey origFlowRegistryKey = FlowRegistryKeyFactory.create(deviceContext.getDeviceInfo().getVersion(), original);
+            final FlowRegistryKey updatedFlowRegistryKey = FlowRegistryKeyFactory.create(deviceContext.getDeviceInfo().getVersion(), updated);
+            final FlowDescriptor origFlowDescriptor = deviceFlowRegistry.retrieveDescriptor(origFlowRegistryKey);
 
             final boolean isUpdate = Objects.nonNull(origFlowDescriptor);
-            final FlowId fLowId = Objects.nonNull(input.getFlowRef())
-                    ? input.getFlowRef().getValue().firstKeyOf(Flow.class).getId()
-                    : isUpdate ? origFlowDescriptor.getFlowId() : deviceFlowRegistry.storeIfNecessary(updatedFlowRegistryKey);
-            final FlowDescriptor updatedFlowDescriptor = FlowDescriptorFactory.create(updated.getTableId(), fLowId);
+            final FlowDescriptor updatedFlowDescriptor;
+
+            if (Objects.nonNull(input.getFlowRef())) {
+               updatedFlowDescriptor = FlowDescriptorFactory.create(updated.getTableId(), input.getFlowRef().getValue().firstKeyOf(Flow.class).getId());
+            } else {
+                if (isUpdate) {
+                    updatedFlowDescriptor = origFlowDescriptor;
+                } else {
+                    deviceFlowRegistry.store(updatedFlowRegistryKey);
+                    updatedFlowDescriptor = deviceFlowRegistry.retrieveDescriptor(updatedFlowRegistryKey);
+                }
+            }
+
             if (isUpdate) {
-                deviceFlowRegistry.removeDescriptor(origFlowRegistryKey);
-                deviceFlowRegistry.store(updatedFlowRegistryKey, updatedFlowDescriptor);
+                deviceFlowRegistry.addMark(origFlowRegistryKey);
+                deviceFlowRegistry.storeDescriptor(updatedFlowRegistryKey, updatedFlowDescriptor);
             }
 
             if (itemLifecycleListener != null) {
@@ -263,4 +272,4 @@ public class SalFlowServiceImpl implements SalFlowService, ItemLifeCycleSource {
             LOG.warn("Service call for updating flow={} failed, reason: {}", input, throwable);
         }
     }
-}
\ No newline at end of file
+}
index a6264a1ba704c68f552197d76712a3970a092121..3bbe45aeefbbd58a75c28ffe426c19a5c7b1da30 100644 (file)
@@ -126,7 +126,7 @@ public class SalGroupServiceImpl implements SalGroupService, ItemLifeCycleSource
                     if (LOG.isDebugEnabled()) {
                         LOG.debug("Group remove with id={} finished without error", input.getGroupId().getValue());
                     }
-                    removeGroup.getDeviceRegistry().getDeviceGroupRegistry().markToBeremoved(input.getGroupId());
+                    removeGroup.getDeviceRegistry().getDeviceGroupRegistry().addMark(input.getGroupId());
                     removeIfNecessaryFromDS(input.getGroupId());
                 } else {
                     if (LOG.isDebugEnabled()) {
index 02f72dc6ab8195da6c55f43f32682d7580ca5960..1a4ac4c3dbd682b9a3b260f5e92ebd204e21a888 100644 (file)
@@ -119,7 +119,6 @@ public class SalMeterServiceImpl implements SalMeterService, ItemLifeCycleSource
 
     @Override
     public Future<RpcResult<RemoveMeterOutput>> removeMeter(final RemoveMeterInput input) {
-        removeMeter.getDeviceRegistry().getDeviceMeterRegistry().markToBeremoved(input.getMeterId());
         final ListenableFuture<RpcResult<RemoveMeterOutput>> resultFuture = removeMeter.handleServiceCall(input);
         Futures.addCallback(resultFuture, new FutureCallback<RpcResult<RemoveMeterOutput>>() {
             @Override
@@ -128,6 +127,7 @@ public class SalMeterServiceImpl implements SalMeterService, ItemLifeCycleSource
                     if (LOG.isDebugEnabled()) {
                         LOG.debug("Meter remove with id={} finished without error", input.getMeterId());
                     }
+                    removeMeter.getDeviceRegistry().getDeviceMeterRegistry().addMark(input.getMeterId());
                     removeIfNecessaryFromDS(input.getMeterId());
                 } else {
                     if (LOG.isDebugEnabled()) {
@@ -164,4 +164,4 @@ public class SalMeterServiceImpl implements SalMeterService, ItemLifeCycleSource
     private static KeyedInstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter, MeterKey> createMeterPath(final MeterId meterId, final KeyedInstanceIdentifier<Node, NodeKey> nodePath) {
         return nodePath.augmentation(FlowCapableNode.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter.class, new MeterKey(meterId));
     }
-}
\ No newline at end of file
+}
index 4b5b7be9ca84ba0be030879e7521eb8b4a6821ab..fed62cab3e2dd7210c64a6daf5ef8790545b2411 100644 (file)
@@ -234,7 +234,7 @@ class StatisticsContextImpl implements StatisticsContext {
             }
         } else {
             try {
-                stopClusterServices(true).get();
+                stopClusterServices().get();
             } catch (Exception e) {
                 LOG.debug("Failed to close StatisticsContext for node {} with exception: ", getDeviceInfo().getLOGValue(), e);
             }
@@ -316,7 +316,7 @@ class StatisticsContextImpl implements StatisticsContext {
                 case RIP:
                     final String errMsg = String.format("Device connection doesn't exist anymore. Primary connection status : %s",
                             deviceContext.getPrimaryConnectionContext().getConnectionState());
-                    resultingFuture = Futures.immediateFailedFuture(new Throwable(errMsg));
+                    resultingFuture = Futures.immediateFailedFuture(new ConnectionException(errMsg));
                     break;
                 default:
                     resultingFuture = Futures.immediateCheckedFuture(Boolean.TRUE);
@@ -440,7 +440,7 @@ class StatisticsContextImpl implements StatisticsContext {
     }
 
     @Override
-    public ListenableFuture<Void> stopClusterServices(boolean connectionInterrupted) {
+    public ListenableFuture<Void> stopClusterServices() {
         if (CONTEXT_STATE.TERMINATION.equals(getState())) {
             return Futures.immediateCancelledFuture();
         }
index 0ef733691a083946a69e9f5cccc40bdfa5a07d8b..e59b17ff59e7e42860b4b952c7b9415edaa6ef0d 100644 (file)
@@ -16,6 +16,7 @@ import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.JdkFutureAdapters;
 import com.google.common.util.concurrent.ListenableFuture;
+import java.util.Objects;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
@@ -25,6 +26,7 @@ import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceRegistry;
 import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
 import org.opendaylight.openflowplugin.api.openflow.registry.flow.DeviceFlowRegistry;
+import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowDescriptor;
 import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey;
 import org.opendaylight.openflowplugin.api.openflow.registry.group.DeviceGroupRegistry;
 import org.opendaylight.openflowplugin.api.openflow.registry.meter.DeviceMeterRegistry;
@@ -321,6 +323,7 @@ public final class StatisticsGatheringUtils {
             writeFlowStatistics(data, deviceInfo, flowRegistry, txFacade);
             txFacade.submitTransaction();
             EventsTimeCounter.markEnd(eventIdentifier);
+            flowRegistry.processMarks();
             return Boolean.TRUE;
         });
     }
@@ -338,15 +341,20 @@ public final class StatisticsGatheringUtils {
                             refineFlowStatisticsAugmentation(flowStat).build());
 
                     final short tableId = flowStat.getTableId();
-                    final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(flowBuilder.build());
-                    final FlowId flowId = registry.storeIfNecessary(flowRegistryKey);
-
-                    final FlowKey flowKey = new FlowKey(flowId);
-                    flowBuilder.setKey(flowKey);
-                    final TableKey tableKey = new TableKey(tableId);
-                    final InstanceIdentifier<Flow> flowIdent
-                            = fNodeIdent.child(Table.class, tableKey).child(Flow.class, flowKey);
-                    txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, flowIdent, flowBuilder.build());
+                    final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flowBuilder.build());
+                    registry.store(flowRegistryKey);
+                    final FlowDescriptor flowDescriptor = registry.retrieveDescriptor(flowRegistryKey);
+
+                    if (Objects.nonNull(flowDescriptor)) {
+                        final FlowId flowId = flowDescriptor.getFlowId();
+
+                        final FlowKey flowKey = new FlowKey(flowId);
+                        flowBuilder.setKey(flowKey);
+                        final TableKey tableKey = new TableKey(tableId);
+                        final InstanceIdentifier<Flow> flowIdent
+                                = fNodeIdent.child(Table.class, tableKey).child(Flow.class, flowKey);
+                        txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, flowIdent, flowBuilder.build());
+                    }
                 }
             }
         } catch (TransactionChainClosedException e) {
@@ -522,11 +530,11 @@ public final class StatisticsGatheringUtils {
             final DeviceMeterRegistry meterRegistry,
             final InstanceIdentifier<FlowCapableNode> flowNodeIdent,
             final TxFacade txFacade) throws TransactionChainClosedException {
-        for (final MeterId meterId : meterRegistry.getAllMeterIds()) {
+        meterRegistry.forEach(meterId -> {
             final InstanceIdentifier<Meter> meterIdent = flowNodeIdent.child(Meter.class, new MeterKey(meterId));
             txFacade.addDeleteToTxChain(LogicalDatastoreType.OPERATIONAL, meterIdent);
-        }
-        meterRegistry.removeMarked();
+        });
+        meterRegistry.processMarks();
     }
 
     private static void processGroupDescStats(
@@ -558,11 +566,11 @@ public final class StatisticsGatheringUtils {
             final TxFacade txFacade,
             final InstanceIdentifier<FlowCapableNode> flowNodeIdent,
             final DeviceGroupRegistry groupRegistry) throws TransactionChainClosedException {
-        for (final GroupId groupId : groupRegistry.getAllGroupIds()) {
+        groupRegistry.forEach(groupId -> {
             final InstanceIdentifier<Group> groupIdent = flowNodeIdent.child(Group.class, new GroupKey(groupId));
             txFacade.addDeleteToTxChain(LogicalDatastoreType.OPERATIONAL, groupIdent);
-        }
-        groupRegistry.removeMarked();
+        });
+        groupRegistry.processMarks();
     }
 
     private static void processGroupStatistics(
index 06dc64de2688f7183a14cf35543128e70912402d..81628c4f8eba8699b040ec5f6d9853a95c21b681 100644 (file)
@@ -65,9 +65,9 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag
 
     private final ConcurrentMap<DeviceInfo, StatisticsContext> contexts = new ConcurrentHashMap<>();
 
-    private static long basicTimerDelay;
-    private static long currentTimerDelay;
-    private static long maximumTimerDelay; //wait time for next statistics
+    private long basicTimerDelay;
+    private long currentTimerDelay;
+    private long maximumTimerDelay; //wait time for next statistics
 
     private StatisticsWorkMode workMode = StatisticsWorkMode.COLLECTALL;
     private final Semaphore workModeGuard = new Semaphore(1, true);
@@ -82,20 +82,13 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag
     }
 
     public StatisticsManagerImpl(final RpcProviderRegistry rpcProviderRegistry,
-                                 final boolean isStatisticsPollingOn,
                                  final HashedWheelTimer hashedWheelTimer,
-                                 final ConvertorExecutor convertorExecutor,
-                                 final long basicTimerDelay,
-                                 final long maximumTimerDelay) {
+                                 final ConvertorExecutor convertorExecutor) {
         Preconditions.checkArgument(rpcProviderRegistry != null);
            this.converterExecutor = convertorExecutor;
         this.controlServiceRegistration = Preconditions.checkNotNull(
                 rpcProviderRegistry.addRpcImplementation(StatisticsManagerControlService.class, this)
         );
-        this.isStatisticsPollingOn = isStatisticsPollingOn;
-        this.basicTimerDelay = basicTimerDelay;
-        this.currentTimerDelay = basicTimerDelay;
-        this.maximumTimerDelay = maximumTimerDelay;
         this.hashedWheelTimer = hashedWheelTimer;
     }
 
@@ -111,11 +104,17 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag
                         converterExecutor,
                         this);
 
+        // Clean up stale context if present
+        StatisticsContext staleContext = contexts.remove(deviceInfo);
+        if (staleContext != null){
+            LOG.warn("Previous statistics context for node {} was not closed, closing the context.", deviceInfo);
+            staleContext.close();
+        }
+
         Verify.verify(
                 contexts.putIfAbsent(deviceInfo, statisticsContext) == null,
                 "StatisticsCtx still not closed for Node {}", deviceInfo.getLOGValue()
         );
-
         lifecycleService.setStatContext(statisticsContext);
         lifecycleService.registerDeviceRemovedHandler(this);
         deviceInitPhaseHandler.onDeviceContextLevelUp(deviceInfo, lifecycleService);
@@ -224,7 +223,7 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag
     }
 
     @VisibleForTesting
-    static long getCurrentTimerDelay() {
+    long getCurrentTimerDelay() {
         return currentTimerDelay;
     }
 
@@ -363,6 +362,7 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag
     @Override
     public void setBasicTimerDelay(final long basicTimerDelay) {
         this.basicTimerDelay = basicTimerDelay;
+        this.currentTimerDelay = basicTimerDelay;
     }
 
     @Override
index d8ad2ae86b3e47b65709ffe78e0720e12424a9e6..6ce7eb96b89da36fba7e5f6d792f9fe4c1834c37 100644 (file)
@@ -8,7 +8,6 @@
 
 package org.opendaylight.openflowplugin.impl.statistics.services.direct;
 
-import com.google.common.base.Function;
 import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.AsyncFunction;
 import com.google.common.util.concurrent.Futures;
@@ -41,17 +40,6 @@ import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
  */
 public abstract class AbstractDirectStatisticsService<I extends StoreStatsGrouping, O> extends AbstractMultipartService<I> {
 
-    private final Function<RpcResult<List<MultipartReply>>, RpcResult<O>> resultTransformFunction =
-            new Function<RpcResult<List<MultipartReply>>, RpcResult<O>>() {
-                @Nullable
-                @Override
-                public RpcResult<O> apply(@Nullable RpcResult<List<MultipartReply>> input) {
-                    Preconditions.checkNotNull(input);
-                    final O reply = buildReply(input.getResult(), input.isSuccessful());
-                    return RpcResultBuilder.success(reply).build();
-                }
-            };
-
     private final AsyncFunction<RpcResult<O>, RpcResult<O>> resultStoreFunction =
             new AsyncFunction<RpcResult<O>, RpcResult<O>>() {
                 @Nullable
@@ -98,7 +86,7 @@ public abstract class AbstractDirectStatisticsService<I extends StoreStatsGroupi
      */
     public Future<RpcResult<O>> handleAndReply(final I input) {
         final ListenableFuture<RpcResult<List<MultipartReply>>> rpcReply = handleServiceCall(input);
-        ListenableFuture<RpcResult<O>> rpcResult = Futures.transform(rpcReply, resultTransformFunction);
+        ListenableFuture<RpcResult<O>> rpcResult = Futures.transform(rpcReply, this::transformResult);
 
         if (Boolean.TRUE.equals(input.isStoreStats())) {
             rpcResult = Futures.transform(rpcResult, resultStoreFunction);
@@ -107,6 +95,12 @@ public abstract class AbstractDirectStatisticsService<I extends StoreStatsGroupi
         return rpcResult;
     }
 
+    private RpcResult<O> transformResult(final RpcResult<List<MultipartReply>> input) {
+        return Preconditions.checkNotNull(input).isSuccessful()
+            ? RpcResultBuilder.success(buildReply(input.getResult(), input.isSuccessful())).build()
+            : RpcResultBuilder.<O>failed().withRpcErrors(input.getErrors()).build();
+    }
+
     @Override
     protected OfHeader buildRequest(Xid xid, I input) throws ServiceException {
         return RequestInputUtils.createMultipartHeader(multipartType, xid.getValue(), getVersion())
index adbd1e9736c72165540269734e8627d7222d00e2..e6d6181fb64db1bfe59d542981b3e383928dc193 100644 (file)
@@ -20,7 +20,6 @@ import org.opendaylight.openflowplugin.extension.api.path.MatchPath;
 import org.opendaylight.openflowplugin.impl.registry.flow.FlowRegistryKeyFactory;
 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.FlowStatsResponseConvertorData;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData;
 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchReactor;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsOutput;
@@ -167,7 +166,8 @@ public class FlowDirectStatisticsService extends AbstractDirectStatisticsService
         final FlowBuilder flowBuilder = new FlowBuilder(flowStatistics)
                 .addAugmentation(FlowStatisticsData.class, flowStatisticsDataBld.build());
 
-        final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(flowBuilder.build());
-        return getDeviceRegistry().getDeviceFlowRegistry().storeIfNecessary(flowRegistryKey);
+        final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(getVersion(), flowBuilder.build());
+        getDeviceRegistry().getDeviceFlowRegistry().store(flowRegistryKey);
+        return getDeviceRegistry().getDeviceFlowRegistry().retrieveDescriptor(flowRegistryKey).getFlowId();
     }
 }
diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/AddressNormalizationUtil.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/AddressNormalizationUtil.java
new file mode 100644 (file)
index 0000000..b61e2b6
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * 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.impl.util;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Objects;
+import javax.annotation.Nullable;
+import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.IpConversionUtil;
+import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
+import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.opendaylight.ipv6.arbitrary.bitmask.fields.rev160224.Ipv6ArbitraryMask;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Utility class used for converting OpenFlow port numbers, Ipv4 and Ipv6 addresses to normalized format.
+ */
+public class AddressNormalizationUtil {
+    private static final Logger LOG = LoggerFactory.getLogger(AddressNormalizationUtil.class);
+
+    private static final String NO_ETH_MASK = "ff:ff:ff:ff:ff:ff";
+    private static final String PREFIX_SEPARATOR = "/";
+
+    /**
+     * Extract port number from URI and convert it to OpenFlow specific textual representation.
+     *
+     * @param port            the OpenFlow port
+     * @param protocolVersion the OpenFLow protocol version
+     * @return normalized uri
+     */
+    @Nullable
+    public static Uri normalizeProtocolAgnosticPort(@Nullable final Uri port, final short protocolVersion) {
+        if (Objects.isNull(port)) {
+            return null;
+        }
+
+        return OpenflowPortsUtil.getProtocolAgnosticPortUri(protocolVersion, InventoryDataServiceUtil
+                .portNumberfromNodeConnectorId(OpenflowVersion.get(protocolVersion), port.getValue()));
+    }
+
+    /**
+     * Normalize Ipv6 address with prefix mask (ex. 1234:5678:9ABC::/76) and apply prefix mask to Ipv6 address.
+     *
+     * @param ipv6Prefix the Ipv6 prefix
+     * @return normalized Ipv6 prefix
+     */
+    @Nullable
+    public static Ipv6Prefix normalizeIpv6Prefix(@Nullable final Ipv6Prefix ipv6Prefix) {
+        if (Objects.isNull(ipv6Prefix)) {
+            return null;
+        }
+
+        final byte[] address = IetfInetUtil.INSTANCE.ipv6AddressBytes(IpConversionUtil.extractIpv6Address(ipv6Prefix));
+        final byte[] mask = IpConversionUtil.convertIpv6PrefixToByteArray(IpConversionUtil.extractIpv6Prefix(ipv6Prefix));
+        return normalizeIpv6Address(address, mask);
+    }
+
+    /**
+     * Normalize Ipv6 address and arbitrary mask and apply arbitrary mask to Ipv6 address.
+     *
+     * @param ipv6Address the Ipv4 address
+     * @param ipv4Mask    the Ipv4 mask
+     * @return normalized Ipv6 prefix
+     */
+    @Nullable
+    public static Ipv6Prefix normalizeIpv6Arbitrary(@Nullable final Ipv6Address ipv6Address, @Nullable final Ipv6ArbitraryMask ipv4Mask) {
+        if (Objects.isNull(ipv6Address)) {
+            return null;
+        }
+
+        final byte[] address = IetfInetUtil.INSTANCE.ipv6AddressBytes(ipv6Address);
+        final byte[] mask = IpConversionUtil.convertIpv6ArbitraryMaskToByteArray(ipv4Mask);
+        return normalizeIpv6Address(address, mask);
+    }
+
+    /**
+     * Normalize ipv 6 address without mask.
+     *
+     * @param ipv6Address the Ipv6 address
+     * @return normalized Ipv6 address
+     */
+    @Nullable
+    public static Ipv6Address normalizeIpv6AddressWithoutMask(@Nullable final Ipv6Address ipv6Address) {
+        final Ipv6Prefix ipv6Prefix = normalizeIpv6Arbitrary(ipv6Address, null);
+        return Objects.nonNull(ipv6Prefix)
+                ? new Ipv6Address(ipv6Prefix.getValue().split(PREFIX_SEPARATOR)[0])
+                : null;
+    }
+
+    /**
+     * Normalize Ipv4 address with prefix mask (ex. 192.168.0.1/24) and apply prefix mask to Ipv4 address.
+     *
+     * @param ipv4Prefix the Ipv4 prefix
+     * @return normalized Ipv4 prefix
+     */
+    @Nullable
+    public static Ipv4Prefix normalizeIpv4Prefix(@Nullable final Ipv4Prefix ipv4Prefix) {
+        if (Objects.isNull(ipv4Prefix)) {
+            return null;
+        }
+
+        final byte[] address = IetfInetUtil.INSTANCE.ipv4AddressBytes(IpConversionUtil.extractIpv4Address(ipv4Prefix));
+        final byte[] mask = IpConversionUtil.convertArbitraryMaskToByteArray(IpConversionUtil.extractIpv4AddressMask(ipv4Prefix));
+        return normalizeIpv4Address(address, mask);
+    }
+
+    /**
+     * Normalize Ipv4 address and arbitrary mask and apply arbitrary mask to Ipv4 address.
+     *
+     * @param ipv4Address the Ipv4 address
+     * @param ipv4Mask    the Ipv4 mask
+     * @return normalized Ipv4 prefix
+     */
+    @Nullable
+    public static Ipv4Prefix normalizeIpv4Arbitrary(@Nullable final Ipv4Address ipv4Address, @Nullable final DottedQuad ipv4Mask) {
+        if (Objects.isNull(ipv4Address)) {
+            return null;
+        }
+
+        final byte[] address = IetfInetUtil.INSTANCE.ipv4AddressBytes(ipv4Address);
+        final byte[] mask = IpConversionUtil.convertArbitraryMaskToByteArray(ipv4Mask);
+        return normalizeIpv4Address(address, mask);
+    }
+
+    /**
+     * Normalize Ipv4 address and arbitrary mask in byte array format and apply arbitrary mask to Ipv4 address.
+     *
+     * @param address Ipv4 address byte array
+     * @param mask    Ipv4 mask byte array
+     * @return normalized Ipv4 prefix
+     */
+    @Nullable
+    public static Ipv4Prefix normalizeIpv4Address(@Nullable final byte[] address, @Nullable final byte[] mask) {
+        final String addressPrefix = normalizeInetAddressWithMask(normalizeIpAddress(address, mask), mask);
+
+        if (Objects.isNull(addressPrefix)) {
+            return null;
+        }
+
+        return new Ipv4Prefix(addressPrefix);
+    }
+
+
+    /**
+     * Normalize Ipv6 address and arbitrary mask in byte array format and apply arbitrary mask to Ipv6 address.
+     *
+     * @param address Ipv6 address byte array
+     * @param mask    Ipv6 mask byte array
+     * @return normalized Ipv6 prefix
+     */
+    @Nullable
+    public static Ipv6Prefix normalizeIpv6Address(@Nullable final byte[] address, @Nullable final byte[] mask) {
+        final String addressPrefix = normalizeInetAddressWithMask(normalizeIpAddress(address, mask), mask);
+
+        if (Objects.isNull(addressPrefix)) {
+            return null;
+        }
+
+        return new Ipv6Prefix(addressPrefix);
+    }
+
+    /**
+     * Normalize generic IP address and arbitrary mask in byte array format and apply arbitrary mask to IP address.
+     *
+     * @param address address byte array
+     * @param mask    mask byte array
+     * @return normalized Inet address
+     */
+    @Nullable
+    public static InetAddress normalizeIpAddress(@Nullable final byte[] address, @Nullable final byte[] mask) {
+        if (Objects.isNull(address)) {
+            return null;
+        }
+
+        final byte[] result = new byte[address.length];
+
+        for (int i = 0; i < address.length; i++) {
+            result[i] = Objects.nonNull(mask) ?
+                    (byte) (address[i] & mask[i]) :
+                    address[i];
+        }
+
+        try {
+            return InetAddress.getByAddress(result);
+        } catch (UnknownHostException e) {
+            LOG.warn("Failed to recognize the host while normalizing IP address from bytes ", e);
+            return null;
+        }
+    }
+
+    /**
+     * Convert arbitrary mask to prefix mask and append it to textual representation of Inet address
+     *
+     * @param address the address
+     * @param mask    the mask
+     * @return the string
+     */
+    @Nullable
+    public static String normalizeInetAddressWithMask(@Nullable final InetAddress address, @Nullable final byte[] mask) {
+        if (Objects.isNull(address)) {
+            return null;
+        }
+
+        return address.getHostAddress() +
+                (Objects.nonNull(mask)
+                        ? PREFIX_SEPARATOR + String.valueOf(IpConversionUtil.countBits(mask))
+                        : "");
+    }
+
+    /**
+     * Convert MAC address to it's lower case format
+     *
+     * @param macAddress the MAC address
+     * @return normalized MAC address
+     */
+    @Nullable
+    public static MacAddress normalizeMacAddress(@Nullable final MacAddress macAddress) {
+        if (Objects.isNull(macAddress)) {
+            return null;
+        }
+
+        return new MacAddress(macAddress.getValue().toLowerCase());
+    }
+
+    /**
+     * Convert MAC address mask to it's lower case format and if it is full F mask, return null
+     *
+     * @param macAddress the MAC address
+     * @return normalized MAC address
+     */
+    @Nullable
+    public static MacAddress normalizeMacAddressMask(@Nullable final MacAddress macAddress) {
+        final MacAddress normalizedMacAddress = normalizeMacAddress(macAddress);
+
+        if (Objects.isNull(normalizedMacAddress)) {
+            return null;
+        }
+
+        if (NO_ETH_MASK.equals(normalizedMacAddress.getValue())) {
+            return null;
+        }
+
+        return normalizedMacAddress;
+    }
+
+}
index 0bdbe08a9c82e01be756b0cabec21d027f6a2863..fa70f6201ef733f4d2c39cd1928604eb52254712 100644 (file)
@@ -22,6 +22,8 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueue;
 import org.opendaylight.openflowplugin.api.ConnectionException;
@@ -152,7 +154,18 @@ public class DeviceInitializationUtils {
             final Capabilities capabilities = connectionContext.getFeatures().getCapabilities();
             LOG.debug("Setting capabilities for device {}", deviceInfo.getNodeId());
             DeviceStateUtil.setDeviceStateBasedOnV13Capabilities(deviceState, capabilities);
-            createDeviceFeaturesForOF13(deviceContext, switchFeaturesMandatory, convertorExecutor).get();
+            try {
+              // Collect device feature
+              if (createDeviceFeaturesForOF13(
+                      deviceContext, switchFeaturesMandatory, convertorExecutor).get(30,TimeUnit.SECONDS) == null){
+                  LOG.warn("Device features are empty for node {}, returning an unexpected exception.", deviceInfo
+                          .getLOGValue());
+                  throw new ExecutionException(new Exception("Device features were not retrieved."));
+              }
+            }catch (TimeoutException e){
+                LOG.warn("Timeout occurred while retrieving features for node {}.", deviceInfo.getLOGValue());
+                throw new ExecutionException(new TimeoutException("Device features were not retrieved in time"));
+            }
         } else {
             throw new ExecutionException(new ConnectionException("Unsupported version " + version));
         }
diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/IntegerIpAddress.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/IntegerIpAddress.java
deleted file mode 100644 (file)
index d4ae17c..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * Copyright (c) 2015 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,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.openflowplugin.impl.util;
-
-/**
- * 4B base + 4B mask wrapper
- */
-public class IntegerIpAddress {
-
-    int ip;
-    int mask;
-
-    public IntegerIpAddress(final int ip, final int mask) {
-        this.ip = ip;
-        this.mask = mask;
-    }
-
-    public int getIp() {
-        return ip;
-    }
-
-    public int getMask() {
-        return mask;
-    }
-}
diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MatchComparatorFactory.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MatchComparatorFactory.java
deleted file mode 100644 (file)
index 8c3b48e..0000000
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright (c) 2013, 2015 IBM Corporation 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.impl.util;
-
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * Provides comparator for comparing according to various {@link Match} attributes
- *
- */
-public final class MatchComparatorFactory {
-
-    private MatchComparatorFactory() {
-        // NOOP
-    }
-
-    private static final Collection<SimpleComparator<Match>> MATCH_COMPARATORS = new ArrayList<>();
-    static {
-        MATCH_COMPARATORS.add(MatchComparatorFactory.createEthernet());
-        MATCH_COMPARATORS.add(MatchComparatorFactory.createIcmpv4());
-        MATCH_COMPARATORS.add(MatchComparatorFactory.createInPhyPort());
-        MATCH_COMPARATORS.add(MatchComparatorFactory.createInPort());
-        MATCH_COMPARATORS.add(MatchComparatorFactory.createIp());
-        MATCH_COMPARATORS.add(MatchComparatorFactory.createL3());
-        MATCH_COMPARATORS.add(MatchComparatorFactory.createL4());
-        MATCH_COMPARATORS.add(MatchComparatorFactory.createProtocolMatchFields());
-        MATCH_COMPARATORS.add(MatchComparatorFactory.createMetadata());
-        MATCH_COMPARATORS.add(MatchComparatorFactory.createNull());
-        MATCH_COMPARATORS.add(MatchComparatorFactory.createTunnel());
-        MATCH_COMPARATORS.add(MatchComparatorFactory.createVlan());
-    }
-
-    public static SimpleComparator<Match> createNull() {
-        return new SimpleComparator<Match>() {
-            /**
-             * Comparation by whole object
-             */
-            @Override
-            public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
-                return (statsMatch == null) == (storedMatch == null);
-            }
-        };
-    }
-
-    public static SimpleComparator<Match> createVlan() {
-        return new SimpleComparator<Match>() {
-            /**
-             * Comparation by VLAN
-             */
-            @Override
-            public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
-                if (storedMatch == null) {
-                    return false;
-                }
-                if (storedMatch.getVlanMatch() == null) {
-                    if (statsMatch.getVlanMatch() != null) {
-                        return false;
-                    }
-                } else if (!storedMatch.getVlanMatch().equals(statsMatch.getVlanMatch())) {
-                    return false;
-                }
-                return true;
-            }
-        };
-    }
-
-    public static SimpleComparator<Match> createTunnel() {
-        return new SimpleComparator<Match>() {
-            /**
-             * Comparation by tunnel
-             */
-            @Override
-            public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
-                if (storedMatch == null) {
-                    return false;
-                }
-                if (storedMatch.getTunnel() == null) {
-                    if (statsMatch.getTunnel() != null) {
-                        return false;
-                    }
-                } else if (!storedMatch.getTunnel().equals(statsMatch.getTunnel())) {
-                    return false;
-                }
-                return true;
-            }
-        };
-    }
-
-    public static SimpleComparator<Match> createProtocolMatchFields() {
-        return new SimpleComparator<Match>() {
-            /**
-             * Comparation by protocol fields
-             */
-            @Override
-            public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
-                if (storedMatch == null) {
-                    return false;
-                }
-                if (storedMatch.getProtocolMatchFields() == null) {
-                    if (statsMatch.getProtocolMatchFields() != null) {
-                        return false;
-                    }
-                } else if (!storedMatch.getProtocolMatchFields().equals(statsMatch.getProtocolMatchFields())) {
-                    return false;
-                }
-                return true;
-            }
-        };
-    }
-
-    public static SimpleComparator<Match> createMetadata() {
-        return new SimpleComparator<Match>() {
-            /**
-             * Comparation by metadata
-             */
-            @Override
-            public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
-                if (storedMatch == null) {
-                    return false;
-                }
-                if (storedMatch.getMetadata() == null) {
-                    if (statsMatch.getMetadata() != null) {
-                        return false;
-                    }
-                } else if (!storedMatch.getMetadata().equals(statsMatch.getMetadata())) {
-                    return false;
-                }
-                return true;
-            }
-        };
-    }
-
-    public static SimpleComparator<Match> createL4() {
-        return new SimpleComparator<Match>() {
-            /**
-             * Comparation by layer4
-             */
-            @Override
-            public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
-                if (storedMatch == null) {
-                    return false;
-                }
-                if (storedMatch.getLayer4Match() == null) {
-                    if (statsMatch.getLayer4Match() != null) {
-                        return false;
-                    }
-                } else if (!storedMatch.getLayer4Match().equals(statsMatch.getLayer4Match())) {
-                    return false;
-                }
-                return true;
-            }
-        };
-    }
-
-    public static SimpleComparator<Match> createL3() {
-        return new SimpleComparator<Match>() {
-            /**
-             * Comparation by layer3
-             */
-            @Override
-            public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
-                if (storedMatch == null) {
-                    return false;
-                }
-                if (storedMatch.getLayer3Match() == null) {
-                    if (statsMatch.getLayer3Match() != null) {
-                        return false;
-                    }
-                } else if (!MatchComparatorHelper.layer3MatchEquals(statsMatch.getLayer3Match(), storedMatch.getLayer3Match())) {
-                    return false;
-                }
-                return true;
-            }
-        };
-    }
-
-    public static SimpleComparator<Match> createIp() {
-        return new SimpleComparator<Match>() {
-            /**
-             * Comparation by Ip
-             */
-            @Override
-            public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
-                if (storedMatch == null) {
-                    return false;
-                }
-                if (storedMatch.getIpMatch() == null) {
-                    if (statsMatch.getIpMatch() != null) {
-                        return false;
-                    }
-                } else if (!storedMatch.getIpMatch().equals(statsMatch.getIpMatch())) {
-                    return false;
-                }
-                return true;
-            }
-        };
-    }
-
-    public static SimpleComparator<Match> createInPort() {
-        return new SimpleComparator<Match>() {
-            /**
-             * Comparation by InPort
-             */
-            @Override
-            public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
-                if (storedMatch == null) {
-                    return false;
-                }
-                if (storedMatch.getInPort() == null) {
-                    if (statsMatch.getInPort() != null) {
-                        return false;
-                    }
-                } else if (!storedMatch.getInPort().equals(statsMatch.getInPort())) {
-                    return false;
-                }
-                return true;
-            }
-        };
-    }
-
-    public static SimpleComparator<Match> createInPhyPort() {
-        return new SimpleComparator<Match>() {
-            /**
-             * Comparation by InPhyPort
-             */
-            @Override
-            public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
-                if (storedMatch == null) {
-                    return false;
-                }
-                if (storedMatch.getInPhyPort() == null) {
-                    if (statsMatch.getInPhyPort() != null) {
-                        return false;
-                    }
-                } else if (!storedMatch.getInPhyPort().equals(statsMatch.getInPhyPort())) {
-                    return false;
-                }
-                return true;
-            }
-        };
-    }
-
-    public static SimpleComparator<Match> createEthernet() {
-        return new SimpleComparator<Match>() {
-            /**
-             * Comparation by Ethernet
-             */
-            @Override
-            public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
-                if (storedMatch == null) {
-                    return false;
-                }
-                if (storedMatch.getEthernetMatch() == null) {
-                    if (statsMatch.getEthernetMatch() != null) {
-                        return false;
-                    }
-                } else if (!MatchComparatorHelper.ethernetMatchEquals(statsMatch.getEthernetMatch(), storedMatch.getEthernetMatch())) {
-                    return false;
-                }
-                return true;
-            }
-        };
-    }
-
-    public static SimpleComparator<Match> createIcmpv4() {
-        return new SimpleComparator<Match>() {
-            /**
-             * Comparation by Icmpv4
-             */
-            @Override
-            public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
-                if (storedMatch == null) {
-                    return false;
-                }
-                if (storedMatch.getIcmpv4Match() == null) {
-                    if (statsMatch.getIcmpv4Match() != null) {
-                        return false;
-                    }
-                } else if (!storedMatch.getIcmpv4Match().equals(statsMatch.getIcmpv4Match())) {
-                    return false;
-                }
-                return true;
-            }
-        };
-    }
-
-    public static SimpleComparator<Match> createMatch() {
-        return new SimpleComparator<Match>() {
-            /**
-             * Compares flows by whole match
-             */
-            @Override
-            public boolean areObjectsEqual(final Match statsFlow, final Match storedFlow) {
-                if (statsFlow == null) {
-                    if (storedFlow != null) {
-                        return false;
-                    }
-                } else if (!compareMatches(statsFlow, storedFlow)) {
-                    return false;
-                }
-                return true;
-            }
-        };
-    }
-
-
-    /**
-     * Explicit equals method to compare the 'match' for flows stored in the data-stores and flow fetched from the switch.
-     * Flow installation process has three steps
-     * 1) Store flow in config data store
-     * 2) and send it to plugin for installation
-     * 3) Flow gets installed in switch
-     *
-     * The flow user wants to install and what finally gets installed in switch can be slightly different.
-     * E.g, If user installs flow with src/dst ip=10.0.0.1/24, when it get installed in the switch
-     * src/dst ip will be changes to 10.0.0.0/24 because of netmask of 24. When statistics manager fetch
-     * stats it gets 10.0.0.0/24 rather then 10.0.0.1/24. Custom match takes care of by using masked ip
-     * while comparing two ip addresses.
-     *
-     * Sometimes when user don't provide few values that is required by flow installation request, like
-     * priority,hard timeout, idle timeout, cookies etc, plugin usages default values before sending
-     * request to the switch. So when statistics manager gets flow statistics, it gets the default value.
-     * But the flow stored in config data store don't have those defaults value. I included those checks
-     * in the customer flow/match equal function.
-     *
-     *
-     * @param statsMatch
-     * @param storedMatch
-     * @return
-     */
-    private static boolean compareMatches(final Match statsMatch, final Match storedMatch) {
-        if (statsMatch == storedMatch) {
-            return true;
-        }
-
-        for (SimpleComparator<Match> matchComp : MATCH_COMPARATORS) {
-            if (!matchComp.areObjectsEqual(statsMatch, storedMatch)) {
-                return false;
-            }
-        }
-        return true;
-    }
-}
diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MatchComparatorHelper.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MatchComparatorHelper.java
deleted file mode 100644 (file)
index 456a731..0000000
+++ /dev/null
@@ -1,705 +0,0 @@
-/**
- * Copyright (c) 2015 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,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.openflowplugin.impl.util;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.net.InetAddresses;
-import com.google.common.primitives.UnsignedBytes;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.MacAddressFilter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchArbitraryBitMask;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchArbitraryBitMask;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.opendaylight.ipv6.arbitrary.bitmask.fields.rev160224.Ipv6ArbitraryMask;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.math.BigInteger;
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-/**
- * @author joe
- * @author sai.marapareddy@gmail.com
- *
- */
-public class MatchComparatorHelper {
-
-    private static final Logger LOG = LoggerFactory.getLogger(MatchComparatorHelper.class);
-    private static final int DEFAULT_SUBNET = 32;
-    private static final int IPV4_MASK_LENGTH = 32;
-    private static final int SHIFT_OCTET_1 = 24;
-    private static final int SHIFT_OCTET_2 = 16;
-    private static final int SHIFT_OCTET_3 = 8;
-    private static final int SHIFT_OCTET_4 = 0;
-    private static final int POSITION_OCTET_1 = 0;
-    private static final int POSITION_OCTET_2 = 1;
-    private static final int POSITION_OCTET_3 = 2;
-    private static final int POSITION_OCTET_4 = 3;
-    private static final String DEFAULT_ARBITRARY_BIT_MASK = "255.255.255.255";
-    private static final String DEFAULT_IPV6_ARBITRARY_BIT_MASK = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
-    private static final String PREFIX_SEPARATOR = "/";
-    private static final int IPV4_ADDRESS_LENGTH = 32;
-    private static final int IPV6_ADDRESS_LENGTH = 128;
-    private static final int BYTE_SIZE = 8;
-
-    /*
-     * Custom EthernetMatch is required because mac address string provided by user in EthernetMatch can be in any case
-     * (upper or lower or mix). Ethernet Match which controller receives from switch is always an upper case string.
-     * Default EthernetMatch equals doesn't use equalsIgnoreCase() and hence it fails. E.g User provided mac address
-     * string in flow match is aa:bb:cc:dd:ee:ff and when controller fetch statistic data, openflow driver library
-     * returns AA:BB:CC:DD:EE:FF and default eqauls fails here.
-     */
-    @VisibleForTesting
-    static boolean ethernetMatchEquals(final EthernetMatch statsEthernetMatch, final EthernetMatch storedEthernetMatch) {
-        boolean verdict = true;
-        final Boolean checkNullValues = checkNullValues(statsEthernetMatch, storedEthernetMatch);
-        if (checkNullValues != null) {
-            verdict = checkNullValues;
-        } else {
-            verdict = ethernetMatchFieldsEquals(statsEthernetMatch.getEthernetSource(),
-                    storedEthernetMatch.getEthernetSource());
-            if (verdict) {
-                verdict = ethernetMatchFieldsEquals(statsEthernetMatch.getEthernetDestination(),
-                        storedEthernetMatch.getEthernetDestination());
-            }
-            if (verdict) {
-                if (statsEthernetMatch.getEthernetType() == null) {
-                    if (storedEthernetMatch.getEthernetType() != null) {
-                        verdict = false;
-                    }
-                } else {
-                    verdict = statsEthernetMatch.getEthernetType().equals(storedEthernetMatch.getEthernetType());
-                }
-            }
-        }
-        return verdict;
-    }
-
-    static boolean ethernetMatchFieldsEquals(final MacAddressFilter statsEthernetMatchFields,
-                                             final MacAddressFilter storedEthernetMatchFields) {
-        boolean verdict = true;
-        final Boolean checkNullValues = checkNullValues(statsEthernetMatchFields, storedEthernetMatchFields);
-        if (checkNullValues != null) {
-            verdict = checkNullValues;
-        } else {
-            verdict = macAddressEquals(statsEthernetMatchFields.getAddress(), storedEthernetMatchFields.getAddress());
-            if (verdict) {
-                verdict = macAddressEquals(statsEthernetMatchFields.getMask(), storedEthernetMatchFields.getMask());
-            }
-        }
-        return verdict;
-    }
-
-    static boolean macAddressEquals(final MacAddress statsMacAddress, final MacAddress storedMacAddress) {
-        boolean verdict = true;
-        final Boolean checkNullValues = checkNullValues(statsMacAddress, storedMacAddress);
-        if (checkNullValues != null) {
-            verdict = checkNullValues;
-        } else {
-            verdict = statsMacAddress.getValue().equalsIgnoreCase(storedMacAddress.getValue());
-        }
-        return verdict;
-    }
-
-    @VisibleForTesting
-    static boolean layer3MatchEquals(final Layer3Match statsLayer3Match, final Layer3Match storedLayer3Match) {
-        boolean verdict = true;
-        if (statsLayer3Match instanceof Ipv4Match && storedLayer3Match instanceof Ipv4Match) {
-            final Ipv4Match statsIpv4Match = (Ipv4Match) statsLayer3Match;
-            final Ipv4Match storedIpv4Match = (Ipv4Match) storedLayer3Match;
-            verdict = MatchComparatorHelper.compareIpv4PrefixNullSafe(storedIpv4Match.getIpv4Destination(),
-                    statsIpv4Match.getIpv4Destination());
-            if (verdict) {
-                verdict = MatchComparatorHelper.compareIpv4PrefixNullSafe(statsIpv4Match.getIpv4Source(),
-                        storedIpv4Match.getIpv4Source());
-            }
-        } else if (statsLayer3Match instanceof Ipv6Match && storedLayer3Match instanceof Ipv6Match) {
-            final Ipv6Match statsIpv6Match = (Ipv6Match) statsLayer3Match;
-            final Ipv6Match storedIpv6Match = (Ipv6Match) storedLayer3Match;
-            verdict = MatchComparatorHelper.compareIpv6PrefixNullSafe(storedIpv6Match.getIpv6Destination(),
-                    statsIpv6Match.getIpv6Destination());
-            if (verdict) {
-                verdict = MatchComparatorHelper.compareIpv6PrefixNullSafe(statsIpv6Match.getIpv6Source(),
-                        storedIpv6Match.getIpv6Source());
-            }
-        } else if (statsLayer3Match instanceof  Ipv4MatchArbitraryBitMask && storedLayer3Match instanceof Ipv4MatchArbitraryBitMask) {
-            // At this moment storedIpv4MatchArbitraryBitMask & statsIpv4MatchArbitraryBitMask will always have non null arbitrary masks.
-            // In case of no / null arbitrary mask, statsLayer3Match will be an instance of Ipv4Match.
-            // Eg:- stats -> 1.0.1.0/255.0.255.0  stored -> 1.1.1.0/255.0.255.0
-            final Ipv4MatchArbitraryBitMask statsIpv4MatchArbitraryBitMask= (Ipv4MatchArbitraryBitMask) statsLayer3Match;
-            final Ipv4MatchArbitraryBitMask storedIpv4MatchArbitraryBitMask = (Ipv4MatchArbitraryBitMask) storedLayer3Match;
-            if ((storedIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask() != null |
-                    storedIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask() != null)) {
-                if (storedIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask() != null) {
-                    String storedDstIpAddress = normalizeIpv4Address(storedIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask(),
-                            storedIpv4MatchArbitraryBitMask.getIpv4DestinationArbitraryBitmask());
-                    String statsDstIpAddress = normalizeIpv4Address(statsIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask(),
-                            statsIpv4MatchArbitraryBitMask.getIpv4DestinationArbitraryBitmask());
-                    if (MatchComparatorHelper.compareStringNullSafe(storedIpv4MatchArbitraryBitMask.getIpv4DestinationArbitraryBitmask().getValue(),
-                            statsIpv4MatchArbitraryBitMask.getIpv4DestinationArbitraryBitmask().getValue())) {
-                        verdict = MatchComparatorHelper.compareStringNullSafe(storedDstIpAddress,
-                                statsDstIpAddress);
-                    } else {
-                        verdict = false;
-                        return verdict;
-                    }
-                }
-                if (storedIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask() != null) {
-                    String storedSrcIpAddress = normalizeIpv4Address(storedIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask()
-                            ,storedIpv4MatchArbitraryBitMask.getIpv4SourceArbitraryBitmask());
-                    String statsSrcIpAddress = normalizeIpv4Address(statsIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask()
-                            ,statsIpv4MatchArbitraryBitMask.getIpv4SourceArbitraryBitmask());
-                    if (MatchComparatorHelper.compareStringNullSafe(storedIpv4MatchArbitraryBitMask.getIpv4SourceArbitraryBitmask().getValue(),
-                            statsIpv4MatchArbitraryBitMask.getIpv4SourceArbitraryBitmask().getValue())) {
-                        verdict = MatchComparatorHelper.compareStringNullSafe(storedSrcIpAddress,
-                                statsSrcIpAddress);
-                    } else {
-                        verdict = false;
-                    }
-                }
-            } else {
-                final Boolean nullCheckOut = checkNullValues(storedLayer3Match, statsLayer3Match);
-                if (nullCheckOut != null) {
-                    verdict = nullCheckOut;
-                } else {
-                    verdict = storedLayer3Match.equals(statsLayer3Match);
-                }
-            }
-        } else if (statsLayer3Match instanceof Ipv4Match && storedLayer3Match instanceof Ipv4MatchArbitraryBitMask) {
-            // Here stored netmask is an instance of Ipv4MatchArbitraryBitMask, when it is pushed in to switch
-            // it automatically converts it in to cidr format in case of certain subnet masks ( consecutive ones or zeroes)
-            // Eg:- stats src/dest -> 1.1.1.0/24  stored src/dest -> 1.1.1.0/255.255.255.0
-            final Ipv4Match statsIpv4Match = (Ipv4Match) statsLayer3Match;
-            final Ipv4MatchArbitraryBitMask storedIpv4MatchArbitraryBitMask = (Ipv4MatchArbitraryBitMask) storedLayer3Match;
-            if (storedIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask() != null) {
-                Ipv4Prefix ipv4PrefixDestination;
-                if (storedIpv4MatchArbitraryBitMask.getIpv4DestinationArbitraryBitmask() != null) {
-                    byte[] destByteMask = convertArbitraryMaskToByteArray(storedIpv4MatchArbitraryBitMask.getIpv4DestinationArbitraryBitmask());
-                    ipv4PrefixDestination = createPrefix(storedIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask(), destByteMask);
-                } else {
-                    ipv4PrefixDestination = createPrefix(storedIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask());
-                }
-                verdict = MatchComparatorHelper.compareIpv4PrefixNullSafe(ipv4PrefixDestination, statsIpv4Match.getIpv4Destination());
-                if (verdict == false) {
-                    return verdict;
-                }
-            }
-            if (storedIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask() != null) {
-                Ipv4Prefix ipv4PrefixSource;
-                if (storedIpv4MatchArbitraryBitMask.getIpv4SourceArbitraryBitmask() != null) {
-                    byte[] srcByteMask = convertArbitraryMaskToByteArray(storedIpv4MatchArbitraryBitMask.getIpv4SourceArbitraryBitmask());
-                    ipv4PrefixSource = createPrefix(storedIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask(), srcByteMask);
-                } else {
-                    ipv4PrefixSource = createPrefix(storedIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask());
-                }
-                verdict = MatchComparatorHelper.compareIpv4PrefixNullSafe(ipv4PrefixSource, statsIpv4Match.getIpv4Source());
-            }
-        } else if (statsLayer3Match instanceof Ipv4MatchArbitraryBitMask && storedLayer3Match instanceof Ipv4Match) {
-            // Here stored netmask is an instance of Ipv4MatchArbitraryBitMask, when it is pushed in to switch
-            // it automatically converts it in to cidr format in case of certain subnet masks ( consecutive ones or zeroes)
-            // Eg:- stats src/dest -> 1.1.1.0/24  stored src/dest -> 1.1.1.0/255.255.255.0
-            final Ipv4Match storedIpv4Match = (Ipv4Match) storedLayer3Match;
-            final Ipv4MatchArbitraryBitMask statsIpv4MatchArbitraryBitMask = (Ipv4MatchArbitraryBitMask) statsLayer3Match;
-            if (statsIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask() != null) {
-                Ipv4Prefix ipv4PrefixDestination;
-                if (statsIpv4MatchArbitraryBitMask.getIpv4DestinationArbitraryBitmask() != null) {
-                    byte[] destByteMask = convertArbitraryMaskToByteArray(statsIpv4MatchArbitraryBitMask.getIpv4DestinationArbitraryBitmask());
-                    ipv4PrefixDestination = createPrefix(statsIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask(), destByteMask);
-                } else {
-                    ipv4PrefixDestination = createPrefix(statsIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask());
-                }
-                verdict = MatchComparatorHelper.compareIpv4PrefixNullSafe(ipv4PrefixDestination, storedIpv4Match.getIpv4Destination());
-                if (verdict == false) {
-                    return verdict;
-                }
-            }
-            if (statsIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask() != null) {
-                Ipv4Prefix ipv4PrefixSource;
-                if (statsIpv4MatchArbitraryBitMask.getIpv4SourceArbitraryBitmask() != null) {
-                    byte[] srcByteMask = convertArbitraryMaskToByteArray(statsIpv4MatchArbitraryBitMask.getIpv4SourceArbitraryBitmask());
-                    ipv4PrefixSource = createPrefix(statsIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask(), srcByteMask);
-                } else {
-                    ipv4PrefixSource = createPrefix(statsIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask());
-                }
-                verdict = MatchComparatorHelper.compareIpv4PrefixNullSafe(ipv4PrefixSource, storedIpv4Match.getIpv4Source());
-            }
-        } else if (statsLayer3Match instanceof Ipv6MatchArbitraryBitMask && storedLayer3Match instanceof Ipv6MatchArbitraryBitMask) {
-            // At this moment storedIpv6MatchArbitraryBitMask & statsIpv6MatchArbitraryBitMask will always have non null arbitrary masks.
-            // In case of no / null arbitrary mask, statsLayer3Match will be an instance of Ipv6Match.
-            // Eg:- stats src/dest  -> 2001:2001:2001:2001:2001:2001:2001:2001/FFFF:FFFF:FFFF:FFFF:0000:FFFF:FFFF:FFF0
-            //     stored src/dest  -> 2001:2001:2001:2001:2001:2001:2001:2001/FFFF:FFFF:FFFF:FFFF:0000:FFFF:FFFF:FFF0
-            final Ipv6MatchArbitraryBitMask statsIpv6MatchArbitraryBitMask= (Ipv6MatchArbitraryBitMask) statsLayer3Match;
-            final Ipv6MatchArbitraryBitMask storedIpv6MatchArbitraryBitMask = (Ipv6MatchArbitraryBitMask) storedLayer3Match;
-            if ((storedIpv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask() != null |
-                    storedIpv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask() != null)) {
-                if (storedIpv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask() != null) {
-                    String storedDstIpAddress = normalizeIpv6Address(storedIpv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask(),
-                            storedIpv6MatchArbitraryBitMask.getIpv6DestinationArbitraryBitmask());
-                    String statsDstIpAddress = normalizeIpv6Address(statsIpv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask(),
-                            statsIpv6MatchArbitraryBitMask.getIpv6DestinationArbitraryBitmask());
-                    String storedDstMask = extractIpv6CanonicalForm(storedIpv6MatchArbitraryBitMask.
-                            getIpv6DestinationArbitraryBitmask().getValue()).getHostAddress();
-                    String statsDstMask = extractIpv6CanonicalForm(statsIpv6MatchArbitraryBitMask.
-                            getIpv6DestinationArbitraryBitmask().getValue()).getHostAddress();
-                    if (MatchComparatorHelper.compareStringNullSafe(storedDstMask,statsDstMask)) {
-                        verdict = MatchComparatorHelper.compareStringNullSafe(storedDstIpAddress,
-                                statsDstIpAddress);
-                    } else {
-                        verdict = false;
-                        return verdict;
-                    }
-                }
-                if (storedIpv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask() != null) {
-                    String storedSrcIpAddress = normalizeIpv6Address(storedIpv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask()
-                            ,storedIpv6MatchArbitraryBitMask.getIpv6SourceArbitraryBitmask());
-                    String statsSrcIpAddress = normalizeIpv6Address(statsIpv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask()
-                            ,statsIpv6MatchArbitraryBitMask.getIpv6SourceArbitraryBitmask());
-                    String storedSrcMask = extractIpv6CanonicalForm(storedIpv6MatchArbitraryBitMask.
-                            getIpv6SourceArbitraryBitmask().getValue()).getHostAddress();
-                    String statsSrcMask = extractIpv6CanonicalForm(statsIpv6MatchArbitraryBitMask.
-                            getIpv6SourceArbitraryBitmask().getValue()).getHostAddress();
-                    if (MatchComparatorHelper.compareStringNullSafe(storedSrcMask, statsSrcMask)) {
-                        verdict = MatchComparatorHelper.compareStringNullSafe(storedSrcIpAddress,
-                                statsSrcIpAddress);
-                    } else {
-                        verdict = false;
-                    }
-                }
-            } else {
-                final Boolean nullCheckOut = checkNullValues(storedLayer3Match, statsLayer3Match);
-                if (nullCheckOut != null) {
-                    verdict = nullCheckOut;
-                } else {
-                    verdict = storedLayer3Match.equals(statsLayer3Match);
-                }
-            }
-        } else if (statsLayer3Match instanceof Ipv6Match && storedLayer3Match instanceof Ipv6MatchArbitraryBitMask) {
-            // Here stored netmask is an instance of Ipv6MatchArbitraryBitMask, when it is pushed in to switch
-            // it automatically converts it in to cidr format in case of certain subnet masks ( consecutive ones or zeroes)
-            // Eg:- stats src/dest -> 2001:2001:2001:2001:2001:2001:2001:2001/124
-            // stored src/dest -> 2001:2001:2001:2001:2001:2001:2001:2001/FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFF0
-            final Ipv6Match statsIpv6Match = (Ipv6Match) statsLayer3Match;
-            final Ipv6MatchArbitraryBitMask storedIpv6MatchArbitraryBitMask = (Ipv6MatchArbitraryBitMask) storedLayer3Match;
-            if (storedIpv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask() != null) {
-                Ipv6Prefix ipv6PrefixDestination;
-                if (storedIpv6MatchArbitraryBitMask.getIpv6DestinationArbitraryBitmask() != null) {
-                    byte[] destByteMask = convertIpv6ArbitraryMaskToByteArray(storedIpv6MatchArbitraryBitMask.getIpv6DestinationArbitraryBitmask());
-                    ipv6PrefixDestination = createPrefix(storedIpv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask(), destByteMask);
-                } else {
-                    ipv6PrefixDestination = createPrefix(storedIpv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask());
-                }
-                verdict = MatchComparatorHelper.compareIpv6PrefixNullSafe(ipv6PrefixDestination, statsIpv6Match.getIpv6Destination());
-                if (verdict == false) {
-                    return verdict;
-                }
-            }
-            if (storedIpv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask() != null) {
-                Ipv6Prefix ipv6PrefixSource;
-                if (storedIpv6MatchArbitraryBitMask.getIpv6SourceArbitraryBitmask() != null) {
-                    byte[] srcByteMask = convertIpv6ArbitraryMaskToByteArray(storedIpv6MatchArbitraryBitMask.getIpv6SourceArbitraryBitmask());
-                    ipv6PrefixSource = createPrefix(storedIpv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask(), srcByteMask);
-                } else {
-                    ipv6PrefixSource = createPrefix(storedIpv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask());
-                }
-                verdict = MatchComparatorHelper.compareIpv6PrefixNullSafe(ipv6PrefixSource, statsIpv6Match.getIpv6Source());
-            }
-        } else if (statsLayer3Match instanceof Ipv6MatchArbitraryBitMask && storedLayer3Match instanceof Ipv6Match) {
-            // Here stored netmask is an instance of Ipv6MatchArbitraryBitMask, when it is pushed in to switch
-            // it automatically converts it in to cidr format in case of certain subnet masks ( consecutive ones or zeroes)
-            // Eg:- stats src/dest -> 2001:2001:2001:2001:2001:2001:2001:2001/124
-            // stored src/dest -> 2001:2001:2001:2001:2001:2001:2001:2001/FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFF0
-            final Ipv6Match storedIpv6Match = (Ipv6Match) storedLayer3Match;
-            final Ipv6MatchArbitraryBitMask statsIpv6MatchArbitraryBitMask = (Ipv6MatchArbitraryBitMask) statsLayer3Match;
-            if (statsIpv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask() != null) {
-                Ipv6Prefix ipv6PrefixDestination;
-                if (statsIpv6MatchArbitraryBitMask.getIpv6DestinationArbitraryBitmask() != null) {
-                    byte[] destByteMask = convertIpv6ArbitraryMaskToByteArray(statsIpv6MatchArbitraryBitMask.getIpv6DestinationArbitraryBitmask());
-                    ipv6PrefixDestination = createPrefix(statsIpv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask(), destByteMask);
-                } else {
-                    ipv6PrefixDestination = createPrefix(statsIpv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask());
-                }
-                verdict = MatchComparatorHelper.compareIpv6PrefixNullSafe(ipv6PrefixDestination, storedIpv6Match.getIpv6Destination());
-                if (verdict == false) {
-                    return verdict;
-                }
-            }
-            if (statsIpv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask() != null) {
-                Ipv6Prefix ipv6PrefixSource;
-                if (statsIpv6MatchArbitraryBitMask.getIpv6SourceArbitraryBitmask() != null) {
-                    byte[] srcByteMask = convertIpv6ArbitraryMaskToByteArray(statsIpv6MatchArbitraryBitMask.getIpv6SourceArbitraryBitmask());
-                    ipv6PrefixSource = createPrefix(statsIpv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask(), srcByteMask);
-                } else {
-                    ipv6PrefixSource = createPrefix(statsIpv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask());
-                }
-                verdict = MatchComparatorHelper.compareIpv6PrefixNullSafe(ipv6PrefixSource, storedIpv6Match.getIpv6Source());
-            }
-        } else if (statsLayer3Match instanceof ArpMatch && storedLayer3Match instanceof ArpMatch) {
-            verdict = arpMatchEquals((ArpMatch)statsLayer3Match, (ArpMatch)storedLayer3Match);
-        } else {
-            final Boolean nullCheckOut = checkNullValues(storedLayer3Match, statsLayer3Match);
-            if (nullCheckOut != null) {
-                verdict = nullCheckOut;
-            } else {
-                verdict = storedLayer3Match.equals(statsLayer3Match);
-            }
-        }
-        return verdict;
-    }
-
-    static boolean arpMatchEquals(final ArpMatch statsArpMatch, final ArpMatch storedArpMatch) {
-
-        Integer statsOp = statsArpMatch.getArpOp();
-        Integer storedOp = storedArpMatch.getArpOp();
-
-        Boolean nullCheck = checkNullValues(statsOp, storedOp);
-        if (nullCheck != null) {
-            if (nullCheck == false) {
-                return false;
-            }
-        } else if (!statsOp.equals(storedOp)) {
-            return false;
-        }
-
-        Ipv4Prefix statsIp = statsArpMatch.getArpSourceTransportAddress();
-        Ipv4Prefix storedIp = storedArpMatch.getArpSourceTransportAddress();
-        if (!compareIpv4PrefixNullSafe(statsIp, storedIp)) {
-            return false;
-        }
-
-        statsIp = statsArpMatch.getArpTargetTransportAddress();
-        storedIp = storedArpMatch.getArpTargetTransportAddress();
-        if (!compareIpv4PrefixNullSafe(statsIp, storedIp)) {
-            return false;
-        }
-
-        MacAddressFilter statsMac = statsArpMatch.getArpSourceHardwareAddress();
-        MacAddressFilter storedMac = storedArpMatch.getArpSourceHardwareAddress();
-        if (!ethernetMatchFieldsEquals(statsMac, storedMac)) {
-            return false;
-        }
-
-        statsMac = statsArpMatch.getArpTargetHardwareAddress();
-        storedMac = storedArpMatch.getArpTargetHardwareAddress();
-        if (!ethernetMatchFieldsEquals(statsMac, storedMac)) {
-            return false;
-        }
-
-        return true;
-    }
-
-
-    /**
-     * TODO: why don't we use the default Ipv4Prefix.equals()?
-     *
-     * @param statsIpAddress
-     * @param storedIpAddress
-     * @return true if IPv4prefixes equals
-     */
-    static boolean IpAddressEquals(final Ipv4Prefix statsIpAddress, final Ipv4Prefix storedIpAddress) {
-        final IntegerIpAddress statsIpAddressInt = MatchComparatorHelper.strIpToIntIp(statsIpAddress.getValue());
-        final IntegerIpAddress storedIpAddressInt = MatchComparatorHelper.strIpToIntIp(storedIpAddress.getValue());
-
-        if (ipAndMaskBasedMatch(statsIpAddressInt, storedIpAddressInt)) {
-            return true;
-        }
-        if (ipBasedMatch(statsIpAddressInt, storedIpAddressInt)) {
-            return true;
-        }
-        return false;
-    }
-
-    static boolean ipAndMaskBasedMatch(final IntegerIpAddress statsIpAddressInt,
-                                       final IntegerIpAddress storedIpAddressInt) {
-        return ((statsIpAddressInt.getIp() & statsIpAddressInt.getMask()) == (storedIpAddressInt.getIp() & storedIpAddressInt
-                .getMask()));
-    }
-
-    static boolean ipBasedMatch(final IntegerIpAddress statsIpAddressInt, final IntegerIpAddress storedIpAddressInt) {
-        return (statsIpAddressInt.getIp() == storedIpAddressInt.getIp());
-    }
-
-
-    private static boolean IpAddressEquals(Ipv6Prefix statsIpv6, Ipv6Prefix storedIpv6) {
-        final String[] statsIpMask = statsIpv6.getValue().split("/");
-        final String[] storedIpMask = storedIpv6.getValue().split("/");
-        if (! (statsIpMask.length > 1 && storedIpMask.length > 1 &&  statsIpMask[1].equals(storedIpMask[1]))){
-            return false;
-        }
-
-        final int prefix = Integer.parseInt(statsIpMask[1]);
-        final int byteIndex = prefix/BYTE_SIZE;
-        final int lastByteBits = BYTE_SIZE - (prefix % BYTE_SIZE);
-        final InetAddress statsIp = InetAddresses.forString(statsIpMask[0]);
-        final InetAddress storedIp = InetAddresses.forString(storedIpMask[0]);
-        byte[] statsIpArr = Arrays.copyOfRange(statsIp.getAddress(),0,byteIndex+1);
-        byte[] storedIpArr = Arrays.copyOfRange(storedIp.getAddress(),0,byteIndex+1);
-        statsIpArr[byteIndex] = (byte) (statsIpArr[byteIndex] & (0XFF << lastByteBits));
-        storedIpArr[byteIndex] = (byte) (storedIpArr[byteIndex] & (0XFF << lastByteBits));
-        if(Arrays.equals(statsIpArr,storedIpArr)) {
-            return true;
-        }
-        return false;
-    }
-
-    static Boolean checkNullValues(final Object v1, final Object v2) {
-        Boolean verdict = null;
-        if (v1 == null && v2 != null) {
-            verdict = Boolean.FALSE;
-        } else if (v1 != null && v2 == null) {
-            verdict = Boolean.FALSE;
-        } else if (v1 == null && v2 == null) {
-            verdict = Boolean.TRUE;
-        }
-        return verdict;
-    }
-
-    static boolean compareIpv4PrefixNullSafe(final Ipv4Prefix statsIpv4, final Ipv4Prefix storedIpv4) {
-        boolean verdict = true;
-        final Boolean checkDestNullValuesOut = checkNullValues(storedIpv4, statsIpv4);
-        if (checkDestNullValuesOut != null) {
-            verdict = checkDestNullValuesOut;
-        } else if (!IpAddressEquals(statsIpv4, storedIpv4)) {
-            verdict = false;
-        }
-        return verdict;
-    }
-
-    static boolean compareStringNullSafe(final String stringA, final String stringB) {
-        boolean verdict = true;
-        final Boolean checkDestNullValuesOut = checkNullValues(stringA,stringB);
-        if (checkDestNullValuesOut != null) {
-            verdict = checkDestNullValuesOut;
-        } else if (!stringA.equals(stringB)) {
-            verdict = false;
-        }
-        return verdict;
-    }
-
-    private static boolean compareIpv6PrefixNullSafe(Ipv6Prefix statsIpv6, Ipv6Prefix storedIpv6) {
-        boolean verdict = true;
-        final Boolean checkDestNullValuesOut = checkNullValues(statsIpv6, storedIpv6);
-        if (checkDestNullValuesOut != null) {
-            verdict = checkDestNullValuesOut;
-        } else if (!IpAddressEquals(statsIpv6, storedIpv6)) {
-            verdict = false;
-        }
-        return verdict;
-    }
-
-    /**
-     * Method return integer version of ip address. Converted int will be mask if mask specified
-     */
-    static IntegerIpAddress strIpToIntIp(final String ipAddresss) {
-
-        final String[] parts = ipAddresss.split("/");
-        final String ip = parts[0];
-        int prefix;
-
-        if (parts.length < 2) {
-            prefix = DEFAULT_SUBNET;
-        } else {
-            prefix = Integer.parseInt(parts[1]);
-            if (prefix < 0 || prefix > IPV4_MASK_LENGTH) {
-                final StringBuilder stringBuilder = new StringBuilder(
-                        "Valid values for mask are from range 0 - 32. Value ");
-                stringBuilder.append(prefix);
-                stringBuilder.append(" is invalid.");
-                throw new IllegalStateException(stringBuilder.toString());
-            }
-        }
-
-        IntegerIpAddress integerIpAddress = null;
-
-        final Inet4Address addr = ((Inet4Address) InetAddresses.forString(ip));
-        final byte[] addrBytes = addr.getAddress();
-        // FIXME: what is meaning of anding with 0xFF? Probably could be removed.
-        final int ipInt = ((addrBytes[POSITION_OCTET_1] & 0xFF) << SHIFT_OCTET_1)
-                | ((addrBytes[POSITION_OCTET_2] & 0xFF) << SHIFT_OCTET_2)
-                | ((addrBytes[POSITION_OCTET_3] & 0xFF) << SHIFT_OCTET_3)
-                | ((addrBytes[POSITION_OCTET_4] & 0xFF) << SHIFT_OCTET_4);
-
-        // FIXME: Is this valid?
-        final int mask = 0xffffffff << DEFAULT_SUBNET - prefix;
-
-        integerIpAddress = new IntegerIpAddress(ipInt, mask);
-
-        return integerIpAddress;
-    }
-
-    static boolean isArbitraryBitMask(byte[] byteMask) {
-        if (byteMask == null) {
-            return false;
-        } else {
-            ArrayList<Integer> integerMaskArrayList = new ArrayList<Integer>();
-            String maskInBits;
-            // converting byte array to bits
-            maskInBits = new BigInteger(1, byteMask).toString(2);
-            ArrayList<String> stringMaskArrayList = new ArrayList<String>(Arrays.asList(maskInBits.split("(?!^)")));
-            for(String string:stringMaskArrayList){
-                integerMaskArrayList.add(Integer.parseInt(string));
-            }
-            return checkArbitraryBitMask(integerMaskArrayList);
-        }
-    }
-
-    static boolean checkArbitraryBitMask(ArrayList<Integer> arrayList) {
-        if (arrayList.size()>0 && arrayList.size()< IPV4_MASK_LENGTH ) {
-            // checks 0*1* case - Leading zeros in arrayList are truncated
-            return true;
-        } else {
-            //checks 1*0*1 case
-            for(int i=0; i<arrayList.size()-1;i++) {
-                if(arrayList.get(i) ==0 && arrayList.get(i+1) == 1) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    static final byte[] convertArbitraryMaskToByteArray(DottedQuad mask) {
-        String maskValue;
-        if (mask.getValue() != null) {
-            maskValue  = mask.getValue();
-        } else {
-            maskValue = DEFAULT_ARBITRARY_BIT_MASK;
-        }
-        InetAddress maskInIpFormat = null;
-        try {
-            maskInIpFormat = InetAddress.getByName(maskValue);
-        } catch (UnknownHostException e) {
-            LOG.error("Failed to recognize the host while converting mask ", e);
-        }
-        byte[] bytes = maskInIpFormat.getAddress();
-        return bytes;
-    }
-
-    private static final byte[] convertIpv6ArbitraryMaskToByteArray ( final Ipv6ArbitraryMask mask) {
-        String maskValue;
-        if (mask.getValue() != null) {
-            maskValue = mask.getValue();
-        } else {
-            maskValue = DEFAULT_IPV6_ARBITRARY_BIT_MASK;
-        }
-        InetAddress maskInIpv6Format = null;
-        try {
-            maskInIpv6Format = InetAddress.getByName(maskValue);
-        } catch (UnknownHostException e) {
-            LOG.error("Failed to convert string mask value to ipv6 format ", e);
-        }
-        return maskInIpv6Format.getAddress();
-    }
-
-    static String normalizeIpv4Address(Ipv4Address ipAddress, DottedQuad netMask) {
-        String actualIpAddress="";
-        String[] netMaskParts = netMask.getValue().split("\\.");
-        String[] ipAddressParts = ipAddress.getValue().split("\\.");
-
-        for (int i=0; i<ipAddressParts.length;i++) {
-            int integerFormatIpAddress=Integer.parseInt(ipAddressParts[i]);
-            int integerFormatNetMask=Integer.parseInt(netMaskParts[i]);
-            int ipAddressPart=(integerFormatIpAddress) & (integerFormatNetMask);
-            actualIpAddress += ipAddressPart;
-            if (i != ipAddressParts.length -1 ) {
-                actualIpAddress = actualIpAddress+".";
-            }
-        }
-        return actualIpAddress;
-    }
-
-    private static String normalizeIpv6Address(final Ipv6Address ipAddress, final Ipv6ArbitraryMask netMask) {
-        byte[] ipAddressParts = convertIpv6ToBytes(ipAddress.getValue());
-        byte[] netMaskParts  = convertIpv6ToBytes(netMask.getValue());
-        byte[] actualIpv6Bytes = new byte[16];
-
-        for (int i=0; i<ipAddressParts.length;i++) {
-            byte ipAddressPart= (byte) (ipAddressParts[i] & netMaskParts[i]);
-            actualIpv6Bytes[i] = ipAddressPart;
-        }
-        InetAddress ipv6Address = null;
-        try {
-            ipv6Address = InetAddress.getByAddress(actualIpv6Bytes);
-        } catch (UnknownHostException e) {
-            LOG.error("Failed to recognize the host while normalizing IPv6 address from bytes ", e);
-        }
-        return ipv6Address.getHostAddress();
-    }
-
-    private static byte[] convertIpv6ToBytes(final String ipv6Address) {
-        return extractIpv6CanonicalForm(ipv6Address).getAddress();
-    }
-
-    private static InetAddress extractIpv6CanonicalForm(final String ipv6Address) {
-        InetAddress address = null;
-        try {
-            address = InetAddress.getByName(ipv6Address);
-        } catch (UnknownHostException e) {
-            LOG.error("Failed to recognize the host while converting IPv6 to bytes ", e);
-        }
-        return address;
-    }
-
-    static Ipv4Prefix createPrefix(final Ipv4Address ipv4Address, final byte [] bytemask){
-        return createPrefix(ipv4Address, String.valueOf(countBits(bytemask)));
-    }
-
-    private static Ipv6Prefix createPrefix(final Ipv6Address ipv6Address, final byte [] bytemask) {
-        return createPrefix(ipv6Address, String.valueOf(countBits(bytemask)));
-    }
-
-    private static Ipv6Prefix createPrefix(final Ipv6Address ipv6Address, final String mask) {
-        if (mask != null && !mask.isEmpty()) {
-            return new Ipv6Prefix(ipv6Address.getValue() + PREFIX_SEPARATOR + mask);
-        } else {
-            return new Ipv6Prefix(ipv6Address.getValue() + PREFIX_SEPARATOR + IPV6_ADDRESS_LENGTH);
-        }
-    }
-
-    private static Ipv6Prefix createPrefix(final Ipv6Address ipv6Address) {
-        return new Ipv6Prefix(ipv6Address.getValue() + PREFIX_SEPARATOR + IPV6_ADDRESS_LENGTH);
-    }
-
-    static int countBits(final byte[] mask) {
-        int netmask = 0;
-        for (byte b : mask) {
-            netmask += Integer.bitCount(UnsignedBytes.toInt(b));
-        }
-        return netmask;
-    }
-
-    static Ipv4Prefix createPrefix(final Ipv4Address ipv4Address){
-        return new Ipv4Prefix(ipv4Address.getValue() + PREFIX_SEPARATOR + IPV4_ADDRESS_LENGTH);
-    }
-
-    static Ipv4Prefix createPrefix(final Ipv4Address ipv4Address, final String mask){
-        /*
-         * Ipv4Address has already validated the address part of the prefix,
-         * It is mandated to comply to the same regexp as the address
-         * There is absolutely no point rerunning additional checks vs this
-         * Note - there is no canonical form check here!!!
-         */
-        if (null != mask && !mask.isEmpty()) {
-            return new Ipv4Prefix(ipv4Address.getValue() + PREFIX_SEPARATOR + mask);
-        } else {
-            return new Ipv4Prefix(ipv4Address.getValue() + PREFIX_SEPARATOR + IPV4_ADDRESS_LENGTH);
-        }
-    }
-}
diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MatchNormalizationUtil.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MatchNormalizationUtil.java
new file mode 100644 (file)
index 0000000..0aaffc0
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * 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.impl.util;
+
+import static org.opendaylight.openflowplugin.impl.util.AddressNormalizationUtil.normalizeIpv4Arbitrary;
+import static org.opendaylight.openflowplugin.impl.util.AddressNormalizationUtil.normalizeIpv4Prefix;
+import static org.opendaylight.openflowplugin.impl.util.AddressNormalizationUtil.normalizeIpv6AddressWithoutMask;
+import static org.opendaylight.openflowplugin.impl.util.AddressNormalizationUtil.normalizeIpv6Arbitrary;
+import static org.opendaylight.openflowplugin.impl.util.AddressNormalizationUtil.normalizeIpv6Prefix;
+import static org.opendaylight.openflowplugin.impl.util.AddressNormalizationUtil.normalizeMacAddress;
+import static org.opendaylight.openflowplugin.impl.util.AddressNormalizationUtil.normalizeMacAddressMask;
+import static org.opendaylight.openflowplugin.impl.util.AddressNormalizationUtil.normalizeProtocolAgnosticPort;
+
+import com.google.common.collect.ImmutableMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import javax.annotation.Nonnull;
+import org.opendaylight.openflowplugin.api.OFConstants;
+import org.opendaylight.openflowplugin.extension.api.GroupingLooseResolver;
+import org.opendaylight.openflowplugin.openflow.md.core.extension.ExtensionResolvers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpSourceHardwareAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpTargetHardwareAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchArbitraryBitMask;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchArbitraryBitMask;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.TunnelIpv4Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.TunnelIpv4MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNotifUpdateFlowStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNotifUpdateFlowStatsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralExtensionListGrouping;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+
+/**
+ * Utility class for match normalization
+ */
+public final class MatchNormalizationUtil {
+    // Cache normalizers for common OpenFlow versions
+    private static final Map<Short, Set<Function<MatchBuilder, MatchBuilder>>> NORMALIZERS = ImmutableMap
+            .<Short, Set<Function<MatchBuilder, MatchBuilder>>>builder()
+            .put(OFConstants.OFP_VERSION_1_0, createNormalizers(OFConstants.OFP_VERSION_1_0).collect(Collectors.toSet()))
+            .put(OFConstants.OFP_VERSION_1_3, createNormalizers(OFConstants.OFP_VERSION_1_3).collect(Collectors.toSet()))
+            .build();
+
+    private MatchNormalizationUtil() {
+        throw new RuntimeException("Creating instance of util classes is prohibited");
+    }
+
+    /**
+     * Normalize match.
+     *
+     * @param match   the OpenFlow match
+     * @param version the OpenFlow version
+     * @return normalized OpenFlow match
+     */
+    @Nonnull
+    public static Match normalizeMatch(@Nonnull final Match match, final short version) {
+        final MatchBuilder matchBuilder = new MatchBuilder(match);
+
+        Optional.ofNullable(NORMALIZERS.get(version))
+                .orElseGet(() -> createNormalizers(version).collect(Collectors.toSet()))
+                .forEach(normalizer -> normalizer.apply(matchBuilder));
+
+        return matchBuilder.build();
+    }
+
+    @Nonnull
+    private static Stream<Function<MatchBuilder, MatchBuilder>> createNormalizers(final short version) {
+        return Stream.of(
+                MatchNormalizationUtil::normalizeExtensionMatch,
+                MatchNormalizationUtil::normalizeEthernetMatch,
+                MatchNormalizationUtil::normalizeArpMatch,
+                MatchNormalizationUtil::normalizeTunnelIpv4Match,
+                MatchNormalizationUtil::normalizeIpv4Match,
+                MatchNormalizationUtil::normalizeIpv4MatchArbitraryBitMask,
+                MatchNormalizationUtil::normalizeIpv6Match,
+                MatchNormalizationUtil::normalizeIpv6MatchArbitraryBitMask,
+                (match) -> normalizeInPortMatch(match, version),
+                (match) -> normalizeInPhyPortMatch(match, version));
+    }
+
+    @Nonnull
+    @SuppressWarnings("unchecked")
+    private static MatchBuilder normalizeExtensionMatch(@Nonnull final MatchBuilder match) {
+        final GroupingLooseResolver<GeneralExtensionListGrouping> matchExtensionResolver =
+                ExtensionResolvers.getMatchExtensionResolver();
+
+        return matchExtensionResolver
+                .getExtension(match.build())
+                .transform(statExt -> Optional.ofNullable(statExt.getExtensionList())
+                        .map(extensionLists -> {
+                            matchExtensionResolver.getClasses().forEach(aClass -> match
+                                    .removeAugmentation((Class<? extends Augmentation<Match>>) aClass));
+
+                            return match.addAugmentation(
+                                    GeneralAugMatchNotifUpdateFlowStats.class,
+                                    new GeneralAugMatchNotifUpdateFlowStatsBuilder()
+                                            .setExtensionList(extensionLists)
+                                            .build());
+                        })
+                        .orElse(match))
+                .or(match);
+    }
+
+    @Nonnull
+    private static MatchBuilder normalizeInPortMatch(@Nonnull final MatchBuilder match, final short version) {
+        return Optional
+                .ofNullable(match.getInPort())
+                .flatMap(inPort -> Optional.ofNullable(normalizeProtocolAgnosticPort(inPort, version)))
+                .map(inPortUri -> match.setInPort(new NodeConnectorId(inPortUri)))
+                .orElse(match);
+    }
+
+    @Nonnull
+    private static MatchBuilder normalizeInPhyPortMatch(@Nonnull final MatchBuilder match, final short version) {
+        return Optional
+                .ofNullable(match.getInPhyPort())
+                .flatMap(inPhyPort -> Optional.ofNullable(normalizeProtocolAgnosticPort(inPhyPort, version)))
+                .map(inPhyPortUri -> match.setInPhyPort(new NodeConnectorId(inPhyPortUri)))
+                .orElse(match);
+    }
+
+    @Nonnull
+    private static MatchBuilder normalizeArpMatch(@Nonnull final MatchBuilder match) {
+        return Optional
+                .ofNullable(match.getLayer3Match())
+                .filter(ArpMatch.class::isInstance)
+                .map(ArpMatch.class::cast)
+                .map(arp -> match.setLayer3Match(new ArpMatchBuilder(arp)
+                        .setArpSourceHardwareAddress(Optional
+                                .ofNullable(arp.getArpSourceHardwareAddress())
+                                .map(arpSource -> new ArpSourceHardwareAddressBuilder(arpSource)
+                                        .setAddress(normalizeMacAddress(arpSource.getAddress()))
+                                        .setMask(normalizeMacAddress(arpSource.getMask()))
+                                        .build())
+                                .orElse(arp.getArpSourceHardwareAddress()))
+                        .setArpTargetHardwareAddress(Optional
+                                .ofNullable(arp.getArpTargetHardwareAddress())
+                                .map(arpTarget -> new ArpTargetHardwareAddressBuilder(arpTarget)
+                                        .setAddress(normalizeMacAddress(arpTarget.getAddress()))
+                                        .setMask(normalizeMacAddress(arpTarget.getMask()))
+                                        .build())
+                                .orElse(arp.getArpTargetHardwareAddress()))
+                        .setArpSourceTransportAddress(normalizeIpv4Prefix(arp.getArpSourceTransportAddress()))
+                        .setArpTargetTransportAddress(normalizeIpv4Prefix(arp.getArpTargetTransportAddress()))
+                        .build())
+                )
+                .orElse(match);
+    }
+
+
+    @Nonnull
+    private static MatchBuilder normalizeTunnelIpv4Match(@Nonnull final MatchBuilder match) {
+        return Optional
+                .ofNullable(match.getLayer3Match())
+                .filter(TunnelIpv4Match.class::isInstance)
+                .map(TunnelIpv4Match.class::cast)
+                .map(tunnelIpv4 -> match.setLayer3Match(new TunnelIpv4MatchBuilder(tunnelIpv4)
+                        .setTunnelIpv4Source(normalizeIpv4Prefix(tunnelIpv4.getTunnelIpv4Source()))
+                        .setTunnelIpv4Destination(normalizeIpv4Prefix(tunnelIpv4.getTunnelIpv4Destination()))
+                        .build()))
+                .orElse(match);
+    }
+
+    @Nonnull
+    private static MatchBuilder normalizeIpv4Match(@Nonnull final MatchBuilder match) {
+        return Optional
+                .ofNullable(match.getLayer3Match())
+                .filter(Ipv4Match.class::isInstance)
+                .map(Ipv4Match.class::cast)
+                .map(ipv4 -> match.setLayer3Match(new Ipv4MatchBuilder(ipv4)
+                        .setIpv4Source(normalizeIpv4Prefix(ipv4.getIpv4Source()))
+                        .setIpv4Destination(normalizeIpv4Prefix(ipv4.getIpv4Destination()))
+                        .build()))
+                .orElse(match);
+    }
+
+    @Nonnull
+    private static MatchBuilder normalizeIpv4MatchArbitraryBitMask(@Nonnull final MatchBuilder match) {
+        return Optional
+                .ofNullable(match.getLayer3Match())
+                .filter(Ipv4MatchArbitraryBitMask.class::isInstance)
+                .map(Ipv4MatchArbitraryBitMask.class::cast)
+                .map(ipv4arbitrary -> match.setLayer3Match(new Ipv4MatchBuilder()
+                        .setIpv4Source(normalizeIpv4Arbitrary(
+                                ipv4arbitrary.getIpv4SourceAddressNoMask(),
+                                ipv4arbitrary.getIpv4SourceArbitraryBitmask()))
+                        .setIpv4Destination(normalizeIpv4Arbitrary(
+                                ipv4arbitrary.getIpv4DestinationAddressNoMask(),
+                                ipv4arbitrary.getIpv4DestinationArbitraryBitmask()))
+                        .build()))
+                .orElse(match);
+    }
+
+
+    @Nonnull
+    private static MatchBuilder normalizeIpv6Match(@Nonnull final MatchBuilder match) {
+        return Optional
+                .ofNullable(match.getLayer3Match())
+                .filter(Ipv6Match.class::isInstance)
+                .map(Ipv6Match.class::cast)
+                .map(ipv6 -> match.setLayer3Match(new Ipv6MatchBuilder(ipv6)
+                        .setIpv6NdSll(normalizeMacAddress(ipv6.getIpv6NdSll()))
+                        .setIpv6NdTll(normalizeMacAddress(ipv6.getIpv6NdTll()))
+                        .setIpv6NdTarget(normalizeIpv6AddressWithoutMask(ipv6.getIpv6NdTarget()))
+                        .setIpv6Source(normalizeIpv6Prefix(ipv6.getIpv6Source()))
+                        .setIpv6Destination(normalizeIpv6Prefix(ipv6.getIpv6Destination()))
+                        .build()))
+                .orElse(match);
+    }
+
+
+    @Nonnull
+    private static MatchBuilder normalizeIpv6MatchArbitraryBitMask(@Nonnull final MatchBuilder match) {
+        return Optional
+                .ofNullable(match.getLayer3Match())
+                .filter(Ipv6MatchArbitraryBitMask.class::isInstance)
+                .map(Ipv6MatchArbitraryBitMask.class::cast)
+                .map(ipv6Arbitrary -> match.setLayer3Match(new Ipv6MatchBuilder()
+                        .setIpv6Source(normalizeIpv6Arbitrary(
+                                ipv6Arbitrary.getIpv6SourceAddressNoMask(),
+                                ipv6Arbitrary.getIpv6SourceArbitraryBitmask()))
+                        .setIpv6Destination(normalizeIpv6Arbitrary(
+                                ipv6Arbitrary.getIpv6DestinationAddressNoMask(),
+                                ipv6Arbitrary.getIpv6DestinationArbitraryBitmask()))
+                        .build()))
+                .orElse(match);
+    }
+
+    @Nonnull
+    private static MatchBuilder normalizeEthernetMatch(@Nonnull final MatchBuilder match) {
+        return Optional
+                .ofNullable(match.getEthernetMatch())
+                .map(eth -> match.setEthernetMatch(new EthernetMatchBuilder(eth)
+                        .setEthernetSource(Optional
+                                .ofNullable(eth.getEthernetSource())
+                                .map(filter -> new EthernetSourceBuilder(filter)
+                                        .setAddress(normalizeMacAddress(filter.getAddress()))
+                                        .setMask(normalizeMacAddressMask(filter.getMask()))
+                                        .build())
+                                .orElse(eth.getEthernetSource()))
+                        .setEthernetDestination(Optional
+                                .ofNullable(eth.getEthernetDestination())
+                                .map(filter -> new EthernetDestinationBuilder(filter)
+                                        .setAddress(normalizeMacAddress(filter.getAddress()))
+                                        .setMask(normalizeMacAddressMask(filter.getMask()))
+                                        .build())
+                                .orElse(eth.getEthernetDestination()))
+                        .build()))
+                .orElse(match);
+    }
+
+}
\ No newline at end of file
index 781776ad70eed29cc02fbe3d5369600ecac3b761..9d80ea78e02075cb06a83dbb667ecd4ebf89b19d 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;
@@ -86,8 +86,8 @@ public class MdSalRegistrationUtils {
      * @param deviceContext - every service needs {@link org.opendaylight.openflowplugin.api.openflow.device.DeviceContext} as input parameter
      * @param convertorExecutor
      */
-    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);
diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/SimpleComparator.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/SimpleComparator.java
deleted file mode 100644 (file)
index 55583e9..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (c) 2013, 2015 IBM Corporation 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.impl.util;
-
-public interface SimpleComparator<T> {
-
-    boolean areObjectsEqual(T obj1, T obj2);
-
-}
\ No newline at end of file
index dc619d61fc0f707f2422d9a200b2b81b9bfc1216..96a3a4721b542fe394d98551017636076060e02f 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;
 
@@ -79,17 +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);
-
-        provider.setDataBroker(dataBroker);
-        provider.setRpcProviderRegistry(rpcProviderRegistry);
-        provider.setNotificationProviderService(notificationService);
-        provider.setSwitchConnectionProviders(Lists.newArrayList(switchConnectionProvider));
-        provider.setClusteringSingletonServicesProvider(clusterSingletonServiceProvider);
+                Lists.newArrayList(switchConnectionProvider),
+                dataBroker,
+                rpcProviderRegistry,
+                notificationService,
+                notificationPublishService,
+                clusterSingletonServiceProvider,
+                entityOwnershipService);
+
+        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
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 4eab2e2f04c8082e9183d952cf567cdfd5ae7eef..d2ad7ff60767161f1b90f520baae1fe9b84480a1 100644 (file)
@@ -63,7 +63,6 @@ public class HandshakeListenerImplTest {
         connectionContextSpy = Mockito.spy(new ConnectionContextImpl(connectionAdapter));
         Mockito.when(connectionContextSpy.getConnectionAdapter()).thenReturn(connectionAdapter);
         Mockito.when(features.getDatapathId()).thenReturn(BigInteger.TEN);
-        Mockito.doNothing().when(connectionContextSpy).handshakeSuccessful();
         handshakeListener = new HandshakeListenerImpl(connectionContextSpy, deviceConnectedHandler);
         handshakeListener.setHandshakeContext(handshakeContext);
     }
index 19bb57d8f0d30ae9881b70474cec8beda0958ce1..ea9b6e9f6af900107c5c9fa4e866c916c4176d96 100644 (file)
@@ -173,7 +173,7 @@ public class SystemNotificationsListenerImplTest {
      */
     @Test
     public void testOnSwitchIdleEvent1() throws Exception {
-        final Future<RpcResult<EchoOutput>> echoReply = Futures.immediateFuture(RpcResultBuilder.success(new EchoOutputBuilder().build()).build());
+        final Future<RpcResult<EchoOutput>> echoReply = Futures.immediateFuture(RpcResultBuilder.success(new EchoOutputBuilder().setXid(0L).build()).build());
 
         Mockito.when(connectionAdapter.echo(Matchers.any(EchoInput.class))).thenReturn(echoReply);
 
index 2af535ac9386763edd4d7723f366fbae5b85290f..95e454a98001f6ade7afd1aa346a28c2363d84a5 100644 (file)
@@ -476,9 +476,9 @@ public class DeviceContextImplTest {
                 .thenReturn(flowRemovedMdsalBld.build());
 
         // insert flow+flowId into local registry
-        final FlowRegistryKey flowRegKey = FlowRegistryKeyFactory.create(flowRemovedMdsalBld.build());
+        final FlowRegistryKey flowRegKey = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flowRemovedMdsalBld.build());
         final FlowDescriptor flowDescriptor = FlowDescriptorFactory.create((short) 0, new FlowId("ut-ofp:f456"));
-        deviceContext.getDeviceFlowRegistry().store(flowRegKey, flowDescriptor);
+        deviceContext.getDeviceFlowRegistry().storeDescriptor(flowRegKey, flowDescriptor);
 
         // plug in lifecycleListener
         final ItemLifecycleListener itemLifecycleListener = Mockito.mock(ItemLifecycleListener.class);
@@ -531,9 +531,9 @@ public class DeviceContextImplTest {
     public void testOnDeviceDisconnected() throws Exception {
         final DeviceTerminationPhaseHandler deviceContextClosedHandler = mock(DeviceTerminationPhaseHandler.class);
 
-        assertEquals(0, deviceContext.getDeviceFlowRegistry().getAllFlowDescriptors().size());
-        assertEquals(0, deviceContext.getDeviceGroupRegistry().getAllGroupIds().size());
-        assertEquals(0, deviceContext.getDeviceMeterRegistry().getAllMeterIds().size());
+        assertEquals(0, deviceContext.getDeviceFlowRegistry().size());
+        assertEquals(0, deviceContext.getDeviceGroupRegistry().size());
+        assertEquals(0, deviceContext.getDeviceMeterRegistry().size());
 
     }
 
index 33e54b4d7c313e1bab26b678954fc151a8c95a3c..f3b6c9175cd48c893a66735a531b52ff7b8ee147 100644 (file)
@@ -37,6 +37,8 @@ import org.mockito.stubbing.Answer;
 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
@@ -107,6 +109,10 @@ public class DeviceManagerImplTest {
     @Mock
     private ClusterSingletonServiceProvider clusterSingletonServiceProvider;
     @Mock
+    private EntityOwnershipService entityOwnershipService;
+    @Mock
+    private EntityOwnershipListenerRegistration entityOwnershipListenerRegistration;
+    @Mock
     private ConvertorExecutor convertorExecutor;
     @Mock
     private KeyedInstanceIdentifier<Node, NodeKey> key;
@@ -143,20 +149,14 @@ public class DeviceManagerImplTest {
         when(mockedDataBroker.newWriteOnlyTransaction()).thenReturn(mockedWriteTransaction);
 
         when(mockedWriteTransaction.submit()).thenReturn(mockedFuture);
+        when(entityOwnershipService.registerListener(any(), any())).thenReturn(entityOwnershipListenerRegistration);
 
         final DeviceManagerImpl deviceManager = new DeviceManagerImpl(
                 mockedDataBroker,
-                TEST_VALUE_GLOBAL_NOTIFICATION_QUOTA,
-                false,
-                barrierIntervalNanos,
-                barrierCountLimit,
                 messageIntelligenceAgency,
-                true,
                 clusterSingletonServiceProvider,
-                null,
-                new HashedWheelTimer(),
-                convertorExecutor,
-                false);
+                entityOwnershipService, new HashedWheelTimer(), convertorExecutor, null
+        );
 
         deviceManager.setDeviceInitializationPhaseHandler(deviceInitPhaseHandler);
         deviceManager.setDeviceTerminationPhaseHandler(deviceTerminationPhaseHandler);
index 7d02cdb2e14fd7bd25e47692ff78fc5573870637..4cf06d4eb4bc544ca08bfb00f29f871596f1290b 100644 (file)
@@ -15,6 +15,8 @@ import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
 import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
@@ -48,6 +50,8 @@ public class LifecycleServiceImplTest {
     private ClusterSingletonServiceProvider clusterSingletonServiceProvider;
     @Mock
     private ClusterSingletonServiceRegistration clusterSingletonServiceRegistration;
+    @Mock
+    EntityOwnershipListenerRegistration entityOwnershipListenerRegistration;
 
     private LifecycleService lifecycleService;
 
@@ -63,9 +67,9 @@ public class LifecycleServiceImplTest {
         Mockito.when(clusterSingletonServiceProvider.registerClusterSingletonService(Mockito.any()))
                 .thenReturn(clusterSingletonServiceRegistration);
 
-        Mockito.when(deviceContext.stopClusterServices(Mockito.anyBoolean())).thenReturn(Futures.immediateFuture(null));
-        Mockito.when(statContext.stopClusterServices(Mockito.anyBoolean())).thenReturn(Futures.immediateFuture(null));
-        Mockito.when(rpcContext.stopClusterServices(Mockito.anyBoolean())).thenReturn(Futures.immediateFuture(null));
+        Mockito.when(deviceContext.stopClusterServices()).thenReturn(Futures.immediateFuture(null));
+        Mockito.when(statContext.stopClusterServices()).thenReturn(Futures.immediateFuture(null));
+        Mockito.when(rpcContext.stopClusterServices()).thenReturn(Futures.immediateFuture(null));
 
         lifecycleService = new LifecycleServiceImpl();
         lifecycleService.setDeviceContext(deviceContext);
@@ -86,9 +90,9 @@ public class LifecycleServiceImplTest {
     @Test
     public void closeServiceInstance() throws Exception {
         lifecycleService.closeServiceInstance().get();
-        Mockito.verify(statContext).stopClusterServices(false);
-        Mockito.verify(deviceContext).stopClusterServices(false);
-        Mockito.verify(rpcContext).stopClusterServices(false);
+        Mockito.verify(statContext).stopClusterServices();
+        Mockito.verify(deviceContext).stopClusterServices();
+        Mockito.verify(rpcContext).stopClusterServices();
     }
 
     @Test
index dafa7ca27e233202e06d2f64b3e591fbd66dead1..df6b4863b591f68585b0242d5ce62acee98cc6c1 100644 (file)
@@ -33,6 +33,7 @@ import org.mockito.runners.MockitoJUnitRunner;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.openflowplugin.api.OFConstants;
 import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowDescriptor;
 import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
@@ -73,13 +74,13 @@ public class DeviceFlowRegistryImplTest {
     public void setUp() throws Exception {
         nodeInstanceIdentifier = InstanceIdentifier.create(Nodes.class).child(Node.class, new NodeKey(new NodeId(NODE_ID)));
         when(dataBroker.newReadOnlyTransaction()).thenReturn(readOnlyTransaction);
-        deviceFlowRegistry = new DeviceFlowRegistryImpl(dataBroker, nodeInstanceIdentifier);
+        deviceFlowRegistry = new DeviceFlowRegistryImpl(OFConstants.OFP_VERSION_1_3, dataBroker, nodeInstanceIdentifier);
         final FlowAndStatisticsMapList flowStats = TestFlowHelper.createFlowAndStatisticsMapListBuilder(1).build();
-        key = FlowRegistryKeyFactory.create(flowStats);
+        key = FlowRegistryKeyFactory.create(OFConstants.OFP_VERSION_1_3, flowStats);
         descriptor = FlowDescriptorFactory.create(key.getTableId(), new FlowId("ut:1"));
 
         Assert.assertEquals(0, deviceFlowRegistry.getAllFlowDescriptors().size());
-        deviceFlowRegistry.store(key, descriptor);
+        deviceFlowRegistry.storeDescriptor(key, descriptor);
         Assert.assertEquals(1, deviceFlowRegistry.getAllFlowDescriptors().size());
     }
 
@@ -103,7 +104,7 @@ public class DeviceFlowRegistryImplTest {
                 .build();
 
         final Map<FlowRegistryKey, FlowDescriptor> allFlowDescriptors = testFill(path, flowCapableNode);
-        final FlowRegistryKey key = FlowRegistryKeyFactory.create(flow);
+        final FlowRegistryKey key = FlowRegistryKeyFactory.create(OFConstants.OFP_VERSION_1_3, flow);
 
         InOrder order = inOrder(dataBroker, readOnlyTransaction);
         order.verify(dataBroker).newReadOnlyTransaction();
@@ -112,7 +113,7 @@ public class DeviceFlowRegistryImplTest {
         order.verify(readOnlyTransaction).read(LogicalDatastoreType.OPERATIONAL, path);
         assertTrue(allFlowDescriptors.containsKey(key));
 
-        deviceFlowRegistry.removeDescriptor(key);
+        deviceFlowRegistry.addMark(key);
     }
 
     @Test
@@ -165,23 +166,23 @@ public class DeviceFlowRegistryImplTest {
 
     @Test
     public void testRetrieveIdForFlow() throws Exception {
-        Assert.assertEquals(descriptor, deviceFlowRegistry.retrieveIdForFlow(key));
+        Assert.assertEquals(descriptor, deviceFlowRegistry.retrieveDescriptor(key));
     }
 
     @Test
     public void testStore() throws Exception {
         //store the same key with different value
         final FlowDescriptor descriptor2 = FlowDescriptorFactory.create(key.getTableId(), new FlowId("ut:2"));
-        deviceFlowRegistry.store(key, descriptor2);
+        deviceFlowRegistry.storeDescriptor(key, descriptor2);
         Assert.assertEquals(1, deviceFlowRegistry.getAllFlowDescriptors().size());
-        Assert.assertEquals("ut:2", deviceFlowRegistry.retrieveIdForFlow(key).getFlowId().getValue());
+        Assert.assertEquals("ut:2", deviceFlowRegistry.retrieveDescriptor(key).getFlowId().getValue());
 
         // store new key with old value
         final FlowAndStatisticsMapList flowStats = TestFlowHelper.createFlowAndStatisticsMapListBuilder(2).build();
-        final FlowRegistryKey key2 = FlowRegistryKeyFactory.create(flowStats);
-        deviceFlowRegistry.store(key2, descriptor);
+        final FlowRegistryKey key2 = FlowRegistryKeyFactory.create(OFConstants.OFP_VERSION_1_3, flowStats);
+        deviceFlowRegistry.storeDescriptor(key2, descriptor);
         Assert.assertEquals(2, deviceFlowRegistry.getAllFlowDescriptors().size());
-        Assert.assertEquals("ut:1", deviceFlowRegistry.retrieveIdForFlow(key2).getFlowId().getValue());
+        Assert.assertEquals("ut:1", deviceFlowRegistry.retrieveDescriptor(key2).getFlowId().getValue());
     }
 
     @Test
@@ -189,25 +190,27 @@ public class DeviceFlowRegistryImplTest {
         FlowId newFlowId;
 
         //store existing key
-        newFlowId = deviceFlowRegistry.storeIfNecessary(key);
+        deviceFlowRegistry.store(key);
+        newFlowId = deviceFlowRegistry.retrieveDescriptor(key).getFlowId();
 
         Assert.assertEquals(1, deviceFlowRegistry.getAllFlowDescriptors().size());
-        Assert.assertEquals(descriptor, deviceFlowRegistry.retrieveIdForFlow(key));
+        Assert.assertEquals(descriptor, deviceFlowRegistry.retrieveDescriptor(key));
         Assert.assertEquals(descriptor.getFlowId(), newFlowId);
 
         //store new key
         final String alienPrefix = "#UF$TABLE*2-";
-        final FlowRegistryKey key2 = FlowRegistryKeyFactory.create(TestFlowHelper.createFlowAndStatisticsMapListBuilder(2).build());
-        newFlowId = deviceFlowRegistry.storeIfNecessary(key2);
+        final FlowRegistryKey key2 = FlowRegistryKeyFactory.create(OFConstants.OFP_VERSION_1_3, TestFlowHelper.createFlowAndStatisticsMapListBuilder(2).build());
+        deviceFlowRegistry.store(key2);
+        newFlowId = deviceFlowRegistry.retrieveDescriptor(key2).getFlowId();
 
         Assert.assertTrue(newFlowId.getValue().startsWith(alienPrefix));
-        Assert.assertTrue(deviceFlowRegistry.retrieveIdForFlow(key2).getFlowId().getValue().startsWith(alienPrefix));
+        Assert.assertTrue(deviceFlowRegistry.retrieveDescriptor(key2).getFlowId().getValue().startsWith(alienPrefix));
         Assert.assertEquals(2, deviceFlowRegistry.getAllFlowDescriptors().size());
     }
 
     @Test
     public void testRemoveDescriptor() throws Exception {
-        deviceFlowRegistry.removeDescriptor(key);
+        deviceFlowRegistry.addMark(key);
         Assert.assertEquals(0, deviceFlowRegistry.getAllFlowDescriptors().size());
     }
 
@@ -238,4 +241,4 @@ public class DeviceFlowRegistryImplTest {
 
         return null;
     }
-}
\ No newline at end of file
+}
index 859542376e2e2aed892df0070b868e9ac7071857..67b5a5887d1315914e27f51cdf2c4c0a02d6e904 100644 (file)
@@ -26,7 +26,7 @@ public class FlowDescriptorDtoTest {
         Assert.assertNotNull(flowDescriptor.getTableKey());
     }
 
-    @Test(expected = NullPointerException.class)
+    @Test(expected = Exception.class)
     public void testCreateNegative1() throws Exception {
         FlowDescriptorFactory.create((short) 1, null);
     }
index 26313fc95f9e0db2634bf0fb34e6090d6a8ef172..35e08e6cdf9f5171f915d95bb17c1e7736024597 100644 (file)
@@ -71,8 +71,8 @@ public class FlowRegistryKeyFactoryTest {
 
         HashSet<FlowRegistryKey> flowRegistryKeys = new HashSet<>();
         for (FlowAndStatisticsMapList item : flowStats.getFlowAndStatisticsMapList()) {
-            final FlowRegistryKey key1 = FlowRegistryKeyFactory.create(item);
-            final FlowRegistryKey key2 = FlowRegistryKeyFactory.create(item);
+            final FlowRegistryKey key1 = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), item);
+            final FlowRegistryKey key2 = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), item);
             flowRegistryKeys.add(key1);
             flowRegistryKeys.add(key1);
             flowRegistryKeys.add(key2);
@@ -83,7 +83,7 @@ public class FlowRegistryKeyFactoryTest {
     @Test
     public void testEqualsNegative() throws Exception {
         final FlowAndStatisticsMapList flowStatisticsMapList1 = TestFlowHelper.createFlowAndStatisticsMapListBuilder(1).build();
-        final FlowRegistryKey key1 = FlowRegistryKeyFactory.create(flowStatisticsMapList1);
+        final FlowRegistryKey key1 = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flowStatisticsMapList1);
 
         FlowRegistryKey key2;
         FlowAndStatisticsMapListBuilder flowStatisticsMapListBld2;
@@ -91,19 +91,19 @@ public class FlowRegistryKeyFactoryTest {
         // different priority
         flowStatisticsMapListBld2 = new FlowAndStatisticsMapListBuilder(flowStatisticsMapList1);
         flowStatisticsMapListBld2.setPriority(flowStatisticsMapListBld2.getPriority() + 1);
-        key2 = FlowRegistryKeyFactory.create(flowStatisticsMapListBld2.build());
+        key2 = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flowStatisticsMapListBld2.build());
         Assert.assertFalse(key1.equals(key2));
 
         // different match
         flowStatisticsMapListBld2 = new FlowAndStatisticsMapListBuilder(flowStatisticsMapList1);
         flowStatisticsMapListBld2.setMatch(new MatchBuilder().build());
-        key2 = FlowRegistryKeyFactory.create(flowStatisticsMapListBld2.build());
+        key2 = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flowStatisticsMapListBld2.build());
         Assert.assertFalse(key1.equals(key2));
 
         // different tableId
         flowStatisticsMapListBld2 = new FlowAndStatisticsMapListBuilder(flowStatisticsMapList1);
         flowStatisticsMapListBld2.setTableId((short) (flowStatisticsMapListBld2.getTableId() + 1));
-        key2 = FlowRegistryKeyFactory.create(flowStatisticsMapListBld2.build());
+        key2 = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flowStatisticsMapListBld2.build());
         Assert.assertFalse(key1.equals(key2));
 
         Assert.assertFalse(key1.equals(null));
@@ -119,7 +119,7 @@ public class FlowRegistryKeyFactoryTest {
                 .setPriority(2)
                 .setTableId((short) 0);
 
-        FlowRegistryKey flow1Hash = FlowRegistryKeyFactory.create(flow1Builder.build());
+        FlowRegistryKey flow1Hash = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flow1Builder.build());
         LOG.info("flowHash1: {}", flow1Hash.hashCode());
 
 
@@ -129,7 +129,7 @@ public class FlowRegistryKeyFactoryTest {
                 .setCookie(new FlowCookie(BigInteger.valueOf(148)))
                 .setMatch(match2Builder.build());
 
-        FlowRegistryKey flow2Hash = FlowRegistryKeyFactory.create(flow2Builder.build());
+        FlowRegistryKey flow2Hash = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flow2Builder.build());
         LOG.info("flowHash2: {}", flow2Hash.hashCode());
 
         Assert.assertNotSame(flow1Hash, flow2Hash);
@@ -148,7 +148,7 @@ public class FlowRegistryKeyFactoryTest {
         FlowBuilder fb1 = new FlowBuilder(flow1Builder.build());
         fb1.setTableId(null);
         try {
-            FlowRegistryKeyFactory.create(fb1.build());
+            FlowRegistryKeyFactory.create(deviceInfo.getVersion(), fb1.build());
             Assert.fail("hash creation should have failed because of NPE");
         } catch (Exception e) {
             // expected
@@ -158,7 +158,7 @@ public class FlowRegistryKeyFactoryTest {
         FlowBuilder fb2 = new FlowBuilder(flow1Builder.build());
         fb2.setPriority(null);
         try {
-            FlowRegistryKeyFactory.create(fb2.build());
+            FlowRegistryKeyFactory.create(deviceInfo.getVersion(), fb2.build());
         } catch (Exception e) {
             // not expected
             Assert.fail("no exception was expected while hash was creating.");
@@ -166,7 +166,7 @@ public class FlowRegistryKeyFactoryTest {
 
         FlowBuilder fb3 = new FlowBuilder(flow1Builder.build());
         fb3.setCookie(null);
-        FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(fb3.build());
+        FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), fb3.build());
         Assert.assertNotNull(flowRegistryKey.getCookie());
         Assert.assertEquals(OFConstants.DEFAULT_COOKIE, flowRegistryKey.getCookie());
     }
@@ -176,7 +176,7 @@ public class FlowRegistryKeyFactoryTest {
         FlowsStatisticsUpdate flowStats = FLOWS_STATISTICS_UPDATE_BUILDER.build();
 
         for (FlowAndStatisticsMapList item : flowStats.getFlowAndStatisticsMapList()) {
-            FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(item);
+            FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), item);
             FlowRegistryKey lastHash = null;
             if (null != lastHash) {
                 assertNotEquals(lastHash, flowRegistryKey);
index a0d74b049936b3d8458c2ac7d26436c701523442..6b62e9f16938bb320bf64f5b166dcaecd4aa7cc3 100644 (file)
@@ -40,29 +40,29 @@ public class DeviceGroupRegistryImplTest {
 
     @Test
     public void testRemoveMarked() throws Exception {
-        deviceGroupRegistry.markToBeremoved(groupId);
-        deviceGroupRegistry.removeMarked();
+        deviceGroupRegistry.addMark(groupId);
+        deviceGroupRegistry.processMarks();
         Assert.assertEquals(0, deviceGroupRegistry.getAllGroupIds().size());
     }
 
     @Test
     public void testRemoveMarkedNegative() throws Exception {
-        deviceGroupRegistry.markToBeremoved(groupId2);
-        deviceGroupRegistry.removeMarked();
+        deviceGroupRegistry.addMark(groupId2);
+        deviceGroupRegistry.processMarks();
         Assert.assertEquals(1, deviceGroupRegistry.getAllGroupIds().size());
     }
 
 
     @Test
     public void testClose() throws Exception {
-        deviceGroupRegistry.markToBeremoved(groupId);
+        deviceGroupRegistry.addMark(groupId);
         deviceGroupRegistry.close();
 
         Assert.assertEquals(0, deviceGroupRegistry.getAllGroupIds().size());
         deviceGroupRegistry.store(groupId);
         Assert.assertEquals(1, deviceGroupRegistry.getAllGroupIds().size());
-        deviceGroupRegistry.removeMarked();
+        deviceGroupRegistry.processMarks();
         Assert.assertEquals(1, deviceGroupRegistry.getAllGroupIds().size());
 
     }
-}
\ No newline at end of file
+}
index 08bd755c85c657a9080213fd7ad8aa8d038e2411..dbc3e3aedc85c7e3e6cbc568bcd6747cf060a133 100644 (file)
@@ -40,29 +40,29 @@ public class DeviceMeterRegistryImplTest {
 
     @Test
     public void testRemoveMarked() throws Exception {
-        deviceMeterRegistry.markToBeremoved(meterId);
-        deviceMeterRegistry.removeMarked();
+        deviceMeterRegistry.addMark(meterId);
+        deviceMeterRegistry.processMarks();
         Assert.assertEquals(0, deviceMeterRegistry.getAllMeterIds().size());
     }
 
     @Test
     public void testRemoveMarkedNegative() throws Exception {
-        deviceMeterRegistry.markToBeremoved(meterId2);
-        deviceMeterRegistry.removeMarked();
+        deviceMeterRegistry.addMark(meterId2);
+        deviceMeterRegistry.processMarks();
         Assert.assertEquals(1, deviceMeterRegistry.getAllMeterIds().size());
     }
 
 
     @Test
     public void testClose() throws Exception {
-        deviceMeterRegistry.markToBeremoved(meterId);
+        deviceMeterRegistry.addMark(meterId);
         deviceMeterRegistry.close();
 
         Assert.assertEquals(0, deviceMeterRegistry.getAllMeterIds().size());
         deviceMeterRegistry.store(meterId);
         Assert.assertEquals(1, deviceMeterRegistry.getAllMeterIds().size());
-        deviceMeterRegistry.removeMarked();
+        deviceMeterRegistry.processMarks();
         Assert.assertEquals(1, deviceMeterRegistry.getAllMeterIds().size());
 
     }
-}
\ No newline at end of file
+}
index 62ce9bdade20f254fe879c51bd48df94983d9877..482f76985745e5f8ce06e9b09a9e9966a47d5fe1 100644 (file)
@@ -100,7 +100,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);
         rpcManager.setDeviceInitializationPhaseHandler(deviceINitializationPhaseHandler);
 
         GetFeaturesOutput featuresOutput = new GetFeaturesOutputBuilder()
@@ -132,7 +133,6 @@ public class RpcManagerImplTest {
     @Test
     public void onDeviceContextLevelUpTwice() throws Exception {
         rpcManager.onDeviceContextLevelUp(deviceInfo, lifecycleService);
-        expectedException.expect(VerifyException.class);
         rpcManager.onDeviceContextLevelUp(deviceInfo, lifecycleService);
     }
 
index 5d15eff5cd7e86192ff42eeafd5da300ab46c6b5..692c29feaa1d3600b4d354b47d7633d8cdf62c92 100644 (file)
@@ -9,7 +9,6 @@ package org.opendaylight.openflowplugin.impl.services;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
@@ -138,7 +137,7 @@ public class MultipartRequestOnTheFlyCallbackTest {
         when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState);
         when(mockedDeviceContext.getDeviceInfo()).thenReturn(mockedDeviceInfo);
         when(mockedDeviceContext.getDeviceFlowRegistry()).thenReturn(mockedFlowRegistry);
-        when(mockedFlowRegistry.retrieveIdForFlow(Matchers.any(FlowRegistryKey.class))).thenReturn(mockedFlowDescriptor);
+        when(mockedFlowRegistry.retrieveDescriptor(Matchers.any(FlowRegistryKey.class))).thenReturn(mockedFlowDescriptor);
 
         final InstanceIdentifier<FlowCapableNode> nodePath = mockedDeviceInfo.getNodeInstanceIdentifier().augmentation(FlowCapableNode.class);
         final FlowCapableNodeBuilder flowNodeBuilder = new FlowCapableNodeBuilder();
index 89cbef6d7e49435b9e08035672bddc5fb532c03b..8418e13ac8837cebd0b9b8faa6db7d1daf7b09a6 100644 (file)
@@ -285,8 +285,7 @@ public class SalFlowServiceImplTest extends TestCase {
         when(mockedFlowDescriptor.getFlowId()).thenReturn(flowId);
         when(mockedFlowDescriptor.getTableKey()).thenReturn(new TableKey(DUMMY_TABLE_ID));
 
-        when(deviceFlowRegistry.storeIfNecessary(Matchers.any(FlowRegistryKey.class))).thenReturn(flowId);
-        when(deviceFlowRegistry.retrieveIdForFlow(Matchers.any(FlowRegistryKey.class))).thenReturn(mockedFlowDescriptor);
+        when(deviceFlowRegistry.retrieveDescriptor(Matchers.any(FlowRegistryKey.class))).thenReturn(mockedFlowDescriptor);
     }
 
     private <T extends DataObject> void verifyOutput(Future<RpcResult<T>> rpcResultFuture) throws ExecutionException, InterruptedException {
index f0814d8962320ef7bf1e89ecf42033030a9fcebe..bca07192fb93a9e1ec69ad4103b334a745b90997 100644 (file)
@@ -129,7 +129,7 @@ public class SalGroupServiceImplTest extends ServiceMocking {
 
         salGroupService.removeGroup(removeGroupInput);
         verify(mockedRequestContextStack).createRequestContext();
-        verify(mockedDeviceGroupRegistry).markToBeremoved(eq(dummyGroupId));
+        verify(mockedDeviceGroupRegistry).addMark(eq(dummyGroupId));
 
         if (itemLifecycleListener != null) {
             verify(itemLifecycleListener).onRemoved(Matchers.<KeyedInstanceIdentifier<Group, GroupKey>>any());
index ea20a88647c778e0c1aeb0cdf39a7ba47a050353..0cb47df0261c7aae5871803f15d07fb30a8d2558 100644 (file)
@@ -130,7 +130,7 @@ public class SalMeterServiceImplTest extends ServiceMocking {
 
         salMeterService.removeMeter(removeMeterInput);
         verify(mockedRequestContextStack).createRequestContext();
-        verify(mockedDeviceMeterRegistry).markToBeremoved(eq(dummyMeterId));
+        verify(mockedDeviceMeterRegistry).addMark(eq(dummyMeterId));
 
         if (itemLifecycleListener != null) {
             verify(itemLifecycleListener).onRemoved(Matchers.<KeyedInstanceIdentifier<Meter, MeterKey>>any());
index fafa4df3f810fa407fd820673d42c508a7f54764..92180d798ab28ea05c0d2e527b9bcd72f292d368 100644 (file)
@@ -106,7 +106,7 @@ public abstract class ServiceMocking {
 
         when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(mockedPrimConnectionContext);
         when(mockedDeviceContext.getMessageSpy()).thenReturn(mockedMessagSpy);
-        when(mockedDeviceContext.getDeviceFlowRegistry()).thenReturn(new DeviceFlowRegistryImpl(dataBroker, NODE_II));
+        when(mockedDeviceContext.getDeviceFlowRegistry()).thenReturn(new DeviceFlowRegistryImpl(DUMMY_VERSION, dataBroker, NODE_II));
         when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState);
         when(mockedDeviceContext.getDeviceInfo()).thenReturn(mockedDeviceInfo);
         when(mockedDeviceContext.getMultiMsgCollector(Matchers.any())).thenReturn(multiMessageCollector);
index 607adc0627f987e3e48bf13263afb612886915a5..3d6add0f1f51550fd1398984f149b12a432a5321 100644 (file)
@@ -180,7 +180,7 @@ public class StatisticsGatheringUtilsTest {
         when(deviceContext.getDeviceFlowRegistry()).thenReturn(deviceFlowRegistry);
         when(deviceContext.getDeviceGroupRegistry()).thenReturn(deviceGroupRegistry);
         when(deviceContext.getDeviceMeterRegistry()).thenReturn(deviceMeterRegistry);
-        when(deviceFlowRegistry.retrieveIdForFlow(Matchers.any(FlowRegistryKey.class))).thenReturn(flowDescriptor);
+        when(deviceFlowRegistry.retrieveDescriptor(Matchers.any(FlowRegistryKey.class))).thenReturn(flowDescriptor);
         when(deviceContext.getReadTransaction()).thenReturn(readTx);
         when(txFacade.getReadTransaction()).thenReturn(readTx);
         when(deviceContext.getPrimaryConnectionContext()).thenReturn(connectionAdapter);
@@ -284,7 +284,7 @@ public class StatisticsGatheringUtilsTest {
 
         verify(deviceContext, Mockito.never()).addDeleteToTxChain(
                 Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.<InstanceIdentifier<?>>any());
-        verify(deviceGroupRegistry).removeMarked();
+        verify(deviceGroupRegistry).processMarks();
         verify(deviceGroupRegistry).store(storedGroupId);
         verify(txFacade).writeToTransaction(
                 Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.eq(groupPath), Matchers.any(Group.class));
index 65abd670d9027b382a4a232ae225872b6b3f6f38..562436d28464fd22d15bc331115e581dfc1cbfb9 100644 (file)
@@ -11,7 +11,6 @@ import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import io.netty.util.HashedWheelTimer;
 import io.netty.util.Timeout;
@@ -40,6 +39,7 @@ import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
 import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueue;
+import org.opendaylight.openflowplugin.api.OFConstants;
 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
@@ -66,15 +66,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.N
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FeaturesReply;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.sm.control.rev150812.ChangeStatisticsWorkModeInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.sm.control.rev150812.GetStatisticsWorkModeOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.sm.control.rev150812.StatisticsManagerControlService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.sm.control.rev150812.StatisticsWorkMode;
 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -164,7 +161,7 @@ public class StatisticsManagerImplTest {
         when(mockedDeviceContext.getDeviceInfo()).thenReturn(mockedDeviceInfo);
         when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(mockedPrimConnectionContext);
         when(mockedDeviceContext.getMessageSpy()).thenReturn(mockedMessagSpy);
-        when(mockedDeviceContext.getDeviceFlowRegistry()).thenReturn(new DeviceFlowRegistryImpl(dataBroker, nodePath));
+        when(mockedDeviceContext.getDeviceFlowRegistry()).thenReturn(new DeviceFlowRegistryImpl(OFConstants.OFP_VERSION_1_3, dataBroker, nodePath));
         when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState);
         when(mockedDeviceContext.getMultiMsgCollector(
                 Matchers.<RequestContext<List<MultipartReply>>>any())).thenAnswer(
@@ -184,46 +181,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.setDeviceInitializationPhaseHandler(deviceInitializationPhaseHandler);
-    }
-
-    @Test
-    public void testOnDeviceContextLevelUp() throws Exception {
-        Mockito.doAnswer(new Answer<Void>() {
-            @Override
-            public Void answer(InvocationOnMock invocation) throws Throwable {
-                final FutureCallback<OfHeader> callback = (FutureCallback<OfHeader>) invocation.getArguments()[2];
-                LOG.debug("committing entry: {}", ((MultipartRequestInput) invocation.getArguments()[1]).getType());
-                callback.onSuccess(null);
-                currentRequestContext.setResult(RpcResultBuilder.<List<MultipartReply>>success().build());
-                return null;
-            }
-        }).when(outboundQueue)
-                .commitEntry(Matchers.anyLong(), Matchers.<OfHeader>any(), Matchers.<FutureCallback<OfHeader>>any());
-
-        Mockito.when(lifecycleService.getDeviceContext()).thenReturn(mockedDeviceContext);
-        Mockito.when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState);
-
-        statisticsManager.setDeviceInitializationPhaseHandler(mockedDevicePhaseHandler);
-        statisticsManager.onDeviceContextLevelUp(deviceInfo, lifecycleService);
-        verify(mockedDevicePhaseHandler).onDeviceContextLevelUp(deviceInfo, lifecycleService);
-    }
-
-    @Test
-    public void testOnDeviceContextClosed() throws Exception {
-        final StatisticsContext statisticContext = Mockito.mock(StatisticsContext.class);
-        final Map<DeviceInfo, StatisticsContext> contextsMap = getContextsMap(statisticsManager);
-
-        contextsMap.put(deviceInfo, statisticContext);
-        Assert.assertEquals(1, contextsMap.size());
-
-        statisticsManager.setDeviceTerminationPhaseHandler(mockedTerminationPhaseHandler);
-        statisticsManager.onDeviceContextLevelDown(deviceInfo);
-        verify(statisticContext).close();
-        verify(mockedTerminationPhaseHandler).onDeviceContextLevelDown(deviceInfo);
-        Assert.assertEquals(1, contextsMap.size());
+        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)
@@ -378,9 +340,9 @@ public class StatisticsManagerImplTest {
         when(timeCounter.getAverageTimeBetweenMarks()).thenReturn(2000L, (Long)4000L);
 
         statisticsManager.calculateTimerDelay(timeCounter);
-        Assert.assertEquals(3000L, StatisticsManagerImpl.getCurrentTimerDelay());
+        Assert.assertEquals(3000L, statisticsManager.getCurrentTimerDelay());
         statisticsManager.calculateTimerDelay(timeCounter);
-        Assert.assertEquals(6000L, StatisticsManagerImpl.getCurrentTimerDelay());
+        Assert.assertEquals(6000L, statisticsManager.getCurrentTimerDelay());
     }
 
     @Test
index 9dd7d6aaf954745c388a1e2f5a855a6988f8d044..e2a1869af9c18dd642c78b713b0b6177c38c2d77 100644 (file)
@@ -22,6 +22,8 @@ import java.util.Collections;
 import java.util.List;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.openflowplugin.api.openflow.registry.flow.DeviceFlowRegistry;
+import org.opendaylight.openflowplugin.impl.registry.flow.FlowDescriptorFactory;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractDirectStatisticsServiceTest;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
@@ -45,7 +47,7 @@ public class FlowDirectStatisticsServiceTest extends AbstractDirectStatisticsSer
     public void setUp() throws Exception {
         service = new FlowDirectStatisticsService(requestContextStack, deviceContext, convertorManager);
         final DeviceFlowRegistry registry = mock(DeviceFlowRegistry.class);
-        when(registry.storeIfNecessary(any())).thenReturn(new FlowId("1"));
+        when(registry.retrieveDescriptor(any())).thenReturn(FlowDescriptorFactory.create(TABLE_NO, new FlowId("1")));
         when(deviceContext.getDeviceFlowRegistry()).thenReturn(registry);
     }
 
@@ -107,4 +109,4 @@ public class FlowDirectStatisticsServiceTest extends AbstractDirectStatisticsSer
         service.storeStatistics(output);
         verify(deviceContext).writeToTransactionWithParentsSlow(eq(LogicalDatastoreType.OPERATIONAL), any(), any());
     }
-}
\ No newline at end of file
+}
diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/util/AddressNormalizationUtilTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/util/AddressNormalizationUtilTest.java
new file mode 100644 (file)
index 0000000..0c19036
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * 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.impl.util;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.opendaylight.openflowplugin.api.OFConstants;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.opendaylight.ipv6.arbitrary.bitmask.fields.rev160224.Ipv6ArbitraryMask;
+
+public class AddressNormalizationUtilTest {
+
+    @Test
+    public void normalizeProtocolAgnosticPortOF10() throws Exception {
+        final Uri left = new Uri("openflow:1:INPORT");
+        final Uri right = new Uri("INPORT");
+
+        assertEquals(
+                right,
+                AddressNormalizationUtil.normalizeProtocolAgnosticPort(left, OFConstants.OFP_VERSION_1_0)
+        );
+    }
+
+    @Test
+    public void normalizeProtocolAgnosticPortOF13() throws Exception {
+        final Uri left = new Uri("openflow:1:ANY");
+        final Uri right = new Uri("ANY");
+
+        assertEquals(
+                right,
+                AddressNormalizationUtil.normalizeProtocolAgnosticPort(left, OFConstants.OFP_VERSION_1_3)
+        );
+    }
+
+    @Test
+    public void normalizeIpv6Prefix() throws Exception {
+        final Ipv6Prefix left = new Ipv6Prefix("1E3D:5678:9ABC::/24");
+        final Ipv6Prefix right = new Ipv6Prefix("1e3d:5600:0:0:0:0:0:0/24");
+
+        assertEquals(
+                right,
+                AddressNormalizationUtil.normalizeIpv6Prefix(left)
+        );
+    }
+
+    @Test
+    public void normalizeIpv6Arbitrary() throws Exception {
+        final Ipv6Address leftAddress = new Ipv6Address("1E3D:5678:9ABC::");
+        final Ipv6ArbitraryMask leftMask = new Ipv6ArbitraryMask("FFFF:FF00::");
+        final Ipv6Prefix right = new Ipv6Prefix("1e3d:5600:0:0:0:0:0:0/24");
+
+        assertEquals(
+                right,
+                AddressNormalizationUtil.normalizeIpv6Arbitrary(leftAddress, leftMask)
+        );
+    }
+
+    @Test
+    public void normalizeIpv6AddressWithoutMask() throws Exception {
+        final Ipv6Address left = new Ipv6Address("1E3D:5678:9ABC::");
+        final Ipv6Address right = new Ipv6Address("1e3d:5678:9abc:0:0:0:0:0");
+
+        assertEquals(
+                right,
+                AddressNormalizationUtil.normalizeIpv6AddressWithoutMask(left)
+        );
+    }
+
+    @Test
+    public void normalizeIpv4Prefix() throws Exception {
+        final Ipv4Prefix left = new Ipv4Prefix("192.168.72.1/16");
+        final Ipv4Prefix right = new Ipv4Prefix("192.168.0.0/16");
+
+        assertEquals(
+                right,
+                AddressNormalizationUtil.normalizeIpv4Prefix(left)
+        );
+    }
+
+    @Test
+    public void normalizeIpv4Arbitrary() throws Exception {
+        final Ipv4Address leftAddress = new Ipv4Address("192.168.72.1");
+        final DottedQuad leftMask = new DottedQuad("255.255.0.0");
+        final Ipv4Prefix right = new Ipv4Prefix("192.168.0.0/16");
+
+        assertEquals(
+                right,
+                AddressNormalizationUtil.normalizeIpv4Arbitrary(leftAddress, leftMask)
+        );
+    }
+
+    @Test
+    public void normalizeMacAddress() throws Exception {
+        final MacAddress left = new MacAddress("01:23:45:AB:CD:EF");
+        final MacAddress right = new MacAddress("01:23:45:ab:cd:ef");
+
+        assertEquals(
+                right,
+                AddressNormalizationUtil.normalizeMacAddress(left)
+        );
+    }
+
+    @Test
+    public void normalizeMacAddressMask() throws Exception {
+        final MacAddress left = new MacAddress("FF:FF:FF:FF:FF:FF");
+        final MacAddress right = null;
+
+        assertEquals(
+                right,
+                AddressNormalizationUtil.normalizeMacAddressMask(left)
+        );
+    }
+
+}
\ No newline at end of file
index aa24a465755547b4438879ba4e14188faa5004ad..df8156f75531f0db151b76d1b1fe2a69376a96c1 100644 (file)
@@ -3,7 +3,7 @@
     <parent>
         <groupId>org.opendaylight.openflowplugin</groupId>
         <artifactId>openflowplugin-parent</artifactId>
-        <version>0.3.3-SNAPSHOT</version>
+        <version>0.3.5-SNAPSHOT</version>
         <relativePath>../parent</relativePath>
     </parent>
 
index 0a17e286bec648554f7f065b9e370cf45c074b8d..ab24f6ebb31e00d86a96ef905178882ec9679d60 100644 (file)
@@ -4,7 +4,7 @@
     <parent>
         <groupId>org.opendaylight.openflowplugin</groupId>
         <artifactId>openflowplugin-parent</artifactId>
-        <version>0.3.3-SNAPSHOT</version>
+        <version>0.3.5-SNAPSHOT</version>
         <relativePath>../parent</relativePath>
     </parent>
 
index 8c3f2901f01d8ec488eb5b68654d2380155953df..3bfe7aa340398a849c0669742bdcf03cd1eb43c6 100644 (file)
@@ -8,11 +8,8 @@
 
 package org.opendaylight.openflowplugin.openflow.md.core;
 
-import com.google.common.annotations.VisibleForTesting;
 import com.google.common.util.concurrent.Futures;
 import java.util.concurrent.Future;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionReadyListener;
@@ -94,7 +91,6 @@ public class ConnectionConductorImpl implements OpenflowProtocolListener,
 
     private QueueProcessor<OfHeader, DataObject> queueProcessor;
     private QueueKeeper<OfHeader> queue;
-    private ThreadPoolExecutor hsPool;
     private HandshakeManager handshakeManager;
 
     private boolean firstHelloProcessed;
@@ -124,8 +120,8 @@ public class ConnectionConductorImpl implements OpenflowProtocolListener,
         conductorState = CONDUCTOR_STATE.HANDSHAKING;
         firstHelloProcessed = false;
         handshakeManager = new HandshakeManagerImpl(connectionAdapter,
-                ConnectionConductor.versionOrder.get(0),
-                ConnectionConductor.versionOrder);
+                ConnectionConductor.VERSION_ORDER.get(0),
+                ConnectionConductor.VERSION_ORDER);
         handshakeManager.setUseVersionBitmap(isBitmapNegotiationEnable);
         handshakeManager.setHandshakeListener(this);
         portFeaturesUtils = PortFeaturesUtil.getInstance();
@@ -133,12 +129,6 @@ public class ConnectionConductorImpl implements OpenflowProtocolListener,
 
     @Override
     public void init() {
-        int handshakeThreadLimit = 1;
-        hsPool = new ThreadPoolLoggingExecutor(handshakeThreadLimit,
-                handshakeThreadLimit, 0L, TimeUnit.MILLISECONDS,
-                new LinkedBlockingQueue<Runnable>(), "OFHandshake-"
-                + conductorId);
-
         connectionAdapter.setMessageListener(this);
         connectionAdapter.setSystemListener(this);
         connectionAdapter.setConnectionReadyListener(this);
@@ -202,7 +192,11 @@ public class ConnectionConductorImpl implements OpenflowProtocolListener,
      * @param queueType enqueue type
      */
     private void enqueueMessage(OfHeader message, QueueType queueType) {
-        queue.push(message, this, queueType);
+        if (queue != null) {
+            queue.push(message, this, queueType);
+        } else {
+            LOG.debug("Queue is null");
+        }
     }
 
     @Override
@@ -232,7 +226,9 @@ public class ConnectionConductorImpl implements OpenflowProtocolListener,
         checkState(CONDUCTOR_STATE.HANDSHAKING);
         HandshakeStepWrapper handshakeStepWrapper = new HandshakeStepWrapper(
                 hello, handshakeManager, connectionAdapter);
-        hsPool.submit(handshakeStepWrapper);
+        Thread t = new Thread(handshakeStepWrapper, "OFHandshake-" + conductorId);
+        t.setDaemon(true);
+        t.start();
     }
 
     /**
@@ -448,7 +444,9 @@ public class ConnectionConductorImpl implements OpenflowProtocolListener,
             checkState(CONDUCTOR_STATE.HANDSHAKING);
             HandshakeStepWrapper handshakeStepWrapper = new HandshakeStepWrapper(
                     null, handshakeManager, connectionAdapter);
-            hsPool.execute(handshakeStepWrapper);
+            Thread t = new Thread(handshakeStepWrapper, "OFHandshake-" + conductorId);
+            t.setDaemon(true);
+            t.start();
             firstHelloProcessed = true;
         } else {
             LOG.debug("already touched by hello message");
@@ -488,8 +486,6 @@ public class ConnectionConductorImpl implements OpenflowProtocolListener,
         }
 
         SessionContext sessionContext =  OFSessionUtil.registerSession(this, featureOutput, negotiatedVersion);
-        hsPool.shutdown();
-        hsPool.purge();
         conductorState = CONDUCTOR_STATE.WORKING;
         QueueKeeperFactory.plugQueue(queueProcessor, queue);
     }
@@ -518,24 +514,12 @@ public class ConnectionConductorImpl implements OpenflowProtocolListener,
             }
         } else {
             //This condition will occure when Old Helium openflowplugin implementation will be used.
-            shutdownPoolPolitely();
-        }
-    }
-
-    private void shutdownPoolPolitely() {
-        LOG.debug("Terminating handshake pool for node {}", connectionAdapter.getRemoteAddress());
-        hsPool.shutdown();
-        try {
-            hsPool.awaitTermination(1, TimeUnit.SECONDS);
-        } catch (InterruptedException e) {
-            LOG.debug("Error while awaiting termination of pool. Will force shutdown now.");
-        } finally {
-            hsPool.purge();
-            if (!hsPool.isTerminated()) {
-                hsPool.shutdownNow();
+            try{
+                queue.close();
+                queue = null;
+            }catch (Exception ex){
+                LOG.warn("Closing queue failed: {}", ex.getMessage());
             }
-            LOG.debug("is handshake pool for node {} is terminated : {}",
-                    connectionAdapter.getRemoteAddress(), hsPool.isTerminated());
         }
     }
 
@@ -543,9 +527,4 @@ public class ConnectionConductorImpl implements OpenflowProtocolListener,
     public void setHandshakeContext(HandshakeContext handshakeContext) {
         this.handshakeContext = handshakeContext;
     }
-
-    @VisibleForTesting
-    ThreadPoolExecutor getHsPool() {
-        return hsPool;
-    }
 }
index 78997ef27cc79f90db13a7a2f1ab0fea9dc7bcf1..785a568b4ac38a65ec1a6cf80fcd556c57db9f10 100644 (file)
@@ -267,7 +267,7 @@ public class HandshakeManagerImpl implements HandshakeManager {
             for(Elements element : list) {
                 List<Boolean> bitmap = element.getVersionBitmap();
                 // check for version bitmap
-                for(short bitPos : ConnectionConductor.versionOrder) {
+                for(short bitPos : ConnectionConductor.VERSION_ORDER) {
                     // with all the version it should work.
                     if(bitmap.get(bitPos % Integer.SIZE)) {
                         supportedHighestVersion = bitPos;
index 689f5a3fe4216102b3ba59aa61af79161512b5e9..ec0962abc1e8628e96b5c81f9bb88b5895fe01c6 100644 (file)
@@ -713,7 +713,7 @@ public final class IpConversionUtil {
 
     public static final byte[] convertIpv6ArbitraryMaskToByteArray(final Ipv6ArbitraryMask mask) {
         String maskValue;
-        if (mask.getValue() != null) {
+        if (mask != null && mask.getValue() != null) {
             maskValue  = mask.getValue();
         } else {
             maskValue = DEFAULT_IPV6_ARBITRARY_BITMASK;
index d502c0d6fb7dd0c00600e115541c27473cf11dc0..d1cf4b932a30c1efea93595eb62ab1989b08c2e6 100644 (file)
@@ -12,6 +12,7 @@ import com.google.common.collect.ImmutableBiMap;
 import org.opendaylight.openflowjava.protocol.api.util.BinContent;
 import org.opendaylight.openflowplugin.api.OFConstants;
 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortNumberUni;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.OutputPortValues;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumberValues;
@@ -149,4 +150,14 @@ public class OpenflowPortsUtil {
         }
         return result;
     }
+
+    /**
+     * Converts port number to Uri
+     * @param version openflow version
+     * @param portNumber port number
+     * @return port number uri
+     */
+    public static Uri getProtocolAgnosticPortUri(final short version, final long portNumber) {
+        return new Uri(portNumberToString(getProtocolAgnosticPort(OpenflowVersion.get(version), portNumber)));
+    }
 }
index 8eb350f358900cfd1cc51805db5fde840b0b2160..dc02a5540bffcf1cb00189e2663f2c40d2381b9c 100644 (file)
@@ -199,7 +199,6 @@ public class ConnectionConductorImplTest {
             libSimulation.join();
         }
         queueProcessor.shutdown();
-        connectionConductor.getHsPool().shutdown();
 
         for (Exception problem : adapter.getOccuredExceptions()) {
             LOG.error("during simulation on adapter side: "
@@ -487,7 +486,6 @@ public class ConnectionConductorImplTest {
      */
     private void executeNow() throws InterruptedException {
         execute(true);
-        connectionConductor.getHsPool().shutdown();
     }
 
     /**
index 2b1210bdfce2eefd5a01ffbd3edc818e6e3e6ed4..6db520e4b03c2c4e624513b3dd5689752b47cb40 100644 (file)
@@ -69,7 +69,7 @@ public class HandshakeManagerImplTest {
     @Before
     public void setUp() {
         handshakeManager = new HandshakeManagerImpl(adapter, OFConstants.OFP_VERSION_1_3,
-                ConnectionConductor.versionOrder);
+                ConnectionConductor.VERSION_ORDER);
         handshakeManager.setErrorHandler(errorHandler);
         handshakeManager.setHandshakeListener(handshakeListener);
         handshakeManager.setUseVersionBitmap(false);
index 0169cc71d9146cd555cf644ba98442d7b70486f2..773b161deb1b71e5d70561c1428b582b1159dde3 100644 (file)
@@ -15,15 +15,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev13
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.hello.Elements;
 
-/**
- * @author mirehak
- *
- */
 public class MessageFactoryTest {
 
-    /**
-     * Test method for {@link org.opendaylight.openflowplugin.openflow.md.core.MessageFactory#createHelloInputWoElements(java.lang.Short, java.lang.Long)}.
-     */
     @Test
     public void testCreateHelloInputWoElements() {
         short highestVersion = (short) 0x04;
@@ -35,9 +28,6 @@ public class MessageFactoryTest {
         Assert.assertNull(helloMsg.getElements());
     }
 
-    /**
-     * Test method for {@link org.opendaylight.openflowplugin.openflow.md.core.MessageFactory#createHelloInputWithElements(java.lang.Short, java.lang.Long, java.util.List)}.
-     */
     @Test
     public void testCreateHelloInputWithElements() {
         short highestVersion = (short) 0x04;
@@ -46,7 +36,7 @@ public class MessageFactoryTest {
                 false, true, false, false, true};
         
         HelloInput helloMsg = MessageFactory.createHelloInput(highestVersion, xid, 
-                ConnectionConductor.versionOrder);
+                ConnectionConductor.VERSION_ORDER);
         Assert.assertEquals(highestVersion, helloMsg.getVersion().shortValue());
         Assert.assertEquals(xid, helloMsg.getXid().longValue());
         Assert.assertEquals(1, helloMsg.getElements().size());
index ea8d4fe9990fd6c1bf01a42ce6fcc9fa45368f07..c3c6821e1726216f651321b36125b86e35da7b66 100644 (file)
     <parent>
         <groupId>org.opendaylight.odlparent</groupId>
         <artifactId>odlparent</artifactId>
-        <version>1.7.3-SNAPSHOT</version>
+        <version>1.7.5-SNAPSHOT</version>
         <relativePath/>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
     <groupId>org.opendaylight.openflowplugin</groupId>
     <artifactId>openflowplugin-parent</artifactId>
-    <version>0.3.3-SNAPSHOT</version>
+    <version>0.3.5-SNAPSHOT</version>
     <packaging>pom</packaging>
 
     <scm>
 
     <properties>
         <project.build.sourceEncoding>utf-8</project.build.sourceEncoding>
-        <openflowjava.version>0.8.3-SNAPSHOT</openflowjava.version>
-        <openflowplugin.version>0.3.3-SNAPSHOT</openflowplugin.version>
-        <sal.api.version>0.11.3-SNAPSHOT</sal.api.version>
+        <openflowjava.version>0.8.5-SNAPSHOT</openflowjava.version>
+        <openflowplugin.version>0.3.5-SNAPSHOT</openflowplugin.version>
+        <sal.api.version>0.11.5-SNAPSHOT</sal.api.version>
         <jmxGeneratorPath>target/generated-sources/config</jmxGeneratorPath>
         <salGeneratorPath>target/generated-sources/sal</salGeneratorPath>
         <exi.nagasena.version>0000.0002.0053.0</exi.nagasena.version>
-        <controller.distribution.version>0.4.3-SNAPSHOT</controller.distribution.version>
+        <controller.distribution.version>0.4.5-SNAPSHOT</controller.distribution.version>
 
-        <config.version>0.5.3-SNAPSHOT</config.version>
-        <mdsal.version>1.4.3-SNAPSHOT</mdsal.version>
-        <mdsal.model.version>0.9.3-SNAPSHOT</mdsal.model.version>
-        <yangtools.version>1.0.3-SNAPSHOT</yangtools.version>
+        <config.version>0.5.5-SNAPSHOT</config.version>
+        <mdsal.version>1.4.5-SNAPSHOT</mdsal.version>
+        <mdsal.model.version>0.9.5-SNAPSHOT</mdsal.model.version>
+        <yangtools.version>1.0.5-SNAPSHOT</yangtools.version>
     </properties>
 
     <dependencyManagement>
@@ -65,7 +65,7 @@
             <dependency>
                 <groupId>org.opendaylight.mdsal</groupId>
                 <artifactId>mdsal-artifacts</artifactId>
-                <version>2.1.3-SNAPSHOT</version>
+                <version>2.1.5-SNAPSHOT</version>
                 <scope>import</scope>
                 <type>pom</type>
             </dependency>
diff --git a/pom.xml b/pom.xml
index 60e0cac838fba7c4940141e5591b62f47c00aa0f..8833aa404a09d1a0c3eef0f67d834f27ff7e21b7 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -4,13 +4,13 @@
     <parent>
         <groupId>org.opendaylight.openflowplugin</groupId>
         <artifactId>openflowplugin-parent</artifactId>
-        <version>0.3.3-SNAPSHOT</version>
+        <version>0.3.5-SNAPSHOT</version>
         <relativePath>parent</relativePath>
     </parent>
 
     <groupId>org.opendaylight.openflowplugin</groupId>
     <artifactId>openflowplugin-aggregator</artifactId>
-    <version>0.3.3-SNAPSHOT</version>
+    <version>0.3.5-SNAPSHOT</version>
     <name>openflowplugin</name> <!-- Used by Sonar to set project name -->
     <packaging>pom</packaging>
 
index 63d8f323050e89ab51514582ce31787c35ad37c6..53875272030ae8c64d109ada9d9d28833a29c1bf 100644 (file)
@@ -4,7 +4,7 @@
     <parent>
         <groupId>org.opendaylight.openflowplugin</groupId>
         <artifactId>openflowplugin-parent</artifactId>
-        <version>0.3.3-SNAPSHOT</version>
+        <version>0.3.5-SNAPSHOT</version>
         <relativePath>../../parent</relativePath>
     </parent>
 
index 3df1ab8cd350c7ac0145f77a88aa37caa6124e45..fb9f01f09525fa913076d7af9331eef464b76324 100644 (file)
@@ -4,12 +4,12 @@
     <parent>
         <groupId>org.opendaylight.openflowplugin</groupId>
         <artifactId>openflowplugin-parent</artifactId>
-        <version>0.3.3-SNAPSHOT</version>
+        <version>0.3.5-SNAPSHOT</version>
         <relativePath>../../parent</relativePath>
     </parent>
 
     <artifactId>sample-consumer</artifactId>
-    <version>0.3.3-SNAPSHOT</version>
+    <version>0.3.5-SNAPSHOT</version>
     <packaging>bundle</packaging>
 
     <build>
index 484581ee688dd2eff3a863f5c82f1c470099b010..f7b77cf0acf6c8931510e9ef2df54582473ef150 100644 (file)
@@ -4,7 +4,7 @@
     <parent>
         <groupId>org.opendaylight.openflowplugin</groupId>
         <artifactId>openflowplugin-parent</artifactId>
-        <version>0.3.3-SNAPSHOT</version>
+        <version>0.3.5-SNAPSHOT</version>
         <relativePath>../parent</relativePath>
     </parent>
     <artifactId>test-common</artifactId>
index 9b3d54ecfc9fc1b3ec22aad98ce139fd4b3881e2..68ee3b1649583bc63044f2e99af48a84b3d31246 100644 (file)
@@ -3,7 +3,7 @@
     <parent>
         <groupId>org.opendaylight.openflowplugin</groupId>
         <artifactId>openflowplugin-parent</artifactId>
-        <version>0.3.3-SNAPSHOT</version>
+        <version>0.3.5-SNAPSHOT</version>
         <relativePath>../parent</relativePath>
     </parent>
     <artifactId>test-provider</artifactId>