Merge "Removed duplicate sal-binding-config dependency."
authorAbhijit Kumbhare <abhijit.kumbhare@ericsson.com>
Thu, 23 Jun 2016 15:37:51 +0000 (15:37 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 23 Jun 2016 15:37:51 +0000 (15:37 +0000)
217 files changed:
applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/FlowNodeConnectorInventoryTranslatorImpl.java
applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/FlowNodeReconciliationImpl.java
applications/forwardingrules-sync/pom.xml
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/SyncPlanPushStrategy.java
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/SyncReactor.java
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/dao/FlowCapableNodeCachedDao.java
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/dao/FlowCapableNodeDao.java
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/dao/FlowCapableNodeOdlDao.java
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/dao/FlowCapableNodeSnapshotDao.java
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/impl/AbstractFrmSyncListener.java
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/impl/FlowForwarder.java
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/impl/ForwardingRulesSyncProvider.java
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/impl/FrmExecutors.java
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/impl/MeterForwarder.java
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/impl/SimplifiedConfigListener.java
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/impl/SimplifiedOperationalListener.java
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/impl/SimplifiedOperationalRetryListener.java [new file with mode: 0644]
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/impl/SyncReactorFutureDecorator.java
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/impl/SyncReactorFutureWithCompressionDecorator.java [deleted file]
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/impl/SyncReactorFutureZipDecorator.java [new file with mode: 0644]
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/impl/SyncReactorGuardDecorator.java
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/impl/SyncReactorImpl.java
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/impl/SyncReactorRetryDecorator.java [new file with mode: 0644]
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/impl/strategy/SyncPlanPushStrategyIncrementalImpl.java
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/impl/strategy/SynchronizationDiffInput.java
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/markandsweep/SwitchFlowId.java
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/util/FlowCapableNodeLookups.java
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/util/ItemSyncBox.java
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/util/RetryRegistry.java [new file with mode: 0644]
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/util/SemaphoreKeeperGuavaImpl.java
applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/util/ZipQueueEntry.java [new file with mode: 0644]
applications/forwardingrules-sync/src/test/java/org/opendaylight/openflowplugin/applications/frsync/impl/SimplifiedConfigListenerTest.java
applications/forwardingrules-sync/src/test/java/org/opendaylight/openflowplugin/applications/frsync/impl/SimplifiedOperationalListenerTest.java
applications/forwardingrules-sync/src/test/java/org/opendaylight/openflowplugin/applications/frsync/impl/SimplifiedOperationalRetryListenerTest.java [new file with mode: 0644]
applications/forwardingrules-sync/src/test/java/org/opendaylight/openflowplugin/applications/frsync/impl/SyncReactorFutureZipDecoratorTest.java [new file with mode: 0644]
applications/forwardingrules-sync/src/test/java/org/opendaylight/openflowplugin/applications/frsync/impl/SyncReactorGuardDecoratorTest.java
applications/forwardingrules-sync/src/test/java/org/opendaylight/openflowplugin/applications/frsync/impl/SyncReactorImplTest.java
applications/forwardingrules-sync/src/test/java/org/opendaylight/openflowplugin/applications/frsync/impl/SyncReactorRetryDecoratorTest.java [new file with mode: 0644]
applications/forwardingrules-sync/src/test/java/org/opendaylight/openflowplugin/applications/frsync/impl/strategy/SyncPlanPushStrategyIncrementalImplTest.java
applications/forwardingrules-sync/src/test/java/org/opendaylight/openflowplugin/applications/frsync/util/ReconcileUtilTest.java
applications/forwardingrules-sync/src/test/java/org/opendaylight/openflowplugin/applications/frsync/util/RetryRegistryTest.java [new file with mode: 0644]
applications/forwardingrules-sync/src/test/java/org/opendaylight/openflowplugin/applications/frsync/util/SemaphoreKeeperTest.java
applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatRpcMsgManagerImpl.java
artifacts/pom.xml
distribution/karaf/pom.xml
extension/features-he/pom.xml [moved from extension/features-li/pom.xml with 94% similarity]
extension/features-he/src/main/features/features.xml [moved from extension/features-li/src/main/features/features.xml with 82% similarity]
extension/openflowjava-extension-nicira/pom.xml
extension/openflowjava-extension-nicira/src/main/java/org/opendaylight/openflowjava/nx/NiciraExtensionsRegistrator.java
extension/openflowjava-extension-nicira/src/main/java/org/opendaylight/openflowjava/nx/codec/match/TcpDstCodec.java
extension/openflowjava-extension-nicira/src/main/java/org/opendaylight/openflowjava/nx/codec/match/TcpSrcCodec.java
extension/openflowjava-extension-nicira/src/main/java/org/opendaylight/openflowjava/nx/codec/match/UdpDstCodec.java
extension/openflowjava-extension-nicira/src/main/java/org/opendaylight/openflowjava/nx/codec/match/UdpSrcCodec.java
extension/openflowjava-extension-nicira/src/test/java/org/opendaylight/openflowjava/nx/NiciraExtensionsRegistratorTest.java [new file with mode: 0644]
extension/pom.xml
features-he/pom.xml [moved from features-li/pom.xml with 92% similarity]
features-he/src/main/features/features.xml [moved from features-li/src/main/features/features.xml with 69% similarity]
features/pom.xml
features/src/main/features/features.xml
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OFPContext.java [new file with mode: 0644]
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OFPManager.java [new file with mode: 0644]
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/connection/ConnectionContext.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/DeviceInfo.java [new file with mode: 0644]
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceManager.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceRegistry.java [new file with mode: 0644]
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceState.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceSynchronizeListener.java [new file with mode: 0644]
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceValidListener.java [new file with mode: 0644]
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/MessageTranslator.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/PortNumberCache.java [deleted file]
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/handlers/DeviceInitializationPhaseHandler.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/handlers/DeviceTerminationPhaseHandler.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/lifecycle/DeviceContextChangeListener.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/lifecycle/LifecycleConductor.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/lifecycle/RoleChangeListener.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/lifecycle/ServiceChangeListener.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/NotificationQueueWrapper.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/SessionManager.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/util/PollableQueuesZipper.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/role/RoleContext.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/role/RoleManager.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/rpc/RpcContext.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/rpc/RpcManager.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/statistics/StatisticsContext.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/statistics/StatisticsManager.java
openflowplugin-api/src/main/yang/openflow-provider-config.yang
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/LifecycleConductorImpl.java
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/ConnectionContextImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/connection/ConnectionManagerImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/connection/HandshakeContextImpl.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/DeviceStateImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/TransactionChainManager.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/role/RoleContextImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/role/RoleManagerImpl.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/AbstractMultipartOnTheFlyService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestOnTheFlyCallback.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/RoleService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalExperimenterMessageServiceImpl.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/services/SalRoleServiceImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalTableServiceImpl.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/AggregateFlowsInTableService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllFlowsInAllTablesService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllFlowsInTableService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllGroupsStatsService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllMeterConfigStatsService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllMeterStatsService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllPortStatsService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllQueuesAllPortsService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllQueuesOnePortService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/FlowsInTableService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/GroupDescriptionService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/GroupFeaturesService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/GroupStatsService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/MatchingFlowsInTableService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/MeterFeaturesService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/MeterStatsService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/OneQueueOnePortService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/OpendaylightFlowStatisticsServiceImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/OpendaylightFlowTableStatisticsServiceImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/PortStatsService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/FlowStatisticsToNotificationTransformer.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/GroupStatisticsToNotificationTransformer.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/MeterStatisticsToNotificationTransformer.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/NodeConnectorStatisticsToNotificationTransformer.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/QueueStatisticsToNotificationTransformer.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/dedicated/StatisticsGatheringOnTheFlyService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/dedicated/StatisticsGatheringService.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/statistics/services/direct/GroupDirectStatisticsService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/MeterDirectStatisticsService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/NodeConnectorDirectStatisticsService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/OpendaylightDirectStatisticsServiceImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/QueueDirectStatisticsService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/translator/AggregatedFlowStatisticsTranslator.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/translator/FlowRemovedTranslator.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/translator/FlowRemovedV10Translator.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/translator/PacketReceivedTranslator.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/translator/PortUpdateTranslator.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/DeviceInitializationUtils.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MdSalRegistrationUtils.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/LifecycleConductorImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/connection/ConnectionManagerImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/connection/OutboundQueueProviderImplTest.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/device/DeviceStateImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/TransactionChainManagerTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/registry/flow/FlowRegistryKeyFactoryTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/role/RoleContextImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/role/RoleManagerImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/rpc/AbstractRequestContextTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/rpc/ItemLifecycleListenerImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/rpc/RpcContextImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/rpc/RpcManagerImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/AbstractRequestCallbackTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/FlowCapableTransactionServiceImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestOnTheFlyCallbackTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/PacketProcessingServiceImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalExperimenterMessageServiceImplTest.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/SalPortServiceImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalRoleServiceImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/ServiceMocking.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/SinglePurposeMultipartReplyTranslatorTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpMockInitiation.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImplParamTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImplTest.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/ofpspecific/MessageIntelligenceAgencyImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/AbstractStatsServiceTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/OpendaylightFlowStatisticsServiceImpl2Test.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/AbstractCompatibleStatServiceTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/OpendaylightFlowStatisticsServiceDelegateImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/dedicated/StatisticsGatheringOnTheFlyServiceTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractDirectStatisticsServiceTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/FlowDirectStatisticsServiceTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/GroupDirectStatisticsServiceTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/MeterDirectStatisticsServiceTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/NodeConnectorDirectStatisticsServiceTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/OpendaylightDirectStatisticsServiceImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/QueueDirectStatisticsServiceTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/translator/AggregatedFlowStatisticsTranslatorTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/translator/FlowRemovedTranslatorTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/translator/PacketReceivedTranslatorTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/translator/PortUpdateTranslatorTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/util/DeviceInitializationUtilsTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/util/MdSalRegistrationUtilsTest.java
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/FlowConvertor.java
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/session/SessionManagerOFImpl.java
openflowplugin/src/test/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/FlowConvertorTest.java
pom.xml

index 08bdf848532150bbb961b4887fab6a46dab6cd2f..e4b032e370b5875e5852e1d4f4d484e9ed325f62 100644 (file)
@@ -89,7 +89,7 @@ public class FlowNodeConnectorInventoryTranslatorImpl extends AbstractNodeConnec
     @Override
     public void remove(InstanceIdentifier<FlowCapableNodeConnector> identifier, FlowCapableNodeConnector del, InstanceIdentifier<FlowCapableNodeConnector> nodeConnIdent) {
         if(compareInstanceIdentifierTail(identifier,II_TO_FLOW_CAPABLE_NODE_CONNECTOR)){
-            LOG.warn("Node Connector removed");
+            LOG.info("Node Connector removed");
             String sNodeConnectorIdentifier = nodeConnIdent
                     .firstKeyOf(NodeConnector.class, NodeConnectorKey.class).getId().getValue();
             long nDpId = getDpIdFromPortName(sNodeConnectorIdentifier);
@@ -102,7 +102,7 @@ public class FlowNodeConnectorInventoryTranslatorImpl extends AbstractNodeConnec
     @Override
     public void update(InstanceIdentifier<FlowCapableNodeConnector> identifier, FlowCapableNodeConnector original, FlowCapableNodeConnector update, InstanceIdentifier<FlowCapableNodeConnector> nodeConnIdent) {
         if(compareInstanceIdentifierTail(identifier,II_TO_FLOW_CAPABLE_NODE_CONNECTOR)){
-            LOG.warn("Node Connector updated");
+            LOG.info("Node Connector updated");
             //donot need to do anything as we are not considering updates here
         }
     }
@@ -110,7 +110,7 @@ public class FlowNodeConnectorInventoryTranslatorImpl extends AbstractNodeConnec
     @Override
     public void add(InstanceIdentifier<FlowCapableNodeConnector> identifier, FlowCapableNodeConnector add, InstanceIdentifier<FlowCapableNodeConnector> nodeConnIdent) {
         if(compareInstanceIdentifierTail(identifier,II_TO_FLOW_CAPABLE_NODE_CONNECTOR)){
-            LOG.warn("Node Connector added");
+            LOG.info("Node Connector added");
             String sNodeConnectorIdentifier = nodeConnIdent
                     .firstKeyOf(NodeConnector.class, NodeConnectorKey.class).getId().getValue();
             long nDpId = getDpIdFromPortName(sNodeConnectorIdentifier);
index 6c43cd4912f64f43aed34ad0af79cf54839f288a..e372ff557dfbc88b11c8da1e802cead2b75b5ec5 100644 (file)
@@ -175,7 +175,9 @@ public class FlowNodeReconciliationImpl implements FlowNodeReconciliation {
     public void remove(InstanceIdentifier<FlowCapableNode> identifier, FlowCapableNode del,
                        InstanceIdentifier<FlowCapableNode> nodeIdent) {
         if(compareInstanceIdentifierTail(identifier,II_TO_FLOW_CAPABLE_NODE)){
-            LOG.warn("Node removed: {}",nodeIdent.firstKeyOf(Node.class).getId().getValue());
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Node removed: {}",nodeIdent.firstKeyOf(Node.class).getId().getValue());
+            }
 
             if ( ! nodeIdent.isWildcarded()) {
                 flowNodeDisconnected(nodeIdent);
@@ -187,7 +189,9 @@ public class FlowNodeReconciliationImpl implements FlowNodeReconciliation {
     public void add(InstanceIdentifier<FlowCapableNode> identifier, FlowCapableNode add,
                     InstanceIdentifier<FlowCapableNode> nodeIdent) {
         if(compareInstanceIdentifierTail(identifier,II_TO_FLOW_CAPABLE_NODE)){
-            LOG.warn("Node added: {}",nodeIdent.firstKeyOf(Node.class).getId().getValue());
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Node added: {}",nodeIdent.firstKeyOf(Node.class).getId().getValue());
+            }
 
             if ( ! nodeIdent.isWildcarded()) {
                 flowNodeConnected(nodeIdent);
index e9fad3b3163ad9f54a0f633c75b01bfe2107f6a1..067a462f2ee9dccdbbc66a5a3de49400a003ea3d 100644 (file)
             <artifactId>model-inventory</artifactId>
         </dependency>
 
-        <dependency>
-            <groupId>org.opendaylight.openflowplugin.model</groupId>
-            <artifactId>model-flow-base</artifactId>
-        </dependency>
-
         <dependency>
             <groupId>org.opendaylight.openflowplugin.model</groupId>
             <artifactId>model-flow-service</artifactId>
index 9a856cc6b946aa2dbb19b373b0cb5fe874084ff7..5e3838978c9627f577a710020ef79d6eb607eb33 100644 (file)
@@ -22,7 +22,8 @@ public interface SyncPlanPushStrategy {
     /**
      * @param resultVehicle bootstrap future - execution will chain it's async calls to this one
      * @param diffInput     wraps all diff data required for any strategy ({add,remove,update} x {flow,group,meter})
-     * @param counters      reference to internal one-shot statistics - summary off successfully pushed items shall be recorded here
+     * @param counters      reference to internal one-shot statistics - summary off successfully pushed items
+     *                      shall be recorded here
      * @return last future of the chain
      */
     ListenableFuture<RpcResult<Void>> executeSyncStrategy(ListenableFuture<RpcResult<Void>> resultVehicle,
index 141e3b465ae915b87fa06c0e1490d9c7ae7f68bd..cf92bbae60840ff5b1111f0c066ef9a23a6084be 100644 (file)
@@ -9,6 +9,7 @@
 package org.opendaylight.openflowplugin.applications.frsync;
 
 import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
@@ -20,9 +21,10 @@ public interface SyncReactor {
      * @param flowcapableNodePath path to openflow augmentation of node
      * @param configTree configured node
      * @param operationalTree device reflection
+     * @param dsType type of DS change
      * @return synchronization outcome
      */
-    ListenableFuture<Boolean> syncup(InstanceIdentifier<FlowCapableNode> flowcapableNodePath,
-            FlowCapableNode configTree, FlowCapableNode operationalTree) throws InterruptedException;
-
+    ListenableFuture<Boolean> syncup(final InstanceIdentifier<FlowCapableNode> flowcapableNodePath,
+                                     final FlowCapableNode configTree, final FlowCapableNode operationalTree,
+                                     final LogicalDatastoreType dsType) throws InterruptedException;
 }
index 149c25959605e1eb272fb2da055708034b62c5b7..b94bc1e4731dade02f50d527c9b895fc59aa6e30 100644 (file)
@@ -1,40 +1,40 @@
-/**\r
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.openflowplugin.applications.frsync.dao;\r
-\r
-import com.google.common.base.Optional;\r
-import javax.annotation.Nonnull;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;\r
-\r
-/**\r
- * Implementation of data access object for {@link FlowCapableNode}.\r
- * Contains pair of snapshot and odl DAOs.\r
- */\r
-public class FlowCapableNodeCachedDao implements FlowCapableNodeDao {\r
-\r
-    private final FlowCapableNodeDao snapshotDao;\r
-    private final FlowCapableNodeDao odlDao;\r
-\r
-    public FlowCapableNodeCachedDao(FlowCapableNodeDao snapshotDao, FlowCapableNodeDao odlDao) {\r
-        this.snapshotDao = snapshotDao;\r
-        this.odlDao = odlDao;\r
-    }\r
-\r
-    public Optional<FlowCapableNode> loadByNodeId(@Nonnull NodeId nodeId) {\r
-        final Optional<FlowCapableNode> node = snapshotDao.loadByNodeId(nodeId);\r
-\r
-        if (node.isPresent()) {\r
-            return node;\r
-        }\r
-\r
-        return odlDao.loadByNodeId(nodeId);\r
-    }\r
-\r
-}\r
+/**
+ * Copyright (c) 2016 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.applications.frsync.dao;
+
+import com.google.common.base.Optional;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+
+/**
+ * Implementation of data access object for {@link FlowCapableNode}.
+ * Contains pair of snapshot and odl DAOs.
+ */
+public class FlowCapableNodeCachedDao implements FlowCapableNodeDao {
+
+    private final FlowCapableNodeDao snapshotDao;
+    private final FlowCapableNodeDao odlDao;
+
+    public FlowCapableNodeCachedDao(FlowCapableNodeDao snapshotDao, FlowCapableNodeDao odlDao) {
+        this.snapshotDao = snapshotDao;
+        this.odlDao = odlDao;
+    }
+
+    public Optional<FlowCapableNode> loadByNodeId(@Nonnull NodeId nodeId) {
+        final Optional<FlowCapableNode> node = snapshotDao.loadByNodeId(nodeId);
+
+        if (node.isPresent()) {
+            return node;
+        }
+
+        return odlDao.loadByNodeId(nodeId);
+    }
+
+}
index 469fc13cde12b082f50ae9054ba067271872dbcb..7340fccceee69a95eb53b0a910770c484c2baff5 100644 (file)
@@ -1,21 +1,21 @@
-/**\r
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.openflowplugin.applications.frsync.dao;\r
-\r
-import com.google.common.base.Optional;\r
-import javax.annotation.Nonnull;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;\r
-\r
-/**\r
- * Data access object for {@link FlowCapableNode}.\r
- */\r
-public interface FlowCapableNodeDao {\r
-    Optional<FlowCapableNode> loadByNodeId(@Nonnull NodeId nodeId);\r
-}\r
+/**
+ * Copyright (c) 2016 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.applications.frsync.dao;
+
+import com.google.common.base.Optional;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+
+/**
+ * Data access object for {@link FlowCapableNode}.
+ */
+public interface FlowCapableNodeDao {
+    Optional<FlowCapableNode> loadByNodeId(@Nonnull NodeId nodeId);
+}
index a97fcc170836e9898245710a2a872aa78c675395..73467086f47cfd969836ba3210037ebd44c07a7c 100644 (file)
@@ -1,56 +1,56 @@
-/**\r
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.openflowplugin.applications.frsync.dao;\r
-\r
-import com.google.common.base.Optional;\r
-import java.util.concurrent.TimeUnit;\r
-import java.util.concurrent.TimeoutException;\r
-import javax.annotation.Nonnull;\r
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;\r
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;\r
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-/**\r
- * Implementation of data access object for ODL {@link FlowCapableNode}.\r
- */\r
-public class FlowCapableNodeOdlDao implements FlowCapableNodeDao {\r
-\r
-    private static final Logger LOG = LoggerFactory.getLogger(FlowCapableNodeOdlDao.class);\r
-\r
-    private static final InstanceIdentifier<Nodes> NODES_IID = InstanceIdentifier.create(Nodes.class);\r
-    private final DataBroker dataBroker;\r
-    private final LogicalDatastoreType logicalDatastoreType;\r
-\r
-    public FlowCapableNodeOdlDao(DataBroker dataBroker, LogicalDatastoreType logicalDatastoreType) {\r
-        this.dataBroker = dataBroker;\r
-        this.logicalDatastoreType = logicalDatastoreType;\r
-    }\r
-\r
-    public Optional<FlowCapableNode> loadByNodeId(@Nonnull NodeId nodeId) {\r
-        try (final ReadOnlyTransaction roTx = dataBroker.newReadOnlyTransaction()) {\r
-            final InstanceIdentifier<FlowCapableNode> path =\r
-                    NODES_IID.child(Node.class, new NodeKey(nodeId)).augmentation(FlowCapableNode.class);\r
-            return roTx.read(logicalDatastoreType, path).checkedGet(5000, TimeUnit.MILLISECONDS);\r
-        } catch (ReadFailedException | TimeoutException e) {\r
-            LOG.error("error reading {}", nodeId, e);\r
-        }\r
-\r
-        return Optional.absent();\r
-    }\r
-\r
-}\r
+/**
+ * Copyright (c) 2016 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.applications.frsync.dao;
+
+import com.google.common.base.Optional;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+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.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;
+
+/**
+ * Implementation of data access object for ODL {@link FlowCapableNode}.
+ */
+public class FlowCapableNodeOdlDao implements FlowCapableNodeDao {
+
+    private static final Logger LOG = LoggerFactory.getLogger(FlowCapableNodeOdlDao.class);
+
+    private static final InstanceIdentifier<Nodes> NODES_IID = InstanceIdentifier.create(Nodes.class);
+    private final DataBroker dataBroker;
+    private final LogicalDatastoreType logicalDatastoreType;
+
+    public FlowCapableNodeOdlDao(DataBroker dataBroker, LogicalDatastoreType logicalDatastoreType) {
+        this.dataBroker = dataBroker;
+        this.logicalDatastoreType = logicalDatastoreType;
+    }
+
+    public Optional<FlowCapableNode> loadByNodeId(@Nonnull NodeId nodeId) {
+        try (final ReadOnlyTransaction roTx = dataBroker.newReadOnlyTransaction()) {
+            final InstanceIdentifier<FlowCapableNode> path =
+                    NODES_IID.child(Node.class, new NodeKey(nodeId)).augmentation(FlowCapableNode.class);
+            return roTx.read(logicalDatastoreType, path).checkedGet(5000, TimeUnit.MILLISECONDS);
+        } catch (ReadFailedException | TimeoutException e) {
+            LOG.error("error reading {}", nodeId, e);
+        }
+
+        return Optional.absent();
+    }
+
+}
index 5cbf726cc53af6400e2c82a8682f764649761991..4f7835aaccf9c0f562f2149efef0084e1b723059 100644 (file)
@@ -1,37 +1,37 @@
-/**\r
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.openflowplugin.applications.frsync.dao;\r
-\r
-import com.google.common.base.Optional;\r
-import java.util.concurrent.ConcurrentHashMap;\r
-import javax.annotation.Nonnull;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;\r
-\r
-/**\r
- * Adding cache to data access object of {@link FlowCapableNode}.\r
- */\r
-public class FlowCapableNodeSnapshotDao implements FlowCapableNodeDao {\r
-\r
-    private final ConcurrentHashMap<String, FlowCapableNode> cache = new ConcurrentHashMap<>();\r
-\r
-    public void updateCache(@Nonnull NodeId nodeId, Optional<FlowCapableNode> dataAfter) {\r
-        if (dataAfter.isPresent()) {\r
-            cache.put(nodeId.getValue(), dataAfter.get());\r
-        } else {\r
-            cache.remove(nodeId.getValue());\r
-        }\r
-    }\r
-\r
-    public Optional<FlowCapableNode> loadByNodeId(@Nonnull NodeId nodeId) {\r
-        final FlowCapableNode node = cache.get(nodeId.getValue());\r
-        return Optional.fromNullable(node);\r
-    }\r
-\r
-}\r
+/**
+ * Copyright (c) 2016 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.applications.frsync.dao;
+
+import com.google.common.base.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+
+/**
+ * Adding cache to data access object of {@link FlowCapableNode}.
+ */
+public class FlowCapableNodeSnapshotDao implements FlowCapableNodeDao {
+
+    private final ConcurrentHashMap<String, FlowCapableNode> cache = new ConcurrentHashMap<>();
+
+    public void updateCache(@Nonnull NodeId nodeId, Optional<FlowCapableNode> dataAfter) {
+        if (dataAfter.isPresent()) {
+            cache.put(nodeId.getValue(), dataAfter.get());
+        } else {
+            cache.remove(nodeId.getValue());
+        }
+    }
+
+    public Optional<FlowCapableNode> loadByNodeId(@Nonnull NodeId nodeId) {
+        final FlowCapableNode node = cache.get(nodeId.getValue());
+        return Optional.fromNullable(node);
+    }
+
+}
index 2a4d1bd0f5b3d4559cb41778b138203b02b6e67d..aaf4063bd0f21a6e609d686404383a90a8a7223f 100644 (file)
@@ -15,7 +15,6 @@ import java.util.concurrent.TimeUnit;
 import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.openflowplugin.applications.frsync.NodeListener;
 import org.opendaylight.openflowplugin.applications.frsync.util.PathUtil;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
@@ -39,18 +38,18 @@ public abstract class AbstractFrmSyncListener<T extends DataObject> implements N
                 if (optFuture.isPresent()) {
                     final ListenableFuture<Boolean> future = optFuture.get();
                     final Boolean ret = future.get(15000, TimeUnit.MILLISECONDS);
-                    LOG.debug("syncup ret {} {} {} thread:{}", dsType(), ret, nodeId, threadName());
+                    LOG.debug("syncup ret {} {} {} thread:{}", dsType(), ret, nodeId.getValue(), threadName());
                 }
             } catch (InterruptedException e) {
-                LOG.warn("permit for forwarding rules sync not acquired: {}", nodeId);
+                LOG.warn("permit for forwarding rules sync not acquired: {}", nodeId.getValue());
             } catch (Exception e) {
-                LOG.error("error processing inventory node modification: {}", nodeId, e);
+                LOG.error("error processing inventory node modification: {}", nodeId.getValue(), e);
             }
         }
     }
 
     protected abstract Optional<ListenableFuture<Boolean>> processNodeModification(
-            DataTreeModification<T> modification) throws ReadFailedException, InterruptedException;
+            DataTreeModification<T> modification) throws InterruptedException;
 
     protected abstract LogicalDatastoreType dsType();
 
index 8bc18dd0ffec6c228a7f3548b78ebe4a8e30ff56..87237c5f77d8910f00c6de93eb44c2e4ef2bb7f8 100644 (file)
@@ -41,7 +41,7 @@ import org.slf4j.LoggerFactory;
 public class FlowForwarder implements ForwardingRulesCommitter<Flow, AddFlowOutput, RemoveFlowOutput, UpdateFlowOutput> {
 
     private static final Logger LOG = LoggerFactory.getLogger(FlowForwarder.class);
-    private SalFlowService salFlowService;
+    private final SalFlowService salFlowService;
 
     public FlowForwarder(final SalFlowService salFlowService) {
         this.salFlowService = salFlowService;
@@ -53,7 +53,7 @@ public class FlowForwarder implements ForwardingRulesCommitter<Flow, AddFlowOutp
                                                       final InstanceIdentifier<FlowCapableNode> nodeIdent) {
         LOG.trace("Forwarding Flow REMOVE request Tbl id, node Id {} {}",
                 identifier, nodeIdent);
-        
+
         final TableKey tableKey = identifier.firstKeyOf(Table.class, TableKey.class);
         if (tableIdValidationPrecondition(tableKey, removeDataObj)) {
             final RemoveFlowInputBuilder builder = new RemoveFlowInputBuilder(removeDataObj);
@@ -77,7 +77,7 @@ public class FlowForwarder implements ForwardingRulesCommitter<Flow, AddFlowOutp
                                                       final InstanceIdentifier<FlowCapableNode> nodeIdent) {
         LOG.trace("Forwarding Flow UPDATE request [Tbl id, node Id {} {} {}",
                 identifier, nodeIdent, update);
-        
+
         final Future<RpcResult<UpdateFlowOutput>> output;
         final TableKey tableKey = identifier.firstKeyOf(Table.class, TableKey.class);
         if (tableIdValidationPrecondition(tableKey, update)) {
@@ -106,7 +106,7 @@ public class FlowForwarder implements ForwardingRulesCommitter<Flow, AddFlowOutp
                                                 final InstanceIdentifier<FlowCapableNode> nodeIdent) {
         LOG.trace("Forwarding the Flow ADD request [Tbl id, node Id {} {} {}",
                 identifier, nodeIdent, addDataObj);
-        
+
         final Future<RpcResult<AddFlowOutput>> output;
         final TableKey tableKey = identifier.firstKeyOf(Table.class, TableKey.class);
         if (tableIdValidationPrecondition(tableKey, addDataObj)) {
index a35cde26003ea1ab3dc2008615f3deabc32e1e36..24bfeafe06522d730c736a3bd82a83491562a42e 100644 (file)
@@ -27,6 +27,7 @@ import org.opendaylight.openflowplugin.applications.frsync.dao.FlowCapableNodeDa
 import org.opendaylight.openflowplugin.applications.frsync.dao.FlowCapableNodeOdlDao;
 import org.opendaylight.openflowplugin.applications.frsync.dao.FlowCapableNodeSnapshotDao;
 import org.opendaylight.openflowplugin.applications.frsync.impl.strategy.SyncPlanPushStrategyFlatBatchImpl;
+import org.opendaylight.openflowplugin.applications.frsync.util.RetryRegistry;
 import org.opendaylight.openflowplugin.applications.frsync.util.SemaphoreKeeperGuavaImpl;
 import org.opendaylight.openflowplugin.common.wait.SimpleTaskRetryLooper;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.SalFlatBatchService;
@@ -45,17 +46,17 @@ import org.slf4j.LoggerFactory;
 public class ForwardingRulesSyncProvider implements AutoCloseable, BindingAwareProvider {
 
     private static final Logger LOG = LoggerFactory.getLogger(ForwardingRulesSyncProvider.class);
-    public static final int STARTUP_LOOP_TICK = 500;
-    public static final int STARTUP_LOOP_MAX_RETRIES = 8;
+    private static final int STARTUP_LOOP_TICK = 500;
+    private static final int STARTUP_LOOP_MAX_RETRIES = 8;
 
     private final DataBroker dataService;
     private final SalTableService salTableService;
     private final SalFlatBatchService flatBatchService;
 
-    /** wildcard path to flow-capable-node augmentation of inventory node */
+    /** Wildcard path to flow-capable-node augmentation of inventory node. */
     private static final InstanceIdentifier<FlowCapableNode> FLOW_CAPABLE_NODE_WC_PATH =
             InstanceIdentifier.create(Nodes.class).child(Node.class).augmentation(FlowCapableNode.class);
-    /** wildcard path to node (not flow-capable-node augmentation) of inventory node */
+    /** Wildcard path to node (not flow-capable-node augmentation) of inventory node. */
     private static final InstanceIdentifier<Node> NODE_WC_PATH =
             InstanceIdentifier.create(Nodes.class).child(Node.class);
 
@@ -66,7 +67,6 @@ public class ForwardingRulesSyncProvider implements AutoCloseable, BindingAwareP
     private ListenerRegistration<NodeListener> dataTreeConfigChangeListener;
     private ListenerRegistration<NodeListener> dataTreeOperationalChangeListener;
 
-
     public ForwardingRulesSyncProvider(final BindingAwareBroker broker,
                                        final DataBroker dataBroker,
                                        final RpcConsumerRegistry rpcRegistry) {
@@ -106,12 +106,14 @@ public class ForwardingRulesSyncProvider implements AutoCloseable, BindingAwareP
                 .setFlatBatchService(flatBatchService)
                 .setTableForwarder(tableForwarder);
 
-        final SyncReactorImpl syncReactorImpl = new SyncReactorImpl(syncPlanPushStrategy);
-        final SyncReactor syncReactorGuard = new SyncReactorGuardDecorator(syncReactorImpl,
+        final RetryRegistry retryRegistry = new RetryRegistry();
+
+        final SyncReactor syncReactorImpl = new SyncReactorImpl(syncPlanPushStrategy);
+        final SyncReactor syncReactorRetry = new SyncReactorRetryDecorator(syncReactorImpl, retryRegistry);
+        final SyncReactor syncReactorGuard = new SyncReactorGuardDecorator(syncReactorRetry,
                 new SemaphoreKeeperGuavaImpl<InstanceIdentifier<FlowCapableNode>>(1, true));
 
-        final SyncReactor cfgReactor = new SyncReactorFutureWithCompressionDecorator(syncReactorGuard, syncThreadPool);
-        final SyncReactor operReactor = new SyncReactorFutureWithCompressionDecorator(syncReactorGuard, syncThreadPool);
+        final SyncReactor reactor = new SyncReactorFutureZipDecorator(syncReactorGuard, syncThreadPool);
 
         final FlowCapableNodeSnapshotDao configSnapshot = new FlowCapableNodeSnapshotDao();
         final FlowCapableNodeSnapshotDao operationalSnapshot = new FlowCapableNodeSnapshotDao();
@@ -120,8 +122,10 @@ public class ForwardingRulesSyncProvider implements AutoCloseable, BindingAwareP
         final FlowCapableNodeDao operationalDao = new FlowCapableNodeCachedDao(operationalSnapshot,
                 new FlowCapableNodeOdlDao(dataService, LogicalDatastoreType.OPERATIONAL));
 
-        final NodeListener<FlowCapableNode> nodeListenerConfig = new SimplifiedConfigListener(cfgReactor, configSnapshot, operationalDao);
-        final NodeListener<Node> nodeListenerOperational = new SimplifiedOperationalListener(operReactor, operationalSnapshot, configDao);
+        final NodeListener<FlowCapableNode> nodeListenerConfig =
+                new SimplifiedConfigListener(reactor, configSnapshot, operationalDao);
+        final NodeListener<Node> nodeListenerOperational =
+                new SimplifiedOperationalRetryListener(reactor, operationalSnapshot, configDao, retryRegistry);
 
         try {
             SimpleTaskRetryLooper looper1 = new SimpleTaskRetryLooper(STARTUP_LOOP_TICK, STARTUP_LOOP_MAX_RETRIES);
index 17c500f003ca86bf992eed0db8ea6ea0d42de5be..4b8eb4efa8171e108642d8daed78f163943564ee 100644 (file)
@@ -1,43 +1,43 @@
-/**\r
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.openflowplugin.applications.frsync.impl;\r
-\r
-import com.google.common.annotations.VisibleForTesting;\r
-import com.google.common.util.concurrent.ListeningExecutorService;\r
-import com.google.common.util.concurrent.MoreExecutors;\r
-import java.util.concurrent.ExecutorService;\r
-import java.util.concurrent.Executors;\r
-import java.util.concurrent.ThreadFactory;\r
-\r
-/**\r
- * Static Factory for creating ExecutorServices (because there is no dependency injection but\r
- * static getInstance).\r
- */\r
-public final class FrmExecutors {\r
-    public static PceExecutorsFactory instance() {\r
-        return DEFAULT_EXECUTORS;\r
-    }\r
-\r
-    public interface PceExecutorsFactory {\r
-\r
-        ListeningExecutorService newFixedThreadPool(int nThreads, ThreadFactory factory);\r
-    }\r
-\r
-    /**\r
-     * This will be rewritten in JUnits using SynchronousExecutorService\r
-     */\r
-    @VisibleForTesting // should not be private and final\r
-    static PceExecutorsFactory DEFAULT_EXECUTORS = new PceExecutorsFactory() {\r
-\r
-        public ListeningExecutorService newFixedThreadPool(int nThreads, ThreadFactory factory) {\r
-            final ExecutorService executorService = Executors.newFixedThreadPool(nThreads, factory);\r
-            return MoreExecutors.listeningDecorator(executorService);\r
-        }\r
-    };\r
-}\r
+/**
+ * Copyright (c) 2016 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.applications.frsync.impl;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+
+/**
+ * Static Factory for creating ExecutorServices (because there is no dependency injection but
+ * static getInstance).
+ */
+public final class FrmExecutors {
+    public static PceExecutorsFactory instance() {
+        return DEFAULT_EXECUTORS;
+    }
+
+    public interface PceExecutorsFactory {
+
+        ListeningExecutorService newFixedThreadPool(int nThreads, ThreadFactory factory);
+    }
+
+    /**
+     * This will be rewritten in JUnits using SynchronousExecutorService.
+     */
+    @VisibleForTesting // should not be private and final
+    static PceExecutorsFactory DEFAULT_EXECUTORS = new PceExecutorsFactory() {
+
+        public ListeningExecutorService newFixedThreadPool(int nThreads, ThreadFactory factory) {
+            final ExecutorService executorService = Executors.newFixedThreadPool(nThreads, factory);
+            return MoreExecutors.listeningDecorator(executorService);
+        }
+    };
+}
index 58faaab38f5706135eebd49fa8406e70ffe1aca8..aef44f12b64bf85bf395986d60baaac22fa5e186 100644 (file)
@@ -47,7 +47,7 @@ public class MeterForwarder implements ForwardingRulesCommitter<Meter, AddMeterO
 
         LOG.trace("Received the Meter REMOVE request [Tbl id, node Id {} {}",
                 identifier, nodeIdent);
-        
+
         final RemoveMeterInputBuilder builder = new RemoveMeterInputBuilder(removeDataObj);
 
         builder.setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class)));
@@ -61,7 +61,7 @@ public class MeterForwarder implements ForwardingRulesCommitter<Meter, AddMeterO
                                                        final InstanceIdentifier<FlowCapableNode> nodeIdent) {
         LOG.trace("Received the Meter UPDATE request [Tbl id, node Id {} {} {}",
                 identifier, nodeIdent, update);
-        
+
         final UpdateMeterInputBuilder builder = new UpdateMeterInputBuilder();
 
         builder.setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class)));
@@ -77,7 +77,7 @@ public class MeterForwarder implements ForwardingRulesCommitter<Meter, AddMeterO
                                                  final InstanceIdentifier<FlowCapableNode> nodeIdent) {
         LOG.trace("Received the Meter ADD request [Tbl id, node Id {} {} {}",
                 identifier, nodeIdent, addDataObj);
-        
+
         final AddMeterInputBuilder builder = new AddMeterInputBuilder(addDataObj);
 
         builder.setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class)));
index c2298aa7dec155ac6b99bfbe26794d47a0de3779..8cad7e50ed5b1ac36f8b3c32d5b06a1bb043ef3f 100644 (file)
@@ -45,11 +45,10 @@ public class SimplifiedConfigListener extends AbstractFrmSyncListener<FlowCapabl
         LOG.trace("Inventory Config changes {}", modifications.size());
         super.onDataTreeChanged(modifications);
     }
-    
+
     /**
      * Compare cached operational with current config modification. If operational is not present
      * skip calling Inventory RPCs.
-     * 
      * @throws InterruptedException from syncup
      */
     protected Optional<ListenableFuture<Boolean>> processNodeModification(
@@ -63,7 +62,7 @@ public class SimplifiedConfigListener extends AbstractFrmSyncListener<FlowCapabl
         final Optional<FlowCapableNode> operationalNode = operationalDao.loadByNodeId(nodeId);
         if (!operationalNode.isPresent()) {
             LOG.info("Skip syncup, {} operational is not present", nodeId.getValue());
-            return Optional.absent();// we try to reconfigure switch is alive
+            return Optional.absent();
         }
 
         final DataObjectModification<FlowCapableNode> configModification = modification.getRootNode();
@@ -71,11 +70,11 @@ public class SimplifiedConfigListener extends AbstractFrmSyncListener<FlowCapabl
         final FlowCapableNode dataAfter = configModification.getDataAfter();
         final ListenableFuture<Boolean> endResult;
         if (dataBefore == null && dataAfter != null) {
-            endResult = onNodeAdded(nodePath, dataBefore, dataAfter, operationalNode.get());
+            endResult = onNodeAdded(nodePath, dataAfter, operationalNode.get());
         } else if (dataBefore != null && dataAfter == null) {
-            endResult = onNodeDeleted(nodePath, dataBefore, operationalNode.get());
+            endResult = onNodeDeleted(nodePath, dataBefore);
         } else {
-            endResult = onNodeUpdated(nodePath, dataBefore, dataAfter, operationalNode.get());
+            endResult = onNodeUpdated(nodePath, dataBefore, dataAfter);
         }
 
         return Optional.of(endResult);
@@ -91,13 +90,11 @@ public class SimplifiedConfigListener extends AbstractFrmSyncListener<FlowCapabl
      * optimal case (but the switch could be reprogrammed by another person/system.</li>
      * </ul>
      */
-    protected ListenableFuture<Boolean> onNodeAdded(InstanceIdentifier<FlowCapableNode> nodePath,
-            FlowCapableNode dataBefore, FlowCapableNode dataAfter, FlowCapableNode operationalNode)
-                    throws InterruptedException {
-        LOG.trace("onNodeAdded {}", nodePath);
-        
-        final ListenableFuture<Boolean> endResult =
-                reactor.syncup(nodePath, dataAfter, operationalNode);
+    private ListenableFuture<Boolean> onNodeAdded(InstanceIdentifier<FlowCapableNode> nodePath,
+                           FlowCapableNode dataAfter, FlowCapableNode operationalNode) throws InterruptedException {
+        NodeId nodeId = PathUtil.digNodeId(nodePath);
+        LOG.trace("onNodeAdded {}", nodeId);
+        final ListenableFuture<Boolean> endResult = reactor.syncup(nodePath, dataAfter, operationalNode, dsType());
         return endResult;
     }
 
@@ -108,13 +105,11 @@ public class SimplifiedConfigListener extends AbstractFrmSyncListener<FlowCapabl
      * system which is updating operational store (that components is also trying to solve
      * scale/performance issues on several layers).
      */
-    protected ListenableFuture<Boolean> onNodeUpdated(InstanceIdentifier<FlowCapableNode> nodePath,
-            FlowCapableNode dataBefore, FlowCapableNode dataAfter, FlowCapableNode operationalNodeNode)
-                    throws InterruptedException {
-        LOG.trace("onNodeUpdated {}", nodePath);
-        
-        final ListenableFuture<Boolean> endResult =
-                reactor.syncup(nodePath, dataAfter, dataBefore);
+    private ListenableFuture<Boolean> onNodeUpdated(InstanceIdentifier<FlowCapableNode> nodePath,
+                          FlowCapableNode dataBefore, FlowCapableNode dataAfter) throws InterruptedException {
+        NodeId nodeId = PathUtil.digNodeId(nodePath);
+        LOG.trace("onNodeUpdated {}", nodeId);
+        final ListenableFuture<Boolean> endResult = reactor.syncup(nodePath, dataAfter, dataBefore, dsType());
         return endResult;
     }
 
@@ -123,12 +118,11 @@ public class SimplifiedConfigListener extends AbstractFrmSyncListener<FlowCapabl
      * probably optimized using dedicated wipe-out RPC, but it has impact on switch if it is
      * programmed by two person/system
      */
-    protected ListenableFuture<Boolean> onNodeDeleted(InstanceIdentifier<FlowCapableNode> nodePath,
-            FlowCapableNode dataBefore, FlowCapableNode operationalNode) throws InterruptedException {
-        LOG.trace("onNodeDeleted {}", nodePath);
-        
-        final ListenableFuture<Boolean> endResult =
-                reactor.syncup(nodePath, null, dataBefore);
+    private ListenableFuture<Boolean> onNodeDeleted(InstanceIdentifier<FlowCapableNode> nodePath,
+                                                    FlowCapableNode dataBefore) throws InterruptedException {
+        NodeId nodeId = PathUtil.digNodeId(nodePath);
+        LOG.trace("onNodeDeleted {}", nodeId);
+        final ListenableFuture<Boolean> endResult = reactor.syncup(nodePath, null, dataBefore, dsType());
         return endResult;
     }
 
index 573ca80d68d66a9314271af5653d167561d037b9..738a652e5e0e08741a0f47d37d850223e235f573 100644 (file)
@@ -16,7 +16,6 @@ import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.openflowplugin.applications.frsync.SyncReactor;
 import org.opendaylight.openflowplugin.applications.frsync.dao.FlowCapableNodeDao;
 import org.opendaylight.openflowplugin.applications.frsync.dao.FlowCapableNodeSnapshotDao;
@@ -37,11 +36,11 @@ public class SimplifiedOperationalListener extends AbstractFrmSyncListener<Node>
     private static final Logger LOG = LoggerFactory.getLogger(SimplifiedOperationalListener.class);
 
     private final SyncReactor reactor;
-    private FlowCapableNodeSnapshotDao operationalSnapshot;
-    private FlowCapableNodeDao configDao;
+    private final FlowCapableNodeSnapshotDao operationalSnapshot;
+    private final FlowCapableNodeDao configDao;
 
-    public SimplifiedOperationalListener(SyncReactor reactor,
-            FlowCapableNodeSnapshotDao operationalSnapshot, FlowCapableNodeDao configDao) {
+    public SimplifiedOperationalListener(SyncReactor reactor, FlowCapableNodeSnapshotDao operationalSnapshot,
+                                         FlowCapableNodeDao configDao) {
         this.reactor = reactor;
         this.operationalSnapshot = operationalSnapshot;
         this.configDao = configDao;
@@ -64,14 +63,12 @@ public class SimplifiedOperationalListener extends AbstractFrmSyncListener<Node>
      * @throws InterruptedException from syncup
      */
     protected Optional<ListenableFuture<Boolean>> processNodeModification(
-            DataTreeModification<Node> modification) throws ReadFailedException, InterruptedException {
-        updateCache(modification);
+            DataTreeModification<Node> modification) throws InterruptedException {
 
-        if (isAdd(modification) || isAddLogical(modification)) {
+        updateCache(modification);
+        if (isReconciliationNeeded(modification)) {
             return reconciliation(modification);
         }
-        // TODO: else = explicit reconciliation required
-
         return skipModification(modification);
     }
 
@@ -79,32 +76,28 @@ public class SimplifiedOperationalListener extends AbstractFrmSyncListener<Node>
      * Remove if delete. Update only if FlowCapableNode Augmentation modified.
      *
      * @param modification Datastore modification
+     * @return true for cache update, false for cache remove
      */
-    protected void updateCache(DataTreeModification<Node> modification) {
-        try {
-            boolean isDelete = isDelete(modification) || isDeleteLogical(modification);
-            if (isDelete) {
-                operationalSnapshot.updateCache(nodeId(modification), Optional.<FlowCapableNode>absent());
-                return;
-            }
-
-            operationalSnapshot.updateCache(nodeId(modification), Optional.fromNullable(flowCapableNodeAfter(modification)));
-        } catch(Exception e) {
-            LOG.error("update cache failed {}", nodeId(modification), e);
+    protected boolean updateCache(DataTreeModification<Node> modification) {
+        if (isDelete(modification) || isDeleteLogical(modification)) {
+            operationalSnapshot.updateCache(nodeId(modification), Optional.<FlowCapableNode>absent());
+            return false;
         }
+        operationalSnapshot.updateCache(nodeId(modification), Optional.fromNullable(flowCapableNodeAfter(modification)));
+        return true;
     }
 
-    protected Optional<ListenableFuture<Boolean>> skipModification(DataTreeModification<Node> modification) {
+    private Optional<ListenableFuture<Boolean>> skipModification(DataTreeModification<Node> modification) {
         LOG.trace("Skipping Inventory Operational modification {}, before {}, after {}", nodeIdValue(modification),
                 modification.getRootNode().getDataBefore() == null ? "null" : "nonnull",
                 modification.getRootNode().getDataAfter() == null ? "null" : "nonnull");
-        return Optional.absent();// skip otherwise event
+        return Optional.absent();
     }
 
     /**
-     * ModificationType.DELETE
+     * ModificationType.DELETE.
      */
-    protected boolean isDelete(DataTreeModification<Node> modification) {
+    private boolean isDelete(DataTreeModification<Node> modification) {
         if (ModificationType.DELETE == modification.getRootNode().getModificationType()) {
             LOG.trace("Delete {} (physical)", nodeIdValue(modification));
             return true;
@@ -116,7 +109,7 @@ public class SimplifiedOperationalListener extends AbstractFrmSyncListener<Node>
     /**
      * All connectors disappeared from operational store (logical delete).
      */
-    protected boolean isDeleteLogical(DataTreeModification<Node> modification) {
+    private boolean isDeleteLogical(DataTreeModification<Node> modification) {
         final DataObjectModification<Node> rootNode = modification.getRootNode();
         if (!safeConnectorsEmpty(rootNode.getDataBefore()) && safeConnectorsEmpty(rootNode.getDataAfter())) {
             LOG.trace("Delete {} (logical)", nodeIdValue(modification));
@@ -126,7 +119,7 @@ public class SimplifiedOperationalListener extends AbstractFrmSyncListener<Node>
         return false;
     }
 
-    protected boolean isAdd(DataTreeModification<Node> modification) {
+    private boolean isAdd(DataTreeModification<Node> modification) {
         final DataObjectModification<Node> rootNode = modification.getRootNode();
         final Node dataAfter = rootNode.getDataAfter();
         final Node dataBefore = rootNode.getDataBefore();
@@ -141,7 +134,7 @@ public class SimplifiedOperationalListener extends AbstractFrmSyncListener<Node>
     /**
      * All connectors appeared in operational store (logical add).
      */
-    protected boolean isAddLogical(DataTreeModification<Node> modification) {
+    private boolean isAddLogical(DataTreeModification<Node> modification) {
         final DataObjectModification<Node> rootNode = modification.getRootNode();
         if (safeConnectorsEmpty(rootNode.getDataBefore()) && !safeConnectorsEmpty(rootNode.getDataAfter())) {
             LOG.trace("Add {} (logical)", nodeIdValue(modification));
@@ -151,23 +144,25 @@ public class SimplifiedOperationalListener extends AbstractFrmSyncListener<Node>
         return false;
     }
 
-    protected Optional<ListenableFuture<Boolean>> reconciliation(
-            DataTreeModification<Node> modification) throws InterruptedException {
-        final NodeId nodeId = nodeId(modification);
-
-        LOG.debug("Reconciliation: {}", nodeId.getValue());
+    protected boolean isReconciliationNeeded(DataTreeModification<Node> modification) {
+        return isAdd(modification) || isAddLogical(modification);
+    }
 
+    private Optional<ListenableFuture<Boolean>> reconciliation(DataTreeModification<Node> modification) throws InterruptedException {
+        final NodeId nodeId = nodeId(modification);
         final Optional<FlowCapableNode> nodeConfiguration = configDao.loadByNodeId(nodeId);
-        final InstanceIdentifier<FlowCapableNode> nodePath = InstanceIdentifier.create(Nodes.class)
-                .child(Node.class, new NodeKey(nodeId(modification))).augmentation(FlowCapableNode.class);
 
-        if (nodeConfiguration.isPresent())
-            return Optional.of(reactor.syncup(nodePath, nodeConfiguration.get(), flowCapableNodeAfter(modification)));
-        else
+        if (nodeConfiguration.isPresent()) {
+            LOG.debug("Reconciliation: {}", nodeId.getValue());
+            final InstanceIdentifier<FlowCapableNode> nodePath = InstanceIdentifier.create(Nodes.class)
+                    .child(Node.class, new NodeKey(nodeId(modification))).augmentation(FlowCapableNode.class);
+            return Optional.of(reactor.syncup(nodePath, nodeConfiguration.get(), flowCapableNodeAfter(modification), dsType()));
+        } else {
             return skipModification(modification);
+        }
     }
 
-    static FlowCapableNode flowCapableNodeAfter(DataTreeModification<Node> modification) {
+    private static FlowCapableNode flowCapableNodeAfter(DataTreeModification<Node> modification) {
         final Node dataAfter = modification.getRootNode().getDataAfter();
         if (dataAfter == null) {
             return null;
@@ -175,7 +170,7 @@ public class SimplifiedOperationalListener extends AbstractFrmSyncListener<Node>
         return dataAfter.getAugmentation(FlowCapableNode.class);
     }
 
-    static boolean safeConnectorsEmpty(Node node) {
+    private static boolean safeConnectorsEmpty(Node node) {
         if (node == null) {
             return true;
         }
@@ -185,7 +180,7 @@ public class SimplifiedOperationalListener extends AbstractFrmSyncListener<Node>
         return nodeConnectors == null || nodeConnectors.isEmpty();
     }
 
-    static String nodeIdValue(DataTreeModification<Node> modification) {
+    private static String nodeIdValue(DataTreeModification<Node> modification) {
         final NodeId nodeId = nodeId(modification);
 
         if (nodeId == null) {
@@ -199,7 +194,6 @@ public class SimplifiedOperationalListener extends AbstractFrmSyncListener<Node>
         final DataObjectModification<Node> rootNode = modification.getRootNode();
         final Node dataAfter = rootNode.getDataAfter();
 
-
         if (dataAfter != null) {
             return dataAfter.getId();
         }
diff --git a/applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/impl/SimplifiedOperationalRetryListener.java b/applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/impl/SimplifiedOperationalRetryListener.java
new file mode 100644 (file)
index 0000000..924e26f
--- /dev/null
@@ -0,0 +1,112 @@
+/**
+ * Copyright (c) 2016 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.applications.frsync.impl;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.openflowplugin.applications.frsync.SyncReactor;
+import org.opendaylight.openflowplugin.applications.frsync.dao.FlowCapableNodeDao;
+import org.opendaylight.openflowplugin.applications.frsync.dao.FlowCapableNodeSnapshotDao;
+import org.opendaylight.openflowplugin.applications.frsync.util.PathUtil;
+import org.opendaylight.openflowplugin.applications.frsync.util.RetryRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableStatisticsGatheringStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.snapshot.gathering.status.grouping.SnapshotGatheringStatusEnd;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Modified {@link SimplifiedOperationalListener} for usage of retry mechanism.
+ */
+public class SimplifiedOperationalRetryListener extends SimplifiedOperationalListener {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SimplifiedOperationalRetryListener.class);
+    private final RetryRegistry retryRegistry;
+
+    public SimplifiedOperationalRetryListener(SyncReactor reactor, FlowCapableNodeSnapshotDao operationalSnapshot,
+                                              FlowCapableNodeDao configDao, RetryRegistry retryRegistry) {
+        super(reactor, operationalSnapshot, configDao);
+        this.retryRegistry = retryRegistry;
+    }
+
+    /**
+     * Adding condition check for retry.
+     *
+     * @param modification operational datastore modification
+     * @return true if reconciliation is needed, false otherwise
+     */
+    protected boolean isReconciliationNeeded(DataTreeModification<Node> modification) {
+        return super.isReconciliationNeeded(modification) || isRegisteredAndConsistentForRetry(modification);
+    }
+
+    /**
+     * If node is removed unregister for retry in addition.
+     *
+     * @param modification operational datastore modification
+     * @return true for cache update, false for cache remove and retry unregister
+     */
+    protected boolean updateCache(DataTreeModification<Node> modification) {
+        boolean nodeUpdated = super.updateCache(modification);
+        if (!nodeUpdated) { // node removed if not updated
+            retryRegistry.unregisterIfRegistered(nodeId(modification));
+        }
+        return nodeUpdated;
+    }
+
+    /**
+     * Check if retry should be proceeded.
+     *
+     * @param modification operational modification
+     * @return true if device is registered for retry and actual modification is consistent, false otherwise
+     */
+    private boolean isRegisteredAndConsistentForRetry(DataTreeModification<Node> modification) {
+        final NodeId nodeId = PathUtil.digNodeId(modification.getRootPath().getRootIdentifier());
+
+        if (!retryRegistry.isRegistered(nodeId)) {
+            return false;
+        }
+
+        final FlowCapableStatisticsGatheringStatus gatheringStatus = modification.getRootNode().getDataAfter()
+                .getAugmentation(FlowCapableStatisticsGatheringStatus.class);
+
+        if (gatheringStatus == null) {
+            LOG.trace("Statistics gathering never started for: {}", nodeId.getValue());
+            return false;
+        }
+
+        final SnapshotGatheringStatusEnd gatheringStatusEnd = gatheringStatus.getSnapshotGatheringStatusEnd();
+
+        if (gatheringStatusEnd == null) {
+            LOG.trace("Statistics gathering is not over yet for: {}", nodeId.getValue());
+            return false;
+        }
+
+        if (!gatheringStatusEnd.isSucceeded()) {
+            LOG.debug("Statistics gathering was not successful for: {}", nodeId.getValue());
+            return false;
+        }
+
+        try {
+            Date timestampOfRegistration = retryRegistry.getRegistration(nodeId);
+            final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(RetryRegistry.DATE_AND_TIME_FORMAT);
+            Date timestampOfStatistics = simpleDateFormat.parse(gatheringStatusEnd.getEnd().getValue());
+            if (timestampOfStatistics.after(timestampOfRegistration)) {
+                LOG.debug("Fresh operational present for: {} -> going retry!", nodeId.getValue());
+                return true;
+            }
+        } catch (ParseException e) {
+            LOG.error("Timestamp parsing error {}", e);
+        }
+        LOG.debug("Fresh operational not present for: {}", nodeId.getValue());
+        return false;
+    }
+}
index 33db6ea9c54f467253abea1125571fba0a2f2f0d..f05db11009bb3e718b00e15c9008a893caf3e824 100644 (file)
-/**\r
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.openflowplugin.applications.frsync.impl;\r
-\r
-import com.google.common.util.concurrent.ListenableFuture;\r
-import com.google.common.util.concurrent.ListeningExecutorService;\r
-import java.util.concurrent.Callable;\r
-import java.util.concurrent.TimeUnit;\r
-import java.util.concurrent.TimeoutException;\r
-import org.opendaylight.openflowplugin.applications.frsync.SyncReactor;\r
-import org.opendaylight.openflowplugin.applications.frsync.util.PathUtil;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;\r
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-/**\r
- * Decorator for running delegate syncup in Future.\r
- */\r
-public class SyncReactorFutureDecorator implements SyncReactor {\r
-\r
-    private static final Logger LOG = LoggerFactory.getLogger(SyncReactorFutureDecorator.class);\r
-\r
-    private final SyncReactor delegate;\r
-    private final ListeningExecutorService executorService;\r
-\r
-    public static final String FRM_RPC_CLIENT_PREFIX = "FRM-RPC-client-";\r
-\r
-    public SyncReactorFutureDecorator(SyncReactor delegate, ListeningExecutorService executorService) {\r
-        this.delegate = delegate;\r
-        this.executorService = executorService;\r
-    }\r
-\r
-    public ListenableFuture<Boolean> syncup(final InstanceIdentifier<FlowCapableNode> flowcapableNodePath,\r
-            final FlowCapableNode configTree, final FlowCapableNode operationalTree) throws InterruptedException {\r
-        final NodeId nodeId = PathUtil.digNodeId(flowcapableNodePath);\r
-        LOG.trace("syncup {}", nodeId.getValue());\r
-\r
-        final ListenableFuture<Boolean> syncup = executorService.submit(new Callable<Boolean>() {\r
-            public Boolean call() throws Exception {\r
-                final String oldThreadName = updateThreadName(nodeId);\r
-\r
-                try {\r
-                    final Boolean ret = doSyncupInFuture(flowcapableNodePath, configTree, operationalTree)\r
-                            .get(10000, TimeUnit.MILLISECONDS);\r
-                    LOG.trace("ret {} {}", nodeId.getValue(), ret);\r
-                    return true;\r
-                } catch (TimeoutException e) {\r
-                    LOG.error("doSyncupInFuture timeout occured {}", nodeId.getValue(), e);\r
-                    return false;\r
-                } finally {\r
-                    updateThreadName(oldThreadName);\r
-                }\r
-            }\r
-        });\r
-        \r
-        return syncup;\r
-    }\r
-\r
-    protected ListenableFuture<Boolean> doSyncupInFuture(final InstanceIdentifier<FlowCapableNode> flowcapableNodePath,\r
-            final FlowCapableNode configTree, final FlowCapableNode operationalTree)\r
-                    throws InterruptedException {\r
-        final NodeId nodeId = PathUtil.digNodeId(flowcapableNodePath);\r
-        LOG.trace("doSyncupInFuture {}", nodeId.getValue());\r
-\r
-        return delegate.syncup(flowcapableNodePath, configTree, operationalTree);\r
-    }\r
-\r
-    static String threadName() {\r
-        final Thread currentThread = Thread.currentThread();\r
-        return currentThread.getName();\r
-    }\r
-\r
-    protected String updateThreadName(NodeId nodeId) {\r
-        final Thread currentThread = Thread.currentThread();\r
-        final String oldName = currentThread.getName();\r
-        try {\r
-            if (oldName.startsWith(SyncReactorFutureDecorator.FRM_RPC_CLIENT_PREFIX)) {\r
-                currentThread.setName(oldName + "@" + nodeId.getValue());\r
-            } else {\r
-                LOG.warn("try to update foreign thread name {} {}", nodeId, oldName);\r
-            }\r
-        } catch (Exception e) {\r
-            LOG.error("failed updating threadName {}", nodeId, e);\r
-        }\r
-        return oldName;\r
-    }\r
-\r
-    protected String updateThreadName(String name) {\r
-        final Thread currentThread = Thread.currentThread();\r
-        final String oldName = currentThread.getName();\r
-        try {\r
-            if (oldName.startsWith(SyncReactorFutureDecorator.FRM_RPC_CLIENT_PREFIX)) {\r
-                currentThread.setName(name);\r
-            } else {\r
-                LOG.warn("try to update foreign thread name {} {}", oldName, name);\r
-            }\r
-        } catch (Exception e) {\r
-            LOG.error("failed updating threadName {}", name, e);\r
-        }\r
-        return oldName;\r
-    }\r
-}\r
+/**
+ * Copyright (c) 2016 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.applications.frsync.impl;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.openflowplugin.applications.frsync.SyncReactor;
+import org.opendaylight.openflowplugin.applications.frsync.util.PathUtil;
+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.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Decorator for running delegate syncup in Future.
+ */
+public class SyncReactorFutureDecorator implements SyncReactor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SyncReactorFutureDecorator.class);
+    public static final String FRM_RPC_CLIENT_PREFIX = "FRM-RPC-client-";
+    private final SyncReactor delegate;
+    private final ListeningExecutorService executorService;
+
+    public SyncReactorFutureDecorator(SyncReactor delegate, ListeningExecutorService executorService) {
+        this.delegate = delegate;
+        this.executorService = executorService;
+    }
+
+    public ListenableFuture<Boolean> syncup(final InstanceIdentifier<FlowCapableNode> flowcapableNodePath,
+                                            final FlowCapableNode configTree, final FlowCapableNode operationalTree,
+                                            final LogicalDatastoreType dsType) throws InterruptedException {
+        final NodeId nodeId = PathUtil.digNodeId(flowcapableNodePath);
+        LOG.trace("syncup future {}", nodeId.getValue());
+
+        final ListenableFuture<Boolean> syncup = executorService.submit(new Callable<Boolean>() {
+            public Boolean call() throws Exception {
+                final String oldThreadName = updateThreadName(nodeId);
+
+                try {
+                    final Boolean ret = doSyncupInFuture(flowcapableNodePath, configTree, operationalTree, dsType)
+                            .get(10000, TimeUnit.MILLISECONDS);
+                    LOG.trace("ret {} {}", nodeId.getValue(), ret);
+                    return true;
+                } catch (TimeoutException e) {
+                    LOG.error("doSyncupInFuture timeout occured {}", nodeId.getValue(), e);
+                    return false;
+                } finally {
+                    updateThreadName(oldThreadName);
+                }
+            }
+        });
+
+        return syncup;
+    }
+
+    protected ListenableFuture<Boolean> doSyncupInFuture(final InstanceIdentifier<FlowCapableNode> flowcapableNodePath,
+                                                         final FlowCapableNode configTree, final FlowCapableNode operationalTree,
+                                                         final LogicalDatastoreType dsType) throws InterruptedException {
+        final NodeId nodeId = PathUtil.digNodeId(flowcapableNodePath);
+        LOG.trace("doSyncupInFuture future {}", nodeId.getValue());
+
+        return delegate.syncup(flowcapableNodePath, configTree, operationalTree, dsType);
+    }
+
+    private String updateThreadName(NodeId nodeId) {
+        final Thread currentThread = Thread.currentThread();
+        final String oldName = currentThread.getName();
+        try {
+            if (oldName.startsWith(SyncReactorFutureDecorator.FRM_RPC_CLIENT_PREFIX)) {
+                currentThread.setName(oldName + "@" + nodeId.getValue());
+            } else {
+                LOG.warn("try to update foreign thread name {} {}", nodeId, oldName);
+            }
+        } catch (Exception e) {
+            LOG.error("failed updating threadName {}", nodeId, e);
+        }
+        return oldName;
+    }
+
+    private String updateThreadName(String name) {
+        final Thread currentThread = Thread.currentThread();
+        final String oldName = currentThread.getName();
+        try {
+            if (oldName.startsWith(SyncReactorFutureDecorator.FRM_RPC_CLIENT_PREFIX)) {
+                currentThread.setName(name);
+            } else {
+                LOG.warn("try to update foreign thread name {} {}", oldName, name);
+            }
+        } catch (Exception e) {
+            LOG.error("failed updating threadName {}", name, e);
+        }
+        return oldName;
+    }
+}
diff --git a/applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/impl/SyncReactorFutureWithCompressionDecorator.java b/applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/impl/SyncReactorFutureWithCompressionDecorator.java
deleted file mode 100644 (file)
index ce7c579..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/**\r
- * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.openflowplugin.applications.frsync.impl;\r
-\r
-import com.google.common.util.concurrent.Futures;\r
-import com.google.common.util.concurrent.ListenableFuture;\r
-import com.google.common.util.concurrent.ListeningExecutorService;\r
-import java.util.HashMap;\r
-import java.util.Map;\r
-import java.util.concurrent.Semaphore;\r
-import javax.annotation.concurrent.GuardedBy;\r
-import org.apache.commons.lang3.tuple.Pair;\r
-import org.opendaylight.openflowplugin.applications.frsync.SyncReactor;\r
-import org.opendaylight.openflowplugin.applications.frsync.util.PathUtil;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;\r
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-/**\r
- * Enriches {@link SyncReactorFutureDecorator} with state compression.\r
- */\r
-public class SyncReactorFutureWithCompressionDecorator extends SyncReactorFutureDecorator {\r
-\r
-    private static final Logger LOG = LoggerFactory.getLogger(SyncReactorFutureWithCompressionDecorator.class);\r
-\r
-    @GuardedBy("compressionGuard")\r
-    final Map<InstanceIdentifier<FlowCapableNode>, Pair<FlowCapableNode, FlowCapableNode>> compressionQueue =\r
-            new HashMap<>();\r
-    final Semaphore compressionGuard = new Semaphore(1, false);\r
-\r
-    public SyncReactorFutureWithCompressionDecorator(SyncReactor delegate, ListeningExecutorService executorService) {\r
-        super(delegate, executorService);\r
-    }\r
-\r
-    public ListenableFuture<Boolean> syncup(final InstanceIdentifier<FlowCapableNode> flowcapableNodePath,\r
-            final FlowCapableNode configTree, final FlowCapableNode operationalTree) throws InterruptedException {\r
-        final NodeId nodeId = PathUtil.digNodeId(flowcapableNodePath);\r
-        LOG.trace("syncup {}", nodeId.getValue());\r
-\r
-        try {\r
-            compressionGuard.acquire();\r
-\r
-            final boolean newFutureNecessary = updateCompressionState(flowcapableNodePath, configTree, operationalTree);\r
-            if (newFutureNecessary) {\r
-                super.syncup(flowcapableNodePath, configTree, operationalTree);\r
-            }\r
-            return Futures.immediateFuture(true);\r
-        } finally {\r
-            compressionGuard.release();\r
-        }\r
-    }\r
-\r
-    protected ListenableFuture<Boolean> doSyncupInFuture(final InstanceIdentifier<FlowCapableNode> flowcapableNodePath,\r
-            final FlowCapableNode configTree, final FlowCapableNode operationalTree)\r
-                    throws InterruptedException {\r
-        final NodeId nodeId = PathUtil.digNodeId(flowcapableNodePath);\r
-        LOG.trace("doSyncupInFuture {}", nodeId.getValue());\r
-\r
-        final Pair<FlowCapableNode, FlowCapableNode> lastCompressionState =\r
-                removeLastCompressionState(flowcapableNodePath);\r
-        if (lastCompressionState == null) {\r
-            return Futures.immediateFuture(true);\r
-        } else {\r
-            return super.doSyncupInFuture(flowcapableNodePath,\r
-                    lastCompressionState.getLeft(), lastCompressionState.getRight());\r
-        }\r
-    }\r
-\r
-    protected boolean updateCompressionState(final InstanceIdentifier<FlowCapableNode> flowcapableNodePath,\r
-            final FlowCapableNode configTree, final FlowCapableNode operationalTree) {\r
-        final Pair<FlowCapableNode, FlowCapableNode> previous = compressionQueue.get(flowcapableNodePath);\r
-        if (previous != null) {\r
-            final FlowCapableNode previousOperational = previous.getRight();\r
-            compressionQueue.put(flowcapableNodePath, Pair.of(configTree, previousOperational));\r
-            return false;\r
-        } else {\r
-            compressionQueue.put(flowcapableNodePath, Pair.of(configTree, operationalTree));\r
-            return true;\r
-        }\r
-    }\r
-\r
-    protected Pair<FlowCapableNode/* config */, FlowCapableNode/* operational */> removeLastCompressionState(\r
-            final InstanceIdentifier<FlowCapableNode> flowcapableNodePath) {\r
-        try {\r
-            try {\r
-                compressionGuard.acquire();\r
-            } catch (InterruptedException e) {\r
-                return null;\r
-            }\r
-\r
-            return compressionQueue.remove(flowcapableNodePath);\r
-        } finally {\r
-            compressionGuard.release();\r
-        }\r
-    }\r
-}\r
diff --git a/applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/impl/SyncReactorFutureZipDecorator.java b/applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/impl/SyncReactorFutureZipDecorator.java
new file mode 100644 (file)
index 0000000..a3edde0
--- /dev/null
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2016 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.applications.frsync.impl;
+
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Semaphore;
+import javax.annotation.concurrent.GuardedBy;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.openflowplugin.applications.frsync.SyncReactor;
+import org.opendaylight.openflowplugin.applications.frsync.util.PathUtil;
+import org.opendaylight.openflowplugin.applications.frsync.util.ZipQueueEntry;
+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.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Enriches {@link SyncReactorFutureDecorator} with state compression.
+ */
+public class SyncReactorFutureZipDecorator extends SyncReactorFutureDecorator {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SyncReactorFutureZipDecorator.class);
+
+    @GuardedBy("compressionGuard")
+    private final Map<InstanceIdentifier<FlowCapableNode>, ZipQueueEntry> compressionQueue = new HashMap<>();
+    private final Semaphore compressionGuard = new Semaphore(1, false);
+
+    public SyncReactorFutureZipDecorator(SyncReactor delegate, ListeningExecutorService executorService) {
+        super(delegate, executorService);
+    }
+
+    public ListenableFuture<Boolean> syncup(final InstanceIdentifier<FlowCapableNode> flowcapableNodePath,
+                                            final FlowCapableNode configTree, final FlowCapableNode operationalTree,
+                                            final LogicalDatastoreType dsType) throws InterruptedException {
+        final NodeId nodeId = PathUtil.digNodeId(flowcapableNodePath);
+        LOG.trace("syncup zip {}", nodeId.getValue());
+
+        try {
+            compressionGuard.acquire();
+
+            final boolean newFutureNecessary = updateCompressionState(flowcapableNodePath, configTree, operationalTree, dsType);
+            if (newFutureNecessary) {
+                super.syncup(flowcapableNodePath, configTree, operationalTree, dsType);
+            }
+            return Futures.immediateFuture(true);
+        } finally {
+            compressionGuard.release();
+        }
+    }
+
+    protected ListenableFuture<Boolean> doSyncupInFuture(final InstanceIdentifier<FlowCapableNode> flowcapableNodePath,
+                                                         final FlowCapableNode configTree, final FlowCapableNode operationalTree,
+                                                         final LogicalDatastoreType dsType) throws InterruptedException {
+        final NodeId nodeId = PathUtil.digNodeId(flowcapableNodePath);
+        LOG.trace("doSyncupInFuture zip {}", nodeId.getValue());
+
+        final ZipQueueEntry lastCompressionState = removeLastCompressionState(flowcapableNodePath);
+        if (lastCompressionState == null) {
+            return Futures.immediateFuture(true);
+        } else {
+            return super.doSyncupInFuture(flowcapableNodePath,
+                    lastCompressionState.getLeft(), lastCompressionState.getRight(), dsType);
+        }
+    }
+
+    /**
+     * If there is config delta in compression queue for the device and new configuration is coming,
+     * update its zip queue entry. Create/replace zip queue entry for the device with operational delta otherwise.
+     */
+    private boolean updateCompressionState(final InstanceIdentifier<FlowCapableNode> flowcapableNodePath,
+                                           final FlowCapableNode configTree, final FlowCapableNode operationalTree,
+                                           final LogicalDatastoreType dsType) {
+        final ZipQueueEntry previousEntry = compressionQueue.get(flowcapableNodePath);
+
+        if (previousEntry != null && dsType == LogicalDatastoreType.CONFIGURATION
+                && previousEntry.getDsType() == LogicalDatastoreType.CONFIGURATION) {
+            putOptimizedConfigDelta(flowcapableNodePath, configTree, previousEntry);
+        } else {
+            putLatestOperationalDelta(flowcapableNodePath, configTree, operationalTree, dsType);
+        }
+        return previousEntry == null;
+    }
+
+    private void putOptimizedConfigDelta(InstanceIdentifier<FlowCapableNode> flowcapableNodePath, FlowCapableNode configTree,
+                                         ZipQueueEntry previous) {
+        compressionQueue.put(flowcapableNodePath, new ZipQueueEntry(configTree, previous.getRight(), previous.getDsType()));
+    }
+
+    private void putLatestOperationalDelta(InstanceIdentifier<FlowCapableNode> flowcapableNodePath, FlowCapableNode configTree,
+                                           FlowCapableNode operationalTree, LogicalDatastoreType dsType) {
+        compressionQueue.put(flowcapableNodePath, new ZipQueueEntry(configTree, operationalTree, dsType));
+    }
+
+    private ZipQueueEntry removeLastCompressionState(
+            final InstanceIdentifier<FlowCapableNode> flowcapableNodePath) {
+        try {
+            try {
+                compressionGuard.acquire();
+            } catch (InterruptedException e) {
+                return null;
+            }
+
+            return compressionQueue.remove(flowcapableNodePath);
+        } finally {
+            compressionGuard.release();
+        }
+    }
+
+}
\ No newline at end of file
index 92627831e7b8f007a086a5434a82dec0522f1f31..9def21853c861d8d4634ec978cf3499779d7f3e6 100644 (file)
-/**\r
- * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.openflowplugin.applications.frsync.impl;\r
-\r
-import com.google.common.base.Preconditions;\r
-import com.google.common.util.concurrent.FutureCallback;\r
-import com.google.common.util.concurrent.Futures;\r
-import com.google.common.util.concurrent.ListenableFuture;\r
-import java.util.concurrent.Semaphore;\r
-import java.util.concurrent.TimeUnit;\r
-import javax.annotation.Nullable;\r
-import org.opendaylight.openflowplugin.applications.frsync.SemaphoreKeeper;\r
-import org.opendaylight.openflowplugin.applications.frsync.SyncReactor;\r
-import org.opendaylight.openflowplugin.applications.frsync.util.PathUtil;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;\r
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-/**\r
- * Decorator for NodeId level syncup locking.\r
- */\r
-public class SyncReactorGuardDecorator implements SyncReactor {\r
-\r
-    private static final Logger LOG = LoggerFactory.getLogger(SyncReactorGuardDecorator.class);\r
-\r
-    private final SyncReactor delegate;\r
-    private final SemaphoreKeeper<InstanceIdentifier<FlowCapableNode>> semaphoreKeeper;\r
-\r
-    public SyncReactorGuardDecorator(SyncReactor delegate,\r
-            SemaphoreKeeper<InstanceIdentifier<FlowCapableNode>> semaphoreKeeper) {\r
-        this.delegate = delegate;\r
-        this.semaphoreKeeper = semaphoreKeeper;\r
-    }\r
-\r
-    public ListenableFuture<Boolean> syncup(final InstanceIdentifier<FlowCapableNode> flowcapableNodePath,\r
-            final FlowCapableNode configTree, final FlowCapableNode operationalTree) throws InterruptedException {\r
-        final NodeId nodeId = PathUtil.digNodeId(flowcapableNodePath);\r
-        LOG.trace("syncup {}", nodeId.getValue());\r
-\r
-        final long stampBeforeGuard = System.nanoTime();\r
-        final Semaphore guard = summonGuardAndAcquire(flowcapableNodePath);//TODO handle InteruptedException\r
-\r
-        try {\r
-            final long stampAfterGuard = System.nanoTime();\r
-            if (LOG.isDebugEnabled()) {\r
-                LOG.debug("syncup start {} waiting:{} guard:{} thread:{}", nodeId.getValue(),\r
-                        formatNanos(stampAfterGuard - stampBeforeGuard),\r
-                        guard, threadName());\r
-            }\r
-            \r
-            final ListenableFuture<Boolean> endResult =\r
-                    delegate.syncup(flowcapableNodePath, configTree, operationalTree);//TODO handle InteruptedException\r
-            \r
-            Futures.addCallback(endResult, new FutureCallback<Boolean>() {\r
-                @Override\r
-                public void onSuccess(@Nullable final Boolean result) {\r
-                    if (LOG.isDebugEnabled()) {\r
-                        final long stampFinished = System.nanoTime();\r
-                        LOG.debug("syncup finished {} took:{} rpc:{} wait:{} guard:{}, thread:{}", nodeId.getValue(),\r
-                                formatNanos(stampFinished - stampBeforeGuard),\r
-                                formatNanos(stampFinished - stampAfterGuard),\r
-                                formatNanos(stampAfterGuard - stampBeforeGuard),\r
-                                guard, threadName());\r
-                    }\r
-\r
-                    releaseGuardForNodeId(nodeId, guard);\r
-                }\r
-\r
-                @Override\r
-                public void onFailure(final Throwable t) {\r
-                    if (LOG.isDebugEnabled()) {\r
-                        final long stampFinished = System.nanoTime();\r
-                        LOG.warn("syncup failed {} took:{} rpc:{} wait:{} guard:{} thread:{}", nodeId.getValue(),\r
-                                formatNanos(stampFinished - stampBeforeGuard),\r
-                                formatNanos(stampFinished - stampAfterGuard),\r
-                                formatNanos(stampAfterGuard - stampBeforeGuard),\r
-                                guard, threadName());\r
-                    }\r
-\r
-                    releaseGuardForNodeId(nodeId, guard);\r
-                }\r
-            });\r
-            return endResult;\r
-        } catch(InterruptedException e) {\r
-            releaseGuardForNodeId(nodeId, guard);\r
-            throw e;\r
-        }\r
-    }\r
-\r
-    protected String formatNanos(long nanos) {\r
-        return "'" + TimeUnit.NANOSECONDS.toMillis(nanos) + " ms'";\r
-    }\r
-\r
-    /**\r
-     * get guard\r
-     *\r
-     * @param flowcapableNodePath II of node for which guard should be acquired\r
-     * @return semaphore guard\r
-     */\r
-    protected Semaphore summonGuardAndAcquire(final InstanceIdentifier<FlowCapableNode> flowcapableNodePath)\r
-            throws InterruptedException {\r
-        final Semaphore guard = Preconditions.checkNotNull(semaphoreKeeper.summonGuard(flowcapableNodePath),\r
-                "no guard for " + flowcapableNodePath);\r
-\r
-        if (LOG.isDebugEnabled()) {\r
-            final NodeId nodeId = PathUtil.digNodeId(flowcapableNodePath);\r
-            try {\r
-                LOG.debug("syncup summon {} guard:{} thread:{}", nodeId.getValue(), guard, threadName());\r
-            } catch (Exception e) {\r
-                LOG.error("error logging guard after summon before aquiring {}", nodeId);\r
-            }\r
-        }\r
-\r
-        guard.acquire();\r
-        return guard;\r
-    }\r
-\r
-    /**\r
-     * unlock per node\r
-     *\r
-     * @param nodeId NodeId of node which should be unlocked\r
-     * @param guard semaphore guard\r
-     */\r
-    protected void releaseGuardForNodeId(final NodeId nodeId, final Semaphore guard) {\r
-        if (guard == null) {\r
-            return;\r
-        }\r
-        guard.release();\r
-    }\r
-\r
-    static String threadName() {\r
-        final Thread currentThread = Thread.currentThread();\r
-        return currentThread.getName();\r
-    }\r
-\r
-}\r
+/**
+ * Copyright (c) 2016 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.applications.frsync.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 java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import javax.annotation.Nullable;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.openflowplugin.applications.frsync.SemaphoreKeeper;
+import org.opendaylight.openflowplugin.applications.frsync.SyncReactor;
+import org.opendaylight.openflowplugin.applications.frsync.util.PathUtil;
+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.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Decorator for NodeId level syncup locking.
+ */
+public class SyncReactorGuardDecorator implements SyncReactor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SyncReactorGuardDecorator.class);
+
+    private final SyncReactor delegate;
+    private final SemaphoreKeeper<InstanceIdentifier<FlowCapableNode>> semaphoreKeeper;
+
+    public SyncReactorGuardDecorator(SyncReactor delegate,
+            SemaphoreKeeper<InstanceIdentifier<FlowCapableNode>> semaphoreKeeper) {
+        this.delegate = delegate;
+        this.semaphoreKeeper = semaphoreKeeper;
+    }
+
+    public ListenableFuture<Boolean> syncup(final InstanceIdentifier<FlowCapableNode> flowcapableNodePath,
+                                            final FlowCapableNode configTree, final FlowCapableNode operationalTree,
+                                            final LogicalDatastoreType dsType) throws InterruptedException {
+        final NodeId nodeId = PathUtil.digNodeId(flowcapableNodePath);
+        LOG.trace("syncup guard {}", nodeId.getValue());
+
+        final long stampBeforeGuard = System.nanoTime();
+        final Semaphore guard = summonGuardAndAcquire(flowcapableNodePath);//TODO handle InteruptedException
+
+        try {
+            final long stampAfterGuard = System.nanoTime();
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("syncup start {} waiting:{} guard:{} thread:{}", nodeId.getValue(),
+                        formatNanos(stampAfterGuard - stampBeforeGuard),
+                        guard, threadName());
+            }
+
+            final ListenableFuture<Boolean> endResult =
+                    delegate.syncup(flowcapableNodePath, configTree, operationalTree, dsType);//TODO handle InteruptedException
+
+            Futures.addCallback(endResult, new FutureCallback<Boolean>() {
+                @Override
+                public void onSuccess(@Nullable final Boolean result) {
+                    if (LOG.isDebugEnabled()) {
+                        final long stampFinished = System.nanoTime();
+                        LOG.debug("syncup finished {} took:{} rpc:{} wait:{} guard:{} permits thread:{}", nodeId.getValue(),
+                                formatNanos(stampFinished - stampBeforeGuard),
+                                formatNanos(stampFinished - stampAfterGuard),
+                                formatNanos(stampAfterGuard - stampBeforeGuard),
+                                guard.availablePermits(), threadName());
+                    }
+
+                    releaseGuardForNodeId(guard);
+                }
+
+                @Override
+                public void onFailure(final Throwable t) {
+                    if (LOG.isDebugEnabled()) {
+                        final long stampFinished = System.nanoTime();
+                        LOG.warn("syncup failed {} took:{} rpc:{} wait:{} guard:{} permits thread:{}", nodeId.getValue(),
+                                formatNanos(stampFinished - stampBeforeGuard),
+                                formatNanos(stampFinished - stampAfterGuard),
+                                formatNanos(stampAfterGuard - stampBeforeGuard),
+                                guard.availablePermits(), threadName());
+                    }
+
+                    releaseGuardForNodeId(guard);
+                }
+            });
+            return endResult;
+        } catch(InterruptedException e) {
+            releaseGuardForNodeId(guard);
+            throw e;
+        }
+    }
+
+    private String formatNanos(long nanos) {
+        return "'" + TimeUnit.NANOSECONDS.toMillis(nanos) + " ms'";
+    }
+
+    /**
+     * Get guard and lock for node.
+     * @param flowcapableNodePath II of node for which guard should be acquired
+     * @return semaphore guard
+     */
+    private Semaphore summonGuardAndAcquire(final InstanceIdentifier<FlowCapableNode> flowcapableNodePath)
+            throws InterruptedException {
+        final Semaphore guard = Preconditions.checkNotNull(semaphoreKeeper.summonGuard(flowcapableNodePath),
+                "no guard for " + flowcapableNodePath);
+
+        if (LOG.isDebugEnabled()) {
+            final NodeId nodeId = PathUtil.digNodeId(flowcapableNodePath);
+            try {
+                LOG.debug("syncup summon {} guard:{} thread:{}", nodeId.getValue(), guard, threadName());
+            } catch (Exception e) {
+                LOG.error("error logging guard after summon before aquiring {}", nodeId);
+            }
+        }
+
+        guard.acquire();
+        return guard;
+    }
+
+    /**
+     * Unlock and release guard.
+     * @param guard semaphore guard which should be unlocked
+     */
+    private void releaseGuardForNodeId(final Semaphore guard) {
+        if (guard == null) {
+            return;
+        }
+        guard.release();
+    }
+
+    private static String threadName() {
+        final Thread currentThread = Thread.currentThread();
+        return currentThread.getName();
+    }
+
+}
index de4819e11d79787886ffb527125f3890ea35ad60..504d583d032f8a02dc029067e20e4cc593265a9f 100644 (file)
@@ -18,6 +18,7 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.openflowplugin.applications.frsync.SyncPlanPushStrategy;
 import org.opendaylight.openflowplugin.applications.frsync.SyncReactor;
 import org.opendaylight.openflowplugin.applications.frsync.impl.strategy.SynchronizationDiffInput;
@@ -56,10 +57,13 @@ public class SyncReactorImpl implements SyncReactor {
 
     @Override
     public ListenableFuture<Boolean> syncup(final InstanceIdentifier<FlowCapableNode> nodeIdent,
-                                            final FlowCapableNode configTree, final FlowCapableNode operationalTree) {
+                                            final FlowCapableNode configTree, final FlowCapableNode operationalTree,
+                                            final LogicalDatastoreType dsType) {
 
-        LOG.trace("syncup {} cfg:{} oper:{}", nodeIdent, configTree == null ? "is null" : "non null", operationalTree == null ? "is null" : "non null");
+        final NodeId nodeId = PathUtil.digNodeId(nodeIdent);
+        LOG.trace("syncup impl {} cfg:{} oper:{}", nodeId.getValue(), configTree == null ? "is null" : "non null", operationalTree == null ? "is null" : "non null");
         final SyncCrudCounters counters = new SyncCrudCounters();
+
         /**
          * instructions:
          *  - extract diff changes and prepare change steps in safe order
@@ -73,8 +77,6 @@ public class SyncReactorImpl implements SyncReactor {
          *  - flows - meters - groups (reordered)
          **/
 
-        final NodeId nodeId = PathUtil.digNodeId(nodeIdent);
-
         final List<ItemSyncBox<Group>> groupsToAddOrUpdate = extractGroupsToAddOrUpdate(nodeId, configTree, operationalTree);
         final ItemSyncBox<Meter> metersToAddOrUpdate = extractMetersToAddOrUpdate(nodeId, configTree, operationalTree);
         final Map<TableKey, ItemSyncBox<Flow>> flowsToAddOrUpdate = extractFlowsToAddOrUpdate(nodeId, configTree, operationalTree);
@@ -121,15 +123,16 @@ public class SyncReactorImpl implements SyncReactor {
                     );
                 }
 
+                LOG.trace("syncup errors: {}", input.getErrors());
                 return input.isSuccessful();
             }
         });
     }
 
     @VisibleForTesting
-    static List<ItemSyncBox<Group>> extractGroupsToAddOrUpdate(final NodeId nodeId,
-                                                               final FlowCapableNode flowCapableNodeConfigured,
-                                                               final FlowCapableNode flowCapableNodeOperational) {
+    private static List<ItemSyncBox<Group>> extractGroupsToAddOrUpdate(final NodeId nodeId,
+                                                                       final FlowCapableNode flowCapableNodeConfigured,
+                                                                       final FlowCapableNode flowCapableNodeOperational) {
         final List<Group> groupsConfigured = ReconcileUtil.safeGroups(flowCapableNodeConfigured);
         final List<Group> groupsOperational = ReconcileUtil.safeGroups(flowCapableNodeOperational);
         final Map<Long, Group> groupOperationalMap = FlowCapableNodeLookups.wrapGroupsToMap(groupsOperational);
@@ -141,9 +144,9 @@ public class SyncReactorImpl implements SyncReactor {
     }
 
     @VisibleForTesting
-    static ItemSyncBox<Meter> extractMetersToAddOrUpdate(final NodeId nodeId,
-                                                         final FlowCapableNode flowCapableNodeConfigured,
-                                                         final FlowCapableNode flowCapableNodeOperational) {
+    private static ItemSyncBox<Meter> extractMetersToAddOrUpdate(final NodeId nodeId,
+                                                                 final FlowCapableNode flowCapableNodeConfigured,
+                                                                 final FlowCapableNode flowCapableNodeOperational) {
         final List<Meter> metersConfigured = ReconcileUtil.safeMeters(flowCapableNodeConfigured);
         final List<Meter> metersOperational = ReconcileUtil.safeMeters(flowCapableNodeOperational);
         final Map<MeterId, Meter> meterOperationalMap = FlowCapableNodeLookups.wrapMetersToMap(metersOperational);
@@ -152,9 +155,9 @@ public class SyncReactorImpl implements SyncReactor {
     }
 
     @VisibleForTesting
-    static Map<TableKey, ItemSyncBox<Flow>> extractFlowsToAddOrUpdate(final NodeId nodeId,
-                                                                      final FlowCapableNode flowCapableNodeConfigured,
-                                                                      final FlowCapableNode flowCapableNodeOperational) {
+    private static Map<TableKey, ItemSyncBox<Flow>> extractFlowsToAddOrUpdate(final NodeId nodeId,
+                                                                              final FlowCapableNode flowCapableNodeConfigured,
+                                                                              final FlowCapableNode flowCapableNodeOperational) {
         final List<Table> tablesConfigured = ReconcileUtil.safeTables(flowCapableNodeConfigured);
         if (tablesConfigured.isEmpty()) {
             return Collections.emptyMap();
@@ -167,9 +170,9 @@ public class SyncReactorImpl implements SyncReactor {
     }
 
     @VisibleForTesting
-    static Map<TableKey, ItemSyncBox<Flow>> extractFlowsToRemove(final NodeId nodeId,
-                                                                 final FlowCapableNode flowCapableNodeConfigured,
-                                                                 final FlowCapableNode flowCapableNodeOperational) {
+    private static Map<TableKey, ItemSyncBox<Flow>> extractFlowsToRemove(final NodeId nodeId,
+                                                                         final FlowCapableNode flowCapableNodeConfigured,
+                                                                         final FlowCapableNode flowCapableNodeOperational) {
         final List<Table> tablesOperational = ReconcileUtil.safeTables(flowCapableNodeOperational);
         if (tablesOperational.isEmpty()) {
             return Collections.emptyMap();
@@ -182,9 +185,9 @@ public class SyncReactorImpl implements SyncReactor {
     }
 
     @VisibleForTesting
-    static ItemSyncBox<Meter> extractMetersToRemove(final NodeId nodeId,
-                                                    final FlowCapableNode flowCapableNodeConfigured,
-                                                    final FlowCapableNode flowCapableNodeOperational) {
+    private static ItemSyncBox<Meter> extractMetersToRemove(final NodeId nodeId,
+                                                            final FlowCapableNode flowCapableNodeConfigured,
+                                                            final FlowCapableNode flowCapableNodeOperational) {
         final List<Meter> metersConfigured = ReconcileUtil.safeMeters(flowCapableNodeConfigured);
         final List<Meter> metersOperational = ReconcileUtil.safeMeters(flowCapableNodeOperational);
         final Map<MeterId, Meter> meterConfiguredMap = FlowCapableNodeLookups.wrapMetersToMap(metersConfigured);
@@ -193,9 +196,9 @@ public class SyncReactorImpl implements SyncReactor {
     }
 
     @VisibleForTesting
-    static List<ItemSyncBox<Group>> extractGroupsToRemove(final NodeId nodeId,
-                                                          final FlowCapableNode flowCapableNodeConfigured,
-                                                          final FlowCapableNode flowCapableNodeOperational) {
+    private static List<ItemSyncBox<Group>> extractGroupsToRemove(final NodeId nodeId,
+                                                                  final FlowCapableNode flowCapableNodeConfigured,
+                                                                  final FlowCapableNode flowCapableNodeOperational) {
         final List<Group> groupsConfigured = ReconcileUtil.safeGroups(flowCapableNodeConfigured);
         final List<Group> groupsOperational = ReconcileUtil.safeGroups(flowCapableNodeOperational);
         final Map<Long, Group> groupConfiguredMap = FlowCapableNodeLookups.wrapGroupsToMap(groupsConfigured);
diff --git a/applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/impl/SyncReactorRetryDecorator.java b/applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/impl/SyncReactorRetryDecorator.java
new file mode 100644 (file)
index 0000000..d504855
--- /dev/null
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2016 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.applications.frsync.impl;
+
+import com.google.common.base.Function;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.openflowplugin.applications.frsync.SyncReactor;
+import org.opendaylight.openflowplugin.applications.frsync.util.PathUtil;
+import org.opendaylight.openflowplugin.applications.frsync.util.RetryRegistry;
+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.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Adding retry mechanism in case of unsuccessful syncup.
+ */
+public class SyncReactorRetryDecorator implements SyncReactor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SyncReactorRetryDecorator.class);
+
+    private final SyncReactor delegate;
+    private final RetryRegistry retryRegistry;
+
+    public SyncReactorRetryDecorator(final SyncReactor delegate, RetryRegistry retryRegistry) {
+        this.delegate = delegate;
+        this.retryRegistry = retryRegistry;
+    }
+
+    public ListenableFuture<Boolean> syncup(final InstanceIdentifier<FlowCapableNode> flowcapableNodePath,
+                                            final FlowCapableNode configTree, final FlowCapableNode operationalTree,
+                                            final LogicalDatastoreType dsType) throws InterruptedException {
+
+        final NodeId nodeId = PathUtil.digNodeId(flowcapableNodePath);
+        LOG.trace("syncup retry {}", nodeId.getValue());
+
+        if (dsType == LogicalDatastoreType.CONFIGURATION && retryRegistry.isRegistered(nodeId)) {
+            LOG.trace("Config change ignored because device is in retry [{}]", nodeId);
+            return Futures.immediateFuture(Boolean.FALSE);
+        }
+
+        ListenableFuture<Boolean> syncupResult = delegate.syncup(flowcapableNodePath, configTree, operationalTree, dsType);
+
+        return Futures.transform(syncupResult, new Function<Boolean, Boolean>() {
+            @Override
+            public Boolean apply(Boolean result) {
+                LOG.trace("syncup ret in retry {}", result);
+                if (result) {
+                    retryRegistry.unregisterIfRegistered(nodeId);
+                    return true;
+                } else {
+                    retryRegistry.register(nodeId);
+                    // TODO  elicit statistics gathering if not running actually
+                    // triggerStatisticsGathering(nodeId);
+                    return false;
+                }
+            }
+        });
+    }
+}
index 4a56acb38b124625ef4dfd9828b864f6d5e7b238..3f4b53efdb850e00fbe6792a3000fc50d54eb415 100644 (file)
@@ -152,7 +152,7 @@ public class SyncPlanPushStrategyIncrementalImpl implements SyncPlanPushStrategy
     }
 
 
-    protected ListenableFuture<RpcResult<Void>> addMissingFlows(final NodeId nodeId,
+    ListenableFuture<RpcResult<Void>> addMissingFlows(final NodeId nodeId,
                                                                 final InstanceIdentifier<FlowCapableNode> nodeIdent,
                                                                 final Map<TableKey, ItemSyncBox<Flow>> flowsInTablesSyncBox,
                                                                 final SyncCrudCounters counters) {
@@ -216,7 +216,7 @@ public class SyncPlanPushStrategyIncrementalImpl implements SyncPlanPushStrategy
                 */
     }
 
-    protected ListenableFuture<RpcResult<Void>> removeRedundantFlows(final NodeId nodeId,
+    ListenableFuture<RpcResult<Void>> removeRedundantFlows(final NodeId nodeId,
                                                                      final InstanceIdentifier<FlowCapableNode> nodeIdent,
                                                                      final Map<TableKey, ItemSyncBox<Flow>> removalPlan,
                                                                      final SyncCrudCounters counters) {
@@ -249,7 +249,7 @@ public class SyncPlanPushStrategyIncrementalImpl implements SyncPlanPushStrategy
 
     }
 
-    protected ListenableFuture<RpcResult<Void>> removeRedundantMeters(final NodeId nodeId,
+    ListenableFuture<RpcResult<Void>> removeRedundantMeters(final NodeId nodeId,
                                                                       final InstanceIdentifier<FlowCapableNode> nodeIdent,
                                                                       final ItemSyncBox<Meter> meterRemovalPlan,
                                                                       final SyncCrudCounters counters) {
@@ -412,7 +412,7 @@ public class SyncPlanPushStrategyIncrementalImpl implements SyncPlanPushStrategy
                         PathUtil.digNodePath(nodeIdent), transactionService));
     }
 
-    protected ListenableFuture<RpcResult<Void>> addMissingMeters(final NodeId nodeId,
+    ListenableFuture<RpcResult<Void>> addMissingMeters(final NodeId nodeId,
                                                                  final InstanceIdentifier<FlowCapableNode> nodeIdent,
                                                                  final ItemSyncBox<Meter> syncBox,
                                                                  final SyncCrudCounters counters) {
@@ -463,7 +463,7 @@ public class SyncPlanPushStrategyIncrementalImpl implements SyncPlanPushStrategy
                 */
     }
 
-    protected ListenableFuture<RpcResult<Void>> addMissingGroups(final NodeId nodeId,
+    ListenableFuture<RpcResult<Void>> addMissingGroups(final NodeId nodeId,
                                                                  final InstanceIdentifier<FlowCapableNode> nodeIdent,
                                                                  final List<ItemSyncBox<Group>> groupsAddPlan,
                                                                  final SyncCrudCounters counters) {
index a0b9fde0af446c292cdaad3c09188b48b2d36ebe..f5b86cdc741c57c85ba4ce1c84d6a23492503b67 100644 (file)
@@ -24,12 +24,12 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 public class SynchronizationDiffInput {
 
     private final InstanceIdentifier<FlowCapableNode> nodeIdent;
-    final List<ItemSyncBox<Group>> groupsToAddOrUpdate;
-    final ItemSyncBox<Meter> metersToAddOrUpdate;
-    final Map<TableKey, ItemSyncBox<Flow>> flowsToAddOrUpdate;
-    final Map<TableKey, ItemSyncBox<Flow>> flowsToRemove;
-    final ItemSyncBox<Meter> metersToRemove;
-    final List<ItemSyncBox<Group>> groupsToRemove;
+    private final List<ItemSyncBox<Group>> groupsToAddOrUpdate;
+    private final ItemSyncBox<Meter> metersToAddOrUpdate;
+    private final Map<TableKey, ItemSyncBox<Flow>> flowsToAddOrUpdate;
+    private final Map<TableKey, ItemSyncBox<Flow>> flowsToRemove;
+    private final ItemSyncBox<Meter> metersToRemove;
+    private final List<ItemSyncBox<Group>> groupsToRemove;
 
     public SynchronizationDiffInput(final InstanceIdentifier<FlowCapableNode> nodeIdent,
                                     final List<ItemSyncBox<Group>> groupsToAddOrUpdate,
index 86c8cadbdb7223a65c9ccac5c155ed51171ebf34..3cf70b23c2c2244c2ff3709d6214317d39785c58 100644 (file)
@@ -1,68 +1,68 @@
-/**\r
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.openflowplugin.applications.frsync.markandsweep;\r
-\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;\r
-\r
-/**\r
- * Identifier of {@link Flow} on device. Switch does not know about flow-id but,\r
- * it uses combination of these unique fields: table-id, priority, match.\r
- */\r
-public class SwitchFlowId {\r
-\r
-    private final Short tableId;\r
-\r
-    private final Integer priority;\r
-\r
-    private final Match match;\r
-\r
-    public SwitchFlowId(Flow flow) {\r
-        this.tableId = flow.getTableId();\r
-        this.priority = flow.getPriority();\r
-        this.match = flow.getMatch();\r
-    }\r
-\r
-    @Override\r
-    public int hashCode() {\r
-        final int prime = 31;\r
-        int result = 1;\r
-        result = prime * result + ((match == null) ? 0 : match.hashCode());\r
-        result = prime * result + ((priority == null) ? 0 : priority.hashCode());\r
-        result = prime * result + ((tableId == null) ? 0 : tableId.hashCode());\r
-        return result;\r
-    }\r
-\r
-    @Override\r
-    public boolean equals(Object obj) {\r
-        if (this == obj)\r
-            return true;\r
-        if (obj == null)\r
-            return false;\r
-        if (getClass() != obj.getClass())\r
-            return false;\r
-        SwitchFlowId other = (SwitchFlowId) obj;\r
-        if (match == null) {\r
-            if (other.match != null)\r
-                return false;\r
-        } else if (!match.equals(other.match))\r
-            return false;\r
-        if (priority == null) {\r
-            if (other.priority != null)\r
-                return false;\r
-        } else if (!priority.equals(other.priority))\r
-            return false;\r
-        if (tableId == null) {\r
-            if (other.tableId != null)\r
-                return false;\r
-        } else if (!tableId.equals(other.tableId))\r
-            return false;\r
-        return true;\r
-    }\r
-}\r
+/**
+ * Copyright (c) 2016 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.applications.frsync.markandsweep;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
+
+/**
+ * Identifier of {@link Flow} on device. Switch does not know about flow-id but,
+ * it uses combination of these unique fields: table-id, priority, match.
+ */
+public class SwitchFlowId {
+
+    private final Short tableId;
+
+    private final Integer priority;
+
+    private final Match match;
+
+    public SwitchFlowId(Flow flow) {
+        this.tableId = flow.getTableId();
+        this.priority = flow.getPriority();
+        this.match = flow.getMatch();
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((match == null) ? 0 : match.hashCode());
+        result = prime * result + ((priority == null) ? 0 : priority.hashCode());
+        result = prime * result + ((tableId == null) ? 0 : tableId.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        SwitchFlowId other = (SwitchFlowId) obj;
+        if (match == null) {
+            if (other.match != null)
+                return false;
+        } else if (!match.equals(other.match))
+            return false;
+        if (priority == null) {
+            if (other.priority != null)
+                return false;
+        } else if (!priority.equals(other.priority))
+            return false;
+        if (tableId == null) {
+            if (other.tableId != null)
+                return false;
+        } else if (!tableId.equals(other.tableId))
+            return false;
+        return true;
+    }
+}
index 1a6b277962b0fc36011366ea7261338d0543733f..52d0623d00d7a35ce044ce464525bdd7ee768b37 100644 (file)
@@ -68,7 +68,7 @@ public final class FlowCapableNodeLookups {
 
         return flowMap;
     }
-    
+
     public static Flow flowMapLookupExisting(Flow flow, Map<SwitchFlowId, Flow> flowConfigMap) {
         return flowConfigMap.get(new SwitchFlowId(flow));
     }
index 6635d0a5d3ddbc4e44c479366fcbdbc69cb51420..1e9b49ea9ae1d1b70ea53cab3e63f0d7b37d6c2f 100644 (file)
@@ -33,8 +33,7 @@ public class ItemSyncBox<I> {
     }
 
     /**
-     * Tuple holder for original and updated item
-     *
+     * Tuple holder for original and updated item.
      * @param <I> basic type
      */
     public static final class ItemUpdateTuple<I> {
diff --git a/applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/util/RetryRegistry.java b/applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/util/RetryRegistry.java
new file mode 100644 (file)
index 0000000..eedc6c1
--- /dev/null
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2016 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.applications.frsync.util;
+
+import java.util.Date;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Holder of registration request for fresh operational.
+ */
+public class RetryRegistry {
+
+    private static final Logger LOG = LoggerFactory.getLogger(RetryRegistry.class);
+    private final Map<NodeId, Date> registration = new ConcurrentHashMap<>();
+    public static final String DATE_AND_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
+
+    public Date register(NodeId nodeId) {
+        Date timestamp = new Date();
+        registration.put(nodeId, timestamp);
+        if (timestamp != null) {
+            LOG.debug("Registered for next consistent operational: {}", nodeId.getValue());
+        }
+        return timestamp;
+    }
+
+    public Date unregisterIfRegistered(NodeId nodeId) {
+        Date timestamp = registration.remove(nodeId);
+        if (timestamp != null) {
+            LOG.debug("Unregistered for next consistent operational: {}", nodeId.getValue());
+        }
+        return timestamp;
+    }
+
+    public boolean isRegistered(NodeId nodeId) {
+        return registration.get(nodeId) != null;
+    }
+
+    public Date getRegistration(NodeId nodeId) {
+        return registration.get(nodeId);
+    }
+
+}
index 2cd6204033839af51e4372ff0f9980069c3285dc..419525a1326b97c4d2e008bb47d3fa8faf1df534 100644 (file)
@@ -40,7 +40,7 @@ public class SemaphoreKeeperGuavaImpl<K> implements SemaphoreKeeper<K> {
     public Semaphore summonGuard(final @Nonnull K key) {
         return semaphoreCache.getUnchecked(key);
     }
-    
+
     @Override
     public String toString() {
         return super.toString() + " size:" + (semaphoreCache == null ? null : semaphoreCache.size()) + " " + semaphoreCache;
diff --git a/applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/util/ZipQueueEntry.java b/applications/forwardingrules-sync/src/main/java/org/opendaylight/openflowplugin/applications/frsync/util/ZipQueueEntry.java
new file mode 100644 (file)
index 0000000..ec4d8a8
--- /dev/null
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2016 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.applications.frsync.util;
+
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.openflowplugin.applications.frsync.impl.SyncReactorFutureZipDecorator;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+
+/**
+ * Simple compression queue entry for {@link SyncReactorFutureZipDecorator}.
+ */
+public class ZipQueueEntry {
+    private final FlowCapableNode after;
+    private final FlowCapableNode before;
+    private final LogicalDatastoreType dsTypeBefore;
+
+    public ZipQueueEntry(final FlowCapableNode after, final FlowCapableNode before,
+                         final LogicalDatastoreType dsTypeBefore) {
+        this.after = after;
+        this.before = before;
+        this.dsTypeBefore = dsTypeBefore;
+    }
+
+    public FlowCapableNode getLeft() {
+        return after;
+    }
+
+    public FlowCapableNode getRight() {
+        return before;
+    }
+
+    public LogicalDatastoreType getDsType() {
+        return dsTypeBefore;
+    }
+
+}
index 7e37a1f9a5487b930e4b6286edd4f46277f59129..4c20088ded8fa1897bc91bf5c00357c90e348e02 100644 (file)
@@ -43,32 +43,44 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 @RunWith(MockitoJUnitRunner.class)
 public class SimplifiedConfigListenerTest {
 
+    private static final NodeId NODE_ID = new NodeId("testNode");
+    private InstanceIdentifier<FlowCapableNode> fcNodePath;
+    private SimplifiedConfigListener nodeListenerConfig;
+    private LogicalDatastoreType dsType = LogicalDatastoreType.CONFIGURATION;
+
     @Mock
     private SyncReactor reactor;
     @Mock
-    private DataBroker db;
+    private ReadOnlyTransaction roTx;
     @Mock
     private DataTreeModification<FlowCapableNode> dataTreeModification;
     @Mock
-    private ReadOnlyTransaction roTx;
-    @Mock
     private DataObjectModification<FlowCapableNode> configModification;
-
-    private InstanceIdentifier<FlowCapableNode> nodePath;
-    private SimplifiedConfigListener nodeListenerConfig;
+    @Mock
+    private FlowCapableNode dataBefore;
+    @Mock
+    private FlowCapableNode dataAfter;
 
     @Before
     public void setUp() throws Exception {
-        final FlowCapableNodeSnapshotDao configSnaphot = new FlowCapableNodeSnapshotDao();
-        final FlowCapableNodeSnapshotDao operationalSnaphot = new FlowCapableNodeSnapshotDao();
-        final FlowCapableNodeDao operationalDao = new FlowCapableNodeCachedDao(operationalSnaphot,
+        final DataBroker db = Mockito.mock(DataBroker.class);
+        final FlowCapableNodeSnapshotDao configSnapshot = new FlowCapableNodeSnapshotDao();
+        final FlowCapableNodeSnapshotDao operationalSnapshot = new FlowCapableNodeSnapshotDao();
+        final FlowCapableNodeDao operationalDao = new FlowCapableNodeCachedDao(operationalSnapshot,
                 new FlowCapableNodeOdlDao(db, LogicalDatastoreType.OPERATIONAL));
 
-        
-        nodeListenerConfig = new SimplifiedConfigListener(reactor, configSnaphot, operationalDao);
-        nodePath = InstanceIdentifier.create(Nodes.class)
-                .child(Node.class, new NodeKey(new NodeId("testNode")))
+        nodeListenerConfig = new SimplifiedConfigListener(reactor, configSnapshot, operationalDao);
+        fcNodePath = InstanceIdentifier.create(Nodes.class).child(Node.class, new NodeKey(NODE_ID))
                 .augmentation(FlowCapableNode.class);
+
+        final DataTreeIdentifier<FlowCapableNode> dataTreeIdentifier =
+                new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, fcNodePath);
+
+        Mockito.when(db.newReadOnlyTransaction()).thenReturn(roTx);
+        Mockito.when(dataTreeModification.getRootPath()).thenReturn(dataTreeIdentifier);
+        Mockito.when(dataTreeModification.getRootNode()).thenReturn(configModification);
+        Mockito.when(reactor.syncup(Matchers.<InstanceIdentifier<FlowCapableNode>>any(), Matchers.<FlowCapableNode>any(),
+                Matchers.<FlowCapableNode>any(), Matchers.<LogicalDatastoreType>any())).thenReturn(Futures.immediateFuture(Boolean.TRUE));
     }
 
     @Test
@@ -77,24 +89,53 @@ public class SimplifiedConfigListenerTest {
     }
 
     @Test
-    public void testOnDataTreeChanged() throws Exception {
-        final FlowCapableNode configTree = Mockito.mock(FlowCapableNode.class);
-        final FlowCapableNode operationalTree = Mockito.mock(FlowCapableNode.class);
-        final DataTreeIdentifier<FlowCapableNode> dataTreeIdentifier =
-                new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, nodePath);
+    public void testOnDataTreeChangedSyncupAdd() throws InterruptedException {
+        Mockito.when(roTx.read(LogicalDatastoreType.OPERATIONAL, fcNodePath))
+                .thenReturn(Futures.immediateCheckedFuture(Optional.of(dataBefore)));
+        Mockito.when(configModification.getDataAfter()).thenReturn(dataAfter);
 
-        Mockito.when(dataTreeModification.getRootPath()).thenReturn(dataTreeIdentifier);
-        Mockito.when(dataTreeModification.getRootNode()).thenReturn(configModification);
-        Mockito.when(configModification.getDataAfter()).thenReturn(configTree);
-        Mockito.when(db.newReadOnlyTransaction()).thenReturn(roTx);
-        Mockito.doReturn(Futures.immediateCheckedFuture(Optional.of(operationalTree))).when(
-                roTx).read(LogicalDatastoreType.OPERATIONAL, nodePath);
-        Mockito.when(reactor.syncup(Matchers.<InstanceIdentifier<FlowCapableNode>>any(),Matchers.<FlowCapableNode>any(),Matchers.<FlowCapableNode>any()))
-                .thenReturn(Futures.immediateFuture(Boolean.TRUE));
+        nodeListenerConfig.onDataTreeChanged(Collections.singleton(dataTreeModification));
+
+        Mockito.verify(reactor).syncup(fcNodePath, dataAfter, dataBefore, dsType);
+        Mockito.verifyNoMoreInteractions(reactor);
+        Mockito.verify(roTx).close();
+    }
+
+    @Test
+    public void testOnDataTreeChangedSyncupUpdate() throws InterruptedException {
+        Mockito.when(roTx.read(LogicalDatastoreType.OPERATIONAL, fcNodePath))
+                .thenReturn(Futures.immediateCheckedFuture(Optional.of(dataBefore)));
+        Mockito.when(configModification.getDataBefore()).thenReturn(dataBefore);
+        Mockito.when(configModification.getDataAfter()).thenReturn(dataAfter);
+
+        nodeListenerConfig.onDataTreeChanged(Collections.singleton(dataTreeModification));
+
+        Mockito.verify(reactor).syncup(fcNodePath, dataAfter, dataBefore, dsType);
+        Mockito.verifyNoMoreInteractions(reactor);
+        Mockito.verify(roTx).close();
+    }
+
+    @Test
+    public void testOnDataTreeChangedSyncupDelete() throws InterruptedException {
+        Mockito.when(roTx.read(LogicalDatastoreType.OPERATIONAL, fcNodePath))
+                .thenReturn(Futures.immediateCheckedFuture(Optional.of(dataBefore)));
+        Mockito.when(configModification.getDataBefore()).thenReturn(dataBefore);
+
+        nodeListenerConfig.onDataTreeChanged(Collections.singleton(dataTreeModification));
+
+        Mockito.verify(reactor).syncup(fcNodePath, null, dataBefore, dsType);
+        Mockito.verifyNoMoreInteractions(reactor);
+        Mockito.verify(roTx).close();
+    }
+
+    @Test
+    public void testOnDataTreeChangedSkip() {
+        Mockito.when(roTx.read(LogicalDatastoreType.OPERATIONAL, fcNodePath)).
+                thenReturn(Futures.immediateCheckedFuture(Optional.absent()));
 
         nodeListenerConfig.onDataTreeChanged(Collections.singleton(dataTreeModification));
 
-        Mockito.verify(reactor).syncup(nodePath, configTree, operationalTree);
+        Mockito.verifyZeroInteractions(reactor);
         Mockito.verify(roTx).close();
     }
 }
\ No newline at end of file
index 04005d2c0cfb72f477029265b7fddf7bbc063729..30383c0a2200dcfce9414281b36e9e343aaa6acc 100644 (file)
@@ -11,6 +11,7 @@ package org.opendaylight.openflowplugin.applications.frsync.impl;
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.Futures;
 import java.util.Collections;
+import java.util.List;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -21,6 +22,7 @@ import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 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.DataObjectModification.ModificationType;
 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;
@@ -33,6 +35,7 @@ import org.opendaylight.openflowplugin.applications.frsync.dao.FlowCapableNodeSn
 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.node.NodeConnector;
 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;
@@ -43,7 +46,11 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 @RunWith(MockitoJUnitRunner.class)
 public class SimplifiedOperationalListenerTest {
 
-    public static final NodeId NODE_ID = new NodeId("testNode");
+    private static final NodeId NODE_ID = new NodeId("testNode");
+    private InstanceIdentifier<FlowCapableNode> fcNodePath;
+    private SimplifiedOperationalListener nodeListenerOperational;
+    private final LogicalDatastoreType dsType = LogicalDatastoreType.OPERATIONAL;
+
     @Mock
     private SyncReactor reactor;
     @Mock
@@ -51,37 +58,34 @@ public class SimplifiedOperationalListenerTest {
     @Mock
     private DataTreeModification<Node> dataTreeModification;
     @Mock
+    private DataObjectModification<Node> operationalModification;
+    @Mock
     private FlowCapableNode configNode;
     @Mock
+    private Node operationalNode;
+    @Mock
     private FlowCapableNode fcOperationalNode;
 
-    private InstanceIdentifier<Node> nodePath;
-    private InstanceIdentifier<FlowCapableNode> fcNodePath;
-    private SimplifiedOperationalListener nodeListenerOperational;
-
     @Before
     public void setUp() throws Exception {
         final DataBroker db = Mockito.mock(DataBroker.class);
-        final DataObjectModification<Node> operationalModification = Mockito.mock(DataObjectModification.class);
-        final Node operationalNode = Mockito.mock(Node.class);
-
-        final FlowCapableNodeSnapshotDao configSnaphot = new FlowCapableNodeSnapshotDao();
-        final FlowCapableNodeSnapshotDao operationalSnaphot = new FlowCapableNodeSnapshotDao();
-        final FlowCapableNodeDao configDao = new FlowCapableNodeCachedDao(configSnaphot,
+        final FlowCapableNodeSnapshotDao configSnapshot = new FlowCapableNodeSnapshotDao();
+        final FlowCapableNodeSnapshotDao operationalSnapshot = new FlowCapableNodeSnapshotDao();
+        final FlowCapableNodeDao configDao = new FlowCapableNodeCachedDao(configSnapshot,
                 new FlowCapableNodeOdlDao(db, LogicalDatastoreType.CONFIGURATION));
-        nodeListenerOperational = new SimplifiedOperationalListener(reactor, operationalSnaphot, configDao);
-        nodePath = InstanceIdentifier.create(Nodes.class).child(Node.class, new NodeKey(NODE_ID));
+
+        nodeListenerOperational = new SimplifiedOperationalListener(reactor, operationalSnapshot, configDao);
+        InstanceIdentifier<Node> nodePath = InstanceIdentifier.create(Nodes.class).child(Node.class, new NodeKey(NODE_ID));
         fcNodePath = nodePath.augmentation(FlowCapableNode.class);
 
         final DataTreeIdentifier<Node> dataTreeIdentifier =
                 new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, nodePath);
 
-        Mockito.when(operationalNode.getId()).thenReturn(NODE_ID);
         Mockito.when(db.newReadOnlyTransaction()).thenReturn(roTx);
-        Mockito.when(operationalNode.getAugmentation(FlowCapableNode.class)).thenReturn(fcOperationalNode);
+        Mockito.when(operationalNode.getId()).thenReturn(NODE_ID);
         Mockito.when(dataTreeModification.getRootPath()).thenReturn(dataTreeIdentifier);
         Mockito.when(dataTreeModification.getRootNode()).thenReturn(operationalModification);
-        Mockito.when(operationalModification.getDataAfter()).thenReturn(operationalNode);
+        Mockito.when(operationalNode.getAugmentation(FlowCapableNode.class)).thenReturn(fcOperationalNode);
     }
 
     @Test
@@ -90,27 +94,51 @@ public class SimplifiedOperationalListenerTest {
     }
 
     @Test
-    public void testOnDataTreeChangedSyncup() throws Exception {
-        Mockito.when(reactor.syncup(Matchers.<InstanceIdentifier<FlowCapableNode>>any(),Matchers.<FlowCapableNode>any(),
-                Matchers.<FlowCapableNode>any())).thenReturn(Futures.immediateFuture(Boolean.TRUE));
+    public void testOnDataTreeChangedSyncupAdd() throws InterruptedException {
         Mockito.when(roTx.read(LogicalDatastoreType.CONFIGURATION, fcNodePath))
                 .thenReturn(Futures.immediateCheckedFuture(Optional.of(configNode)));
+        Mockito.when(reactor.syncup(Matchers.<InstanceIdentifier<FlowCapableNode>>any(), Matchers.<FlowCapableNode>any(),
+                Matchers.<FlowCapableNode>any(), Matchers.<LogicalDatastoreType>any())).thenReturn(Futures.immediateFuture(Boolean.TRUE));
+        Mockito.when(operationalModification.getDataAfter()).thenReturn(operationalNode);
 
         nodeListenerOperational.onDataTreeChanged(Collections.singleton(dataTreeModification));
 
-        Mockito.verify(reactor, Mockito.times(1)).syncup(fcNodePath, configNode, fcOperationalNode);
+        Mockito.verify(reactor).syncup(fcNodePath, configNode, fcOperationalNode, dsType);
+        Mockito.verifyNoMoreInteractions(reactor);
         Mockito.verify(roTx).close();
     }
 
     @Test
-    public void testOnDataTreeChangedSkip() throws Exception {
+    public void testOnDataTreeChangedAddSkip() {
         // Related to bug 5920 -> https://bugs.opendaylight.org/show_bug.cgi?id=5920
         Mockito.when(roTx.read(LogicalDatastoreType.CONFIGURATION, fcNodePath))
                 .thenReturn(Futures.immediateCheckedFuture(Optional.absent()));
+        Mockito.when(operationalModification.getDataAfter()).thenReturn(operationalNode);
 
         nodeListenerOperational.onDataTreeChanged(Collections.singleton(dataTreeModification));
 
         Mockito.verifyZeroInteractions(reactor);
         Mockito.verify(roTx).close();
     }
+
+    @Test
+    public void testOnDataTreeChangedSyncupDeletePhysical() {
+        Mockito.when(operationalModification.getDataBefore()).thenReturn(operationalNode);
+        Mockito.when(dataTreeModification.getRootNode().getModificationType()).thenReturn(ModificationType.DELETE);
+
+        nodeListenerOperational.onDataTreeChanged(Collections.singleton(dataTreeModification));
+
+        Mockito.verifyZeroInteractions(reactor);
+    }
+
+    @Test
+    public void testOnDataTreeChangedSyncupDeleteLogical() {
+        Mockito.when(operationalModification.getDataBefore()).thenReturn(operationalNode);
+        List<NodeConnector> nodeConnectorList = Mockito.mock(List.class);
+        Mockito.when(operationalNode.getNodeConnector()).thenReturn(nodeConnectorList);
+
+        nodeListenerOperational.onDataTreeChanged(Collections.singleton(dataTreeModification));
+
+        Mockito.verifyZeroInteractions(reactor);
+    }
 }
diff --git a/applications/forwardingrules-sync/src/test/java/org/opendaylight/openflowplugin/applications/frsync/impl/SimplifiedOperationalRetryListenerTest.java b/applications/forwardingrules-sync/src/test/java/org/opendaylight/openflowplugin/applications/frsync/impl/SimplifiedOperationalRetryListenerTest.java
new file mode 100644 (file)
index 0000000..fd23c4a
--- /dev/null
@@ -0,0 +1,205 @@
+/**
+ * Copyright (c) 2016 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.applications.frsync.impl;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.Futures;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Collections;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+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.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.common.api.data.LogicalDatastoreType;
+import org.opendaylight.openflowplugin.applications.frsync.SyncReactor;
+import org.opendaylight.openflowplugin.applications.frsync.dao.FlowCapableNodeCachedDao;
+import org.opendaylight.openflowplugin.applications.frsync.dao.FlowCapableNodeDao;
+import org.opendaylight.openflowplugin.applications.frsync.dao.FlowCapableNodeOdlDao;
+import org.opendaylight.openflowplugin.applications.frsync.dao.FlowCapableNodeSnapshotDao;
+import org.opendaylight.openflowplugin.applications.frsync.util.RetryRegistry;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.DateAndTime;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableStatisticsGatheringStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.snapshot.gathering.status.grouping.SnapshotGatheringStatusEnd;
+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;
+
+/**
+ * Test for {@link SimplifiedOperationalRetryListener}.
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class SimplifiedOperationalRetryListenerTest {
+
+    private final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(RetryRegistry.DATE_AND_TIME_FORMAT);
+    private static final NodeId NODE_ID = new NodeId("testNode");
+    private InstanceIdentifier<FlowCapableNode> fcNodePath;
+    private SimplifiedOperationalRetryListener nodeListenerOperational;
+    private final String timestampBefore = "0000-12-12T01:01:01.000-07:00";
+    private final String timestampAfter = "9999-12-12T01:01:01.000-07:00";
+    private final LogicalDatastoreType dsType = LogicalDatastoreType.OPERATIONAL;
+
+    @Mock
+    private SyncReactor reactor;
+    @Mock
+    private ReadOnlyTransaction roTx;
+    @Mock
+    private DataTreeModification<Node> dataTreeModification;
+    @Mock
+    private DataObjectModification<Node> operationalModification;
+    @Mock
+    private FlowCapableNode configNode;
+    @Mock
+    private Node operationalNode;
+    @Mock
+    private FlowCapableNode fcOperationalNode;
+    @Mock
+    private RetryRegistry retryRegistry;
+    @Mock
+    private FlowCapableStatisticsGatheringStatus statisticsGatheringStatus;
+    @Mock
+    private SnapshotGatheringStatusEnd snapshotGatheringStatusEnd;
+
+    @Before
+    public void setUp() throws Exception {
+        final DataBroker db = Mockito.mock(DataBroker.class);
+        final FlowCapableNodeSnapshotDao configSnapshot = new FlowCapableNodeSnapshotDao();
+        final FlowCapableNodeSnapshotDao operationalSnapshot = new FlowCapableNodeSnapshotDao();
+        final FlowCapableNodeDao configDao = new FlowCapableNodeCachedDao(configSnapshot,
+                new FlowCapableNodeOdlDao(db, LogicalDatastoreType.CONFIGURATION));
+
+        nodeListenerOperational = new SimplifiedOperationalRetryListener(reactor, operationalSnapshot, configDao, retryRegistry);
+        InstanceIdentifier<Node> nodePath = InstanceIdentifier.create(Nodes.class).child(Node.class, new NodeKey(NODE_ID));
+        fcNodePath = nodePath.augmentation(FlowCapableNode.class);
+
+        final DataTreeIdentifier<Node> dataTreeIdentifier =
+                new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, nodePath);
+
+        Mockito.when(db.newReadOnlyTransaction()).thenReturn(roTx);
+        Mockito.when(operationalNode.getId()).thenReturn(NODE_ID);
+        Mockito.when(dataTreeModification.getRootPath()).thenReturn(dataTreeIdentifier);
+        Mockito.when(dataTreeModification.getRootNode()).thenReturn(operationalModification);
+        Mockito.when(operationalNode.getAugmentation(FlowCapableNode.class)).thenReturn(fcOperationalNode);
+    }
+
+    @Test
+    public void testOnDataTreeChangedRetryNotRegistered() {
+        Mockito.when(operationalModification.getDataBefore()).thenReturn(operationalNode);
+        Mockito.when(operationalModification.getDataAfter()).thenReturn(operationalNode);
+        Mockito.when(retryRegistry.isRegistered(NODE_ID)).thenReturn(false);
+
+        nodeListenerOperational.onDataTreeChanged(Collections.singleton(dataTreeModification));
+
+        Mockito.verifyZeroInteractions(reactor);
+    }
+
+    @Test
+    public void testOnDataTreeChangedRetryButStaticsGatheringNotStarted() {
+        Mockito.when(operationalModification.getDataBefore()).thenReturn(operationalNode);
+        Mockito.when(operationalModification.getDataAfter()).thenReturn(operationalNode);
+        Mockito.when(retryRegistry.isRegistered(NODE_ID)).thenReturn(true);
+        Mockito.when(operationalNode.getAugmentation(FlowCapableStatisticsGatheringStatus.class)).thenReturn(null);
+
+        nodeListenerOperational.onDataTreeChanged(Collections.singleton(dataTreeModification));
+
+        Mockito.verifyZeroInteractions(reactor);
+    }
+
+    @Test
+    public void testOnDataTreeChangedRetryButStaticsGatheringNotFinished() {
+        Mockito.when(operationalModification.getDataBefore()).thenReturn(operationalNode);
+        Mockito.when(operationalModification.getDataAfter()).thenReturn(operationalNode);
+        Mockito.when(retryRegistry.isRegistered(NODE_ID)).thenReturn(true);
+        Mockito.when(operationalNode.getAugmentation(FlowCapableStatisticsGatheringStatus.class)).thenReturn(statisticsGatheringStatus);
+        Mockito.when(statisticsGatheringStatus.getSnapshotGatheringStatusEnd()).thenReturn(null);
+
+        nodeListenerOperational.onDataTreeChanged(Collections.singleton(dataTreeModification));
+
+        Mockito.verifyZeroInteractions(reactor);
+    }
+
+    @Test
+    public void testOnDataTreeChangedRetryButStaticsGatheringNotSuccessful() {
+        Mockito.when(operationalModification.getDataBefore()).thenReturn(operationalNode);
+        Mockito.when(operationalModification.getDataAfter()).thenReturn(operationalNode);
+        Mockito.when(retryRegistry.isRegistered(NODE_ID)).thenReturn(true);
+        Mockito.when(operationalNode.getAugmentation(FlowCapableStatisticsGatheringStatus.class)).thenReturn(statisticsGatheringStatus);
+        Mockito.when(statisticsGatheringStatus.getSnapshotGatheringStatusEnd()).thenReturn(snapshotGatheringStatusEnd);
+        Mockito.when(snapshotGatheringStatusEnd.isSucceeded()).thenReturn(false);
+
+        nodeListenerOperational.onDataTreeChanged(Collections.singleton(dataTreeModification));
+
+        Mockito.verifyZeroInteractions(reactor);
+    }
+
+    @Test
+    public void testOnDataTreeChangedRetryAndFreshOperationalNotPresent() throws ParseException {
+        final DateAndTime timestamp = Mockito.mock(DateAndTime.class);
+        Mockito.when(operationalModification.getDataBefore()).thenReturn(operationalNode);
+        Mockito.when(operationalModification.getDataAfter()).thenReturn(operationalNode);
+        Mockito.when(retryRegistry.isRegistered(NODE_ID)).thenReturn(true);
+        Mockito.when(operationalNode.getAugmentation(FlowCapableStatisticsGatheringStatus.class)).thenReturn(statisticsGatheringStatus);
+        Mockito.when(statisticsGatheringStatus.getSnapshotGatheringStatusEnd()).thenReturn(snapshotGatheringStatusEnd);
+        Mockito.when(snapshotGatheringStatusEnd.isSucceeded()).thenReturn(true);
+        Mockito.when(snapshotGatheringStatusEnd.getEnd()).thenReturn(timestamp);
+        Mockito.when(snapshotGatheringStatusEnd.getEnd().getValue()).thenReturn(timestampBefore);
+        Mockito.when(retryRegistry.getRegistration(NODE_ID)).thenReturn(simpleDateFormat.parse(timestampAfter));
+
+        nodeListenerOperational.onDataTreeChanged(Collections.singleton(dataTreeModification));
+
+        Mockito.verifyZeroInteractions(reactor);
+    }
+
+    @Test
+    public void testOnDataTreeChangedRetryAndFreshOperationalPresent() throws Exception {
+        final DateAndTime timestamp = Mockito.mock(DateAndTime.class);
+        Mockito.when(roTx.read(LogicalDatastoreType.CONFIGURATION, fcNodePath))
+                .thenReturn(Futures.immediateCheckedFuture(Optional.of(configNode)));
+        Mockito.when(reactor.syncup(Matchers.<InstanceIdentifier<FlowCapableNode>>any(), Matchers.<FlowCapableNode>any(),
+                Matchers.<FlowCapableNode>any(), Matchers.<LogicalDatastoreType>any())).thenReturn(Futures.immediateFuture(Boolean.TRUE));
+        Mockito.when(operationalModification.getDataBefore()).thenReturn(operationalNode);
+        Mockito.when(operationalModification.getDataAfter()).thenReturn(operationalNode);
+        Mockito.when(retryRegistry.isRegistered(NODE_ID)).thenReturn(true);
+        Mockito.when(operationalNode.getAugmentation(FlowCapableStatisticsGatheringStatus.class)).thenReturn(statisticsGatheringStatus);
+        Mockito.when(statisticsGatheringStatus.getSnapshotGatheringStatusEnd()).thenReturn(snapshotGatheringStatusEnd);
+        Mockito.when(snapshotGatheringStatusEnd.isSucceeded()).thenReturn(true);
+        Mockito.when(snapshotGatheringStatusEnd.getEnd()).thenReturn(timestamp);
+        Mockito.when(snapshotGatheringStatusEnd.getEnd().getValue()).thenReturn(timestampAfter);
+        Mockito.when(retryRegistry.getRegistration(NODE_ID)).thenReturn(simpleDateFormat.parse(timestampBefore));
+
+        nodeListenerOperational.onDataTreeChanged(Collections.singleton(dataTreeModification));
+
+        Mockito.verify(reactor).syncup(fcNodePath, configNode, fcOperationalNode, dsType);
+        Mockito.verifyNoMoreInteractions(reactor);
+        Mockito.verify(roTx).close();
+    }
+
+    @Test
+    public void testOnDataTreeChangedRetryAndNodeDeleted() {
+        Mockito.when(operationalModification.getDataBefore()).thenReturn(operationalNode);
+        Mockito.when(dataTreeModification.getRootNode().getModificationType()).thenReturn(DataObjectModification.ModificationType.DELETE);
+
+        nodeListenerOperational.onDataTreeChanged(Collections.singleton(dataTreeModification));
+
+        Mockito.verify(retryRegistry).unregisterIfRegistered(NODE_ID);
+        Mockito.verifyZeroInteractions(reactor);
+    }
+
+}
\ No newline at end of file
diff --git a/applications/forwardingrules-sync/src/test/java/org/opendaylight/openflowplugin/applications/frsync/impl/SyncReactorFutureZipDecoratorTest.java b/applications/forwardingrules-sync/src/test/java/org/opendaylight/openflowplugin/applications/frsync/impl/SyncReactorFutureZipDecoratorTest.java
new file mode 100644 (file)
index 0000000..f9fb441
--- /dev/null
@@ -0,0 +1,186 @@
+/**
+ * Copyright (c) 2016 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.applications.frsync.impl;
+
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.stubbing.Answer;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+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;
+
+/**
+ * Test for {@link SyncReactorFutureZipDecorator}.
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class SyncReactorFutureZipDecoratorTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SyncReactorFutureZipDecoratorTest.class);
+    private static final NodeId NODE_ID = new NodeId("testNode");
+    private SyncReactorFutureZipDecorator reactor;
+    private InstanceIdentifier<FlowCapableNode> fcNodePath;
+    private ListeningExecutorService syncThreadPool;
+
+    @Mock
+    private SyncReactorGuardDecorator delegate;
+
+    @Before
+    public void setUp() {
+        syncThreadPool = FrmExecutors.instance()
+                .newFixedThreadPool(1, new ThreadFactoryBuilder()
+                        .setNameFormat(SyncReactorFutureDecorator.FRM_RPC_CLIENT_PREFIX + "%d")
+                        .setDaemon(false)
+                        .build());
+
+        reactor = new SyncReactorFutureZipDecorator(delegate, syncThreadPool);
+        fcNodePath = InstanceIdentifier.create(Nodes.class).child(Node.class, new NodeKey(NODE_ID))
+                .augmentation(FlowCapableNode.class);
+    }
+
+    @Test
+    public void testSyncupWithOptimizedConfigDeltaCompression() throws Exception {
+        final FlowCapableNode dataBefore = Mockito.mock(FlowCapableNode.class);
+        final FlowCapableNode dataAfter = Mockito.mock(FlowCapableNode.class);
+        final FlowCapableNode dataAfter2 = Mockito.mock(FlowCapableNode.class);
+        final CountDownLatch latchForFirst = new CountDownLatch(1);
+        final CountDownLatch latchForNext = new CountDownLatch(1);
+        final LogicalDatastoreType dsType = LogicalDatastoreType.CONFIGURATION;
+
+        Mockito.when(delegate.syncup(Matchers.<InstanceIdentifier<FlowCapableNode>>any(), Matchers.<FlowCapableNode>any(),
+                Matchers.<FlowCapableNode>any(), Matchers.<LogicalDatastoreType>any())).thenAnswer(new Answer<ListenableFuture<Boolean>>() {
+                    @Override
+                    public ListenableFuture<Boolean> answer(final InvocationOnMock invocationOnMock) throws Throwable {
+                        LOG.info("unlocking next configs");
+                        latchForNext.countDown();
+                        latchForFirst.await();
+                        LOG.info("unlocking first delegate");
+                        return Futures.immediateFuture(Boolean.TRUE);
+                    }
+                }).thenReturn(Futures.immediateFuture(Boolean.TRUE));
+
+        final List<ListenableFuture<Boolean>> allResults = new ArrayList<>();
+        allResults.add(reactor.syncup(fcNodePath, dataBefore, null, dsType));
+        latchForNext.await();
+
+        allResults.add(reactor.syncup(fcNodePath, dataAfter, dataBefore, dsType));
+        allResults.add(reactor.syncup(fcNodePath, null, dataAfter, dsType));
+        allResults.add(reactor.syncup(fcNodePath, dataAfter2, null, dsType));
+        latchForFirst.countDown();
+
+        Futures.allAsList(allResults).get(1, TimeUnit.SECONDS);
+        LOG.info("all configs done");
+
+        syncThreadPool.shutdown();
+        boolean terminated = syncThreadPool.awaitTermination(1, TimeUnit.SECONDS);
+        if (!terminated) {
+            LOG.info("thread pool not terminated.");
+            syncThreadPool.shutdownNow();
+        }
+        final InOrder inOrder = Mockito.inOrder(delegate);
+        inOrder.verify(delegate).syncup(fcNodePath, dataBefore, null, dsType);
+        inOrder.verify(delegate).syncup(fcNodePath, dataAfter2, dataBefore, dsType);
+        inOrder.verifyNoMoreInteractions();
+    }
+
+    @Test
+    public void testSyncupConfigEmptyQueue() throws Exception {
+        final FlowCapableNode dataBefore = Mockito.mock(FlowCapableNode.class);
+        final FlowCapableNode dataAfter = Mockito.mock(FlowCapableNode.class);
+        final CountDownLatch latchForNext = new CountDownLatch(1);
+        final LogicalDatastoreType dsType = LogicalDatastoreType.CONFIGURATION;
+
+        Mockito.when(delegate.syncup(Matchers.<InstanceIdentifier<FlowCapableNode>>any(), Matchers.<FlowCapableNode>any(),
+                Matchers.<FlowCapableNode>any(), Matchers.<LogicalDatastoreType>any())).thenAnswer(new Answer<ListenableFuture<Boolean>>() {
+            @Override
+            public ListenableFuture<Boolean> answer(final InvocationOnMock invocationOnMock) throws Throwable {
+                LOG.info("unlocking next config");
+                latchForNext.countDown();
+                return Futures.immediateFuture(Boolean.TRUE);
+            }
+            }).thenReturn(Futures.immediateFuture(Boolean.TRUE));
+
+        reactor.syncup(fcNodePath, dataBefore, null, dsType);
+        latchForNext.await();
+        reactor.syncup(fcNodePath, dataAfter, dataBefore, dsType);
+
+        boolean terminated = syncThreadPool.awaitTermination(1, TimeUnit.SECONDS);
+        if (!terminated) {
+            LOG.info("thread pool not terminated.");
+            syncThreadPool.shutdownNow();
+        }
+        final InOrder inOrder = Mockito.inOrder(delegate);
+        inOrder.verify(delegate).syncup(fcNodePath, dataBefore, null, dsType);
+        inOrder.verify(delegate).syncup(fcNodePath, dataAfter, dataBefore, dsType);
+        inOrder.verifyNoMoreInteractions();
+
+    }
+
+    @Test
+    public void testSyncupRewriteZipEntryWithOperationalDelta() throws Exception {
+        final FlowCapableNode configBefore = Mockito.mock(FlowCapableNode.class);
+        final FlowCapableNode configAfter = Mockito.mock(FlowCapableNode.class);
+        final FlowCapableNode configActual = Mockito.mock(FlowCapableNode.class);
+        final FlowCapableNode freshOperational = Mockito.mock(FlowCapableNode.class);
+        final CountDownLatch latchForFirst = new CountDownLatch(1);
+        final CountDownLatch latchForNext = new CountDownLatch(1);
+
+        Mockito.when(delegate.syncup(Matchers.<InstanceIdentifier<FlowCapableNode>>any(), Matchers.<FlowCapableNode>any(),
+                Matchers.<FlowCapableNode>any(), Matchers.<LogicalDatastoreType>any())).thenAnswer(new Answer<ListenableFuture<Boolean>>() {
+            @Override
+            public ListenableFuture<Boolean> answer(final InvocationOnMock invocationOnMock) throws Throwable {
+                LOG.info("unlocking for fresh operational");
+                latchForNext.countDown();
+                latchForFirst.await();
+                LOG.info("unlocking first delegate");
+                return Futures.immediateFuture(Boolean.TRUE);
+            }
+        }).thenReturn(Futures.immediateFuture(Boolean.TRUE));
+
+        reactor.syncup(fcNodePath, configAfter, configBefore, LogicalDatastoreType.CONFIGURATION);
+        latchForNext.await();
+
+        reactor.syncup(fcNodePath, configActual, freshOperational, LogicalDatastoreType.OPERATIONAL);
+        latchForFirst.countDown();
+
+        syncThreadPool.shutdown();
+        boolean terminated = syncThreadPool.awaitTermination(1, TimeUnit.SECONDS);
+        if (!terminated) {
+            LOG.info("thread pool not terminated.");
+            syncThreadPool.shutdownNow();
+        }
+        Mockito.verify(delegate, Mockito.times(1)).syncup(fcNodePath, configActual, freshOperational, LogicalDatastoreType.OPERATIONAL);
+    }
+
+    @After
+    public void tearDown() {
+        syncThreadPool.shutdownNow();
+    }
+}
\ No newline at end of file
index 8eda58c26c695ac73a9665e44fc6192582bafd8a..d10a228bb7c94c0fa831a19b624807d2c19a9b52 100644 (file)
@@ -16,6 +16,7 @@ import org.mockito.Matchers;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.openflowplugin.applications.frsync.util.SemaphoreKeeperGuavaImpl;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
@@ -33,9 +34,10 @@ public class SyncReactorGuardDecoratorTest {
     private static final NodeId NODE_ID = new NodeId("test-node");
     private SyncReactorGuardDecorator reactor;
     private InstanceIdentifier<FlowCapableNode> fcNodePath;
+    private final LogicalDatastoreType dsType = LogicalDatastoreType.CONFIGURATION;
 
     @Mock
-    private SyncReactorImpl delegate;
+    private SyncReactorRetryDecorator delegate;
     @Mock
     private FlowCapableNode fcConfigNode;
     @Mock
@@ -43,7 +45,8 @@ public class SyncReactorGuardDecoratorTest {
 
     @Before
     public void setUp() throws Exception {
-        reactor = new SyncReactorGuardDecorator(delegate, new SemaphoreKeeperGuavaImpl<InstanceIdentifier<FlowCapableNode>>(1, true));
+        final SemaphoreKeeperGuavaImpl semaphoreKeeper = new SemaphoreKeeperGuavaImpl<InstanceIdentifier<FlowCapableNode>>(1, true);
+        reactor = new SyncReactorGuardDecorator(delegate, semaphoreKeeper);
         InstanceIdentifier<Node> nodePath = InstanceIdentifier.create(Nodes.class).child(Node.class, new NodeKey(NODE_ID));
         fcNodePath = nodePath.augmentation(FlowCapableNode.class);
 
@@ -54,19 +57,24 @@ public class SyncReactorGuardDecoratorTest {
 
     @Test
     public void testSyncupSuccess() throws Exception {
-        Mockito.when(delegate.syncup(Matchers.<InstanceIdentifier<FlowCapableNode>>any(),Matchers.<FlowCapableNode>any(),
-                Matchers.<FlowCapableNode>any())).thenReturn(Futures.immediateFuture(Boolean.TRUE));
-        reactor.syncup(fcNodePath, fcConfigNode, fcOperationalNode);
-        Mockito.verify(delegate).syncup(fcNodePath, fcConfigNode, fcOperationalNode);
+        Mockito.when(delegate.syncup(Matchers.<InstanceIdentifier<FlowCapableNode>>any(), Matchers.<FlowCapableNode>any(),
+                Matchers.<FlowCapableNode>any(), Matchers.<LogicalDatastoreType>any())).thenReturn(Futures.immediateFuture(Boolean.TRUE));
 
+        reactor.syncup(fcNodePath, fcConfigNode, fcOperationalNode, dsType);
+
+        Mockito.verify(delegate).syncup(fcNodePath, fcConfigNode, fcOperationalNode, dsType);
+        Mockito.verifyNoMoreInteractions(delegate);
     }
 
     @Test
     public void testSyncupFail() throws Exception {
-        Mockito.when(delegate.syncup(Matchers.<InstanceIdentifier<FlowCapableNode>>any(),Matchers.<FlowCapableNode>any(),
-                Matchers.<FlowCapableNode>any())).thenReturn(Futures.immediateFailedFuture(new Exception()));
-        reactor.syncup(fcNodePath, fcConfigNode, fcOperationalNode);
-        Mockito.verify(delegate).syncup(fcNodePath, fcConfigNode, fcOperationalNode);
+        Mockito.when(delegate.syncup(Matchers.<InstanceIdentifier<FlowCapableNode>>any(), Matchers.<FlowCapableNode>any(),
+                Matchers.<FlowCapableNode>any(), Matchers.<LogicalDatastoreType>any())).thenReturn(Futures.immediateFailedFuture(new Exception()));
+
+        reactor.syncup(fcNodePath, fcConfigNode, fcOperationalNode, dsType);
+
+        Mockito.verify(delegate).syncup(fcNodePath, fcConfigNode, fcOperationalNode, dsType);
+        Mockito.verifyNoMoreInteractions(delegate);
 
     }
 
index 17f470bb2e363dda02a3760b691ea148f365be78..588a4019369bafdfb9983a4df32ecb11fb5d820d 100644 (file)
@@ -22,6 +22,7 @@ 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.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.openflowplugin.applications.frsync.SyncPlanPushStrategy;
 import org.opendaylight.openflowplugin.applications.frsync.impl.strategy.SynchronizationDiffInput;
 import org.opendaylight.openflowplugin.applications.frsync.util.ReconcileUtil;
@@ -54,13 +55,12 @@ public class SyncReactorImplTest {
     private static final NodeId NODE_ID = new NodeId("unit-nodeId");
     private static final InstanceIdentifier<FlowCapableNode> NODE_IDENT = InstanceIdentifier.create(Nodes.class)
             .child(Node.class, new NodeKey(NODE_ID)).augmentation(FlowCapableNode.class);
-
     private SyncReactorImpl reactor;
+
     @Mock
     private DataBroker db;
     @Mock
     private SyncPlanPushStrategy syncPlanPushStrategy;
-
     @Captor
     private ArgumentCaptor<Group> groupCaptor;
     @Captor
@@ -107,7 +107,7 @@ public class SyncReactorImplTest {
                 Matchers.<SyncCrudCounters>any()))
                 .thenReturn(RpcResultBuilder.<Void>success().buildFuture());
 
-        final ListenableFuture<Boolean> syncupResult = reactor.syncup(NODE_IDENT, configFcn, operationalFcn);
+        final ListenableFuture<Boolean> syncupResult = reactor.syncup(NODE_IDENT, configFcn, operationalFcn, LogicalDatastoreType.CONFIGURATION);
         try {
             Assert.assertTrue(syncupResult.isDone());
             final Boolean voidRpcResult = syncupResult.get(2, TimeUnit.SECONDS);
diff --git a/applications/forwardingrules-sync/src/test/java/org/opendaylight/openflowplugin/applications/frsync/impl/SyncReactorRetryDecoratorTest.java b/applications/forwardingrules-sync/src/test/java/org/opendaylight/openflowplugin/applications/frsync/impl/SyncReactorRetryDecoratorTest.java
new file mode 100644 (file)
index 0000000..1bf41a4
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2016 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.applications.frsync.impl;
+
+import com.google.common.util.concurrent.Futures;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.openflowplugin.applications.frsync.util.RetryRegistry;
+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;
+
+/**
+ * Test for {@link SyncReactorRetryDecorator}
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class SyncReactorRetryDecoratorTest {
+
+    private static final NodeId NODE_ID = new NodeId("test-node");
+    private SyncReactorRetryDecorator reactor;
+    private InstanceIdentifier<FlowCapableNode> fcNodePath;
+    private final LogicalDatastoreType dsType = LogicalDatastoreType.CONFIGURATION;
+
+    @Mock
+    private SyncReactorImpl delegate;
+    @Mock
+    private RetryRegistry retryRegistry;
+    @Mock
+    private FlowCapableNode fcConfigNode;
+    @Mock
+    private FlowCapableNode fcOperationalNode;
+
+    @Before
+    public void setUp() {
+        reactor = new SyncReactorRetryDecorator(delegate, retryRegistry);
+        InstanceIdentifier<Node> nodePath = InstanceIdentifier.create(Nodes.class).child(Node.class, new NodeKey(NODE_ID));
+        fcNodePath = nodePath.augmentation(FlowCapableNode.class);
+
+        final Node operationalNode = Mockito.mock(Node.class);
+        Mockito.when(operationalNode.getId()).thenReturn(NODE_ID);
+        Mockito.when(operationalNode.getAugmentation(FlowCapableNode.class)).thenReturn(fcOperationalNode);
+    }
+
+    @Test
+    public void testSyncupSuccess() throws InterruptedException {
+        Mockito.when(delegate.syncup(Matchers.<InstanceIdentifier<FlowCapableNode>>any(), Matchers.<FlowCapableNode>any(),
+                Matchers.<FlowCapableNode>any(), Matchers.<LogicalDatastoreType>any())).thenReturn(Futures.immediateFuture(Boolean.TRUE));
+
+        reactor.syncup(fcNodePath, fcConfigNode, fcOperationalNode, dsType);
+
+        Mockito.verify(delegate).syncup(fcNodePath, fcConfigNode, fcOperationalNode, dsType);
+        Mockito.verifyNoMoreInteractions(delegate);
+        Mockito.verify(retryRegistry).unregisterIfRegistered(NODE_ID);
+    }
+
+    @Test
+    public void testSyncupFail() throws InterruptedException {
+        Mockito.when(delegate.syncup(Matchers.<InstanceIdentifier<FlowCapableNode>>any(), Matchers.<FlowCapableNode>any(),
+                Matchers.<FlowCapableNode>any(), Matchers.<LogicalDatastoreType>any())).thenReturn(Futures.immediateFuture(Boolean.FALSE));
+
+        reactor.syncup(fcNodePath, fcConfigNode, fcOperationalNode, dsType);
+
+        Mockito.verify(delegate).syncup(fcNodePath, fcConfigNode, fcOperationalNode, dsType);
+        Mockito.verifyNoMoreInteractions(delegate);
+        Mockito.verify(retryRegistry).register(NODE_ID);
+    }
+
+    @Test
+    public void testSyncupConfigIgnoreInRetry() throws InterruptedException {
+        Mockito.when(retryRegistry.isRegistered(NODE_ID)).thenReturn(true);
+
+        reactor.syncup(fcNodePath, fcConfigNode, fcOperationalNode, dsType);
+
+        Mockito.verifyZeroInteractions(delegate);
+    }
+
+}
\ No newline at end of file
index 75a34b81a09920396f4e74a35386c6770217ebd1..99358de3e2b0e71b0b56889bcef398813342af01 100644 (file)
@@ -65,8 +65,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Test for {@link SyncPlanPushStrategyIncrementalImpl}.
@@ -74,8 +72,6 @@ import org.slf4j.LoggerFactory;
 @RunWith(MockitoJUnitRunner.class)
 public class SyncPlanPushStrategyIncrementalImplTest {
 
-    private static final Logger LOG = LoggerFactory.getLogger(SyncPlanPushStrategyIncrementalImplTest.class);
-
     private static final NodeId NODE_ID = new NodeId("unit-nodeId");
     private static final InstanceIdentifier<FlowCapableNode> NODE_IDENT = InstanceIdentifier.create(Nodes.class)
             .child(Node.class, new NodeKey(NODE_ID)).augmentation(FlowCapableNode.class);
index ee09da96ee7447fd94ea482fb237f14537eb5d34..61fd6384b828e844fafbb5af1c2bd972a9313799 100644 (file)
@@ -61,7 +61,7 @@ import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 public class ReconcileUtilTest {
 
     private static final NodeId NODE_ID = new NodeId("unit-node-id");
-    private InstanceIdentifier<Node> NODE_IDENT = InstanceIdentifier.create(Nodes.class)
+    private final InstanceIdentifier<Node> NODE_IDENT = InstanceIdentifier.create(Nodes.class)
             .child(Node.class, new NodeKey(NODE_ID));
     private static final Splitter COMMA_SPLITTER = Splitter.on(",");
 
diff --git a/applications/forwardingrules-sync/src/test/java/org/opendaylight/openflowplugin/applications/frsync/util/RetryRegistryTest.java b/applications/forwardingrules-sync/src/test/java/org/opendaylight/openflowplugin/applications/frsync/util/RetryRegistryTest.java
new file mode 100644 (file)
index 0000000..115bb2c
--- /dev/null
@@ -0,0 +1,55 @@
+/**
+ * Copyright (c) 2016 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.applications.frsync.util;
+
+import java.util.Date;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+
+/**
+ * Test for {@link RetryRegistry}.
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class RetryRegistryTest {
+
+    private static final NodeId NODE_ID = new NodeId("testNode");
+    private RetryRegistry retryRegistry;
+
+    @Before
+    public void setUp() throws Exception {
+        retryRegistry = new RetryRegistry();
+    }
+
+    @Test
+    public void testRegister() {
+        Date timestamp = retryRegistry.register(NODE_ID);
+        Assert.assertEquals(true, retryRegistry.isRegistered(NODE_ID));
+        Assert.assertNotNull(timestamp);
+    }
+
+    @Test
+    public void testUnregisterIfRegistered() {
+        retryRegistry.register(NODE_ID);
+        Date timestamp = retryRegistry.unregisterIfRegistered(NODE_ID);
+        Assert.assertEquals(false, retryRegistry.isRegistered(NODE_ID));
+        Assert.assertNotNull(timestamp);
+    }
+
+    @Test
+    public void testUnregisterIfNotRegistered() {
+        Date timestamp = retryRegistry.unregisterIfRegistered(NODE_ID);
+        Assert.assertEquals(false, retryRegistry.isRegistered(NODE_ID));
+        Assert.assertNull(timestamp);
+    }
+
+}
index b2d38d06ec87c36de820629eb7bbbc4e5f36fae1..8affd2a5b2444bed518cfd6019d796c810d42ef8 100644 (file)
@@ -91,7 +91,7 @@ public class SemaphoreKeeperTest {
             for (int i = 0; i < steps; i++) {
                 executorService.submit(task);
             }
-            Thread.sleep(1000L);
+            Thread.sleep(100L);
             System.gc();
 
             executorService.shutdown();
index 1717f3af4d0ca9a26472600ef6c474a788191629..43074a70bf82f626c4abbf2a6665ac7edb11adc3 100644 (file)
@@ -188,6 +188,10 @@ public class StatRpcMsgManagerImpl implements StatRpcMsgManager {
                     String[] multipartRequestName = result.getResult().getClass().getSimpleName().split("(?=\\p{Upper})");
                     LOG.warn("Node [{}] does not support statistics request type : {}",
                             nodeKey.getId(),Joiner.on(" ").join(Arrays.copyOfRange(multipartRequestName, 2, multipartRequestName.length-2)));
+                    if (resultTransId != null) {
+                        resultTransId.setException(
+                            new UnsupportedOperationException());
+                    }
                 } else {
                     if (resultTransId != null) {
                         resultTransId.set(id);
@@ -202,8 +206,10 @@ public class StatRpcMsgManagerImpl implements StatRpcMsgManager {
             @Override
             public void onFailure(final Throwable t) {
                 LOG.warn("Response Registration for Statistics RPC call fail!", t);
+                if (resultTransId != null) {
+                    resultTransId.setException(t);
+                }
             }
-
         }
 
         Futures.addCallback(JdkFutureAdapters.listenInPoolThread(future),new FutureCallbackImpl());
index 9fa056f00b5cd0803b15ebff5de53546c25cf994..e70f62bddb06542b7009d4fe335941533aecbf3c 100644 (file)
 
             <dependency>
                 <groupId>${project.groupId}</groupId>
-                <artifactId>features-openflowplugin</artifactId>
+                <artifactId>features-openflowplugin-he</artifactId>
                 <version>${project.version}</version>
                 <classifier>features</classifier>
                 <type>xml</type>
             </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
-                <artifactId>features-openflowplugin-li</artifactId>
+                <artifactId>features-openflowplugin</artifactId>
                 <version>${project.version}</version>
                 <classifier>features</classifier>
                 <type>xml</type>
             </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
-                <artifactId>features-openflowplugin-extension</artifactId>
+                <artifactId>features-openflowplugin-extension-he</artifactId>
                 <version>${project.version}</version>
                 <classifier>features</classifier>
                 <type>xml</type>
             </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
-                <artifactId>features-openflowplugin-extension-li</artifactId>
+                <artifactId>features-openflowplugin-extension</artifactId>
                 <version>${project.version}</version>
                 <classifier>features</classifier>
                 <type>xml</type>
index 91b1871efacfec1f6e829c093bca9ddd24c4d9ce..22315d8ede5377d83be0f4bc0c2d6e724ad1a603 100644 (file)
     </dependency>
     <!-- openflowplugin feature -->
     <dependency>
-      <artifactId>features-openflowplugin</artifactId>
+      <artifactId>features-openflowplugin-he</artifactId>
       <groupId>org.opendaylight.openflowplugin</groupId>
       <classifier>features</classifier>
       <type>xml</type>
       <scope>runtime</scope>
     </dependency>
     <dependency>
-      <artifactId>features-openflowplugin-li</artifactId>
+      <artifactId>features-openflowplugin</artifactId>
       <groupId>org.opendaylight.openflowplugin</groupId>
       <classifier>features</classifier>
       <type>xml</type>
     <!-- openflowplugin extension feature -->
     <dependency>
       <groupId>org.opendaylight.openflowplugin</groupId>
-      <artifactId>features-openflowplugin-extension</artifactId>
+      <artifactId>features-openflowplugin-extension-he</artifactId>
       <classifier>features</classifier>
       <type>xml</type>
       <scope>runtime</scope>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.openflowplugin</groupId>
-      <artifactId>features-openflowplugin-extension-li</artifactId>
+      <artifactId>features-openflowplugin-extension</artifactId>
       <classifier>features</classifier>
       <type>xml</type>
       <scope>runtime</scope>
similarity index 94%
rename from extension/features-li/pom.xml
rename to extension/features-he/pom.xml
index 18632cca21ecff770672c96098a68b67aa00de36..a8b77513becf219a03aa27981414ea31f69f6d10 100644 (file)
@@ -9,7 +9,7 @@
   </parent>
   <groupId>org.opendaylight.openflowplugin</groupId>
   <version>0.3.0-SNAPSHOT</version>
-  <artifactId>features-openflowplugin-extension-li</artifactId>
+  <artifactId>features-openflowplugin-extension-he</artifactId>
 
   <packaging>jar</packaging>
 
@@ -34,7 +34,7 @@
     <!-- feature dependencies -->
     <dependency>
       <groupId>org.opendaylight.openflowplugin</groupId>
-      <artifactId>features-openflowplugin-li</artifactId>
+      <artifactId>features-openflowplugin-he</artifactId>
       <classifier>features</classifier>
       <type>xml</type>
     </dependency>
similarity index 82%
rename from extension/features-li/src/main/features/features.xml
rename to extension/features-he/src/main/features/features.xml
index f0434f0b4b21c90043098eb624445d38e2e0d148..52869fa1c117124ae7a60443149c2ce7b87b9533 100644 (file)
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
-<features name="openflowplugin-extension-li-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+<features name="openflowplugin-extension-he-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
-    <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin-li/${project.version}/xml/features</repository>
+    <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin-he/${project.version}/xml/features</repository>
 
-    <feature name="odl-openflowplugin-nxm-extensions-li" description="OpenDaylight :: Openflow Plugin :: Nicira Extensions" version='${project.version}'>
-        <feature version="${project.version}">odl-openflowplugin-southbound-li</feature>
+    <feature name="odl-openflowplugin-nxm-extensions-he" description="OpenDaylight :: Openflow Plugin :: Nicira Extensions" version='${project.version}'>
+        <feature version="${project.version}">odl-openflowplugin-southbound-he</feature>
         <configfile finalname="etc/opendaylight/karaf/43-openflowjava-nx-config.xml">mvn:org.opendaylight.openflowplugin/openflowplugin-extension-nicira-config/{{VERSION}}/xml/config</configfile>
         <bundle>mvn:org.opendaylight.openflowplugin/openflowjava-extension-nicira-api/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.openflowplugin/openflowjava-extension-nicira/{{VERSION}}</bundle>
index 50e4d98563588353248c658e43673aed18128c95..d5dd73e4cf4866031f19a306c143f7072a6a1149 100644 (file)
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>config-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-all</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
index 761dc649cf880ccf6de44cad6339033db84e2e2c..61b4a7248fae8dfcaea28834280dbfde504efd0d 100644 (file)
@@ -83,16 +83,21 @@ public class NiciraExtensionsRegistrator implements AutoCloseable {
         registrator.registerActionSerializer(SetNspCodec.SERIALIZER_KEY, NiciraActionCodecs.SET_NSP_CODEC);
         registrator.registerActionDeserializer(SetNshc1Codec.DESERIALIZER_KEY, NiciraActionCodecs.SET_NSC1_CODEC);
         registrator.registerActionSerializer(SetNshc1Codec.SERIALIZER_KEY, NiciraActionCodecs.SET_NSC1_CODEC);
+        //BUG nshc2 codec is registered with same subtype as Conntrack codec
         registrator.registerActionDeserializer(SetNshc2Codec.DESERIALIZER_KEY, NiciraActionCodecs.SET_NSC2_CODEC);
         registrator.registerActionSerializer(SetNshc2Codec.SERIALIZER_KEY, NiciraActionCodecs.SET_NSC2_CODEC);
+        //Continue
         registrator.registerActionDeserializer(SetNshc3Codec.DESERIALIZER_KEY, NiciraActionCodecs.SET_NSC3_CODEC);
         registrator.registerActionSerializer(SetNshc3Codec.SERIALIZER_KEY, NiciraActionCodecs.SET_NSC3_CODEC);
         registrator.registerActionDeserializer(SetNshc4Codec.DESERIALIZER_KEY, NiciraActionCodecs.SET_NSC4_CODEC);
         registrator.registerActionSerializer(SetNshc4Codec.SERIALIZER_KEY, NiciraActionCodecs.SET_NSC4_CODEC);
         registrator.registerActionDeserializer(SetNsiCodec.DESERIALIZER_KEY, NiciraActionCodecs.SET_NSI_CODEC);
         registrator.registerActionSerializer(SetNsiCodec.SERIALIZER_KEY, NiciraActionCodecs.SET_NSI_CODEC);
+        //BUG Conntrack codec is registered with same subtype as Nshc2 codec
         registrator.registerActionSerializer(ConntrackCodec.SERIALIZER_KEY, NiciraActionCodecs.CONNTRACK_CODEC);
         registrator.registerActionDeserializer(ConntrackCodec.DESERIALIZER_KEY, NiciraActionCodecs.CONNTRACK_CODEC);
+        //Continue
+
 
         registrator.registerMatchEntrySerializer(Reg0Codec.SERIALIZER_KEY, NiciraMatchCodecs.REG0_CODEC);
         registrator.registerMatchEntryDeserializer(Reg0Codec.DESERIALIZER_KEY, NiciraMatchCodecs.REG0_CODEC);
@@ -174,6 +179,8 @@ public class NiciraExtensionsRegistrator implements AutoCloseable {
         registrator.unregisterActionSerializer(SetNsiCodec.SERIALIZER_KEY);
         registrator.unregisterActionDeserializer(SetNspCodec.DESERIALIZER_KEY);
         registrator.unregisterActionSerializer(SetNspCodec.SERIALIZER_KEY);
+        //Added this line (unregisterDeserialize was missing)
+        registrator.unregisterActionDeserializer(SetNshc1Codec.DESERIALIZER_KEY);
         registrator.unregisterActionSerializer(SetNshc1Codec.SERIALIZER_KEY);
         registrator.unregisterActionDeserializer(SetNshc2Codec.DESERIALIZER_KEY);
         registrator.unregisterActionSerializer(SetNshc2Codec.SERIALIZER_KEY);
@@ -181,9 +188,10 @@ public class NiciraExtensionsRegistrator implements AutoCloseable {
         registrator.unregisterActionSerializer(SetNshc3Codec.SERIALIZER_KEY);
         registrator.unregisterActionDeserializer(SetNshc4Codec.DESERIALIZER_KEY);
         registrator.unregisterActionSerializer(SetNshc4Codec.SERIALIZER_KEY);
+        //BUG unregistering with same subtype as Nshc2
         registrator.unregisterActionSerializer(ConntrackCodec.SERIALIZER_KEY);
         registrator.unregisterActionDeserializer(ConntrackCodec.DESERIALIZER_KEY);
-
+        //CONTINUE
         registrator.unregisterMatchEntrySerializer(Reg0Codec.SERIALIZER_KEY);
         registrator.unregisterMatchEntryDeserializer(Reg0Codec.DESERIALIZER_KEY);
         registrator.unregisterMatchEntrySerializer(Reg1Codec.SERIALIZER_KEY);
index 38d3fd208f4d97f45aaf88af436095869862dcb7..ad46e6abf94abcfb1366423de4b86d4cc1269a49 100644 (file)
@@ -44,20 +44,15 @@ public class TcpDstCodec extends AbstractMatchCodec {
         serializeHeader(input, outBuffer);
         TcpDstCaseValue tcpDstCase = ((TcpDstCaseValue) input.getMatchEntryValue());
         outBuffer.writeShort(tcpDstCase.getTcpDstValues().getPort().getValue());
-        outBuffer.writeShort(tcpDstCase.getTcpDstValues().getMask());
     }
 
     @Override
     public MatchEntry deserialize(ByteBuf message) {
         MatchEntryBuilder matchEntryBuilder = deserializeHeader(message);
-        matchEntryBuilder.setHasMask(true);
         int portNo = message.readUnsignedShort();
-        int mask = message.readUnsignedShort();
-        message.readBytes(mask);
         TcpDstCaseValueBuilder caseBuilder = new TcpDstCaseValueBuilder();
         TcpDstValuesBuilder tcpDstValuesBuilder = new TcpDstValuesBuilder();
         tcpDstValuesBuilder.setPort(new PortNumber(portNo));
-        tcpDstValuesBuilder.setMask(portNo);
         caseBuilder.setTcpDstValues(tcpDstValuesBuilder.build());
         matchEntryBuilder.setMatchEntryValue(caseBuilder.build());
         return matchEntryBuilder.build();
@@ -79,9 +74,7 @@ public class TcpDstCodec extends AbstractMatchCodec {
     }
 
     @Override
-    public Class<? extends MatchField> getNxmField() {
-        return NxmOfTcpDst.class;
-    }
+    public Class<? extends MatchField> getNxmField() { return NxmOfTcpDst.class; }
 
     @Override
     public Class<? extends OxmClassBase> getOxmClass() {
index 5c483870a09dc64ed3a07ae5cd467f6bd98e14cb..ec7f57c2be5991da1b9d06b6ee10a25938f09f91 100644 (file)
@@ -43,20 +43,16 @@ public class TcpSrcCodec extends AbstractMatchCodec {
         serializeHeader(input, outBuffer);
         TcpSrcCaseValue tcpSrcCase = ((TcpSrcCaseValue) input.getMatchEntryValue());
         outBuffer.writeShort(tcpSrcCase.getTcpSrcValues().getPort().getValue());
-        outBuffer.writeShort(tcpSrcCase.getTcpSrcValues().getMask());
     }
 
     @Override
     public MatchEntry deserialize(ByteBuf message) {
         MatchEntryBuilder matchEntryBuilder = deserializeHeader(message);
-        matchEntryBuilder.setHasMask(true);
+        matchEntryBuilder.setHasMask(false);
         int portNo = message.readUnsignedShort();
-        int mask = message.readUnsignedShort();
-        message.readBytes(mask);
         TcpSrcCaseValueBuilder caseBuilder = new TcpSrcCaseValueBuilder();
         TcpSrcValuesBuilder tcpSrcValuesBuilder = new TcpSrcValuesBuilder();
         tcpSrcValuesBuilder.setPort(new PortNumber(portNo));
-        tcpSrcValuesBuilder.setMask(portNo);
         caseBuilder.setTcpSrcValues(tcpSrcValuesBuilder.build());
         matchEntryBuilder.setMatchEntryValue(caseBuilder.build());
         return matchEntryBuilder.build();
index 9347dcd7d0fa5b2ee8ec5d3b080bf9eba9c16c88..3bf3d374fea87678f37ea8048f85aa53ac4def9a 100644 (file)
@@ -45,20 +45,16 @@ public class UdpDstCodec extends AbstractMatchCodec {
         serializeHeader(input, outBuffer);
         UdpDstCaseValue udpDstCase = ((UdpDstCaseValue) input.getMatchEntryValue());
         outBuffer.writeShort(udpDstCase.getUdpDstValues().getPort().getValue());
-        outBuffer.writeShort(udpDstCase.getUdpDstValues().getMask());
     }
 
     @Override
     public MatchEntry deserialize(ByteBuf message) {
         MatchEntryBuilder matchEntryBuilder = deserializeHeader(message);
-        matchEntryBuilder.setHasMask(true);
+        matchEntryBuilder.setHasMask(false);
         int portNo = message.readUnsignedShort();
-        int mask = message.readUnsignedShort();
-        message.readBytes(mask);
         UdpDstCaseValueBuilder caseBuilder = new UdpDstCaseValueBuilder();
         UdpDstValuesBuilder udpDstValuesBuilder = new UdpDstValuesBuilder();
         udpDstValuesBuilder.setPort(new PortNumber(portNo));
-        udpDstValuesBuilder.setMask(portNo);
         caseBuilder.setUdpDstValues(udpDstValuesBuilder.build());
         matchEntryBuilder.setMatchEntryValue(caseBuilder.build());
         return matchEntryBuilder.build();
index 44c2e64ea76a811c2125760f0c8a89b9ab371112..0e1ba3ee3d16dce5915039e2615ed03861f96547 100644 (file)
@@ -45,20 +45,16 @@ public class UdpSrcCodec extends AbstractMatchCodec {
         serializeHeader(input, outBuffer);
         UdpSrcCaseValue udpSrcCase = ((UdpSrcCaseValue) input.getMatchEntryValue());
         outBuffer.writeShort(udpSrcCase.getUdpSrcValues().getPort().getValue());
-        outBuffer.writeShort(udpSrcCase.getUdpSrcValues().getMask());
     }
 
     @Override
     public MatchEntry deserialize(ByteBuf message) {
         MatchEntryBuilder matchEntryBuilder = deserializeHeader(message);
-        matchEntryBuilder.setHasMask(true);
+        matchEntryBuilder.setHasMask(false);
         int portNo = message.readUnsignedShort();
-        int mask = message.readUnsignedShort();
-        message.readBytes(mask);
         UdpSrcCaseValueBuilder caseBuilder = new UdpSrcCaseValueBuilder();
         UdpSrcValuesBuilder udpSrcValuesBuilder = new UdpSrcValuesBuilder();
         udpSrcValuesBuilder.setPort(new PortNumber(portNo));
-        udpSrcValuesBuilder.setMask(portNo);
         caseBuilder.setUdpSrcValues(udpSrcValuesBuilder.build());
         matchEntryBuilder.setMatchEntryValue(caseBuilder.build());
         return matchEntryBuilder.build();
diff --git a/extension/openflowjava-extension-nicira/src/test/java/org/opendaylight/openflowjava/nx/NiciraExtensionsRegistratorTest.java b/extension/openflowjava-extension-nicira/src/test/java/org/opendaylight/openflowjava/nx/NiciraExtensionsRegistratorTest.java
new file mode 100644 (file)
index 0000000..04c45f0
--- /dev/null
@@ -0,0 +1,301 @@
+/**
+ * Copyright (c) 2016 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.openflowjava.nx;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.openflowjava.nx.api.NiciraActionDeserializerKey;
+import org.opendaylight.openflowjava.nx.api.NiciraActionSerializerKey;
+import org.opendaylight.openflowjava.nx.api.NiciraExtensionCodecRegistrator;
+import org.opendaylight.openflowjava.nx.codec.action.MultipathCodec;
+import org.opendaylight.openflowjava.nx.codec.action.OutputRegCodec;
+import org.opendaylight.openflowjava.nx.codec.action.RegLoadCodec;
+import org.opendaylight.openflowjava.nx.codec.action.RegMoveCodec;
+import org.opendaylight.openflowjava.nx.codec.action.ResubmitCodec;
+import org.opendaylight.openflowjava.nx.codec.action.SetNshc1Codec;
+import org.opendaylight.openflowjava.nx.codec.action.SetNshc3Codec;
+import org.opendaylight.openflowjava.nx.codec.action.SetNshc4Codec;
+import org.opendaylight.openflowjava.nx.codec.action.SetNsiCodec;
+import org.opendaylight.openflowjava.nx.codec.action.SetNspCodec;
+import org.opendaylight.openflowjava.nx.codec.match.ArpOpCodec;
+import org.opendaylight.openflowjava.nx.codec.match.ArpShaCodec;
+import org.opendaylight.openflowjava.nx.codec.match.ArpSpaCodec;
+import org.opendaylight.openflowjava.nx.codec.match.ArpThaCodec;
+import org.opendaylight.openflowjava.nx.codec.match.ArpTpaCodec;
+import org.opendaylight.openflowjava.nx.codec.match.CtStateCodec;
+import org.opendaylight.openflowjava.nx.codec.match.CtZoneCodec;
+import org.opendaylight.openflowjava.nx.codec.match.EthDstCodec;
+import org.opendaylight.openflowjava.nx.codec.match.EthSrcCodec;
+import org.opendaylight.openflowjava.nx.codec.match.EthTypeCodec;
+import org.opendaylight.openflowjava.nx.codec.match.Nshc1Codec;
+import org.opendaylight.openflowjava.nx.codec.match.Nshc2Codec;
+import org.opendaylight.openflowjava.nx.codec.match.Nshc3Codec;
+import org.opendaylight.openflowjava.nx.codec.match.Nshc4Codec;
+import org.opendaylight.openflowjava.nx.codec.match.NsiCodec;
+import org.opendaylight.openflowjava.nx.codec.match.NspCodec;
+import org.opendaylight.openflowjava.nx.codec.match.Reg0Codec;
+import org.opendaylight.openflowjava.nx.codec.match.Reg1Codec;
+import org.opendaylight.openflowjava.nx.codec.match.Reg2Codec;
+import org.opendaylight.openflowjava.nx.codec.match.Reg3Codec;
+import org.opendaylight.openflowjava.nx.codec.match.Reg4Codec;
+import org.opendaylight.openflowjava.nx.codec.match.Reg5Codec;
+import org.opendaylight.openflowjava.nx.codec.match.Reg6Codec;
+import org.opendaylight.openflowjava.nx.codec.match.Reg7Codec;
+import org.opendaylight.openflowjava.nx.codec.match.TcpDstCodec;
+import org.opendaylight.openflowjava.nx.codec.match.TcpSrcCodec;
+import org.opendaylight.openflowjava.nx.codec.match.TunIdCodec;
+import org.opendaylight.openflowjava.nx.codec.match.TunIpv4DstCodec;
+import org.opendaylight.openflowjava.nx.codec.match.TunIpv4SrcCodec;
+import org.opendaylight.openflowjava.nx.codec.match.UdpDstCodec;
+import org.opendaylight.openflowjava.nx.codec.match.UdpSrcCodec;
+import org.opendaylight.openflowjava.protocol.api.keys.MatchEntryDeserializerKey;
+import org.opendaylight.openflowjava.protocol.api.keys.MatchEntrySerializerKey;
+import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
+import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Nxm0Class;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Nxm1Class;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionConntrack;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionMultipath;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionOutputReg;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegLoad;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegMove;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionResubmit;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionSetNshc1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionSetNshc3;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionSetNshc4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionSetNsi;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionSetNsp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxArpSha;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxArpTha;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxCtState;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxCtZone;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxNshc1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxNshc2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxNshc3;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxNshc4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxNsi;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxNsp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg3;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg5;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxTunId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxTunIpv4Dst;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxTunIpv4Src;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmOfArpOp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmOfArpSpa;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmOfArpTpa;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmOfEthDst;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmOfEthSrc;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmOfEthType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmOfTcpDst;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmOfTcpSrc;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmOfUdpDst;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmOfUdpSrc;
+
+@RunWith(MockitoJUnitRunner.class)
+public class NiciraExtensionsRegistratorTest {
+
+    NiciraExtensionsRegistrator niciraExtensionsRegistrator;
+
+    @Mock
+    NiciraExtensionCodecRegistrator registrator;
+
+    @Before
+    public void setUp() {
+        niciraExtensionsRegistrator = new NiciraExtensionsRegistrator(registrator);
+    }
+
+    @Test
+    public void registerNiciraExtensionsTest() {
+        niciraExtensionsRegistrator.registerNiciraExtensions();
+
+        Mockito.verify(registrator).registerActionDeserializer(Matchers.eq(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 7)), Matchers.any(RegLoadCodec.class));
+        Mockito.verify(registrator).registerActionSerializer(Matchers.eq(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionRegLoad.class)), Matchers.any(RegLoadCodec.class));
+        Mockito.verify(registrator).registerActionDeserializer(Matchers.eq(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 6)), Matchers.any(RegMoveCodec.class));
+        Mockito.verify(registrator).registerActionSerializer(Matchers.eq(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionRegMove.class)), Matchers.any(RegMoveCodec.class));
+        Mockito.verify(registrator).registerActionDeserializer(Matchers.eq(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 15)), Matchers.any(OutputRegCodec.class));
+        Mockito.verify(registrator).registerActionSerializer(Matchers.eq(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionOutputReg.class)), Matchers.any(OutputRegCodec.class));
+        Mockito.verify(registrator).registerActionSerializer(Matchers.eq(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionResubmit.class)), Matchers.any(ResubmitCodec.class));
+        Mockito.verify(registrator).registerActionDeserializer(Matchers.eq(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 1)), Matchers.any(ResubmitCodec.class));
+        Mockito.verify(registrator).registerActionDeserializer(Matchers.eq(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 14)), Matchers.any(ResubmitCodec.class));
+        Mockito.verify(registrator).registerActionSerializer(Matchers.eq(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionMultipath.class)), Matchers.any(MultipathCodec.class));
+        Mockito.verify(registrator).registerActionDeserializer(Matchers.eq(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 10)), Matchers.any(MultipathCodec.class));
+        Mockito.verify(registrator).registerActionDeserializer(Matchers.eq(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 32)), Matchers.any(SetNspCodec.class));
+        Mockito.verify(registrator).registerActionSerializer(Matchers.eq(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionSetNsp.class)), Matchers.any(SetNspCodec.class));
+        Mockito.verify(registrator).registerActionDeserializer(Matchers.eq(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 34)), Matchers.any(SetNshc1Codec.class));
+        Mockito.verify(registrator).registerActionSerializer(Matchers.eq(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionSetNshc1.class)), Matchers.any(SetNshc1Codec.class));
+        Mockito.verify(registrator).registerActionDeserializer(Matchers.eq(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 36)), Matchers.any(SetNshc3Codec.class));
+        Mockito.verify(registrator).registerActionSerializer(Matchers.eq(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionSetNshc3.class)), Matchers.any(SetNshc3Codec.class));
+        Mockito.verify(registrator).registerActionDeserializer(Matchers.eq(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 37)), Matchers.any(SetNshc4Codec.class));
+        Mockito.verify(registrator).registerActionSerializer(Matchers.eq(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionSetNshc4.class)), Matchers.any(SetNshc4Codec.class));
+        Mockito.verify(registrator).registerActionDeserializer(Matchers.eq(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 33)), Matchers.any(SetNsiCodec.class));
+        Mockito.verify(registrator).registerActionSerializer(Matchers.eq(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionSetNsi.class)), Matchers.any(SetNsiCodec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxReg0.class)), Matchers.any(Reg0Codec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 0)), Matchers.any(Reg0Codec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxReg1.class)), Matchers.any(Reg1Codec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 1)), Matchers.any(Reg1Codec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxReg2.class)), Matchers.any(Reg2Codec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 2)), Matchers.any(Reg2Codec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxReg3.class)), Matchers.any(Reg3Codec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 3)), Matchers.any(Reg3Codec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxReg4.class)), Matchers.any(Reg4Codec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 4)), Matchers.any(Reg4Codec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxReg5.class)), Matchers.any(Reg5Codec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 5)), Matchers.any(Reg5Codec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxReg6.class)), Matchers.any(Reg6Codec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 6)), Matchers.any(Reg6Codec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxReg7.class)), Matchers.any(Reg7Codec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 7)), Matchers.any(Reg7Codec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxTunId.class)), Matchers.any(TunIdCodec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 16)), Matchers.any(TunIdCodec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm0Class.class, NxmOfArpOp.class)), Matchers.any(ArpOpCodec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_0_CLASS, 15)), Matchers.any(ArpOpCodec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxArpSha.class)), Matchers.any(ArpShaCodec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 17)), Matchers.any(ArpShaCodec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm0Class.class, NxmOfArpSpa.class)), Matchers.any(ArpSpaCodec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_0_CLASS, 16)), Matchers.any(ArpSpaCodec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxArpTha.class)), Matchers.any(ArpThaCodec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 18)), Matchers.any(ArpThaCodec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm0Class.class, NxmOfArpTpa.class)), Matchers.any(ArpTpaCodec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_0_CLASS, 17)), Matchers.any(ArpTpaCodec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm0Class.class, NxmOfEthDst.class)), Matchers.any(EthDstCodec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_0_CLASS, 1)), Matchers.any(EthDstCodec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm0Class.class, NxmOfEthSrc.class)), Matchers.any(EthSrcCodec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_0_CLASS, 2)), Matchers.any(EthSrcCodec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm0Class.class, NxmOfEthType.class)), Matchers.any(EthTypeCodec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_0_CLASS, 3)), Matchers.any(EthTypeCodec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxNsp.class)), Matchers.any(NspCodec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 37)), Matchers.any(NspCodec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxNshc1.class)), Matchers.any(Nshc1Codec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 39)), Matchers.any(Nshc1Codec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxNshc2.class)), Matchers.any(Nshc2Codec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 40)), Matchers.any(Nshc2Codec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxNshc3.class)), Matchers.any(Nshc3Codec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 41)), Matchers.any(Nshc3Codec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxNshc4.class)), Matchers.any(Nshc4Codec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 42)), Matchers.any(Nshc4Codec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxNsi.class)), Matchers.any(NsiCodec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 38)), Matchers.any(NsiCodec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxTunIpv4Dst.class)), Matchers.any(TunIpv4DstCodec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 32)), Matchers.any(TunIpv4DstCodec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxTunIpv4Src.class)), Matchers.any(TunIpv4SrcCodec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 31)), Matchers.any(TunIpv4SrcCodec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm0Class.class, NxmOfTcpSrc.class)), Matchers.any(TcpSrcCodec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_0_CLASS, 9)), Matchers.any(TcpSrcCodec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm0Class.class, NxmOfTcpDst.class)), Matchers.any(TcpDstCodec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_0_CLASS, 10)), Matchers.any(TcpDstCodec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm0Class.class, NxmOfUdpSrc.class)), Matchers.any(UdpSrcCodec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_0_CLASS, 11)), Matchers.any(UdpSrcCodec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm0Class.class, NxmOfUdpDst.class)), Matchers.any(UdpDstCodec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_0_CLASS, 12)), Matchers.any(UdpDstCodec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxCtState.class)), Matchers.any(CtStateCodec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 105)), Matchers.any(CtStateCodec.class));
+        Mockito.verify(registrator).registerMatchEntrySerializer(Matchers.eq(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxCtZone.class)), Matchers.any(CtZoneCodec.class));
+        Mockito.verify(registrator).registerMatchEntryDeserializer(Matchers.eq(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 106)), Matchers.any(CtZoneCodec.class));
+    }
+
+    @Test
+    public void unregisterExtensionsTest() {
+        niciraExtensionsRegistrator.unregisterExtensions();
+
+        Mockito.verify(registrator).unregisterActionDeserializer(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 7));
+        Mockito.verify(registrator).unregisterActionSerializer(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionRegLoad.class));
+        Mockito.verify(registrator).unregisterActionDeserializer(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 6));
+        Mockito.verify(registrator).unregisterActionSerializer(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionRegMove.class));
+        Mockito.verify(registrator).unregisterActionDeserializer(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 15));
+        Mockito.verify(registrator).unregisterActionSerializer(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionOutputReg.class));
+        Mockito.verify(registrator).unregisterActionDeserializer(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 1));
+        Mockito.verify(registrator).unregisterActionDeserializer(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 14));
+        Mockito.verify(registrator).unregisterActionSerializer(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionResubmit.class));
+        Mockito.verify(registrator).unregisterActionDeserializer(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 10));
+        Mockito.verify(registrator).unregisterActionSerializer(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionMultipath.class));
+        Mockito.verify(registrator).unregisterActionDeserializer(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 33));
+        Mockito.verify(registrator).unregisterActionSerializer(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionSetNsi.class));
+        Mockito.verify(registrator).unregisterActionDeserializer(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 32));
+        Mockito.verify(registrator).unregisterActionSerializer(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionSetNsp.class));
+        Mockito.verify(registrator).unregisterActionDeserializer(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 34));
+        Mockito.verify(registrator).unregisterActionSerializer(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionSetNshc1.class));
+        Mockito.verify(registrator).unregisterActionDeserializer(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 36));
+        Mockito.verify(registrator).unregisterActionSerializer(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionSetNshc3.class));
+        Mockito.verify(registrator).unregisterActionDeserializer(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 37));
+        Mockito.verify(registrator).unregisterActionSerializer(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionSetNshc4.class));
+        Mockito.verify(registrator).unregisterActionSerializer(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionConntrack.class));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxReg0.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 0));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxReg1.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 1));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxReg2.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 2));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxReg3.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 3));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxReg4.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 4));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxReg5.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 5));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxReg6.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 6));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxReg7.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 7));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxTunId.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 16));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm0Class.class, NxmOfArpOp.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_0_CLASS, 15));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxArpSha.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 17));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm0Class.class, NxmOfArpSpa.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_0_CLASS, 16));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxArpTha.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 18));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm0Class.class, NxmOfArpTpa.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_0_CLASS, 17));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm0Class.class, NxmOfEthDst.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_0_CLASS, 1));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm0Class.class, NxmOfEthSrc.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_0_CLASS, 2));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm0Class.class, NxmOfEthType.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_0_CLASS, 3));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxNsp.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 37));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxNsi.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 38));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxNshc1.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 39));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxNshc2.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 40));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxNshc3.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 41));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxNshc4.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 42));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxTunIpv4Dst.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 32));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxTunIpv4Src.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 31));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm0Class.class, NxmOfTcpSrc.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_0_CLASS, 9));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm0Class.class, NxmOfTcpDst.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_0_CLASS, 10));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm0Class.class, NxmOfUdpSrc.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_0_CLASS, 11));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm0Class.class, NxmOfUdpDst.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_0_CLASS, 12));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxCtState.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 105));
+        Mockito.verify(registrator).unregisterMatchEntrySerializer(new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, Nxm1Class.class, NxmNxCtZone.class));
+        Mockito.verify(registrator).unregisterMatchEntryDeserializer(new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.NXM_1_CLASS, 106));
+    }
+}
index 1195d5eb3b419df0c58be9148347100a3080a837..f71839f4fb2e42ce0719c579fc168dbcd69e91c3 100644 (file)
@@ -18,8 +18,8 @@
         <module>openflowplugin-extension-api</module>
         <module>openflowplugin-extension-nicira</module>
         <module>openflowplugin-extension-nicira-config</module>
+        <module>features-he</module>
         <module>features</module>
-        <module>features-li</module>
         <module>test-extension</module>
     </modules>
 </project>
similarity index 92%
rename from features-li/pom.xml
rename to features-he/pom.xml
index acfdf568d386aa3fa3768654247d3bf83c1e2486..ef1ceec9f72414bcbff242940db58ca88b3e42aa 100644 (file)
@@ -10,7 +10,7 @@
     </parent>
 
     <groupId>org.opendaylight.openflowplugin</groupId>
-    <artifactId>features-openflowplugin-li</artifactId>
+    <artifactId>features-openflowplugin-he</artifactId>
     <packaging>jar</packaging>
     <version>0.3.0-SNAPSHOT</version>
 
@@ -22,7 +22,6 @@
         <openflowplugin.version>0.3.0-SNAPSHOT</openflowplugin.version>
         <dlux.version>0.4.0-SNAPSHOT</dlux.version>
         <lldp.version>0.11.0-SNAPSHOT</lldp.version>
-
         <config.configfile.directory>etc/opendaylight/karaf</config.configfile.directory>
         <restconf.version>1.4.0-SNAPSHOT</restconf.version>
         <mdsal.model.version>0.9.0-SNAPSHOT</mdsal.model.version>
             <groupId>org.opendaylight.openflowplugin.applications</groupId>
             <artifactId>forwardingrules-manager</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.opendaylight.openflowplugin.applications</groupId>
-            <artifactId>forwardingrules-sync</artifactId>
-        </dependency>
         <dependency>
             <groupId>org.opendaylight.openflowplugin.applications</groupId>
             <artifactId>inventory-manager</artifactId>
             <groupId>org.opendaylight.openflowplugin.applications</groupId>
             <artifactId>statistics-manager</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.opendaylight.openflowplugin</groupId>
-            <artifactId>openflowplugin-blueprint-config</artifactId>
-            <version>${project.version}</version>
-        </dependency>
 
         <dependency>
             <groupId>org.opendaylight.dlux</groupId>
             <groupId>org.opendaylight.openflowplugin</groupId>
             <artifactId>openflowplugin-impl</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.openflowplugin</groupId>
+            <artifactId>openflowplugin-blueprint-config-he</artifactId>
+            <version>${project.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.openflowplugin.applications</groupId>
             <artifactId>table-miss-enforcer</artifactId>
             <groupId>org.opendaylight.openflowplugin</groupId>
             <artifactId>openflowplugin-controller-config</artifactId>
             <type>xml</type>
-            <classifier>config-Li</classifier>
+            <classifier>config-He</classifier>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.openflowplugin</groupId>
             <type>xml</type>
             <classifier>config</classifier>
         </dependency>
-        <dependency>
-            <groupId>org.opendaylight.openflowplugin.applications</groupId>
-            <artifactId>notification-supplier</artifactId>
-            <type>xml</type>
-            <classifier>config</classifier>
-        </dependency>
-        <dependency>
-            <groupId>org.opendaylight.openflowplugin.applications</groupId>
-            <artifactId>notification-supplier</artifactId>
-        </dependency>
     </dependencies>
 </project>
similarity index 69%
rename from features-li/src/main/features/features.xml
rename to features-he/src/main/features/features.xml
index f8f4c04297ded2c5ff1278ac02f6729f351759a7..a581af2ef2cfb7d5ac66633876db4e80e226c449 100644 (file)
@@ -8,9 +8,9 @@
   ~ and is available at http://www.eclipse.org/legal/epl-v10.html
   -->
 
-<features name="openflowplugin-li-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
-          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-          xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+<features name="openflowplugin-he-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
     <repository>mvn:org.opendaylight.controller/features-mdsal/${mdsal.version}/xml/features</repository>
     <repository>mvn:org.opendaylight.netconf/features-restconf/${restconf.version}/xml/features</repository>
     <repository>mvn:org.opendaylight.openflowjava/features-openflowjava/${openflowjava.version}/xml/features</repository>
     <repository>mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features</repository>
     <repository>mvn:org.opendaylight.mdsal.model/features-mdsal-model/${mdsal.model.version}/xml/features</repository>
 
-
-    <feature name='odl-openflowplugin-all-li' description="OpenDaylight :: Openflow Plugin :: All" version='${project.version}'>
-        <feature version="${project.version}">odl-openflowplugin-southbound-li</feature>
-        <feature version="${project.version}">odl-openflowplugin-flow-services-li</feature>
-        <feature version="${project.version}">odl-openflowplugin-flow-services-rest-li</feature>
-        <feature version="${project.version}">odl-openflowplugin-flow-services-ui-li</feature>
+    <feature name='odl-openflowplugin-all-he' description="OpenDaylight :: Openflow Plugin :: All" version='${project.version}'>
+        <feature version="${project.version}">odl-openflowplugin-southbound-he</feature>
+        <feature version="${project.version}">odl-openflowplugin-flow-services-he</feature>
+        <feature version="${project.version}">odl-openflowplugin-flow-services-rest-he</feature>
+        <feature version="${project.version}">odl-openflowplugin-flow-services-ui-he</feature>
     </feature>
 
-    <feature name='odl-openflowplugin-southbound-li' description="OpenDaylight :: Openflow Plugin :: Li southBound API implementation " version='${project.version}'>
+    <feature name='odl-openflowplugin-southbound-he' description="OpenDaylight :: Openflow Plugin :: SouthBound" version='${project.version}'>
         <feature version="${mdsal.version}">odl-mdsal-broker</feature>
-        <feature version="${project.version}">odl-openflowplugin-nsf-services-li</feature>
+        <feature version="${project.version}">odl-openflowplugin-nsf-model-he</feature>
         <feature version="${openflowjava.version}">odl-openflowjava-protocol</feature>
         <bundle>mvn:org.opendaylight.openflowplugin/openflowplugin-common/{{VERSION}}</bundle>
-        <bundle>mvn:org.opendaylight.openflowplugin/openflowplugin-api/{{VERSION}}</bundle>
-        <!-- TODO : remove dependency on openflowplugin in the future -->
         <bundle>mvn:org.opendaylight.openflowplugin/openflowplugin/{{VERSION}}</bundle>
-        <bundle>mvn:org.opendaylight.openflowplugin/openflowplugin-impl/{{VERSION}}</bundle>
+        <bundle>mvn:org.opendaylight.openflowplugin/openflowplugin-api/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.openflowplugin/openflowplugin-extension-api/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.controller/liblldp/{{VERSION}}</bundle>
-        <bundle>mvn:org.opendaylight.openflowplugin/openflowplugin-blueprint-config/{{VERSION}}</bundle>
-        <configfile finalname="etc/opendaylight/karaf/42-openflowplugin-Li.xml">mvn:org.opendaylight.openflowplugin/openflowplugin-controller-config/{{VERSION}}/xml/config-Li</configfile>
+        <bundle>mvn:org.opendaylight.openflowplugin.applications/inventory-manager/{{VERSION}}</bundle>
+        <bundle>mvn:org.opendaylight.openflowplugin.applications/statistics-manager/{{VERSION}}</bundle>
+        <bundle>mvn:org.opendaylight.openflowplugin/openflowplugin-blueprint-config-he/{{VERSION}}</bundle>
+        <configfile finalname="etc/opendaylight/karaf/42-openflowplugin-He.xml">mvn:org.opendaylight.openflowplugin/openflowplugin-controller-config/{{VERSION}}/xml/config-He</configfile>
+        <configfile finalname="etc/opendaylight/karaf/43-msg-spy.xml">mvn:org.opendaylight.openflowplugin/openflowplugin-controller-config/{{VERSION}}/xml/configmsgspy</configfile>
     </feature>
 
-    <feature name='odl-openflowplugin-flow-services-li' description="OpenDaylight :: Openflow Plugin :: Flow Services" version='${project.version}'>
-        <feature version="${project.version}">odl-openflowplugin-southbound-li</feature>
-        <feature version="${project.version}">odl-openflowplugin-app-config-pusher-li</feature>
-        <feature version="${project.version}">odl-openflowplugin-app-lldp-speaker-li</feature>
-        <feature version="${project.version}">odl-openflowplugin-nsf-services-li</feature>
-
+    <feature name='odl-openflowplugin-flow-services-he' description="OpenDaylight :: Openflow Plugin :: Flow Services" version='${project.version}'>
+        <feature version="${project.version}">odl-openflowplugin-southbound-he</feature>
+        <feature version="${project.version}">odl-openflowplugin-app-config-pusher-he</feature>
+        <feature version="${project.version}">odl-openflowplugin-app-lldp-speaker-he</feature>
+        <feature version="${project.version}">odl-openflowplugin-nsf-services-he</feature>
     </feature>
 
-    <feature name='odl-openflowplugin-nsf-services-li' version='${project.version}'
-             description="OpenDaylight :: OpenflowPlugin :: NSF :: Services">
+    <feature name='odl-openflowplugin-nsf-services-he' version='${project.version}'
+        description="OpenDaylight :: OpenflowPlugin :: NSF :: Services">
         <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
-        <feature version='${project.version}'>odl-openflowplugin-nsf-model-li</feature>
+        <feature version='${project.version}'>odl-openflowplugin-nsf-model-he</feature>
         <bundle>mvn:org.opendaylight.openflowplugin/openflowplugin-common/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.openflowplugin.applications/topology-manager/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.openflowplugin.applications/topology-lldp-discovery/{{VERSION}}</bundle>
@@ -60,8 +59,8 @@
         <bundle>mvn:org.opendaylight.controller/liblldp/{{VERSION}}</bundle>
     </feature>
 
-    <feature name='odl-openflowplugin-nsf-model-li' version='${project.version}'
-             description="OpenDaylight :: OpenflowPlugin :: NSF :: Model">
+    <feature name='odl-openflowplugin-nsf-model-he' version='${project.version}'
+        description="OpenDaylight :: OpenflowPlugin :: NSF :: Model">
         <!-- general models -->
         <feature version='${mdsal.model.version}'>odl-mdsal-models</feature>
        <bundle>mvn:org.opendaylight.controller.model/model-inventory/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.openflowplugin.model/model-flow-service/{{VERSION}}</bundle>
     </feature>
 
-    <feature name='odl-openflowplugin-flow-services-rest-li' description="OpenDaylight :: Openflow Plugin :: Flow Services :: REST" version='${project.version}'>
-        <feature version="${project.version}">odl-openflowplugin-flow-services-li</feature>
+    <feature name='odl-openflowplugin-flow-services-rest-he' description="OpenDaylight :: Openflow Plugin :: Flow Services :: REST" version='${project.version}'>
+        <feature version="${project.version}">odl-openflowplugin-flow-services-he</feature>
         <feature version="${restconf.version}">odl-restconf</feature>
     </feature>
-    <feature name='odl-openflowplugin-flow-services-ui-li' description="OpenDaylight :: Openflow Plugin :: Flow Services :: UI" version='${project.version}'>
-        <feature version="${project.version}">odl-openflowplugin-flow-services-rest-li</feature>
+    <feature name='odl-openflowplugin-flow-services-ui-he' description="OpenDaylight :: Openflow Plugin :: Flow Services :: UI" version='${project.version}'>
+        <feature version="${project.version}">odl-openflowplugin-flow-services-rest-he</feature>
         <feature version="${dlux.version}">odl-dlux-core</feature>
         <feature version="${restconf.version}">odl-mdsal-apidocs</feature>
         <feature version="${mdsal.version}">odl-mdsal-xsql</feature>
     </feature>
 
     <!-- CBENCH TESTING -->
-    <feature name='odl-openflowplugin-drop-test-li' description="OpenDaylight :: Openflow Plugin :: Drop Test" version='${project.version}'>
-        <feature version="${project.version}">odl-openflowplugin-flow-services-li</feature>
+    <feature name='odl-openflowplugin-drop-test-he' description="OpenDaylight :: Openflow Plugin :: Drop Test" version='${project.version}'>
+        <feature version="${project.version}">odl-openflowplugin-flow-services-he</feature>
         <bundle>mvn:org.opendaylight.openflowplugin/test-common/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.openflowplugin/drop-test-karaf/{{VERSION}}</bundle>
     </feature>
 
     <!-- APPLICATIONS -->
-    <feature name='odl-openflowplugin-app-table-miss-enforcer-li' description="OpenDaylight :: Openflow Plugin :: Application - table-miss-enforcer" version='${project.version}'>
-        <feature version="${project.version}">odl-openflowplugin-southbound-li</feature>
+    <feature name='odl-openflowplugin-app-table-miss-enforcer-he' description="OpenDaylight :: Openflow Plugin :: Application - table-miss-enforcer" version='${project.version}'>
+        <feature version="${project.version}">odl-openflowplugin-southbound-he</feature>
         <bundle>mvn:org.opendaylight.openflowplugin.applications/table-miss-enforcer/{{VERSION}}</bundle>
     </feature>
-    <feature name='odl-openflowplugin-app-config-pusher-li' description="OpenDaylight :: Openflow Plugin :: app - default config-pusher" version='${project.version}'>
-        <feature version="${project.version}">odl-openflowplugin-southbound-li</feature>
+    <feature name='odl-openflowplugin-app-config-pusher-he' description="OpenDaylight :: Openflow Plugin :: app - default config-pusher" version='${project.version}'>
+        <feature version="${project.version}">odl-openflowplugin-southbound-he</feature>
         <bundle>mvn:org.opendaylight.openflowplugin.applications/of-switch-config-pusher/{{VERSION}}</bundle>
     </feature>
 
-    <feature name='odl-openflowplugin-app-lldp-speaker-li' description="OpenDaylight :: Openflow Plugin :: app lldp-speaker" version='${project.version}'>
-        <feature version="${project.version}">odl-openflowplugin-southbound-li</feature>
+    <feature name='odl-openflowplugin-app-lldp-speaker-he' description="OpenDaylight :: Openflow Plugin :: app lldp-speaker" version='${project.version}'>
+        <feature version="${project.version}">odl-openflowplugin-southbound-he</feature>
+        <bundle>mvn:org.opendaylight.openflowplugin.applications/topology-lldp-discovery/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.openflowplugin.applications/lldp-speaker/{{VERSION}}</bundle>
     </feature>
 
-    <feature name='odl-openflowplugin-app-bulk-o-matic-li' description="OpenDaylight :: Openflow Plugin :: app bulk flow operations support" version='${project.version}'>
-        <feature version="${project.version}">odl-openflowplugin-southbound-li</feature>
-        <bundle>mvn:org.opendaylight.openflowplugin.applications/bulk-o-matic/${project.version}</bundle>
-        <configfile finalname="etc/opendaylight/karaf/71-bulk-o-matic.xml">mvn:org.opendaylight.openflowplugin.applications/bulk-o-matic/${project.version}/xml/config</configfile>
-    </feature>
-
-    <feature name='odl-openflowplugin-notifications-li' description="OpenDaylight :: Openflow Plugin :: app notifications supplier" version='${project.version}'>
-        <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
-        <feature version="${project.version}">odl-openflowplugin-nsf-model-li</feature>
-        <bundle>mvn:org.opendaylight.openflowplugin.applications/notification-supplier/{{VERSION}}</bundle>
-        <configfile finalname="etc/opendaylight/karaf/73-notification-supplier.xml">mvn:org.opendaylight.openflowplugin.applications/notification-supplier/{{VERSION}}/xml/config</configfile>
+    <feature name='odl-openflowplugin-app-bulk-o-matic-he' description="OpenDaylight :: Openflow Plugin :: app bulk flow operations support" version='${project.version}'>
+        <feature version="${project.version}">odl-openflowplugin-southbound-he</feature>
+        <bundle>mvn:org.opendaylight.openflowplugin.applications/bulk-o-matic/{{VERSION}}</bundle>
+        <configfile finalname="etc/opendaylight/karaf/71-bulk-o-matic.xml">mvn:org.opendaylight.openflowplugin.applications/bulk-o-matic/{{VERSION}}/xml/config</configfile>
     </feature>
 
 </features>
index f4acbcca3bfd49adbbd63551d8b2e7ae202a4066..f375253e25d77663c9d8ce4b669e622ba5b90dd5 100644 (file)
@@ -22,7 +22,6 @@
         <openflowplugin.version>0.3.0-SNAPSHOT</openflowplugin.version>
         <dlux.version>0.4.0-SNAPSHOT</dlux.version>
         <lldp.version>0.11.0-SNAPSHOT</lldp.version>
-
         <config.configfile.directory>etc/opendaylight/karaf</config.configfile.directory>
         <restconf.version>1.4.0-SNAPSHOT</restconf.version>
         <mdsal.model.version>0.9.0-SNAPSHOT</mdsal.model.version>
             <groupId>org.opendaylight.openflowplugin.applications</groupId>
             <artifactId>forwardingrules-manager</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.openflowplugin.applications</groupId>
+            <artifactId>forwardingrules-sync</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.openflowplugin.applications</groupId>
             <artifactId>inventory-manager</artifactId>
             <groupId>org.opendaylight.openflowplugin.applications</groupId>
             <artifactId>statistics-manager</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.openflowplugin</groupId>
+            <artifactId>openflowplugin-blueprint-config</artifactId>
+            <version>${project.version}</version>
+        </dependency>
 
         <dependency>
             <groupId>org.opendaylight.dlux</groupId>
             <groupId>org.opendaylight.openflowplugin</groupId>
             <artifactId>openflowplugin-impl</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.opendaylight.openflowplugin</groupId>
-            <artifactId>openflowplugin-blueprint-config-he</artifactId>
-            <version>${project.version}</version>
-        </dependency>
         <dependency>
             <groupId>org.opendaylight.openflowplugin.applications</groupId>
             <artifactId>table-miss-enforcer</artifactId>
             <groupId>org.opendaylight.openflowplugin.applications</groupId>
             <artifactId>topology-lldp-discovery</artifactId>
         </dependency>
+
         <dependency>
             <groupId>org.opendaylight.openflowplugin.applications</groupId>
             <artifactId>topology-manager</artifactId>
             <groupId>org.opendaylight.openflowplugin</groupId>
             <artifactId>openflowplugin-controller-config</artifactId>
             <type>xml</type>
-            <classifier>config-He</classifier>
+            <classifier>config-Li</classifier>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.openflowplugin</groupId>
             <type>xml</type>
             <classifier>config</classifier>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.openflowplugin.applications</groupId>
+            <artifactId>notification-supplier</artifactId>
+            <type>xml</type>
+            <classifier>config</classifier>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.openflowplugin.applications</groupId>
+            <artifactId>notification-supplier</artifactId>
+        </dependency>
     </dependencies>
 
-    <scm>
-        <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
-        <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
-        <tag>HEAD</tag>
-        <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
-    </scm>
 </project>
index 4e15c5c09641fdf808e7c5dde23de42d56595323..02dc31fa816a0e7830a23dd691a4dcfcc29423ec 100644 (file)
@@ -9,8 +9,8 @@
   -->
 
 <features name="openflowplugin-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
-   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-   xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
     <repository>mvn:org.opendaylight.controller/features-mdsal/${mdsal.version}/xml/features</repository>
     <repository>mvn:org.opendaylight.netconf/features-restconf/${restconf.version}/xml/features</repository>
     <repository>mvn:org.opendaylight.openflowjava/features-openflowjava/${openflowjava.version}/xml/features</repository>
@@ -18,6 +18,7 @@
     <repository>mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features</repository>
     <repository>mvn:org.opendaylight.mdsal.model/features-mdsal-model/${mdsal.model.version}/xml/features</repository>
 
+
     <feature name='odl-openflowplugin-all' description="OpenDaylight :: Openflow Plugin :: All" version='${project.version}'>
         <feature version="${project.version}">odl-openflowplugin-southbound</feature>
         <feature version="${project.version}">odl-openflowplugin-flow-services</feature>
         <feature version="${project.version}">odl-openflowplugin-flow-services-ui</feature>
     </feature>
 
-    <feature name='odl-openflowplugin-southbound' description="OpenDaylight :: Openflow Plugin :: SouthBound" version='${project.version}'>
+    <feature name='odl-openflowplugin-southbound' description="OpenDaylight :: Openflow Plugin :: Li southBound API implementation " version='${project.version}'>
         <feature version="${mdsal.version}">odl-mdsal-broker</feature>
-        <feature version="${project.version}">odl-openflowplugin-nsf-model</feature>
+        <feature version="${project.version}">odl-openflowplugin-nsf-services</feature>
         <feature version="${openflowjava.version}">odl-openflowjava-protocol</feature>
         <bundle>mvn:org.opendaylight.openflowplugin/openflowplugin-common/{{VERSION}}</bundle>
-        <bundle>mvn:org.opendaylight.openflowplugin/openflowplugin/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.openflowplugin/openflowplugin-api/{{VERSION}}</bundle>
+        <!-- TODO : remove dependency on openflowplugin in the future -->
+        <bundle>mvn:org.opendaylight.openflowplugin/openflowplugin/{{VERSION}}</bundle>
+        <bundle>mvn:org.opendaylight.openflowplugin/openflowplugin-impl/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.openflowplugin/openflowplugin-extension-api/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.controller/liblldp/{{VERSION}}</bundle>
-        <bundle>mvn:org.opendaylight.openflowplugin.applications/inventory-manager/{{VERSION}}</bundle>
-        <bundle>mvn:org.opendaylight.openflowplugin.applications/statistics-manager/{{VERSION}}</bundle>
-        <bundle>mvn:org.opendaylight.openflowplugin/openflowplugin-blueprint-config-he/{{VERSION}}</bundle>
-        <configfile finalname="etc/opendaylight/karaf/42-openflowplugin-He.xml">mvn:org.opendaylight.openflowplugin/openflowplugin-controller-config/{{VERSION}}/xml/config-He</configfile>
-        <configfile finalname="etc/opendaylight/karaf/43-msg-spy.xml">mvn:org.opendaylight.openflowplugin/openflowplugin-controller-config/{{VERSION}}/xml/configmsgspy</configfile>
+        <bundle>mvn:org.opendaylight.openflowplugin/openflowplugin-blueprint-config/{{VERSION}}</bundle>
+        <configfile finalname="etc/opendaylight/karaf/42-openflowplugin-Li.xml">mvn:org.opendaylight.openflowplugin/openflowplugin-controller-config/{{VERSION}}/xml/config-Li</configfile>
     </feature>
 
     <feature name='odl-openflowplugin-flow-services' description="OpenDaylight :: Openflow Plugin :: Flow Services" version='${project.version}'>
         <feature version="${project.version}">odl-openflowplugin-app-config-pusher</feature>
         <feature version="${project.version}">odl-openflowplugin-app-lldp-speaker</feature>
         <feature version="${project.version}">odl-openflowplugin-nsf-services</feature>
+
     </feature>
 
     <feature name='odl-openflowplugin-nsf-services' version='${project.version}'
-        description="OpenDaylight :: OpenflowPlugin :: NSF :: Services">
+             description="OpenDaylight :: OpenflowPlugin :: NSF :: Services">
         <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
         <feature version='${project.version}'>odl-openflowplugin-nsf-model</feature>
         <bundle>mvn:org.opendaylight.openflowplugin/openflowplugin-common/{{VERSION}}</bundle>
@@ -60,7 +61,7 @@
     </feature>
 
     <feature name='odl-openflowplugin-nsf-model' version='${project.version}'
-        description="OpenDaylight :: OpenflowPlugin :: NSF :: Model">
+             description="OpenDaylight :: OpenflowPlugin :: NSF :: Model">
         <!-- general models -->
         <feature version='${mdsal.model.version}'>odl-mdsal-models</feature>
        <bundle>mvn:org.opendaylight.controller.model/model-inventory/{{VERSION}}</bundle>
 
     <feature name='odl-openflowplugin-app-lldp-speaker' description="OpenDaylight :: Openflow Plugin :: app lldp-speaker" version='${project.version}'>
         <feature version="${project.version}">odl-openflowplugin-southbound</feature>
-        <bundle>mvn:org.opendaylight.openflowplugin.applications/topology-lldp-discovery/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.openflowplugin.applications/lldp-speaker/{{VERSION}}</bundle>
     </feature>
 
     <feature name='odl-openflowplugin-app-bulk-o-matic' description="OpenDaylight :: Openflow Plugin :: app bulk flow operations support" version='${project.version}'>
         <feature version="${project.version}">odl-openflowplugin-southbound</feature>
-        <bundle>mvn:org.opendaylight.openflowplugin.applications/bulk-o-matic/{{VERSION}}</bundle>
-        <configfile finalname="etc/opendaylight/karaf/71-bulk-o-matic.xml">mvn:org.opendaylight.openflowplugin.applications/bulk-o-matic/{{VERSION}}/xml/config</configfile>
+        <bundle>mvn:org.opendaylight.openflowplugin.applications/bulk-o-matic/${project.version}</bundle>
+        <configfile finalname="etc/opendaylight/karaf/71-bulk-o-matic.xml">mvn:org.opendaylight.openflowplugin.applications/bulk-o-matic/${project.version}/xml/config</configfile>
+    </feature>
+
+    <feature name='odl-openflowplugin-notifications' description="OpenDaylight :: Openflow Plugin :: app notifications supplier" version='${project.version}'>
+        <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
+        <feature version="${project.version}">odl-openflowplugin-nsf-model</feature>
+        <bundle>mvn:org.opendaylight.openflowplugin.applications/notification-supplier/{{VERSION}}</bundle>
+        <configfile finalname="etc/opendaylight/karaf/73-notification-supplier.xml">mvn:org.opendaylight.openflowplugin.applications/notification-supplier/{{VERSION}}/xml/config</configfile>
     </feature>
 
 </features>
diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OFPContext.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OFPContext.java
new file mode 100644 (file)
index 0000000..788f0c5
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 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.api.openflow;
+
+/**
+ * General API for all OFP Context
+ */
+public interface OFPContext {
+
+    /**
+     * distinguished device context states
+     */
+    enum CONTEXT_STATE {
+        /**
+         * initial phase
+         */
+        INITIALIZATION,
+        /**
+         * standard phase
+         */
+        WORKING,
+        /**
+         * termination phase
+         */
+        TERMINATION
+    }
+
+    CONTEXT_STATE getState();
+
+}
diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OFPManager.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OFPManager.java
new file mode 100644 (file)
index 0000000..1879a4c
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * 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.api.openflow;
+
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
+
+/**
+ * Generic API for all managers
+ */
+public interface OFPManager {
+
+    <T extends OFPContext> T gainContext(final DeviceInfo deviceInfo);
+
+}
index 839541d4e3193300d3884edc3ea28dffc290a94c..88e1c9174f379e9f9b63dbb74cd2650afcc4a073 100644 (file)
@@ -11,6 +11,7 @@ package org.opendaylight.openflowplugin.api.openflow.connection;
 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
 import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueue;
 import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueHandlerRegistration;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceDisconnectedHandler;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FeaturesReply;
@@ -20,7 +21,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
  * Each OpenFlow session is tracked by a Connection Context. These attach to a particular Device Context in such a way,
  * that there is at most one primary session associated with a Device Context.
  * </p>
- * Created by Martin Bobak &lt;mbobak@cisco.com&gt; on 25.2.2015.
  */
 public interface ConnectionContext {
 
@@ -136,4 +136,15 @@ public interface ConnectionContext {
      * change internal state to {@link ConnectionContext.CONNECTION_STATE#WORKING}
      */
     void changeStateToWorking();
+
+    /**
+     * Create and return basic device info
+     * @return
+     */
+    DeviceInfo getDeviceInfo();
+
+    /**
+     * This method creates a basic device information. Should be called after nodeId and features are set in connection context
+     */
+    void handshakeSuccessful();
 }
index b2c70f70535cd40d58c6e22fb07a6199f927c3af..c5baf45cf6dade2d5cfdbc072af403f4efb421ee 100644 (file)
@@ -12,21 +12,14 @@ import com.google.common.util.concurrent.ListenableFuture;
 import io.netty.util.Timeout;
 import java.math.BigInteger;
 import java.util.List;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
+import org.opendaylight.openflowplugin.api.openflow.OFPContext;
 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceReplyProcessor;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.MultiMsgCollector;
 import org.opendaylight.openflowplugin.api.openflow.registry.ItemLifeCycleRegistry;
-import org.opendaylight.openflowplugin.api.openflow.registry.flow.DeviceFlowRegistry;
-import org.opendaylight.openflowplugin.api.openflow.registry.group.DeviceGroupRegistry;
-import org.opendaylight.openflowplugin.api.openflow.registry.meter.DeviceMeterRegistry;
-import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext;
-import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsContext;
 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.OfpRole;
 
 /**
  * <p>
@@ -43,40 +36,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.OfpR
  * Context can have at any point in time. Should this quota be exceeded, any further attempt to make
  * a request to the switch will fail immediately, with proper error indication.
  * </p>
- * Created by Martin Bobak &lt;mbobak@cisco.com&gt; on 25.2.2015.
  */
 public interface DeviceContext extends AutoCloseable,
         DeviceReplyProcessor,
-        PortNumberCache,
         TxFacade,
-        XidSequencer {
-
-    void setStatisticsRpcEnabled(boolean isStatisticsRpcEnabled);
-
-    /**
-     * distinguished device context states
-     */
-    enum DEVICE_CONTEXT_STATE {
-        /**
-         * initial phase of talking to switch
-         */
-        INITIALIZATION,
-        /**
-         * standard phase - interacting with switch
-         */
-        WORKING,
-        /**
-         * termination phase of talking to switch
-         */
-        TERMINATION
-    }
-
-    /**
-     * Method returns current device context state.
-     *
-     * @return {@link DeviceContext.DEVICE_CONTEXT_STATE}
-     */
-    DEVICE_CONTEXT_STATE getDeviceContextState();
+        XidSequencer,
+        OFPContext,
+        DeviceRegistry{
 
     /**
      * Method close all auxiliary connections and primary connection.
@@ -104,34 +70,7 @@ public interface DeviceContext extends AutoCloseable,
      */
     DeviceState getDeviceState();
 
-    /**
-     * Method has to activate (MASTER) or deactivate (SLAVE) TransactionChainManager.
-     * TransactionChainManager represents possibility to write or delete Node subtree data
-     * for actual Controller Cluster Node. We are able to have an active TxManager only if
-     * newRole is {@link OfpRole#BECOMESLAVE}.
-     * Parameters are used as marker to be sure it is change to SLAVE from MASTER or from
-     * MASTER to SLAVE and the last parameter "cleanDataStore" is used for validation only.
-     * @param oldRole - old role for quick validation for needed processing
-     * @param role - NewRole expect to be {@link OfpRole#BECOMESLAVE} or {@link OfpRole#BECOMEMASTER}
-     * @return RoleChangeTxChainManager future for activation/deactivation
-     * @deprecated replaced by method onDeviceTakeClusterLeadership and onDevicLostClusterLeadership
-     */
-    @Deprecated
-    ListenableFuture<Void> onClusterRoleChange(@Nullable OfpRole oldRole, @CheckForNull OfpRole role);
-
-    /**
-     * Method has to activate TransactionChainManager and prepare all Contexts from Device Contects suite
-     * to Taking ClusterLeadership role {@link OfpRole#BECOMEMASTER} (e.g. Routed RPC registration, StatPolling ...)
-     * @return DeviceInitialization furure
-     */
-    ListenableFuture<Void> onDeviceTakeClusterLeadership();
-
-    /**
-     * Method has to deactivate TransactionChainManager and prepare all Contexts from Device Contects suite
-     * to Lost ClusterLeadership role {@link OfpRole#BECOMESLAVE} (e.g. Stop RPC rounting, stop StatPolling ...)
-     * @return RoleChangeTxChainManager future for deactivation
-     */
-    ListenableFuture<Void> onDeviceLostClusterLeadership();
+    DeviceInfo getDeviceInfo();
 
     /**
      * Method has to close TxManager ASAP we are notified about Closed Connection
@@ -153,27 +92,6 @@ public interface DeviceContext extends AutoCloseable,
      */
     ConnectionContext getAuxiliaryConnectiobContexts(BigInteger cookie);
 
-    /**
-     * Method exposes flow registry used for storing flow ids identified by calculated flow hash.
-     *
-     * @return
-     */
-    DeviceFlowRegistry getDeviceFlowRegistry();
-
-    /**
-     * Method exposes device group registry used for storing group ids.
-     *
-     * @return
-     */
-    DeviceGroupRegistry getDeviceGroupRegistry();
-
-    /**
-     * Method exposes device meter registry used for storing meter ids.
-     *
-     * @return
-     */
-    DeviceMeterRegistry getDeviceMeterRegistry();
-
 
     /**
      * @return translator library
@@ -213,14 +131,6 @@ public interface DeviceContext extends AutoCloseable,
      */
     ItemLifeCycleRegistry getItemLifeCycleSourceRegistry();
 
-    void setRpcContext(RpcContext rpcContext);
-
-    RpcContext getRpcContext();
-
-    void setStatisticsContext(StatisticsContext statisticsContext);
-
-    StatisticsContext getStatisticsContext();
-
     @Override
     void close();
 }
diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceInfo.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceInfo.java
new file mode 100644 (file)
index 0000000..75b0f13
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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.api.openflow.device;
+
+import java.math.BigInteger;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+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.KeyedInstanceIdentifier;
+
+/**
+ * API defining basic device information
+ */
+public interface DeviceInfo {
+
+    /**
+     * @return id of encapsulated node
+     */
+    NodeId getNodeId();
+
+    /**
+     * @return {@link Node} instance identifier
+     */
+    KeyedInstanceIdentifier<Node, NodeKey> getNodeInstanceIdentifier();
+
+    /**
+     * @return version
+     */
+    Short getVersion();
+
+    /**
+     * @return datapathId
+     */
+    BigInteger getDatapathId();
+
+}
index 15d59383eb906dbbaf6f8fc9d0449f99bc6c2df7..55f68da8b7efe3689563127cd383cae4a10ff3a8 100644 (file)
@@ -8,45 +8,69 @@
 
 package org.opendaylight.openflowplugin.api.openflow.device;
 
-import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.openflowplugin.api.openflow.OFPManager;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceConnectedHandler;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceDisconnectedHandler;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceInitializationPhaseHandler;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceLifecycleSupervisor;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceTerminationPhaseHandler;
 import org.opendaylight.openflowplugin.api.openflow.translator.TranslatorLibrarian;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.OfpRole;
 
 /**
  * This interface is responsible for instantiating DeviceContext and
  * registering transaction chain for each DeviceContext. Each device
  * has its own device context managed by this manager.
- * Created by Martin Bobak &lt;mbobak@cisco.com&gt; on 25.2.2015.
  */
 public interface DeviceManager extends DeviceConnectedHandler, DeviceDisconnectedHandler, DeviceLifecycleSupervisor,
-        DeviceInitializationPhaseHandler, DeviceTerminationPhaseHandler, TranslatorLibrarian, AutoCloseable {
+        DeviceInitializationPhaseHandler, DeviceTerminationPhaseHandler, TranslatorLibrarian, AutoCloseable, OFPManager {
+
 
     /**
-     * Sets notification publish service
+     * invoked after all services injected
+     */
+    void initialize();
+
+    /**
+     * Method has to activate (MASTER) or deactivate (SLAVE) TransactionChainManager.
+     * TransactionChainManager represents possibility to write or delete Node subtree data
+     * for actual Controller Cluster Node. We are able to have an active TxManager only if
+     * newRole is {@link OfpRole#BECOMESLAVE}.
+     * Parameters are used as marker to be sure it is change to SLAVE from MASTER or from
+     * MASTER to SLAVE and the last parameter "cleanDataStore" is used for validation only.
      *
-     * @param notificationPublishService
+     * @param deviceInfo which device
+     * @param role - NewRole expect to be {@link OfpRole#BECOMESLAVE} or {@link OfpRole#BECOMEMASTER}
+     * @return RoleChangeTxChainManager future for activation/deactivation
      */
-    void setNotificationPublishService(NotificationPublishService notificationPublishService);
+    ListenableFuture<Void> onClusterRoleChange(final DeviceInfo deviceInfo, final OfpRole role);
 
     /**
-     * invoked after all services injected
+     * Register device synchronize listeners
+     * @param deviceSynchronizeListener are notified if device is synchronized or not
      */
-    void initialize();
+    void addDeviceSynchronizeListener(final DeviceSynchronizeListener deviceSynchronizeListener);
+
+    /**
+     * Notify all registered listeners about synchronized status
+     * @param deviceInfo which device
+     * @param deviceSynchronized true if device is synchronized
+     */
+    void notifyDeviceSynchronizeListeners(final DeviceInfo deviceInfo, final boolean deviceSynchronized);
+
+    /**
+     * Register device valid listeners
+     * @param deviceValidListener are notified if device is valid or not
+     */
+    void addDeviceValidListener(final DeviceValidListener deviceValidListener);
 
     /**
-     * Returning device context from map maintained in device manager
-     * This prevent to send whole device context to another context
-     * If device context not exists for nodeId it will return null
-     * @param nodeId
-     * @return device context or null
+     * Notify all registered listeners about valid status
+     * @param deviceInfo which device
+     * @param deviceValid true if device is valid
      */
-    DeviceContext getDeviceContextFromNodeId(NodeId nodeId);
+    void notifyDeviceValidListeners(final DeviceInfo deviceInfo, final boolean deviceValid);
 
-    void setStatisticsRpcEnabled(boolean isStatisticsRpcEnabled);
 }
 
diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceRegistry.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceRegistry.java
new file mode 100644 (file)
index 0000000..9d50835
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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.api.openflow.device;
+
+import org.opendaylight.openflowplugin.api.openflow.registry.flow.DeviceFlowRegistry;
+import org.opendaylight.openflowplugin.api.openflow.registry.group.DeviceGroupRegistry;
+import org.opendaylight.openflowplugin.api.openflow.registry.meter.DeviceMeterRegistry;
+
+/**
+ * Flows, Groups and Meter registry
+ */
+public interface DeviceRegistry {
+
+    /**
+     * Method exposes flow registry used for storing flow ids identified by calculated flow hash.
+     *
+     * @return
+     */
+    DeviceFlowRegistry getDeviceFlowRegistry();
+
+    /**
+     * Method exposes device group registry used for storing group ids.
+     *
+     * @return
+     */
+    DeviceGroupRegistry getDeviceGroupRegistry();
+
+    /**
+     * Method exposes device meter registry used for storing meter ids.
+     *
+     * @return
+     */
+    DeviceMeterRegistry getDeviceMeterRegistry();
+
+}
index 36161c386ad0e7b14d38240d54e1d3f6e23eb384..0ca7e2df60eb99d58c089dde12e859b1ff83e81d 100644 (file)
@@ -8,49 +8,16 @@
 
 package org.opendaylight.openflowplugin.api.openflow.device;
 
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-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.openflow.protocol.rev130731.GetFeaturesOutput;
-import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
-
 /**
- * Created by Martin Bobak &lt;mbobak@cisco.com&gt; on 25.2.2015.
+ * Holder of device's structure
  */
-public interface DeviceState {
-
-    /**
-     * @return id of encapsulated node
-     */
-    NodeId getNodeId();
-
-    /**
-     * @return {@link Node} instance identifier
-     */
-    KeyedInstanceIdentifier<Node, NodeKey> getNodeInstanceIdentifier();
-
-    /**
-     * @return the features of corresponding switch
-     */
-    GetFeaturesOutput getFeatures();
+public interface DeviceState extends DeviceSynchronizeListener, DeviceValidListener {
 
     /**
      * @return true if this session is valid
      */
     boolean isValid();
 
-    /**
-     * @param valid the valid to set
-     */
-    void setValid(boolean valid);
-
-    /**
-     * Return node current OF protocol version
-     *
-     * @return
-     */
-    short getVersion();
-
     /**
      * Return true if we have relevant meter information
      * from device
@@ -120,8 +87,6 @@ public interface DeviceState {
 
     void setQueueStatisticsAvailable(boolean available);
 
-    void setDeviceSynchronized(boolean deviceSynchronized);
-
     boolean isStatisticsPollingEnabled();
 
     void setStatisticsPollingEnabledProp(boolean statPollEnabled);
diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceSynchronizeListener.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceSynchronizeListener.java
new file mode 100644 (file)
index 0000000..6c49c52
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * 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.api.openflow.device;
+
+/**
+ * API for device synchronized listeners
+ */
+public interface DeviceSynchronizeListener {
+
+    void deviceIsSynchronized(final DeviceInfo deviceInfo, final boolean isSynchronized);
+
+}
diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceValidListener.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceValidListener.java
new file mode 100644 (file)
index 0000000..55153a0
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * 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.api.openflow.device;
+
+/**
+ * API for device synchronized listeners
+ */
+public interface DeviceValidListener {
+
+    void deviceIsValid(final DeviceInfo deviceInfo, final boolean isValid);
+
+}
index 4738218827153ce24a9390523a25dc4cee0a0d1d..2dea3a85ee8a2891f67adc9318757475ebf5dcce 100644 (file)
@@ -18,10 +18,10 @@ public interface MessageTranslator<I, O> {
     /**
      * Translates from input to output
      * @param input
-     * @param deviceState
+     * @param deviceInfo
      * @param connectionDistinguisher
      * @return message of output type
      */
-    O translate(I input, DeviceState deviceState, Object connectionDistinguisher);
+    O translate(I input, DeviceInfo deviceInfo, Object connectionDistinguisher);
 
 }
diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/PortNumberCache.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/PortNumberCache.java
deleted file mode 100644 (file)
index 83655b4..0000000
+++ /dev/null
@@ -1,34 +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.api.openflow.device;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
-
-/**
- * keeps mapping between port number (protocol based) and {@link NodeConnectorRef}
- */
-public interface PortNumberCache {
-
-    /**
-     * @param portNumber
-     * @return corresponding nodeConnectorRef if present
-     */
-    @Nullable
-    @Deprecated
-    NodeConnectorRef lookupNodeConnectorRef(Long portNumber);
-
-    /**
-     * @param portNumber       protocol port number
-     * @param nodeConnectorRef corresponding value of {@link NodeConnectorRef}
-     */
-    @Deprecated
-    void storeNodeConnectorRef(@Nonnull Long portNumber, @Nonnull NodeConnectorRef nodeConnectorRef);
-}
index 3e7bf34298fe063ec52d6219074001c24486470c..41884c9d490143c2693f74e715ea2676e8a40479 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.openflowplugin.api.openflow.device.handlers;
 
 import javax.annotation.CheckForNull;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 
 /**
  * openflowplugin-api
@@ -26,8 +26,8 @@ public interface DeviceInitializationPhaseHandler {
     /**
      * Method represents an initialization cycle for {@link DeviceContext} preparation for use.
      *
-     * @param nodeId
+     * @param deviceInfo
      * @throws Exception - needs to be catch in ConnectionHandler implementation
      */
-    void onDeviceContextLevelUp(@CheckForNull NodeId nodeId) throws Exception;
+    void onDeviceContextLevelUp(@CheckForNull DeviceInfo deviceInfo) throws Exception;
 }
index 2ef28f0ce276a9dc17e825d3df3a969ab822940b..e1c140e92bb82afe1de48c90aea43c8ea5d4fca9 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.openflowplugin.api.openflow.device.handlers;
 
 import javax.annotation.CheckForNull;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 
 /**
  * Interface represent handler for dead device connection annihilating cycle.
@@ -21,7 +22,7 @@ public interface DeviceTerminationPhaseHandler {
     /**
      * Method represents a termination cycle for {@link DeviceContext}.
      *
-     * @param deviceContext - {@link DeviceContext}
+     * @param deviceInfo - {@link DeviceInfo}
      */
-    void onDeviceContextLevelDown(@CheckForNull DeviceContext deviceContext);
+    void onDeviceContextLevelDown(@CheckForNull DeviceInfo deviceInfo);
 }
index 19854c7913a1f91eb6307f08043d7d708f8d916a..33d63b78617a330ad83ba6030325e45ade03a3da 100644 (file)
@@ -8,7 +8,7 @@
 
 package org.opendaylight.openflowplugin.api.openflow.lifecycle;
 
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 
 /**
  * This API is for all listeners who wish to know about device context in cluster
@@ -17,16 +17,16 @@ public interface DeviceContextChangeListener {
 
     /**
      * Notification about start phase in device context, right after successful handshake
-     * @param nodeId
+     * @param deviceInfo
      * @param success or failure
      */
-    void deviceStartInitializationDone(final NodeId nodeId, final boolean success);
+    void deviceStartInitializationDone(final DeviceInfo deviceInfo, final boolean success);
 
     /**
      * Notification about start phase in device context, after all other contexts initialized properly
-     * @param nodeId
+     * @param deviceInfo
      * @param success
      */
-    void deviceInitializationDone(final NodeId nodeId, final boolean success);
+    void deviceInitializationDone(final DeviceInfo deviceInfo, final boolean success);
 
 }
index 879bd63acd20635160c810159ac55ed850263225..fcddb2cd4bfff4d83388de0cd527e795463f1700 100644 (file)
@@ -10,14 +10,15 @@ package org.opendaylight.openflowplugin.api.openflow.lifecycle;
 
 import io.netty.util.Timeout;
 import io.netty.util.TimerTask;
+import java.util.concurrent.TimeUnit;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
+import org.opendaylight.openflowplugin.api.openflow.OFPManager;
+import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceManager;
-import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsManager;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
+import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsContext;
 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageIntelligenceAgency;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-
-import javax.annotation.Nonnull;
-import java.util.concurrent.TimeUnit;
 
 /**
  * This class is a binder between all managers
@@ -27,24 +28,31 @@ public interface LifecycleConductor {
 
     /**
      * Returns device context from device manager device contexts maps
-     * @param nodeId node identification
-     * @return null if context doesn't exists
+     *
+     * @param deviceInfo@return null if context doesn't exists
+     */
+    DeviceContext getDeviceContext(DeviceInfo deviceInfo);
+
+
+    /**
+     * Setter for device manager once set it cant be unset or overwritten
+     * @param manager
      */
-    DeviceContext getDeviceContext(final NodeId nodeId);
+    void setSafelyManager(OFPManager manager);
 
     /**
      * Registers ont time listener for notify when services rpc, statistics are done stop or start
      * @param manager service change listener
-     * @param nodeId node identification
+     * @param deviceInfo node identification
      */
-    void addOneTimeListenerWhenServicesChangesDone(final ServiceChangeListener manager, final NodeId nodeId);
+    void addOneTimeListenerWhenServicesChangesDone(final ServiceChangeListener manager, final DeviceInfo deviceInfo);
 
     /**
-     * Returns device of version
-     * @param nodeId node identification
-     * @return null if device context doesn't exists
+     * Returns statistics context from statistics managers contexts maps
+     *
+     * @param deviceInfo@return null if context doesn't exists
      */
-    Short gainVersionSafely(final NodeId nodeId);
+    StatisticsContext getStatisticsContext(DeviceInfo deviceInfo);
 
     /**
      * Set new timeout for {@link io.netty.util.HashedWheelTimer}
@@ -63,26 +71,20 @@ public interface LifecycleConductor {
 
     /**
      * Interrupt connection for the node
-     * @param nodeId node identification
+     * @param deviceInfo node identification
      */
-    void closeConnection(final NodeId nodeId);
+    void closeConnection(final DeviceInfo deviceInfo);
 
-    /**
-     * Setter for device manager once set it cant be unset or overwritten
-     * @param deviceManager should be set in OpenFlowPluginProviderImpl
-     */
-    void setSafelyDeviceManager(final DeviceManager deviceManager);
-
-    /**
-     * Setter for statistics manager once set it cant be unset or overwritten
-     * @param statisticsManager should be set in OpenFlowPluginProviderImpl
-     */
-    void setSafelyStatisticsManager(final StatisticsManager statisticsManager);
+    ConnectionContext.CONNECTION_STATE gainConnectionStateSafely(DeviceInfo deviceInfo);
 
     /**
      * Xid from outboundqueue
-     * @param nodeId
+     * @param deviceInfo
      * @return
      */
-    Long reserveXidForDeviceMessage(final NodeId nodeId);
+    Long reserveXidForDeviceMessage(final DeviceInfo deviceInfo);
+
+    NotificationPublishService getNotificationPublishService();
+
+    void setNotificationPublishService(NotificationPublishService notificationPublishService);
 }
index f830966234d3889cff9bef183ebc3e0d54249d88..77ad9fa3e62dc43d626fbbad986eb786808e2262 100644 (file)
@@ -8,7 +8,7 @@
 
 package org.opendaylight.openflowplugin.api.openflow.lifecycle;
 
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.OfpRole;
 
 /**
@@ -18,18 +18,18 @@ public interface RoleChangeListener {
 
     /**
      * Notification when initialization for role context is done
-     * @param nodeId
+     * @param deviceInfo
      * @param success or failure
      */
-    void roleInitializationDone(final NodeId nodeId, final boolean success);
+    void roleInitializationDone(final DeviceInfo deviceInfo, final boolean success);
 
     /**
      * Notification when the role change on device is done
-     * @param nodeId
+     * @param deviceInfo
      * @param success
      * @param newRole
      * @param initializationPhase
      */
-    void roleChangeOnDevice(final NodeId nodeId, final boolean success, final OfpRole newRole, final boolean initializationPhase);
+    void roleChangeOnDevice(final DeviceInfo deviceInfo, final boolean success, final OfpRole newRole, final boolean initializationPhase);
 
 }
index 5afe5bba906f3711621ea42a8136bc50df8129d2..ae94d4be7cd5d9fe2b17ff051ba2914090b46543 100644 (file)
@@ -8,7 +8,7 @@
 
 package org.opendaylight.openflowplugin.api.openflow.lifecycle;
 
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 
 /**
  * This API is defined for listening when services (Statistics and RPCs) are fully stopped
@@ -18,9 +18,9 @@ public interface ServiceChangeListener {
 
     /**
      * Notification when services (rpc, statistics) are started or stopped working
-     * @param nodeId
+     * @param deviceInfo
      * @param success
      */
-    void servicesChangeDone(NodeId nodeId, boolean success);
+    void servicesChangeDone(DeviceInfo deviceInfo, boolean success);
 
 }
index a4a0abeda5f5a67d1cf16da4e5a60fb2bd1f120e..e1ea51f563f2db37dec124dfd9ef0bd2c50fed86 100644 (file)
@@ -8,17 +8,15 @@
 
 package org.opendaylight.openflowplugin.api.openflow.md.core;
 
+import com.google.common.collect.Lists;
 import java.util.List;
 import java.util.concurrent.Future;
-
 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
 import org.opendaylight.openflowplugin.api.openflow.md.core.session.SessionContext;
 import org.opendaylight.openflowplugin.api.openflow.md.queue.QueueProcessor;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 
-import com.google.common.collect.Lists;
-
 
 /**
  * @author mirehak
index 3ba708e08714f995dde6cba48c2a380d971602b5..81d740fea96c6320730b575e73a45ec83c60489d 100644 (file)
@@ -7,12 +7,11 @@
  */
 package org.opendaylight.openflowplugin.api.openflow.md.core;
 
+import com.google.common.base.Preconditions;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
 import org.opendaylight.yangtools.yang.binding.DataContainer;
 import org.opendaylight.yangtools.yang.binding.Notification;
 
-import com.google.common.base.Preconditions;
-
 /**
  * 
  */
index 4d8e2bf2593f3f8584bab610e769faceaf4445c6..5272498d74daaa53943bb4fa2bb1cc48c80f8fbd 100644 (file)
@@ -9,8 +9,9 @@
 package org.opendaylight.openflowplugin.api.openflow.md.core.session;
 
 import java.util.concurrent.Future;
-
 import org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput;
@@ -35,8 +36,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutput;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 
 /**
index 863031a582417fff0ec472c55e29ecd8da892c1a..c7685e56ea2ca0fb0b7660dfe025e24989dcbcbd 100644 (file)
@@ -18,9 +18,9 @@ import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
 import org.opendaylight.openflowplugin.api.openflow.md.core.ConnectionConductor;
 import org.opendaylight.openflowplugin.api.openflow.md.core.IMDMessageTranslator;
 import org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher;
-import org.opendaylight.openflowplugin.api.openflow.statistics.MessageSpy;
 import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
 import org.opendaylight.openflowplugin.api.openflow.md.queue.PopListener;
+import org.opendaylight.openflowplugin.api.openflow.statistics.MessageSpy;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.DataContainer;
index 441bb9b0a22a0164bd5be130ee6f944abcac4026..e1f0e38c4add2e56063e3ecf143a82aa6da21d47 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.openflowplugin.api.openflow.md.queue;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
-
 import org.opendaylight.openflowplugin.api.openflow.md.core.IMDMessageTranslator;
 import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
 
index 4de64b31f3d1383c04f3e0a4f45d69618225376d..7ba8317607234afd97a10d7b535708e6af437135 100644 (file)
@@ -7,13 +7,12 @@
  */
 package org.opendaylight.openflowplugin.api.openflow.md.util;
 
+import com.google.common.collect.Iterators;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Queue;
 
-import com.google.common.collect.Iterators;
-
 /**
  * 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 
index 5b9bbfdb331ead46ea1caa1e2bbb6ea18906ba07..ea3d2435993e031b1842666b9e17f73e888ab82b 100644 (file)
@@ -7,17 +7,17 @@
  */
 package org.opendaylight.openflowplugin.api.openflow.role;
 
+import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
+import org.opendaylight.openflowplugin.api.openflow.OFPContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SalRoleService;
 
-import javax.annotation.Nonnull;
-
 /**
- * Rewrote whole role context to prevent errors to change role on cluster
+ * Role context for change role on cluster
  */
-public interface RoleContext extends  RequestContextStack, AutoCloseable {
+public interface RoleContext extends  RequestContextStack, AutoCloseable, OFPContext {
 
     /**
      * Initialization method is responsible for a registration of
@@ -68,7 +68,7 @@ public interface RoleContext extends  RequestContextStack, AutoCloseable {
      * Actual nodeId
      * @return
      */
-    NodeId getNodeId();
+    DeviceInfo getDeviceInfo();
 
     /**
      * Returns true if main entity is registered
index dee6ec896a289cc605205ef69c079caf16d23261..bc851df3b64418560240a4003d06ccb90a541377 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.openflowplugin.api.openflow.role;
 
+import org.opendaylight.openflowplugin.api.openflow.OFPManager;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceInitializationPhaseHandler;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceLifecycleSupervisor;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceTerminationPhaseHandler;
@@ -16,7 +17,7 @@ import org.opendaylight.openflowplugin.api.openflow.lifecycle.RoleChangeListener
  * Created by kramesha on 8/31/15.
  */
 public interface RoleManager extends DeviceLifecycleSupervisor, DeviceInitializationPhaseHandler, AutoCloseable,
-        DeviceTerminationPhaseHandler {
+        DeviceTerminationPhaseHandler, OFPManager {
     String ENTITY_TYPE = "openflow";
     String TX_ENTITY_TYPE = "ofTransaction";
 
index 4be56a094e788718ca86d5801819a6a9210ef5b2..36965c38eeb119b96beb5398e582c7bfec62bcc9 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.openflowplugin.api.openflow.rpc;
 
+import org.opendaylight.openflowplugin.api.openflow.OFPContext;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 
@@ -15,9 +16,8 @@ import org.opendaylight.yangtools.yang.binding.RpcService;
  * tracks the state of any user requests and how they map onto protocol requests. It uses
  * {@link org.opendaylight.openflowplugin.api.openflow.device.RequestContext} to perform requests.
  * <p>
- * Created by Martin Bobak &lt;mbobak@cisco.com&gt; on 25.2.2015.
  */
-public interface RpcContext extends RequestContextStack, AutoCloseable {
+public interface RpcContext extends RequestContextStack, AutoCloseable, OFPContext {
     <S extends RpcService> void registerRpcServiceImplementation(Class<S> serviceClass, S serviceInstance);
 
     <S extends RpcService> S lookupRpcService(Class<S> serviceClass);
@@ -25,4 +25,8 @@ public interface RpcContext extends RequestContextStack, AutoCloseable {
 
     @Override
     void close();
+
+    void setStatisticsRpcEnabled(boolean isStatisticsRpcEnabled);
+
+    boolean isStatisticsRpcEnabled();
 }
index 63a0c984973c2e3c0eaf668386ae5efb5466a97d..0339f8435edc07a7bcb7110c1c9a32690c6a9128 100644 (file)
@@ -8,18 +8,19 @@
 
 package org.opendaylight.openflowplugin.api.openflow.rpc;
 
+import org.opendaylight.openflowplugin.api.openflow.OFPManager;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceInitializationPhaseHandler;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceLifecycleSupervisor;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceTerminationPhaseHandler;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 
 /**
  * The RPC Manager will maintain an RPC Context for each online switch. RPC context for device is created when
- * {@link org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceInitializationPhaseHandler#onDeviceContextLevelUp(NodeId)}
+ * {@link org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceInitializationPhaseHandler#onDeviceContextLevelUp(org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo)}
  * is called.
  * <p>
  * Created by Martin Bobak &lt;mbobak@cisco.com&gt; on 25.2.2015.
  */
-public interface RpcManager extends DeviceLifecycleSupervisor, DeviceInitializationPhaseHandler, AutoCloseable, DeviceTerminationPhaseHandler {
+public interface RpcManager extends DeviceLifecycleSupervisor, DeviceInitializationPhaseHandler, AutoCloseable, DeviceTerminationPhaseHandler, OFPManager {
 
+    void setStatisticsRpcEnabled(boolean statisticsRpcEnabled);
 }
index 9bc2cda8293d1d403459345922d1de590057ec22..22e975231a5edc7a410878546c6602819c3c4ac7 100644 (file)
@@ -8,20 +8,30 @@
 
 package org.opendaylight.openflowplugin.api.openflow.statistics;
 
-import com.google.common.base.Optional;
 import com.google.common.util.concurrent.ListenableFuture;
 import io.netty.util.Timeout;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import java.util.Optional;
+import org.opendaylight.openflowplugin.api.openflow.OFPContext;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
 import org.opendaylight.openflowplugin.api.openflow.rpc.listener.ItemLifecycleListener;
 
 /**
- * Created by Martin Bobak &lt;mbobak@cisco.com&gt; on 27.2.2015.
+ * Context for statistics
  */
-public interface StatisticsContext extends RequestContextStack, AutoCloseable {
+public interface StatisticsContext extends RequestContextStack, AutoCloseable, OFPContext {
 
+    /**
+     * Gather data from device
+     * @return true if gathering was successful
+     */
     ListenableFuture<Boolean> gatherDynamicData();
 
+    /**
+     * Initial data gathering
+     * @return true if gathering was successful
+     */
+    ListenableFuture<Boolean> initialGatherDynamicData();
+
     /**
      * Method has to be called from DeviceInitialization Method, otherwise
      * we are not able to poll anything. Statistics Context normally initialize
@@ -47,12 +57,6 @@ public interface StatisticsContext extends RequestContextStack, AutoCloseable {
      */
     ItemLifecycleListener getItemLifeCycleListener();
 
-    /**
-     * Statistics Context has to be able to return own DeviceCtx
-     * @return {@link DeviceContext}
-     */
-    DeviceContext getDeviceContext();
-
     @Override
     void close();
 
index e1588be274db166ca8e3adf085dd9f251afd417e..ee4f67273b6d02a28ce0ad1bc90819db3052a8ed 100644 (file)
@@ -8,19 +8,20 @@
 
 package org.opendaylight.openflowplugin.api.openflow.statistics;
 
-import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceTerminationPhaseHandler;
+import org.opendaylight.openflowplugin.api.openflow.OFPManager;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceInitializationPhaseHandler;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceLifecycleSupervisor;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceTerminationPhaseHandler;
 
 /**
- * Created by Martin Bobak &lt;mbobak@cisco.com&gt; on 26.2.2015.
+ * Manager to start or stop scheduling statistics
  */
 public interface StatisticsManager extends DeviceLifecycleSupervisor, DeviceInitializationPhaseHandler,
-        DeviceTerminationPhaseHandler, AutoCloseable {
+        DeviceTerminationPhaseHandler, AutoCloseable, OFPManager {
 
-    void startScheduling(NodeId nodeId);
-    void stopScheduling(NodeId nodeId);
+    void startScheduling(DeviceInfo deviceInfo);
+    void stopScheduling(DeviceInfo deviceInfo);
 
     @Override
     void close();
index 481793eb63c2880442f72b1b81f6e07840f3be29..2d180acbc0119a6c58feaac77c7848b9f789e8fa 100644 (file)
@@ -64,5 +64,23 @@ module openflow-provider-config {
             type non-zero-uint32-type;
             default 2000;
         }
+
+        leaf thread-pool-min-threads {
+            description "Mininum (starting) number of threads in thread pool";
+            type uint16;
+            default 1;
+        }
+
+        leaf thread-pool-max-threads {
+            description "Maximum number of threads in thread pool";
+            type non-zero-uint16-type;
+            default 32000;
+        }
+
+        leaf thread-pool-timeout {
+            description "After how much time (in seconds) of inactivity will be threads in pool terminated";
+            type uint32;
+            default 60;
+        }
     }
 }
\ No newline at end of file
index b55bff8720b3431029b134b7a853f3fe21e8fa26..74c7f39d5422164f6d6ae66e08746da9bd8cb7d8 100644 (file)
@@ -19,129 +19,186 @@ import io.netty.util.TimerTask;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
+import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
+import org.opendaylight.openflowplugin.api.openflow.OFPManager;
 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceManager;
 import org.opendaylight.openflowplugin.api.openflow.lifecycle.DeviceContextChangeListener;
 import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleConductor;
 import org.opendaylight.openflowplugin.api.openflow.lifecycle.RoleChangeListener;
 import org.opendaylight.openflowplugin.api.openflow.lifecycle.ServiceChangeListener;
+import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext;
+import org.opendaylight.openflowplugin.api.openflow.rpc.RpcManager;
+import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsContext;
 import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsManager;
 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageIntelligenceAgency;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.openflowplugin.extension.api.ExtensionConverterProviderKeeper;
+import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
+import org.opendaylight.openflowplugin.impl.util.MdSalRegistrationUtils;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.OfpRole;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
  */
-public final class LifecycleConductorImpl implements LifecycleConductor, RoleChangeListener, DeviceContextChangeListener {
+final class LifecycleConductorImpl implements LifecycleConductor, RoleChangeListener, DeviceContextChangeListener, ExtensionConverterProviderKeeper {
 
     private static final Logger LOG = LoggerFactory.getLogger(LifecycleConductorImpl.class);
     private static final int TICKS_PER_WHEEL = 500;
     private static final long TICK_DURATION = 10; // 0.5 sec.
 
     private final HashedWheelTimer hashedWheelTimer = new HashedWheelTimer(TICK_DURATION, TimeUnit.MILLISECONDS, TICKS_PER_WHEEL);
+    private ExtensionConverterProvider extensionConverterProvider;
     private DeviceManager deviceManager;
-    private final MessageIntelligenceAgency messageIntelligenceAgency;
-    private ConcurrentHashMap<NodeId, ServiceChangeListener> serviceChangeListeners = new ConcurrentHashMap<>();
     private StatisticsManager statisticsManager;
+    private RpcManager rpcManager;
+    private final MessageIntelligenceAgency messageIntelligenceAgency;
+    private ConcurrentHashMap<DeviceInfo, ServiceChangeListener> serviceChangeListeners = new ConcurrentHashMap<>();
+    private NotificationPublishService notificationPublishService;
 
-    public LifecycleConductorImpl(final MessageIntelligenceAgency messageIntelligenceAgency) {
-        Preconditions.checkNotNull(messageIntelligenceAgency);
-        this.messageIntelligenceAgency = messageIntelligenceAgency;
+    LifecycleConductorImpl(final MessageIntelligenceAgency messageIntelligenceAgency) {
+        this.messageIntelligenceAgency = Preconditions.checkNotNull(messageIntelligenceAgency);
     }
 
-    public void setSafelyDeviceManager(final DeviceManager deviceManager) {
-        if (this.deviceManager == null) {
-            this.deviceManager = deviceManager;
-        }
+    @Override
+    public ExtensionConverterProvider getExtensionConverterProvider() {
+        return extensionConverterProvider;
+    }
+
+    @Override
+    public void setExtensionConverterProvider(ExtensionConverterProvider extensionConverterProvider) {
+        this.extensionConverterProvider = extensionConverterProvider;
     }
 
-    public void setSafelyStatisticsManager(final StatisticsManager statisticsManager) {
-        if (this.statisticsManager == null) {
-            this.statisticsManager = statisticsManager;
+    @Override
+    public void setSafelyManager(final OFPManager manager){
+        if (manager instanceof RpcManager) {
+            if (rpcManager != null) {
+                LOG.info("RPC manager {} is already defined in conductor. ", manager);
+                return;
+            }
+            this.rpcManager = (RpcManager) manager;
+        } else {
+            if (manager instanceof StatisticsManager) {
+                if (statisticsManager != null) {
+                    LOG.info("Statistics manager {} is already defined in conductor. ", manager);
+                    return;
+                }
+                this.statisticsManager = (StatisticsManager) manager;
+            } else {
+                if (manager instanceof DeviceManager) {
+                    if (deviceManager != null) {
+                        LOG.info("Device manager {} is already defined in conductor. ", manager);
+                        return;
+                    }
+                    this.deviceManager = (DeviceManager) manager;
+                }
+            }
         }
     }
 
-    public void addOneTimeListenerWhenServicesChangesDone(final ServiceChangeListener manager, final NodeId nodeId){
-        LOG.debug("Listener {} for service change for node {} registered.", manager, nodeId);
-        serviceChangeListeners.put(nodeId, manager);
+    @Override
+    public void addOneTimeListenerWhenServicesChangesDone(final ServiceChangeListener manager, final DeviceInfo deviceInfo){
+        LOG.debug("Listener {} for service change for node {} registered.", manager, deviceInfo.getNodeId());
+        serviceChangeListeners.put(deviceInfo, manager);
     }
 
     @VisibleForTesting
-    void notifyServiceChangeListeners(final NodeId nodeId, final boolean success){
+    void notifyServiceChangeListeners(final DeviceInfo deviceInfo, final boolean success){
         if (serviceChangeListeners.size() == 0) {
             return;
         }
         LOG.debug("Notifying registered listeners for service change, no. of listeners {}", serviceChangeListeners.size());
-        for (final Map.Entry<NodeId, ServiceChangeListener> nodeIdServiceChangeListenerEntry : serviceChangeListeners.entrySet()) {
-            if (nodeIdServiceChangeListenerEntry.getKey().equals(nodeId)) {
-                LOG.debug("Listener {} for service change for node {} was notified. Success was set on {}", nodeIdServiceChangeListenerEntry.getValue(), nodeId, success);
-                nodeIdServiceChangeListenerEntry.getValue().servicesChangeDone(nodeId, success);
-                serviceChangeListeners.remove(nodeId);
+        for (final Map.Entry<DeviceInfo, ServiceChangeListener> nodeIdServiceChangeListenerEntry : serviceChangeListeners.entrySet()) {
+            if (nodeIdServiceChangeListenerEntry.getKey().equals(deviceInfo)) {
+                LOG.debug("Listener {} for service change for node {} was notified. Success was set on {}", nodeIdServiceChangeListenerEntry.getValue(), deviceInfo, success);
+                nodeIdServiceChangeListenerEntry.getValue().servicesChangeDone(deviceInfo, success);
+                serviceChangeListeners.remove(deviceInfo);
             }
         }
     }
 
     @Override
-    public void roleInitializationDone(final NodeId nodeId, final boolean success) {
+    public void roleInitializationDone(final DeviceInfo deviceInfo, final boolean success) {
         if (!success) {
-            LOG.warn("Initialization phase for node {} in role context was NOT successful, closing connection.", nodeId);
-            closeConnection(nodeId);
+            LOG.warn("Initialization phase for node {} in role context was NOT successful, closing connection.", deviceInfo);
+            closeConnection(deviceInfo);
         } else {
-            LOG.info("initialization phase for node {} in role context was successful, continuing to next context.", nodeId);
+            LOG.info("initialization phase for node {} in role context was successful, continuing to next context.", deviceInfo);
         }
     }
 
-    public void closeConnection(final NodeId nodeId) {
-        LOG.debug("Close connection called for node {}", nodeId);
-        final DeviceContext deviceContext = getDeviceContext(nodeId);
+    public void closeConnection(final DeviceInfo deviceInfo) {
+        LOG.debug("Close connection called for node {}", deviceInfo);
+        final DeviceContext deviceContext = getDeviceContext(deviceInfo);
         if (null != deviceContext) {
+            deviceManager.notifyDeviceValidListeners(deviceInfo, false);
             deviceContext.shutdownConnection();
         }
     }
 
     @Override
-    public void roleChangeOnDevice(final NodeId nodeId, final boolean success, final OfpRole newRole, final boolean initializationPhase) {
+    public void roleChangeOnDevice(final DeviceInfo deviceInfo, final boolean success, final OfpRole newRole, final boolean initializationPhase) {
 
-        final DeviceContext deviceContext = getDeviceContext(nodeId);
+        final DeviceContext deviceContext = getDeviceContext(deviceInfo);
 
         if (null == deviceContext) {
             LOG.warn("Something went wrong, device context for nodeId: {} doesn't exists");
             return;
         }
         if (!success) {
-            LOG.warn("Role change to {} in role context for node {} was NOT successful, closing connection", newRole, nodeId);
-            closeConnection(nodeId);
+            LOG.warn("Role change to {} in role context for node {} was NOT successful, closing connection", newRole, deviceInfo);
+            closeConnection(deviceInfo);
         } else {
             if (initializationPhase) {
                 LOG.debug("Initialization phase skipping starting services.");
                 return;
             }
 
-            LOG.info("Role change to {} in role context for node {} was successful, starting/stopping services.", newRole, nodeId);
+            LOG.info("Role change to {} in role context for node {} was successful.", newRole, deviceInfo);
+
+            final String logText;
 
             if (OfpRole.BECOMEMASTER.equals(newRole)) {
-                statisticsManager.startScheduling(nodeId);
+                logText = "Start";
+                statisticsManager.startScheduling(deviceInfo);
+                MdSalRegistrationUtils.registerMasterServices(
+                        rpcManager.gainContext(deviceInfo),
+                        deviceContext,
+                        OfpRole.BECOMEMASTER,
+                        this.extensionConverterProvider);
+                if (((RpcContext)rpcManager.gainContext(deviceInfo)).isStatisticsRpcEnabled()) {
+                    MdSalRegistrationUtils.registerStatCompatibilityServices(
+                            rpcManager.gainContext(deviceInfo),
+                            deviceManager.gainContext(deviceInfo),
+                            notificationPublishService,
+                            new AtomicLong());
+                }
             } else {
-                statisticsManager.stopScheduling(nodeId);
+                logText = "Stopp";
+                statisticsManager.stopScheduling(deviceInfo);
+                MdSalRegistrationUtils.registerSlaveServices(
+                        rpcManager.gainContext(deviceInfo),
+                        OfpRole.BECOMESLAVE);
             }
 
-            final ListenableFuture<Void> onClusterRoleChange = deviceContext.onClusterRoleChange(null, newRole);
+            final ListenableFuture<Void> onClusterRoleChange = deviceManager.onClusterRoleChange(deviceInfo, newRole);
             Futures.addCallback(onClusterRoleChange, new FutureCallback<Void>() {
                 @Override
                 public void onSuccess(@Nullable final Void aVoid) {
-                    LOG.info("Starting/Stopping services for node {} was successful", nodeId);
-                    if (newRole.equals(OfpRole.BECOMESLAVE)) notifyServiceChangeListeners(nodeId, true);
+                    LOG.info("{}ing services for node {} was successful", logText, deviceInfo);
+                    if (newRole.equals(OfpRole.BECOMESLAVE)) notifyServiceChangeListeners(deviceInfo, true);
                 }
 
                 @Override
                 public void onFailure(final Throwable throwable) {
-                    LOG.warn("Starting/Stopping services for node {} was NOT successful, closing connection", nodeId);
-                    closeConnection(nodeId);
+                    LOG.warn("{}ing services for node {} was NOT successful, closing connection", logText, deviceInfo);
+                    closeConnection(deviceInfo);
                 }
             });
         }
@@ -152,49 +209,61 @@ public final class LifecycleConductorImpl implements LifecycleConductor, RoleCha
     }
 
     @Override
-    public DeviceContext getDeviceContext(final NodeId nodeId){
-         return deviceManager.getDeviceContextFromNodeId(nodeId);
+    public DeviceContext getDeviceContext(DeviceInfo deviceInfo){
+         return deviceManager.gainContext(deviceInfo);
     }
 
-    public Short gainVersionSafely(final NodeId nodeId) {
-        return (null != getDeviceContext(nodeId)) ? getDeviceContext(nodeId).getPrimaryConnectionContext().getFeatures().getVersion() : null;
+    @Override
+    public StatisticsContext getStatisticsContext(DeviceInfo deviceInfo){
+        return statisticsManager.gainContext(deviceInfo);
     }
 
     public Timeout newTimeout(@Nonnull TimerTask task, long delay, @Nonnull TimeUnit unit) {
         return hashedWheelTimer.newTimeout(task, delay, unit);
     }
 
-    public ConnectionContext.CONNECTION_STATE gainConnectionStateSafely(final NodeId nodeId){
-        return (null != getDeviceContext(nodeId)) ? getDeviceContext(nodeId).getPrimaryConnectionContext().getConnectionState() : null;
+    @Override
+    public ConnectionContext.CONNECTION_STATE gainConnectionStateSafely(final DeviceInfo deviceInfo){
+        return (null != getDeviceContext(deviceInfo)) ? getDeviceContext(deviceInfo).getPrimaryConnectionContext().getConnectionState() : null;
     }
 
-    public Long reserveXidForDeviceMessage(final NodeId nodeId){
-        return null != getDeviceContext(nodeId) ? getDeviceContext(nodeId).reserveXidForDeviceMessage() : null;
+    @Override
+    public Long reserveXidForDeviceMessage(final DeviceInfo deviceInfo){
+        return null != getDeviceContext(deviceInfo) ? getDeviceContext(deviceInfo).reserveXidForDeviceMessage() : null;
     }
 
     @Override
-    public void deviceStartInitializationDone(final NodeId nodeId, final boolean success) {
+    public void deviceStartInitializationDone(final DeviceInfo deviceInfo, final boolean success) {
         if (!success) {
-            LOG.warn("Initialization phase for node {} in device context was NOT successful, closing connection.", nodeId);
-            closeConnection(nodeId);
+            LOG.warn("Initialization phase for node {} in device context was NOT successful, closing connection.", deviceInfo);
+            closeConnection(deviceInfo);
         } else {
-            LOG.info("initialization phase for node {} in device context was successful. Continuing to next context.", nodeId);
+            LOG.info("initialization phase for node {} in device context was successful. Continuing to next context.", deviceInfo);
         }
     }
 
     @Override
-    public void deviceInitializationDone(final NodeId nodeId, final boolean success) {
+    public void deviceInitializationDone(final DeviceInfo deviceInfo, final boolean success) {
         if (!success) {
-            LOG.warn("Initialization phase for node {} in device context was NOT successful, closing connection.", nodeId);
-            closeConnection(nodeId);
+            LOG.warn("Initialization phase for node {} in device context was NOT successful, closing connection.", deviceInfo);
+            closeConnection(deviceInfo);
         } else {
-            LOG.info("initialization phase for node {} in device context was successful. All phases initialized OK.", nodeId);
+            LOG.info("initialization phase for node {} in device context was successful. All phases initialized OK.", deviceInfo);
         }
     }
 
     @VisibleForTesting
-    public boolean isServiceChangeListenersEmpty() {
+    boolean isServiceChangeListenersEmpty() {
         return this.serviceChangeListeners.isEmpty();
     }
 
+    @Override
+    public NotificationPublishService getNotificationPublishService() {
+        return notificationPublishService;
+    }
+
+    @Override
+    public void setNotificationPublishService(NotificationPublishService notificationPublishService) {
+        this.notificationPublishService = notificationPublishService;
+    }
 }
index 202b177ed1c4a78e32cb0bf53dd07c0eb1bd6621..0ad6129ce6a77b83a6a4db656b49432455102f3c 100644 (file)
@@ -39,8 +39,12 @@ public class OpenFlowPluginProviderFactoryImpl implements OpenFlowPluginProvider
         LOG.info("Initializing new OFP southbound.");
 
         OpenflowPortsUtil.init();
-        OpenFlowPluginProvider openflowPluginProvider = new OpenFlowPluginProviderImpl(providerConfig.getRpcRequestsQuota(),
-                providerConfig.getGlobalNotificationQuota());
+        OpenFlowPluginProvider openflowPluginProvider = new OpenFlowPluginProviderImpl(
+                providerConfig.getRpcRequestsQuota(),
+                providerConfig.getGlobalNotificationQuota(),
+                providerConfig.getThreadPoolMinThreads(),
+                providerConfig.getThreadPoolMaxThreads().getValue(),
+                providerConfig.getThreadPoolTimeout());
 
         openflowPluginProvider.setSwitchConnectionProviders(switchConnectionProviders);
         openflowPluginProvider.setDataBroker(dataBroker);
@@ -57,10 +61,23 @@ public class OpenFlowPluginProviderFactoryImpl implements OpenFlowPluginProvider
 
         openflowPluginProvider.initialize();
 
-        LOG.info("Configured values, StatisticsPollingOff:{}, SwitchFeaturesMandatory:{}, BarrierCountLimit:{}, BarrierTimeoutLimit:{}, EchoReplyTimeout:{}",
-                providerConfig.isIsStatisticsPollingOff(), providerConfig.isSwitchFeaturesMandatory(),
+        LOG.info("Configured values, " +
+                "StatisticsPollingOff:{}, " +
+                "SwitchFeaturesMandatory:{}, " +
+                "BarrierCountLimit:{}, " +
+                "BarrierTimeoutLimit:{}, " +
+                "EchoReplyTimeout:{}, " +
+                "ThreadPoolMinThreads:{}, " +
+                "ThreadPoolMaxThreads:{}, " +
+                "ThreadPoolTimeout:{}",
+                providerConfig.isIsStatisticsPollingOff(),
+                providerConfig.isSwitchFeaturesMandatory(),
                 providerConfig.getBarrierCountLimit().getValue(),
-                providerConfig.getBarrierIntervalTimeoutLimit().getValue(), providerConfig.getEchoReplyTimeout().getValue());
+                providerConfig.getBarrierIntervalTimeoutLimit().getValue(),
+                providerConfig.getEchoReplyTimeout().getValue(),
+                providerConfig.getThreadPoolMinThreads(),
+                providerConfig.getThreadPoolMaxThreads().getValue(),
+                providerConfig.getThreadPoolTimeout());
 
         return openflowPluginProvider;
     }
index ab64a090c49b745e31b2bd889fe93d98afbe428b..7d1fc5caea5677e9beba38cd415d6255284d2f65 100644 (file)
@@ -17,6 +17,9 @@ import java.lang.management.ManagementFactory;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 import javax.annotation.Nonnull;
 import javax.management.InstanceAlreadyExistsException;
 import javax.management.MBeanRegistrationException;
@@ -51,6 +54,7 @@ import org.opendaylight.openflowplugin.impl.statistics.StatisticsManagerImpl;
 import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.MessageIntelligenceAgencyImpl;
 import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.MessageIntelligenceAgencyMXBean;
 import org.opendaylight.openflowplugin.impl.util.TranslatorLibraryUtil;
+import org.opendaylight.openflowplugin.openflow.md.core.ThreadPoolLoggingExecutor;
 import org.opendaylight.openflowplugin.openflow.md.core.extension.ExtensionConverterManagerImpl;
 import org.opendaylight.openflowplugin.openflow.md.core.session.OFSessionUtil;
 import org.slf4j.Logger;
@@ -85,11 +89,26 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF
     private boolean isStatisticsRpcEnabled;
 
     private final LifecycleConductor conductor;
+    private final ThreadPoolExecutor threadPool;
 
-    public OpenFlowPluginProviderImpl(final long rpcRequestsQuota, final Long globalNotificationQuota) {
+    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");
+
         conductor = new LifecycleConductorImpl(messageIntelligenceAgency);
     }
 
@@ -178,7 +197,6 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF
 
     @Override
     public void initialize() {
-
         Preconditions.checkNotNull(dataBroker, "missing data broker");
         Preconditions.checkNotNull(rpcProviderRegistry, "missing RPC provider registry");
         Preconditions.checkNotNull(notificationProviderService, "missing notification provider service");
@@ -188,7 +206,7 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF
         // TODO: rewrite later!
         OFSessionUtil.getSessionManager().setExtensionConverterProvider(extensionConverterManager);
 
-        connectionManager = new ConnectionManagerImpl(echoReplyTimeout);
+        connectionManager = new ConnectionManagerImpl(echoReplyTimeout, threadPool);
 
         registerMXBean(messageIntelligenceAgency);
 
@@ -198,14 +216,18 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF
                 barrierInterval,
                 barrierCountLimit,
                 conductor);
+        ((ExtensionConverterProviderKeeper) conductor).setExtensionConverterProvider(extensionConverterManager);
         ((ExtensionConverterProviderKeeper) deviceManager).setExtensionConverterProvider(extensionConverterManager);
 
-        conductor.setSafelyDeviceManager(deviceManager);
+        conductor.setSafelyManager(deviceManager);
+        conductor.setNotificationPublishService(notificationPublishService);
 
         roleManager = new RoleManagerImpl(entityOwnershipService, dataBroker, conductor);
         statisticsManager = new StatisticsManagerImpl(rpcProviderRegistry, isStatisticsPollingOff, conductor);
-        conductor.setSafelyStatisticsManager(statisticsManager);
+        conductor.setSafelyManager(statisticsManager);
+
         rpcManager = new RpcManagerImpl(rpcProviderRegistry, rpcRequestsQuota, conductor);
+        conductor.setSafelyManager(rpcManager);
 
         roleManager.addRoleChangeListener((RoleChangeListener) conductor);
 
@@ -223,8 +245,7 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF
         statisticsManager.setDeviceTerminationPhaseHandler(roleManager);
         roleManager.setDeviceTerminationPhaseHandler(deviceManager);
 
-        deviceManager.setStatisticsRpcEnabled(isStatisticsRpcEnabled);
-        deviceManager.setNotificationPublishService(notificationPublishService);
+        rpcManager.setStatisticsRpcEnabled(isStatisticsRpcEnabled);
 
         TranslatorLibraryUtil.setBasicTranslatorLibrary(deviceManager);
         deviceManager.initialize();
@@ -278,5 +299,8 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF
         // TODO: needs to close org.opendaylight.openflowplugin.impl.role.OpenflowOwnershipListener after RoleContexts are down
         // TODO: must not be executed prior to all living RoleContexts have been closed (via closing living DeviceContexts)
         roleManager.close();
+
+        // Manually shutdown all remaining running threads in pool
+        threadPool.shutdown();
     }
 }
index 191ea623ff3315e0dfc397a9cb1f1c03008bcbe1..c21a973948fc09a4a2ab0cceb2fd86834e09b534 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.openflowplugin.impl.connection;
 
+import com.google.common.base.Preconditions;
 import java.math.BigInteger;
 import java.net.InetSocketAddress;
 import java.util.concurrent.Callable;
@@ -16,17 +17,21 @@ import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
-
 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
 import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueue;
 import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueHandlerRegistration;
 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
 import org.opendaylight.openflowplugin.api.openflow.connection.HandshakeContext;
 import org.opendaylight.openflowplugin.api.openflow.connection.OutboundQueueProvider;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceDisconnectedHandler;
 import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.SessionStatistics;
+import org.opendaylight.openflowplugin.impl.util.DeviceStateUtil;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+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.openflow.protocol.rev130731.FeaturesReply;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -44,6 +49,7 @@ public class ConnectionContextImpl implements ConnectionContext {
     private OutboundQueueProvider outboundQueueProvider;
     private OutboundQueueHandlerRegistration<OutboundQueueProvider> outboundQueueHandlerRegistration;
     private HandshakeContext handshakeContext;
+    private DeviceInfo deviceInfo;
 
     /**
      * @param connectionAdapter
@@ -219,8 +225,87 @@ public class ConnectionContextImpl implements ConnectionContext {
         connectionState = CONNECTION_STATE.WORKING;
     }
 
+    @Override
+    public DeviceInfo getDeviceInfo() {
+        return this.deviceInfo;
+    }
+
+    @Override
+    public void handshakeSuccessful() {
+        Preconditions.checkNotNull(nodeId, "Cannot create DeviceInfo if 'NodeId' is not set!");
+        Preconditions.checkNotNull(featuresReply, "Cannot create DeviceInfo if 'features' is not set!");
+        this.deviceInfo = new DeviceInfoImpl(
+                nodeId,
+                DeviceStateUtil.createNodeInstanceIdentifier(nodeId),
+                featuresReply.getVersion(),
+                featuresReply.getDatapathId());
+    }
+
     @Override
     public void setHandshakeContext(HandshakeContext handshakeContext) {
         this.handshakeContext = handshakeContext;
     }
+
+
+    private class DeviceInfoImpl implements DeviceInfo {
+
+        final private NodeId nodeId;
+        final private KeyedInstanceIdentifier<Node, NodeKey> nodeII;
+        final private Short version;
+        final private BigInteger datapathId;
+
+        DeviceInfoImpl(
+                final NodeId nodeId,
+                final KeyedInstanceIdentifier<Node, NodeKey> nodeII,
+                final Short version,
+                final BigInteger datapathId) {
+            this.nodeId = nodeId;
+            this.nodeII = nodeII;
+            this.version = version;
+            this.datapathId = datapathId;
+        }
+
+        @Override
+        public NodeId getNodeId() {
+            return nodeId;
+        }
+
+        @Override
+        public KeyedInstanceIdentifier<Node, NodeKey> getNodeInstanceIdentifier() {
+            return nodeII;
+        }
+
+        @Override
+        public Short getVersion() {
+            return version;
+        }
+
+        @Override
+        public BigInteger getDatapathId() {
+            return datapathId;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            DeviceInfoImpl that = (DeviceInfoImpl) o;
+
+            if (!nodeId.equals(that.nodeId)) return false;
+            if (!nodeII.equals(that.nodeII)) return false;
+            if (!version.equals(that.version)) return false;
+            return datapathId.equals(that.datapathId);
+
+        }
+
+        @Override
+        public int hashCode() {
+            int result = nodeId.hashCode();
+            result = 31 * result + nodeII.hashCode();
+            result = 31 * result + version.hashCode();
+            result = 31 * result + datapathId.hashCode();
+            return result;
+        }
+    }
 }
index 31d986c2fc224046827df46db140fd8910986c37..6450e6d647087359314de308a9a52ce740ee40ed 100644 (file)
@@ -9,8 +9,7 @@
 package org.opendaylight.openflowplugin.impl.connection;
 
 import java.net.InetAddress;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
+import java.util.concurrent.ThreadPoolExecutor;
 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionReadyListener;
 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
@@ -26,7 +25,6 @@ import org.opendaylight.openflowplugin.impl.connection.listener.OpenflowProtocol
 import org.opendaylight.openflowplugin.impl.connection.listener.SystemNotificationsListenerImpl;
 import org.opendaylight.openflowplugin.openflow.md.core.ErrorHandlerSimpleImpl;
 import org.opendaylight.openflowplugin.openflow.md.core.HandshakeManagerImpl;
-import org.opendaylight.openflowplugin.openflow.md.core.ThreadPoolLoggingExecutor;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OpenflowProtocolListener;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SystemNotificationsListener;
 import org.slf4j.Logger;
@@ -42,21 +40,15 @@ public class ConnectionManagerImpl implements ConnectionManager {
     private final boolean bitmapNegotiationEnabled = true;
     private DeviceConnectedHandler deviceConnectedHandler;
     private final long echoReplyTimeout;
+    private final ThreadPoolExecutor threadPool;
 
-    public ConnectionManagerImpl(long echoReplyTimeout) {
+    public ConnectionManagerImpl(long echoReplyTimeout, final ThreadPoolExecutor threadPool) {
         this.echoReplyTimeout = echoReplyTimeout;
+        this.threadPool = threadPool;
     }
 
-
     @Override
     public void onSwitchConnected(final ConnectionAdapter connectionAdapter) {
-
-        LOG.trace("preparing handshake: {}", connectionAdapter.getRemoteAddress());
-
-        final int handshakeThreadLimit = 1;
-        final ThreadPoolLoggingExecutor handshakePool = createHandshakePool(
-                connectionAdapter.getRemoteAddress().toString(), handshakeThreadLimit);
-
         LOG.trace("prepare connection context");
         final ConnectionContext connectionContext = new ConnectionContextImpl(connectionAdapter);
 
@@ -64,7 +56,7 @@ public class ConnectionManagerImpl implements ConnectionManager {
         final HandshakeManager handshakeManager = createHandshakeManager(connectionAdapter, handshakeListener);
 
         LOG.trace("prepare handshake context");
-        HandshakeContext handshakeContext = new HandshakeContextImpl(handshakePool, handshakeManager);
+        HandshakeContext handshakeContext = new HandshakeContextImpl(threadPool, handshakeManager);
         handshakeListener.setHandshakeContext(handshakeContext);
         connectionContext.setHandshakeContext(handshakeContext);
 
@@ -77,24 +69,12 @@ public class ConnectionManagerImpl implements ConnectionManager {
                 new OpenflowProtocolListenerInitialImpl(connectionContext, handshakeContext);
         connectionAdapter.setMessageListener(ofMessageListener);
 
-        final SystemNotificationsListener systemListener = new SystemNotificationsListenerImpl(connectionContext, echoReplyTimeout);
+        final SystemNotificationsListener systemListener = new SystemNotificationsListenerImpl(connectionContext, echoReplyTimeout, threadPool);
         connectionAdapter.setSystemListener(systemListener);
 
         LOG.trace("connection ballet finished");
     }
 
-    /**
-     * @param connectionIdentifier
-     * @param handshakeThreadLimit
-     * @return
-     */
-    private static ThreadPoolLoggingExecutor createHandshakePool(
-            final String connectionIdentifier, final int handshakeThreadLimit) {
-        return new ThreadPoolLoggingExecutor(handshakeThreadLimit,
-                handshakeThreadLimit, 0L, TimeUnit.MILLISECONDS,
-                new LinkedBlockingQueue<>(HELLO_LIMIT), "OFHandshake-" + connectionIdentifier);
-    }
-
     /**
      * @param connectionAdapter
      * @param handshakeListener
@@ -119,7 +99,6 @@ public class ConnectionManagerImpl implements ConnectionManager {
         return bitmapNegotiationEnabled;
     }
 
-
     @Override
     public boolean accept(final InetAddress switchAddress) {
         // TODO add connection accept logic based on address
index e7142642b85c6010eaac4735bbb8de3e379c771f..1efadcc18b3a70c5a1c432201b5b4da13f129b14 100644 (file)
@@ -8,19 +8,13 @@
 package org.opendaylight.openflowplugin.impl.connection;
 
 import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
 import org.opendaylight.openflowplugin.api.openflow.connection.HandshakeContext;
 import org.opendaylight.openflowplugin.api.openflow.md.core.HandshakeManager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  *
  */
 public class HandshakeContextImpl implements HandshakeContext {
-
-    private static final Logger LOG = LoggerFactory.getLogger(HandshakeContextImpl.class);
-
     private ThreadPoolExecutor handshakePool;
     private HandshakeManager handshakeManager;
 
@@ -44,23 +38,6 @@ public class HandshakeContextImpl implements HandshakeContext {
     }
 
     @Override
-    public void close() throws Exception {
-        shutdownPoolPolitely();
-    }
-
-    private void shutdownPoolPolitely() {
-        LOG.debug("terminating handshake pool");
-        handshakePool.shutdown();
-        try {
-            handshakePool.awaitTermination(1, TimeUnit.SECONDS);
-        } catch (InterruptedException e) {
-            LOG.error("Error while awaiting termination on pool. Will use shutdownNow method.");
-        } finally {
-            handshakePool.purge();
-            if (! handshakePool.isTerminated()) {
-                handshakePool.shutdownNow();
-            }
-            LOG.debug("pool is terminated: {}", handshakePool.isTerminated());
-        }
+    public void close() {
     }
 }
index f843f59194289cc08368722d94636621fe8d68c0..3760ff79f2ba54c1ff2cd9c234e046a705b1eec5 100644 (file)
@@ -54,6 +54,7 @@ public class HandshakeListenerImpl implements HandshakeListener {
         connectionContext.changeStateToWorking();
         connectionContext.setFeatures(featureOutput);
         connectionContext.setNodeId(InventoryDataServiceUtil.nodeIdFromDatapathId(featureOutput.getDatapathId()));
+        connectionContext.handshakeSuccessful();
 
         // fire barrier in order to sweep all handshake and posthandshake messages before continue
         final ListenableFuture<RpcResult<BarrierOutput>> barrier = fireBarrier(version, 0L);
index 1d99f8073fddbddf78c19527150f086ac4efad7c..ae169a021f8e78730c5031d73eb768b4c7b2d826 100644 (file)
@@ -12,6 +12,7 @@ import com.google.common.base.Preconditions;
 import java.net.InetSocketAddress;
 import java.util.Date;
 import java.util.concurrent.Future;
+import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 import javax.annotation.Nonnull;
 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
@@ -37,8 +38,12 @@ public class SystemNotificationsListenerImpl implements SystemNotificationsListe
     @VisibleForTesting
     static final long MAX_ECHO_REPLY_TIMEOUT = 2000;
     private final long echoReplyTimeout;
+    private final ThreadPoolExecutor threadPool;
 
-    public SystemNotificationsListenerImpl(@Nonnull final ConnectionContext connectionContext, long echoReplyTimeout) {
+    public SystemNotificationsListenerImpl(@Nonnull final ConnectionContext connectionContext,
+                                           long echoReplyTimeout,
+                                           @Nonnull final ThreadPoolExecutor threadPool) {
+        this.threadPool = threadPool;
         this.connectionContext = Preconditions.checkNotNull(connectionContext);
         this.echoReplyTimeout = echoReplyTimeout;
     }
@@ -52,62 +57,59 @@ public class SystemNotificationsListenerImpl implements SystemNotificationsListe
 
     @Override
     public void onSwitchIdleEvent(final SwitchIdleEvent notification) {
-        new Thread(new Runnable() {
-            @Override
-            public void run() {
-                boolean shouldBeDisconnected = true;
+        threadPool.execute(() -> {
+            boolean shouldBeDisconnected = true;
 
-                final InetSocketAddress remoteAddress = connectionContext.getConnectionAdapter().getRemoteAddress();
+            final InetSocketAddress remoteAddress = connectionContext.getConnectionAdapter().getRemoteAddress();
 
-                if (ConnectionContext.CONNECTION_STATE.WORKING.equals(connectionContext.getConnectionState())) {
-                    FeaturesReply features = connectionContext.getFeatures();
-                    LOG.info("Switch Idle state occurred, node={}|auxId={}", remoteAddress, features.getAuxiliaryId());
-                    connectionContext.changeStateToTimeouting();
-                    EchoInputBuilder builder = new EchoInputBuilder();
-                    builder.setVersion(features.getVersion());
-                    Xid xid = new Xid(0L);
-                    builder.setXid(xid.getValue());
+            if (ConnectionContext.CONNECTION_STATE.WORKING.equals(connectionContext.getConnectionState())) {
+                FeaturesReply features = connectionContext.getFeatures();
+                LOG.info("Switch Idle state occurred, node={}|auxId={}", remoteAddress, features.getAuxiliaryId());
+                connectionContext.changeStateToTimeouting();
+                EchoInputBuilder builder = new EchoInputBuilder();
+                builder.setVersion(features.getVersion());
+                Xid xid = new Xid(0L);
+                builder.setXid(xid.getValue());
 
-                    Future<RpcResult<EchoOutput>> echoReplyFuture = connectionContext.getConnectionAdapter().echo(builder.build());
+                Future<RpcResult<EchoOutput>> echoReplyFuture = connectionContext.getConnectionAdapter().echo(builder.build());
 
-                    try {
-                        RpcResult<EchoOutput> echoReplyValue = echoReplyFuture.get(echoReplyTimeout, TimeUnit.MILLISECONDS);
-                        if (echoReplyValue.isSuccessful()) {
-                            connectionContext.changeStateToWorking();
-                            shouldBeDisconnected = false;
-                        } else {
-                            for (RpcError replyError : echoReplyValue.getErrors()) {
-                                Throwable cause = replyError.getCause();
-                                if (LOG.isWarnEnabled()) {
-                                    LOG.warn("Received EchoReply from [{}] in TIMEOUTING state, Error:{}", remoteAddress, cause.getMessage());
-                                }
-
-                                if (LOG.isTraceEnabled()) {
-                                    LOG.trace("Received EchoReply from [{}] in TIMEOUTING state, Error:{}", remoteAddress, cause);
-                                }
+                try {
+                    RpcResult<EchoOutput> echoReplyValue = echoReplyFuture.get(echoReplyTimeout, TimeUnit.MILLISECONDS);
+                    if (echoReplyValue.isSuccessful()) {
+                        connectionContext.changeStateToWorking();
+                        shouldBeDisconnected = false;
+                    } else {
+                        for (RpcError replyError : echoReplyValue.getErrors()) {
+                            Throwable cause = replyError.getCause();
+                            if (LOG.isWarnEnabled()) {
+                                LOG.warn("Received EchoReply from [{}] in TIMEOUTING state, Error:{}", remoteAddress, cause.getMessage());
+                            }
 
+                            if (LOG.isTraceEnabled()) {
+                                LOG.trace("Received EchoReply from [{}] in TIMEOUTING state, Error:{}", remoteAddress, cause);
                             }
-                        }
-                    } catch (Exception e) {
-                        if (LOG.isWarnEnabled()) {
-                            LOG.warn("Exception while  waiting for echoReply from [{}] in TIMEOUTING state: {}", remoteAddress, e.getMessage());
-                        }
 
-                        if (LOG.isTraceEnabled()) {
-                            LOG.trace("Exception while  waiting for echoReply from [{}] in TIMEOUTING state: {}", remoteAddress, e);
                         }
-
                     }
-                }
-                if (shouldBeDisconnected) {
-                    if (LOG.isInfoEnabled()) {
-                        LOG.info("ConnectionEvent:Closing connection as device is idle. Echo sent at {}. Device:{}, NodeId:{}",
-                                new Date(System.currentTimeMillis() - echoReplyTimeout), remoteAddress, connectionContext.getNodeId());
+                } catch (Exception e) {
+                    if (LOG.isWarnEnabled()) {
+                        LOG.warn("Exception while  waiting for echoReply from [{}] in TIMEOUTING state: {}", remoteAddress, e.getMessage());
+                    }
+
+                    if (LOG.isTraceEnabled()) {
+                        LOG.trace("Exception while  waiting for echoReply from [{}] in TIMEOUTING state: {}", remoteAddress, e);
                     }
 
-                    connectionContext.closeConnection(true);
                 }
             }
-        }).start();
+            if (shouldBeDisconnected) {
+                if (LOG.isInfoEnabled()) {
+                    LOG.info("ConnectionEvent:Closing connection as device is idle. Echo sent at {}. Device:{}, NodeId:{}",
+                            new Date(System.currentTimeMillis() - echoReplyTimeout), remoteAddress, connectionContext.getNodeId());
+                }
+
+                connectionContext.closeConnection(true);
+            }
+        });
     }
 }
index 28faad3263745e4c863970cc3486e7ae54237672..f85f29d06f5d6f717090a55095385e0b37b78673 100644 (file)
@@ -8,10 +8,8 @@
 package org.opendaylight.openflowplugin.impl.device;
 
 import com.google.common.annotations.VisibleForTesting;
-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.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -20,9 +18,6 @@ import java.math.BigInteger;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicLong;
-import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
@@ -34,6 +29,7 @@ import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey;
 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
 import org.opendaylight.openflowplugin.api.openflow.connection.OutboundQueueProvider;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
@@ -50,9 +46,7 @@ import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKe
 import org.opendaylight.openflowplugin.api.openflow.registry.group.DeviceGroupRegistry;
 import org.opendaylight.openflowplugin.api.openflow.registry.meter.DeviceMeterRegistry;
 import org.opendaylight.openflowplugin.api.openflow.rpc.ItemLifeCycleKeeper;
-import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext;
 import org.opendaylight.openflowplugin.api.openflow.rpc.listener.ItemLifecycleListener;
-import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsContext;
 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
 import org.opendaylight.openflowplugin.extension.api.ConvertorMessageFromOFJava;
 import org.opendaylight.openflowplugin.extension.api.ExtensionConverterProviderKeeper;
@@ -66,8 +60,6 @@ import org.opendaylight.openflowplugin.impl.registry.flow.DeviceFlowRegistryImpl
 import org.opendaylight.openflowplugin.impl.registry.flow.FlowRegistryKeyFactory;
 import org.opendaylight.openflowplugin.impl.registry.group.DeviceGroupRegistryImpl;
 import org.opendaylight.openflowplugin.impl.registry.meter.DeviceMeterRegistryImpl;
-import org.opendaylight.openflowplugin.impl.util.DeviceInitializationUtils;
-import org.opendaylight.openflowplugin.impl.util.MdSalRegistrationUtils;
 import org.opendaylight.openflowplugin.openflow.md.core.session.SwitchConnectionCookieOFImpl;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.message.service.rev151020.ExperimenterMessageFromDevBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
@@ -76,8 +68,6 @@ 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.Flow;
 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.NodeConnectorRef;
-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.node.NodeConnector;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder;
@@ -98,7 +88,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.experimenter
 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsDataBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.OfpRole;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
@@ -137,19 +126,12 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
     private final MessageTranslator<PacketInMessage, PacketReceived> packetInTranslator;
     private final MessageTranslator<FlowRemoved, org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved> flowRemovedTranslator;
     private final TranslatorLibrary translatorLibrary;
-    private final Map<Long, NodeConnectorRef> nodeConnectorCache;
     private final ItemLifeCycleRegistry itemLifeCycleSourceRegistry;
-    private RpcContext rpcContext;
     private ExtensionConverterProvider extensionConverterProvider;
 
-    private final boolean switchFeaturesMandatory;
-    private StatisticsContext statisticsContext;
-
-    private final NodeId nodeId;
-
-    private volatile DEVICE_CONTEXT_STATE deviceCtxState;
-    private boolean isStatisticsRpcEnabled;
+    private final DeviceInfo deviceInfo;
 
+    private volatile CONTEXT_STATE contextState;
 
     @VisibleForTesting
     DeviceContextImpl(@Nonnull final ConnectionContext primaryConnectionContext,
@@ -157,41 +139,36 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
                       @Nonnull final DataBroker dataBroker,
                       @Nonnull final LifecycleConductor conductor,
                       @Nonnull final OutboundQueueProvider outboundQueueProvider,
-                      @Nonnull final TranslatorLibrary translatorLibrary,
-                      final boolean switchFeaturesMandatory) {
-        this.switchFeaturesMandatory = switchFeaturesMandatory;
+                      @Nonnull final TranslatorLibrary translatorLibrary) {
         this.primaryConnectionContext = Preconditions.checkNotNull(primaryConnectionContext);
         this.deviceState = Preconditions.checkNotNull(deviceState);
         this.dataBroker = Preconditions.checkNotNull(dataBroker);
         Preconditions.checkNotNull(conductor);
         this.outboundQueueProvider = Preconditions.checkNotNull(outboundQueueProvider);
-        this.transactionChainManager = new TransactionChainManager(dataBroker, deviceState, conductor);
+        deviceInfo = primaryConnectionContext.getDeviceInfo();
+        this.transactionChainManager = new TransactionChainManager(dataBroker, deviceInfo, conductor);
         auxiliaryConnectionContexts = new HashMap<>();
         deviceFlowRegistry = new DeviceFlowRegistryImpl();
         deviceGroupRegistry = new DeviceGroupRegistryImpl();
         deviceMeterRegistry = new DeviceMeterRegistryImpl();
         messageSpy = conductor.getMessageIntelligenceAgency();
 
+
         packetInLimiter = new PacketInRateLimiter(primaryConnectionContext.getConnectionAdapter(),
                 /*initial*/ 1000, /*initial*/2000, messageSpy, REJECTED_DRAIN_FACTOR);
 
         this.translatorLibrary = translatorLibrary;
         portStatusTranslator = translatorLibrary.lookupTranslator(
-                new TranslatorKey(deviceState.getVersion(), PortGrouping.class.getName()));
+                new TranslatorKey(deviceInfo.getVersion(), PortGrouping.class.getName()));
         packetInTranslator = translatorLibrary.lookupTranslator(
-                new TranslatorKey(deviceState.getVersion(), PacketIn.class.getName()));
+                new TranslatorKey(deviceInfo.getVersion(), PacketIn.class.getName()));
         flowRemovedTranslator = translatorLibrary.lookupTranslator(
-                new TranslatorKey(deviceState.getVersion(), FlowRemoved.class.getName()));
-
-
-        nodeConnectorCache = new ConcurrentHashMap<>();
+                new TranslatorKey(deviceInfo.getVersion(), FlowRemoved.class.getName()));
 
         itemLifeCycleSourceRegistry = new ItemLifeCycleRegistryImpl();
         flowLifeCycleKeeper = new ItemLifeCycleSourceImpl();
         itemLifeCycleSourceRegistry.registerLifeCycleSource(flowLifeCycleKeeper);
-        deviceCtxState = DEVICE_CONTEXT_STATE.INITIALIZATION;
-
-        nodeId = primaryConnectionContext.getNodeId();
+        contextState = CONTEXT_STATE.INITIALIZATION;
     }
 
     /**
@@ -221,7 +198,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
     public void removeAuxiliaryConnectionContext(final ConnectionContext connectionContext) {
         final SwitchConnectionDistinguisher connectionDistinguisher = createConnectionDistinguisher(connectionContext);
         LOG.debug("auxiliary connection dropped: {}, nodeId:{}", connectionContext.getConnectionAdapter()
-                .getRemoteAddress(), nodeId);
+                .getRemoteAddress(), deviceInfo.getNodeId());
         auxiliaryConnectionContexts.remove(connectionDistinguisher);
     }
 
@@ -231,102 +208,13 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
     }
 
     @Override
-    public ReadOnlyTransaction getReadTransaction() {
-        return dataBroker.newReadOnlyTransaction();
-    }
-
-    @Override
-    public ListenableFuture<Void> onClusterRoleChange(final OfpRole oldRole, @CheckForNull final OfpRole role) {
-        LOG.trace("onClusterRoleChange {} for node:", role, nodeId);
-        Preconditions.checkArgument(role != null);
-        if (role.equals(oldRole)) {
-            LOG.debug("Demanded role change for device {} is not changed. OldRole: {}, NewRole {}", nodeId, oldRole, role);
-            return Futures.immediateFuture(null);
-        }
-        if (OfpRole.BECOMEMASTER.equals(role)) {
-            return onDeviceTakeClusterLeadership();
-        } else if (OfpRole.BECOMESLAVE.equals(role)) {
-            return onDeviceLostClusterLeadership();
-        } else {
-            LOG.warn("Unknown OFCluster Role {} for Node {}", role, nodeId);
-            if (null != rpcContext) {
-                MdSalRegistrationUtils.unregisterServices(rpcContext);
-            }
-            return transactionChainManager.deactivateTransactionManager();
-        }
+    public DeviceInfo getDeviceInfo() {
+        return this.deviceInfo;
     }
 
     @Override
-    public ListenableFuture<Void> onDeviceLostClusterLeadership() {
-        LOG.trace("onDeviceLostClusterLeadership for node: {}", nodeId);
-        if (null != rpcContext) {
-            MdSalRegistrationUtils.registerSlaveServices(rpcContext, OfpRole.BECOMESLAVE);
-        }
-        return transactionChainManager.deactivateTransactionManager();
-    }
-
-    @Override
-    public ListenableFuture<Void> onDeviceTakeClusterLeadership() {
-        LOG.trace("onDeviceTakeClusterLeadership for node: {}", nodeId);
-        /* validation */
-        if (statisticsContext == null) {
-            final String errMsg = String.format("DeviceCtx %s is up but we are missing StatisticsContext", nodeId);
-            LOG.warn(errMsg);
-            return Futures.immediateFailedFuture(new IllegalStateException(errMsg));
-        }
-        if (rpcContext == null) {
-            final String errMsg = String.format("DeviceCtx %s is up but we are missing RpcContext", nodeId);
-            LOG.warn(errMsg);
-            return Futures.immediateFailedFuture(new IllegalStateException(errMsg));
-        }
-        /* Routed RPC registration */
-        MdSalRegistrationUtils.registerMasterServices(getRpcContext(), DeviceContextImpl.this, OfpRole.BECOMEMASTER);
-
-        if (isStatisticsRpcEnabled) {
-            MdSalRegistrationUtils.registerStatCompatibilityServices(getRpcContext(), this,
-                    notificationPublishService, new AtomicLong());
-        }
-
-        /* Prepare init info collecting */
-        getDeviceState().setDeviceSynchronized(false);
-        transactionChainManager.activateTransactionManager();
-        /* Init Collecting NodeInfo */
-        final ListenableFuture<Void> initCollectingDeviceInfo = DeviceInitializationUtils.initializeNodeInformation(
-                DeviceContextImpl.this, switchFeaturesMandatory);
-        /* Init Collecting StatInfo */
-        final ListenableFuture<Boolean> statPollFuture = Futures.transform(initCollectingDeviceInfo,
-                new AsyncFunction<Void, Boolean>() {
-
-                    @Override
-                    public ListenableFuture<Boolean> apply(@Nonnull final Void input) throws Exception {
-                        getStatisticsContext().statListForCollectingInitialization();
-                        return getStatisticsContext().gatherDynamicData();
-                    }
-                });
-
-        return Futures.transform(statPollFuture, new Function<Boolean, Void>() {
-
-            @Override
-            public Void apply(final Boolean input) {
-                if (ConnectionContext.CONNECTION_STATE.RIP.equals(getPrimaryConnectionContext().getConnectionState())) {
-                    final String errMsg = String.format("We lost connection for Device %s, context has to be closed.",
-                            getDeviceState().getNodeId());
-                    LOG.warn(errMsg);
-                    throw new IllegalStateException(errMsg);
-                }
-                if (!input) {
-                    final String errMsg = String.format("Get Initial Device %s information fails",
-                            getDeviceState().getNodeId());
-                    LOG.warn(errMsg);
-                    throw new IllegalStateException(errMsg);
-                }
-                LOG.debug("Get Initial Device {} information is successful", nodeId);
-                getDeviceState().setDeviceSynchronized(true);
-                initialSubmitTransaction();
-                getDeviceState().setStatisticsPollingEnabledProp(true);
-                return null;
-            }
-        });
+    public ReadOnlyTransaction getReadTransaction() {
+        return dataBroker.newReadOnlyTransaction();
     }
 
     @Override
@@ -393,11 +281,14 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
 
     @Override
     public void processFlowRemovedMessage(final FlowRemoved flowRemoved) {
+        //1. translate to general flow (table, priority, match, cookie)
+        final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved flowRemovedNotification =
+                flowRemovedTranslator.translate(flowRemoved, deviceInfo, null);
+        // Trigger off a notification
+        notificationPublishService.offerNotification(flowRemovedNotification);
+
         final ItemLifecycleListener itemLifecycleListener = flowLifeCycleKeeper.getItemLifecycleListener();
         if (itemLifecycleListener != null) {
-            //1. translate to general flow (table, priority, match, cookie)
-            final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved flowRemovedNotification =
-                    flowRemovedTranslator.translate(flowRemoved, this.getDeviceState(), null);
             //2. create registry key
             final FlowRegistryKey flowRegKey = FlowRegistryKeyFactory.create(flowRemovedNotification);
             //3. lookup flowId
@@ -405,17 +296,15 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
             //4. if flowId present:
             if (flowDescriptor != null) {
                 // a) construct flow path
-                final KeyedInstanceIdentifier<Flow, FlowKey> flowPath = getDeviceState().getNodeInstanceIdentifier()
+                final KeyedInstanceIdentifier<Flow, FlowKey> flowPath = getDeviceInfo().getNodeInstanceIdentifier()
                         .augmentation(FlowCapableNode.class)
                         .child(Table.class, flowDescriptor.getTableKey())
                         .child(Flow.class, new FlowKey(flowDescriptor.getFlowId()));
                 // b) notify listener
                 itemLifecycleListener.onRemoved(flowPath);
-                // c) trigger off a notification
-                notificationPublishService.offerNotification(flowRemovedNotification);
             } else {
                 LOG.debug("flow id not found: nodeId={} tableId={}, priority={}",
-                        getDeviceState().getNodeId(), flowRegKey.getTableId(), flowRemovedNotification.getPriority());
+                        getDeviceInfo().getNodeId(), flowRegKey.getTableId(), flowRemovedNotification.getPriority());
             }
         }
     }
@@ -423,7 +312,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
     @Override
     public void processPortStatusMessage(final PortStatusMessage portStatus) {
         messageSpy.spyMessage(portStatus.getImplementedInterface(), MessageSpy.STATISTIC_GROUP.FROM_SWITCH_PUBLISHED_SUCCESS);
-        final FlowCapableNodeConnector flowCapableNodeConnector = portStatusTranslator.translate(portStatus, this.getDeviceState(), null);
+        final FlowCapableNodeConnector flowCapableNodeConnector = portStatusTranslator.translate(portStatus, deviceInfo, null);
 
         final KeyedInstanceIdentifier<NodeConnector, NodeConnectorKey> iiToNodeConnector = provideIIToNodeConnector(portStatus.getPortNo(), portStatus.getVersion());
         try {
@@ -443,8 +332,8 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
     }
 
     private KeyedInstanceIdentifier<NodeConnector, NodeConnectorKey> provideIIToNodeConnector(final long portNo, final short version) {
-        final InstanceIdentifier<Node> iiToNodes = deviceState.getNodeInstanceIdentifier();
-        final BigInteger dataPathId = deviceState.getFeatures().getDatapathId();
+        final InstanceIdentifier<Node> iiToNodes = deviceInfo.getNodeInstanceIdentifier();
+        final BigInteger dataPathId = deviceInfo.getDatapathId();
         final NodeConnectorId nodeConnectorId = NodeStaticReplyTranslatorUtil.nodeConnectorId(dataPathId.toString(), portNo, version);
         return iiToNodes.child(NodeConnector.class, new NodeConnectorKey(nodeConnectorId));
     }
@@ -453,7 +342,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
     public void processPacketInMessage(final PacketInMessage packetInMessage) {
         messageSpy.spyMessage(packetInMessage.getImplementedInterface(), MessageSpy.STATISTIC_GROUP.FROM_SWITCH);
         final ConnectionAdapter connectionAdapter = getPrimaryConnectionContext().getConnectionAdapter();
-        final PacketReceived packetReceived = packetInTranslator.translate(packetInMessage, this.getDeviceState(), null);
+        final PacketReceived packetReceived = packetInTranslator.translate(packetInMessage, deviceInfo, null);
 
         if (packetReceived == null) {
             LOG.debug("Received a null packet from switch {}", connectionAdapter.getRemoteAddress());
@@ -501,13 +390,13 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
         // lookup converter
         final ExperimenterDataOfChoice vendorData = notification.getExperimenterDataOfChoice();
         final MessageTypeKey<? extends ExperimenterDataOfChoice> key = new MessageTypeKey<>(
-                deviceState.getVersion(),
+                deviceInfo.getVersion(),
                 (Class<? extends ExperimenterDataOfChoice>) vendorData.getImplementedInterface());
         final ConvertorMessageFromOFJava<ExperimenterDataOfChoice, MessagePath> messageConverter = extensionConverterProvider.getMessageConverter(key);
         if (messageConverter == null) {
             LOG.warn("custom converter for {}[OF:{}] not found",
                     notification.getExperimenterDataOfChoice().getImplementedInterface(),
-                    deviceState.getVersion());
+                    deviceInfo.getVersion());
             return;
         }
         // build notification
@@ -515,7 +404,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
         try {
             messageOfChoice = messageConverter.convert(vendorData, MessagePath.MESSAGE_NOTIFICATION);
             final ExperimenterMessageFromDevBuilder experimenterMessageFromDevBld = new ExperimenterMessageFromDevBuilder()
-                .setNode(new NodeRef(deviceState.getNodeInstanceIdentifier()))
+                .setNode(new NodeRef(deviceInfo.getNodeInstanceIdentifier()))
                     .setExperimenterMessageOfChoice(messageOfChoice);
             // publish
             notificationPublishService.offerNotification(experimenterMessageFromDevBld.build());
@@ -533,7 +422,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
     public synchronized void close() {
         LOG.debug("closing deviceContext: {}, nodeId:{}",
                 getPrimaryConnectionContext().getConnectionAdapter().getRemoteAddress(),
-                getDeviceState().getNodeId());
+                getDeviceInfo().getNodeId());
         // NOOP
         throw new UnsupportedOperationException("Autocloseble.close will be removed soon");
     }
@@ -560,8 +449,8 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
 
     @Override
     public void onPublished() {
-        Verify.verify(DEVICE_CONTEXT_STATE.INITIALIZATION.equals(deviceCtxState));
-        deviceCtxState = DEVICE_CONTEXT_STATE.WORKING;
+        Verify.verify(CONTEXT_STATE.INITIALIZATION.equals(contextState));
+        contextState = CONTEXT_STATE.WORKING;
         primaryConnectionContext.getConnectionAdapter().setPacketInFiltering(false);
         for (final ConnectionContext switchAuxConnectionContext : auxiliaryConnectionContexts.values()) {
             switchAuxConnectionContext.getConnectionAdapter().setPacketInFiltering(false);
@@ -573,18 +462,6 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
         return new MultiMsgCollectorImpl(this, requestContext);
     }
 
-    @Override
-    public NodeConnectorRef lookupNodeConnectorRef(final Long portNumber) {
-        return nodeConnectorCache.get(portNumber);
-    }
-
-    @Override
-    public void storeNodeConnectorRef(@Nonnull final Long portNumber, @Nonnull final NodeConnectorRef nodeConnectorRef) {
-        nodeConnectorCache.put(
-                Preconditions.checkNotNull(portNumber),
-                Preconditions.checkNotNull(nodeConnectorRef));
-    }
-
     @Override
     public void updatePacketInRateLimit(final long upperBound) {
         packetInLimiter.changeWaterMarks((int) (LOW_WATERMARK_FACTOR * upperBound), (int) (HIGH_WATERMARK_FACTOR * upperBound));
@@ -595,16 +472,6 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
         return itemLifeCycleSourceRegistry;
     }
 
-    @Override
-    public void setRpcContext(final RpcContext rpcContext) {
-        this.rpcContext = rpcContext;
-    }
-
-    @Override
-    public RpcContext getRpcContext() {
-        return rpcContext;
-    }
-
     @Override
     public void setExtensionConverterProvider(final ExtensionConverterProvider extensionConverterProvider) {
         this.extensionConverterProvider = extensionConverterProvider;
@@ -615,28 +482,17 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
         return extensionConverterProvider;
     }
 
-    @Override
-    public void setStatisticsContext(final StatisticsContext statisticsContext) {
-        this.statisticsContext = statisticsContext;
-    }
-
-    @Override
-    public StatisticsContext getStatisticsContext() {
-        return statisticsContext;
-    }
-
     @Override
     public synchronized void shutdownConnection() {
-        LOG.debug("Shutdown method for node {}", nodeId);
-        deviceState.setValid(false);
-        if (DEVICE_CONTEXT_STATE.TERMINATION.equals(deviceCtxState)) {
-            LOG.debug("DeviceCtx for Node {} is in termination process.", nodeId);
+        LOG.debug("Shutdown method for node {}", deviceInfo.getNodeId());
+        if (CONTEXT_STATE.TERMINATION.equals(contextState)) {
+            LOG.debug("DeviceCtx for Node {} is in termination process.", deviceInfo.getNodeId());
             return;
         }
-        deviceCtxState = DEVICE_CONTEXT_STATE.TERMINATION;
+        contextState = CONTEXT_STATE.TERMINATION;
 
         if (ConnectionContext.CONNECTION_STATE.RIP.equals(getPrimaryConnectionContext().getConnectionState())) {
-            LOG.debug("ConnectionCtx for Node {} is in RIP state.", deviceState.getNodeId());
+            LOG.debug("ConnectionCtx for Node {} is in RIP state.", deviceInfo.getNodeId());
             return;
         }
         /* Terminate Auxiliary Connection */
@@ -652,19 +508,8 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
         deviceMeterRegistry.close();
     }
 
-    @Override
-    public void setStatisticsRpcEnabled(boolean isStatisticsRpcEnabled) {
-        this.isStatisticsRpcEnabled = isStatisticsRpcEnabled;
-    }
-
-    @Override
-    public DEVICE_CONTEXT_STATE getDeviceContextState() {
-        return deviceCtxState;
-    }
-
     @Override
     public ListenableFuture<Void> shuttingDownDataStoreTransactions() {
-        deviceState.setValid(false);
         return transactionChainManager.shuttingDown();
     }
 
@@ -672,4 +517,9 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
     TransactionChainManager getTransactionChainManager() {
         return this.transactionChainManager;
     }
+
+    @Override
+    public CONTEXT_STATE getState() {
+        return this.contextState;
+    }
 }
index 31df880261d5dd668047c2b57febe1142531ca44..fce73471c7327f91a309f3c8ebe97ead412a4911 100644 (file)
@@ -8,16 +8,19 @@
 package org.opendaylight.openflowplugin.impl.device;
 
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Verify;
 import com.google.common.collect.Iterators;
+import com.google.common.util.concurrent.AsyncFunction;
 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.Timeout;
 import io.netty.util.TimerTask;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.Iterator;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ExecutionException;
@@ -26,28 +29,33 @@ import java.util.concurrent.TimeUnit;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 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.data.LogicalDatastoreType;
 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
 import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueHandlerRegistration;
+import org.opendaylight.openflowplugin.api.openflow.OFPContext;
 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
 import org.opendaylight.openflowplugin.api.openflow.connection.OutboundQueueProvider;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceManager;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceSynchronizeListener;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceValidListener;
 import org.opendaylight.openflowplugin.api.openflow.device.TranslatorLibrary;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceInitializationPhaseHandler;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceTerminationPhaseHandler;
 import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleConductor;
+import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsContext;
 import org.opendaylight.openflowplugin.extension.api.ExtensionConverterProviderKeeper;
 import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
 import org.opendaylight.openflowplugin.impl.connection.OutboundQueueProviderImpl;
 import org.opendaylight.openflowplugin.impl.device.listener.OpenflowProtocolListenerFullImpl;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.openflowplugin.impl.util.DeviceInitializationUtils;
 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.role.service.rev150727.OfpRole;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -68,17 +76,17 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
     private TranslatorLibrary translatorLibrary;
     private DeviceInitializationPhaseHandler deviceInitPhaseHandler;
     private DeviceTerminationPhaseHandler deviceTerminPhaseHandler;
-    private NotificationPublishService notificationPublishService;
 
-    private final ConcurrentMap<NodeId, DeviceContext> deviceContexts = new ConcurrentHashMap<>();
+    private final ConcurrentMap<DeviceInfo, DeviceContext> deviceContexts = new ConcurrentHashMap<>();
 
     private final long barrierIntervalNanos;
     private final int barrierCountLimit;
     private ExtensionConverterProvider extensionConverterProvider;
     private ScheduledThreadPoolExecutor spyPool;
+    private Set<DeviceSynchronizeListener> deviceSynchronizedListeners;
+    private Set<DeviceValidListener> deviceValidListeners;
 
     private final LifecycleConductor conductor;
-    private boolean isStatisticsRpcEnabled;
 
     public DeviceManagerImpl(@Nonnull final DataBroker dataBroker,
                              final long globalNotificationQuota, final boolean switchFeaturesMandatory,
@@ -105,6 +113,8 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
 
         this.conductor = lifecycleConductor;
         spyPool = new ScheduledThreadPoolExecutor(1);
+        this.deviceSynchronizedListeners = new HashSet<>();
+        this.deviceValidListeners = new HashSet<>();
     }
 
 
@@ -114,10 +124,10 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
     }
 
     @Override
-    public void onDeviceContextLevelUp(final NodeId nodeId) throws Exception {
+    public void onDeviceContextLevelUp(@CheckForNull DeviceInfo deviceInfo) throws Exception {
         // final phase - we have to add new Device to MD-SAL DataStore
-        LOG.debug("Final phase of DeviceContextLevelUp for Node: {} ", nodeId);
-        DeviceContext deviceContext = Preconditions.checkNotNull(deviceContexts.get(nodeId));
+        LOG.debug("Final phase of DeviceContextLevelUp for Node: {} ", deviceInfo.getNodeId());
+        DeviceContext deviceContext = Preconditions.checkNotNull(deviceContexts.get(deviceInfo));
         ((DeviceContextImpl) deviceContext).initialSubmitTransaction();
         deviceContext.onPublished();
     }
@@ -126,19 +136,19 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
     public boolean deviceConnected(@CheckForNull final ConnectionContext connectionContext) throws Exception {
         Preconditions.checkArgument(connectionContext != null);
 
-        NodeId nodeId = connectionContext.getNodeId();
+        DeviceInfo deviceInfo = connectionContext.getDeviceInfo();
         /**
          * This part prevent destroy another device context. Throwing here an exception result to propagate close connection
          * 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(nodeId)) {
+         if (deviceContexts.containsKey(deviceInfo)) {
             LOG.warn("Rejecting connection from node which is already connected and there exist deviceContext for it: {}", connectionContext.getNodeId());
              return false;
          }
 
         LOG.info("ConnectionEvent: Device connected to controller, Device:{}, NodeId:{}",
-                connectionContext.getConnectionAdapter().getRemoteAddress(), nodeId);
+                connectionContext.getConnectionAdapter().getRemoteAddress(), deviceInfo.getNodeId());
 
         // Add Disconnect handler
         connectionContext.setDeviceDisconnectedHandler(DeviceManagerImpl.this);
@@ -148,43 +158,41 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
         //FIXME: as soon as auxiliary connection are fully supported then this is needed only before device context published
         connectionAdapter.setPacketInFiltering(true);
 
-        final Short version = connectionContext.getFeatures().getVersion();
-        final OutboundQueueProvider outboundQueueProvider = new OutboundQueueProviderImpl(version);
+        final OutboundQueueProvider outboundQueueProvider = new OutboundQueueProviderImpl(deviceInfo.getVersion());
 
         connectionContext.setOutboundQueueProvider(outboundQueueProvider);
         final OutboundQueueHandlerRegistration<OutboundQueueProvider> outboundQueueHandlerRegistration =
                 connectionAdapter.registerOutboundQueueHandler(outboundQueueProvider, barrierCountLimit, barrierIntervalNanos);
         connectionContext.setOutboundQueueHandleRegistration(outboundQueueHandlerRegistration);
 
-        final DeviceState deviceState = createDeviceState(connectionContext);
+        final DeviceState deviceState = new DeviceStateImpl(deviceInfo);
+        this.addDeviceSynchronizeListener(deviceState);
+        this.addDeviceValidListener(deviceState);
+
         final DeviceContext deviceContext = new DeviceContextImpl(connectionContext,
                 deviceState,
                 dataBroker,
                 conductor,
                 outboundQueueProvider,
-                translatorLibrary,
-                switchFeaturesMandatory);
+                translatorLibrary);
 
-        Verify.verify(deviceContexts.putIfAbsent(nodeId, deviceContext) == null, "DeviceCtx still not closed.");
+        Verify.verify(deviceContexts.putIfAbsent(deviceInfo, deviceContext) == null, "DeviceCtx still not closed.");
 
         ((ExtensionConverterProviderKeeper) deviceContext).setExtensionConverterProvider(extensionConverterProvider);
-        deviceContext.setStatisticsRpcEnabled(isStatisticsRpcEnabled);
-        deviceContext.setNotificationPublishService(notificationPublishService);
+        deviceContext.setNotificationPublishService(conductor.getNotificationPublishService());
 
         updatePacketInRateLimiters();
 
         final OpenflowProtocolListenerFullImpl messageListener = new OpenflowProtocolListenerFullImpl(
                 connectionAdapter, deviceContext);
         connectionAdapter.setMessageListener(messageListener);
-        deviceState.setValid(true);
+        notifyDeviceValidListeners(deviceInfo, true);
 
-        deviceInitPhaseHandler.onDeviceContextLevelUp(nodeId);
+        deviceInitPhaseHandler.onDeviceContextLevelUp(connectionContext.getDeviceInfo());
 
-        return true;
-    }
+        notifyDeviceSynchronizeListeners(deviceInfo, true);
 
-    private static DeviceStateImpl createDeviceState(final @Nonnull ConnectionContext connectionContext) {
-        return new DeviceStateImpl(connectionContext.getFeatures(), connectionContext.getNodeId());
+        return true;
     }
 
     private void updatePacketInRateLimiters() {
@@ -213,16 +221,12 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
         this.translatorLibrary = translatorLibrary;
     }
 
-    @Override
-    public void setNotificationPublishService(final NotificationPublishService notificationService) {
-        notificationPublishService = notificationService;
-    }
-
     @Override
     public void close() {
         for (final Iterator<DeviceContext> iterator = Iterators.consumingIterator(deviceContexts.values().iterator());
                 iterator.hasNext();) {
             final DeviceContext deviceCtx = iterator.next();
+            notifyDeviceValidListeners(deviceCtx.getDeviceInfo(), false);
             deviceCtx.shutdownConnection();
             deviceCtx.shuttingDownDataStoreTransactions();
         }
@@ -234,9 +238,9 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
     }
 
     @Override
-    public void onDeviceContextLevelDown(final DeviceContext deviceContext) {
-        LOG.debug("onDeviceContextClosed for Node {}", deviceContext.getDeviceState().getNodeId());
-        deviceContexts.remove(deviceContext.getPrimaryConnectionContext().getNodeId(), deviceContext);
+    public void onDeviceContextLevelDown(final DeviceInfo deviceInfo) {
+        LOG.debug("onDeviceContextClosed for Node {}", deviceInfo.getNodeId());
+        deviceContexts.remove(deviceInfo);
         updatePacketInRateLimiters();
     }
 
@@ -245,16 +249,6 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
         spyPool.scheduleAtFixedRate(conductor.getMessageIntelligenceAgency(), spyRate, spyRate, TimeUnit.SECONDS);
     }
 
-    @Override
-    public DeviceContext getDeviceContextFromNodeId(final NodeId nodeId) {
-        return deviceContexts.get(nodeId);
-    }
-
-    @Override
-    public void setStatisticsRpcEnabled(boolean isStatisticsRpcEnabled) {
-        this.isStatisticsRpcEnabled = isStatisticsRpcEnabled;
-    }
-
     @Override
     public void setExtensionConverterProvider(final ExtensionConverterProvider extensionConverterProvider) {
         this.extensionConverterProvider = extensionConverterProvider;
@@ -273,11 +267,11 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
     @Override
     public void onDeviceDisconnected(final ConnectionContext connectionContext) {
         LOG.trace("onDeviceDisconnected method call for Node: {}", connectionContext.getNodeId());
-        final NodeId nodeId = connectionContext.getNodeId();
-        final DeviceContext deviceCtx = this.deviceContexts.get(nodeId);
+        final DeviceInfo deviceInfo = connectionContext.getDeviceInfo();
+        final DeviceContext deviceCtx = this.deviceContexts.get(deviceInfo);
 
         if (null == deviceCtx) {
-            LOG.info("DeviceContext for Node {} was not found. Connection is terminated without OFP context suite.", nodeId);
+            LOG.info("DeviceContext for Node {} was not found. Connection is terminated without OFP context suite.", deviceInfo.getNodeId());
             return;
         }
 
@@ -285,31 +279,28 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
             /* Connection is not PrimaryConnection so try to remove from Auxiliary Connections */
             deviceCtx.removeAuxiliaryConnectionContext(connectionContext);
         } else {
+            notifyDeviceValidListeners(deviceInfo, false);
             /* Device is disconnected and so we need to close TxManager */
             final ListenableFuture<Void> future = deviceCtx.shuttingDownDataStoreTransactions();
             Futures.addCallback(future, new FutureCallback<Void>() {
 
                 @Override
                 public void onSuccess(final Void result) {
-                    LOG.debug("TxChainManager for device {} is closed successful.", nodeId);
-                    deviceTerminPhaseHandler.onDeviceContextLevelDown(deviceCtx);
+                    LOG.debug("TxChainManager for device {} is closed successful.", deviceInfo.getNodeId());
+                    deviceTerminPhaseHandler.onDeviceContextLevelDown(deviceInfo);
                 }
 
                 @Override
                 public void onFailure(final Throwable t) {
-                    LOG.warn("TxChainManager for device {} failed by closing.", nodeId, t);
-                    deviceTerminPhaseHandler.onDeviceContextLevelDown(deviceCtx);
+                    LOG.warn("TxChainManager for device {} failed by closing.", deviceInfo.getNodeId(), t);
+                    deviceTerminPhaseHandler.onDeviceContextLevelDown(deviceInfo);
                 }
             });
             /* Add timer for Close TxManager because it could fain ind cluster without notification */
-            final TimerTask timerTask = new TimerTask() {
-
-                @Override
-                public void run(final Timeout timeout) throws Exception {
-                    if (!future.isDone()) {
-                        LOG.info("Shutting down TxChain for node {} not completed during 10 sec. Continue anyway.", nodeId);
-                        future.cancel(false);
-                    }
+            final TimerTask timerTask = timeout -> {
+                if (!future.isDone()) {
+                    LOG.info("Shutting down TxChain for node {} not completed during 10 sec. Continue anyway.", deviceInfo.getNodeId());
+                    future.cancel(false);
                 }
             };
             conductor.newTimeout(timerTask, 10, TimeUnit.SECONDS);
@@ -317,7 +308,99 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
     }
 
     @VisibleForTesting
-    void addDeviceContextToMap(final NodeId nodeId, final DeviceContext deviceContext){
-        deviceContexts.put(nodeId, deviceContext);
+    void addDeviceContextToMap(final DeviceInfo deviceInfo, final DeviceContext deviceContext){
+        deviceContexts.put(deviceInfo, deviceContext);
+    }
+
+    @Override
+    public <T extends OFPContext> T gainContext(final DeviceInfo deviceInfo) {
+        return (T) deviceContexts.get(deviceInfo);
+    }
+
+    @Override
+    public ListenableFuture<Void> onClusterRoleChange(final DeviceInfo deviceInfo, final OfpRole role) {
+        DeviceContext deviceContext = conductor.getDeviceContext(deviceInfo);
+        LOG.trace("onClusterRoleChange {} for node:", role, deviceInfo.getNodeId());
+        if (OfpRole.BECOMEMASTER.equals(role)) {
+            return onDeviceTakeClusterLeadership(deviceInfo);
+        }
+        return ((DeviceContextImpl)deviceContext).getTransactionChainManager().deactivateTransactionManager();
     }
+
+    @Override
+    public void addDeviceSynchronizeListener(final DeviceSynchronizeListener deviceSynchronizeListener) {
+        this.deviceSynchronizedListeners.add(deviceSynchronizeListener);
+    }
+
+    @Override
+    public void notifyDeviceSynchronizeListeners(final DeviceInfo deviceInfo, final boolean deviceSynchronized) {
+        for (DeviceSynchronizeListener listener : deviceSynchronizedListeners) {
+            listener.deviceIsSynchronized(deviceInfo, deviceSynchronized);
+        }
+    }
+
+    @Override
+    public void addDeviceValidListener(final DeviceValidListener deviceValidListener) {
+        this.deviceValidListeners.add(deviceValidListener);
+    }
+
+    @Override
+    public void notifyDeviceValidListeners(final DeviceInfo deviceInfo, final boolean deviceValid) {
+        for (DeviceValidListener listener : deviceValidListeners) {
+            listener.deviceIsValid(deviceInfo, deviceValid);
+        }
+    }
+
+    private ListenableFuture<Void> onDeviceTakeClusterLeadership(final DeviceInfo deviceInfo) {
+        LOG.trace("onDeviceTakeClusterLeadership for node: {}", deviceInfo.getNodeId());
+        /* validation */
+        StatisticsContext statisticsContext = conductor.getStatisticsContext(deviceInfo);
+        if (statisticsContext == null) {
+            final String errMsg = String.format("DeviceCtx %s is up but we are missing StatisticsContext", deviceInfo.getDatapathId());
+            LOG.warn(errMsg);
+            return Futures.immediateFailedFuture(new IllegalStateException(errMsg));
+        }
+        DeviceContext deviceContext = conductor.getDeviceContext(deviceInfo);
+        /* Prepare init info collecting */
+        notifyDeviceSynchronizeListeners(deviceInfo, false);
+        ((DeviceContextImpl)deviceContext).getTransactionChainManager().activateTransactionManager();
+        /* Init Collecting NodeInfo */
+        final ListenableFuture<Void> initCollectingDeviceInfo = DeviceInitializationUtils.initializeNodeInformation(
+                deviceContext, switchFeaturesMandatory);
+        /* Init Collecting StatInfo */
+        final ListenableFuture<Boolean> statPollFuture = Futures.transform(initCollectingDeviceInfo,
+                new AsyncFunction<Void, Boolean>() {
+
+                    @Override
+                    public ListenableFuture<Boolean> apply(@Nonnull final Void input) throws Exception {
+                        statisticsContext.statListForCollectingInitialization();
+                        return statisticsContext.initialGatherDynamicData();
+                    }
+                });
+
+        return Futures.transform(statPollFuture, new Function<Boolean, Void>() {
+
+            @Override
+            public Void apply(final Boolean input) {
+                if (ConnectionContext.CONNECTION_STATE.RIP.equals(conductor.gainConnectionStateSafely(deviceInfo))) {
+                    final String errMsg = String.format("We lost connection for Device %s, context has to be closed.",
+                            deviceInfo.getNodeId());
+                    LOG.warn(errMsg);
+                    throw new IllegalStateException(errMsg);
+                }
+                if (!input) {
+                    final String errMsg = String.format("Get Initial Device %s information fails",
+                            deviceInfo.getNodeId());
+                    LOG.warn(errMsg);
+                    throw new IllegalStateException(errMsg);
+                }
+                LOG.debug("Get Initial Device {} information is successful", deviceInfo.getNodeId());
+                notifyDeviceSynchronizeListeners(deviceInfo, true);
+                ((DeviceContextImpl)deviceContext).getTransactionChainManager().initialSubmitWriteTransaction();
+                deviceContext.getDeviceState().setStatisticsPollingEnabledProp(true);
+                return null;
+            }
+        });
+    }
+
 }
index 37768bc5e97d2e1592daaa0a2124cd5b6298858f..42162c8ab85e528d039cd3c0f07925d784793561 100644 (file)
@@ -8,18 +8,10 @@
 
 package org.opendaylight.openflowplugin.impl.device;
 
-import com.google.common.base.Preconditions;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nonnull;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
-import org.opendaylight.openflowplugin.impl.util.DeviceStateUtil;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-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.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.GetFeaturesOutputBuilder;
-import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 
 /**
  * openflowplugin-impl
@@ -28,16 +20,10 @@ import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
  * DeviceState is builded from {@link FeaturesReply} and {@link NodeId}. Both values are inside
  * {@link org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext}
  *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *         <p/>
- *         Created: Mar 29, 2015
  */
 class DeviceStateImpl implements DeviceState {
 
-    private final GetFeaturesOutput featuresOutput;
-    private final NodeId nodeId;
-    private final KeyedInstanceIdentifier<Node, NodeKey> nodeII;
-    private final short version;
+    private final DeviceInfo deviceInfo;
     private boolean valid;
     private boolean meterIsAvailable;
     private boolean groupIsAvailable;
@@ -48,46 +34,17 @@ class DeviceStateImpl implements DeviceState {
     private boolean statPollEnabled;
     private boolean queueStatisticsAvailable;
 
-    public DeviceStateImpl(@CheckForNull final FeaturesReply featuresReply, @Nonnull final NodeId nodeId) {
-        Preconditions.checkArgument(featuresReply != null);
-        featuresOutput = new GetFeaturesOutputBuilder(featuresReply).build();
-        this.nodeId = Preconditions.checkNotNull(nodeId);
-        nodeII = DeviceStateUtil.createNodeInstanceIdentifier(nodeId);
-        version = featuresReply.getVersion();
+    public DeviceStateImpl(final DeviceInfo deviceInfo) {
+        this.deviceInfo = deviceInfo;
         statPollEnabled = false;
         deviceSynchronized = false;
     }
 
-    @Override
-    public NodeId getNodeId() {
-        return nodeId;
-    }
-
-    @Override
-    public KeyedInstanceIdentifier<Node, NodeKey> getNodeInstanceIdentifier() {
-        return nodeII;
-    }
-
-    @Override
-    public GetFeaturesOutput getFeatures() {
-        return featuresOutput;
-    }
-
     @Override
     public boolean isValid() {
         return valid;
     }
 
-    @Override
-    public void setValid(final boolean valid) {
-        this.valid = valid;
-    }
-
-    @Override
-    public short getVersion() {
-        return version;
-    }
-
     @Override
     public boolean isMetersAvailable() {
         return meterIsAvailable;
@@ -154,11 +111,6 @@ class DeviceStateImpl implements DeviceState {
 
     }
 
-    @Override
-    public void setDeviceSynchronized(final boolean _deviceSynchronized) {
-        deviceSynchronized = _deviceSynchronized;
-    }
-
     @Override
     public boolean isStatisticsPollingEnabled() {
         return statPollEnabled;
@@ -168,4 +120,18 @@ class DeviceStateImpl implements DeviceState {
     public void setStatisticsPollingEnabledProp(final boolean statPollEnabled) {
         this.statPollEnabled = statPollEnabled;
     }
+
+    @Override
+    public void deviceIsSynchronized(final DeviceInfo deviceInfo, final boolean isSynchronized) {
+        if (this.deviceInfo.equals(deviceInfo)) {
+            this.deviceSynchronized = isSynchronized;
+        }
+    }
+
+    @Override
+    public void deviceIsValid(final DeviceInfo deviceInfo, final boolean isValid) {
+        if (this.deviceInfo.equals(deviceInfo)) {
+            this.valid = isValid;
+        }
+    }
 }
index d85dab8f59632457938b55b0344792df1767e0c4..b782688d02e4dac3f738d506bfa6cadda587d93a 100644 (file)
@@ -25,7 +25,7 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleConductor;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
@@ -55,6 +55,7 @@ class TransactionChainManager implements TransactionChainListener, AutoCloseable
 
     private final Object txLock = new Object();
     private final KeyedInstanceIdentifier<Node, NodeKey> nodeII;
+    private final DeviceInfo deviceInfo;
     private final DataBroker dataBroker;
     private final LifecycleConductor conductor;
 
@@ -77,14 +78,15 @@ class TransactionChainManager implements TransactionChainListener, AutoCloseable
     private TransactionChainManagerStatus transactionChainManagerStatus = TransactionChainManagerStatus.SLEEPING;
 
     TransactionChainManager(@Nonnull final DataBroker dataBroker,
-                            @Nonnull final DeviceState deviceState,
+                            @Nonnull final DeviceInfo deviceInfo,
                             @Nonnull final LifecycleConductor conductor) {
         this.dataBroker = Preconditions.checkNotNull(dataBroker);
         this.conductor = Preconditions.checkNotNull(conductor);
-        this.nodeII = Preconditions.checkNotNull(deviceState.getNodeInstanceIdentifier());
+        this.deviceInfo = deviceInfo;
+        this.nodeII = deviceInfo.getNodeInstanceIdentifier();
         this.transactionChainManagerStatus = TransactionChainManagerStatus.SLEEPING;
         lastSubmittedFuture = Futures.immediateFuture(null);
-        LOG.debug("created txChainManager for {}", nodeII);
+        LOG.debug("created txChainManager for {}", this.nodeII);
     }
 
     private NodeId nodeId() {
@@ -109,7 +111,7 @@ class TransactionChainManager implements TransactionChainListener, AutoCloseable
      * registration for this class instance as {@link TransactionChainListener} to provide possibility a make DS
      * transactions. Call this method for MASTER role only.
      */
-    public void activateTransactionManager() {
+    void activateTransactionManager() {
         LOG.trace("activateTransactionManager for node {} transaction submit is set to {}", nodeId(), submitIsEnabled);
         synchronized (txLock) {
             if (TransactionChainManagerStatus.SLEEPING.equals(transactionChainManagerStatus)) {
@@ -132,7 +134,7 @@ class TransactionChainManager implements TransactionChainListener, AutoCloseable
      * Call this method for SLAVE only.
      * @return Future
      */
-    public ListenableFuture<Void> deactivateTransactionManager() {
+    ListenableFuture<Void> deactivateTransactionManager() {
         final ListenableFuture<Void> future;
         synchronized (txLock) {
             if (TransactionChainManagerStatus.WORKING.equals(transactionChainManagerStatus)) {
@@ -192,7 +194,7 @@ class TransactionChainManager implements TransactionChainListener, AutoCloseable
                     }
                     if (initCommit) {
                         LOG.error("Initial commit failed. {}", t);
-                        conductor.closeConnection(nodeId());
+                        conductor.closeConnection(deviceInfo);
                     }
                 }
             });
index ab8136281671a144ef13ac4f0a8743e9b140d190..5ddf504fbb066de0a50927683df0f363e042e2c9 100644 (file)
@@ -16,11 +16,12 @@ import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlready
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidateRegistration;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
+import org.opendaylight.openflowplugin.api.openflow.OFPContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
 import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleConductor;
 import org.opendaylight.openflowplugin.api.openflow.role.RoleContext;
 import org.opendaylight.openflowplugin.impl.rpc.AbstractRequestContext;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SalRoleService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -34,7 +35,7 @@ class RoleContextImpl implements RoleContext {
     private static final Logger LOG = LoggerFactory.getLogger(RoleContextImpl.class);
     private static final int TIMEOUT = 12;
 
-    private final NodeId nodeId;
+    private final DeviceInfo deviceInfo;
     private final EntityOwnershipService entityOwnershipService;
     private volatile EntityOwnershipCandidateRegistration entityOwnershipCandidateRegistration = null;
     private volatile EntityOwnershipCandidateRegistration txEntityOwnershipCandidateRegistration = null;
@@ -47,24 +48,27 @@ class RoleContextImpl implements RoleContext {
     private final Semaphore roleChangeGuard = new Semaphore(1, true);
 
     private final LifecycleConductor conductor;
+    private volatile CONTEXT_STATE contextState;
 
-    public RoleContextImpl(final NodeId nodeId, final EntityOwnershipService entityOwnershipService, final Entity entity, final Entity txEntity, final LifecycleConductor lifecycleConductor) {
+    RoleContextImpl(final DeviceInfo deviceInfo, final EntityOwnershipService entityOwnershipService, final Entity entity, final Entity txEntity, final LifecycleConductor lifecycleConductor) {
         this.entityOwnershipService = entityOwnershipService;
         this.entity = entity;
         this.txEntity = txEntity;
-        this.nodeId = nodeId;
+        this.deviceInfo = deviceInfo;
         this.conductor = lifecycleConductor;
+        contextState = CONTEXT_STATE.INITIALIZATION;
     }
 
     @Override
     public boolean initialization() {
-        LOG.info("Initialization main candidate for node {}", nodeId);
+        LOG.info("Initialization main candidate for node {}", deviceInfo.getNodeId());
+        contextState = CONTEXT_STATE.WORKING;
         return registerCandidate(this.entity);
     }
 
     @Override
     public void unregisterAllCandidates() {
-        LOG.info("Role context closed, unregistering all candidates for ownership for node {}", nodeId);
+        LOG.info("Role context closed, unregistering all candidates for ownership for node {}", deviceInfo.getNodeId());
         if (isMainCandidateRegistered()) {
             unregisterCandidate(this.entity);
         }
@@ -76,7 +80,7 @@ class RoleContextImpl implements RoleContext {
     @Nullable
     @Override
     public <T> RequestContext<T> createRequestContext() {
-        return new AbstractRequestContext<T>(conductor.reserveXidForDeviceMessage(nodeId)) {
+        return new AbstractRequestContext<T>(conductor.reserveXidForDeviceMessage(deviceInfo)) {
             @Override
             public void close() {
             }
@@ -105,8 +109,8 @@ class RoleContextImpl implements RoleContext {
     }
 
     @Override
-    public NodeId getNodeId() {
-        return nodeId;
+    public DeviceInfo getDeviceInfo() {
+        return deviceInfo;
     }
 
     @Override
@@ -183,10 +187,16 @@ class RoleContextImpl implements RoleContext {
 
     @Override
     public void close() {
+        contextState = CONTEXT_STATE.TERMINATION;
         unregisterAllCandidates();
     }
 
     public boolean isMaster(){
         return (txEntityOwnershipCandidateRegistration != null && entityOwnershipCandidateRegistration != null);
     }
+
+    @Override
+    public CONTEXT_STATE getState() {
+        return contextState;
+    }
 }
index 37a2a6cf8b1708a8c53830d5fb6fc885b18e0b19..07c74c30e26e54a23c0fe1363fdd2af12bc406f7 100644 (file)
@@ -16,9 +16,7 @@ import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.JdkFutureAdapters;
 import com.google.common.util.concurrent.ListenableFuture;
-import io.netty.util.Timeout;
 import io.netty.util.TimerTask;
-
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -29,7 +27,6 @@ import java.util.concurrent.TimeUnit;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
-
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
@@ -40,7 +37,9 @@ import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipS
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.openflowplugin.api.OFConstants;
+import org.opendaylight.openflowplugin.api.openflow.OFPContext;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceInitializationPhaseHandler;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceTerminationPhaseHandler;
 import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleConductor;
@@ -69,11 +68,14 @@ import org.slf4j.LoggerFactory;
 public class RoleManagerImpl implements RoleManager, EntityOwnershipListener, ServiceChangeListener {
     private static final Logger LOG = LoggerFactory.getLogger(RoleManagerImpl.class);
 
+    // Maximum limit of timeout retries when cleaning DS, to prevent infinite recursive loops
+    private static final int MAX_CLEAN_DS_RETRIES = 3;
+
     private DeviceInitializationPhaseHandler deviceInitializationPhaseHandler;
     private DeviceTerminationPhaseHandler deviceTerminationPhaseHandler;
     private final DataBroker dataBroker;
     private final EntityOwnershipService entityOwnershipService;
-    private final ConcurrentMap<NodeId, RoleContext> contexts = new ConcurrentHashMap<>();
+    private final ConcurrentMap<DeviceInfo, RoleContext> contexts = new ConcurrentHashMap<>();
     private final ConcurrentMap<Entity, RoleContext> watchingEntities = new ConcurrentHashMap<>();
     private final EntityOwnershipListenerRegistration entityOwnershipListenerRegistration;
     private final EntityOwnershipListenerRegistration txEntityOwnershipListenerRegistration;
@@ -96,16 +98,16 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener, Se
     }
 
     @Override
-    public void onDeviceContextLevelUp(@CheckForNull final NodeId nodeId) throws Exception {
-        final DeviceContext deviceContext = Preconditions.checkNotNull(conductor.getDeviceContext(nodeId));
-        final RoleContext roleContext = new RoleContextImpl(nodeId, entityOwnershipService, makeEntity(nodeId), makeTxEntity(nodeId), conductor);
+    public void onDeviceContextLevelUp(@CheckForNull final DeviceInfo deviceInfo) throws Exception {
+        final DeviceContext deviceContext = Preconditions.checkNotNull(conductor.getDeviceContext(deviceInfo));
+        final RoleContext roleContext = new RoleContextImpl(deviceInfo, entityOwnershipService, makeEntity(deviceInfo.getNodeId()), makeTxEntity(deviceInfo.getNodeId()), conductor);
         roleContext.setSalRoleService(new SalRoleServiceImpl(roleContext, deviceContext));
-        Verify.verify(contexts.putIfAbsent(nodeId, roleContext) == null, "Role context for master Node %s is still not closed.", nodeId);
+        Verify.verify(contexts.putIfAbsent(deviceInfo, roleContext) == null, "Role context for master Node %s is still not closed.", deviceInfo.getNodeId());
         makeDeviceRoleChange(OfpRole.BECOMESLAVE, roleContext, true);
         /* First start to watch entity so we don't miss any notification, and then try to register in EOS */
         watchingEntities.put(roleContext.getEntity(), roleContext);
-        notifyListenersRoleInitializationDone(roleContext.getNodeId(), roleContext.initialization());
-        deviceInitializationPhaseHandler.onDeviceContextLevelUp(nodeId);
+        notifyListenersRoleInitializationDone(roleContext.getDeviceInfo(), roleContext.initialization());
+        deviceInitializationPhaseHandler.onDeviceContextLevelUp(deviceInfo);
     }
 
     @Override
@@ -118,10 +120,10 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener, Se
             final RoleContext roleContext = iterator.next();
             watchingEntities.remove(roleContext.getEntity());
             watchingEntities.remove(roleContext.getTxEntity());
-            contexts.remove(roleContext.getNodeId());
+            contexts.remove(roleContext.getDeviceInfo());
             if (roleContext.isTxCandidateRegistered()) {
                 LOG.info("Node {} was holder txEntity, so trying to remove device from operational DS.");
-                removeDeviceFromOperationalDS(roleContext.getNodeId());
+                removeDeviceFromOperationalDS(roleContext.getDeviceInfo(), MAX_CLEAN_DS_RETRIES);
             } else {
                 roleContext.close();
             }
@@ -129,20 +131,19 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener, Se
     }
 
     @Override
-    public void onDeviceContextLevelDown(final DeviceContext deviceContext) {
-        final NodeId nodeId = deviceContext.getPrimaryConnectionContext().getNodeId();
-        LOG.trace("onDeviceContextLevelDown for node {}", nodeId);
-        final RoleContext roleContext = contexts.get(nodeId);
+    public void onDeviceContextLevelDown(final DeviceInfo deviceInfo) {
+        LOG.trace("onDeviceContextLevelDown for node {}", deviceInfo.getNodeId());
+        final RoleContext roleContext = contexts.get(deviceInfo);
         if (roleContext != null) {
-            LOG.debug("Found roleContext associated to deviceContext: {}, now trying close the roleContext", nodeId);
+            LOG.debug("Found roleContext associated to deviceContext: {}, now trying close the roleContext", deviceInfo.getNodeId());
             if (roleContext.isMainCandidateRegistered()) {
                 roleContext.unregisterCandidate(roleContext.getEntity());
             } else {
-                contexts.remove(nodeId, roleContext);
+                contexts.remove(deviceInfo.getNodeId(), roleContext);
                 roleContext.close();
             }
         }
-        deviceTerminationPhaseHandler.onDeviceContextLevelDown(deviceContext);
+        deviceTerminationPhaseHandler.onDeviceContextLevelDown(deviceInfo);
     }
 
     @VisibleForTesting
@@ -164,7 +165,7 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener, Se
         LOG.debug("Received EOS message: wasOwner:{} isOwner:{} hasOwner:{} inJeopardy:{} for entity type {} and node {}",
                 ownershipChange.wasOwner(), ownershipChange.isOwner(), ownershipChange.hasOwner(), ownershipChange.inJeopardy(),
                 ownershipChange.getEntity().getType(),
-                roleContext != null ? roleContext.getNodeId() : "-> no watching entity, disregarding notification <-");
+                roleContext != null ? roleContext.getDeviceInfo().getNodeId() : "-> no watching entity, disregarding notification <-");
 
         if (roleContext != null) {
             if (ownershipChange.getEntity().equals(roleContext.getEntity())) {
@@ -183,36 +184,35 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener, Se
 
         if (roleContext.isMainCandidateRegistered()) {
             LOG.debug("Main-EntityOwnershipRegistration is active for entity type {} and node {}",
-                    ownershipChange.getEntity().getType(), roleContext.getNodeId());
+                    ownershipChange.getEntity().getType(), roleContext.getDeviceInfo().getNodeId());
             if (!ownershipChange.wasOwner() && ownershipChange.isOwner() && !ownershipChange.inJeopardy()) {
                 // SLAVE -> MASTER
-                LOG.debug("SLAVE to MASTER for node {}", roleContext.getNodeId());
+                LOG.debug("SLAVE to MASTER for node {}", roleContext.getDeviceInfo().getNodeId());
                 if (roleContext.registerCandidate(roleContext.getTxEntity())) {
-                    LOG.debug("Starting watching tx entity for node {}", roleContext.getNodeId());
+                    LOG.debug("Starting watching tx entity for node {}", roleContext.getDeviceInfo().getNodeId());
                     watchingEntities.putIfAbsent(roleContext.getTxEntity(), roleContext);
                 }
             } else if ((ownershipChange.wasOwner() && !ownershipChange.isOwner()) || (ownershipChange.inJeopardy())) {
                 // MASTER -> SLAVE
-                LOG.debug("MASTER to SLAVE for node {}", roleContext.getNodeId());
-                conductor.addOneTimeListenerWhenServicesChangesDone(this, roleContext.getNodeId());
+                LOG.debug("MASTER to SLAVE for node {}", roleContext.getDeviceInfo().getNodeId());
+                conductor.addOneTimeListenerWhenServicesChangesDone(this, roleContext.getDeviceInfo());
                 makeDeviceRoleChange(OfpRole.BECOMESLAVE, roleContext, false);
             }
         } else {
             LOG.debug("Main-EntityOwnershipRegistration is not active for entity type {} and node {}",
-                    ownershipChange.getEntity(), roleContext.getNodeId());
+                    ownershipChange.getEntity(), roleContext.getDeviceInfo().getNodeId());
             watchingEntities.remove(ownershipChange.getEntity(), roleContext);
             if (roleContext.isTxCandidateRegistered()) {
-                LOG.debug("tx candidate still registered for node {}, probably connection lost, trying to unregister tx candidate", roleContext.getNodeId());
+                LOG.debug("tx candidate still registered for node {}, probably connection lost, trying to unregister tx candidate", roleContext.getDeviceInfo().getNodeId());
                 roleContext.unregisterCandidate(roleContext.getTxEntity());
                 if (ownershipChange.wasOwner() && !ownershipChange.isOwner() && !ownershipChange.hasOwner()) {
-                    LOG.debug("Trying to remove from operational node: {}", roleContext.getNodeId());
-                    removeDeviceFromOperationalDS(roleContext.getNodeId());
+                    LOG.debug("Trying to remove from operational node: {}", roleContext.getDeviceInfo().getNodeId());
+                    removeDeviceFromOperationalDS(roleContext.getDeviceInfo(), MAX_CLEAN_DS_RETRIES);
                 }
             } else {
-                final NodeId nodeId = roleContext.getNodeId();
-                contexts.remove(nodeId, roleContext);
+                contexts.remove(roleContext.getDeviceInfo(), roleContext);
                 roleContext.close();
-                conductor.closeConnection(nodeId);
+                conductor.closeConnection(roleContext.getDeviceInfo());
             }
         }
     }
@@ -224,7 +224,7 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener, Se
         if (roleContext.isTxCandidateRegistered()) {
             LOG.debug("Tx-EntityOwnershipRegistration is active for entity type {} and node {}",
                     ownershipChange.getEntity().getType(),
-                    roleContext.getNodeId());
+                    roleContext.getDeviceInfo().getNodeId());
             if (ownershipChange.inJeopardy()) {
                 LOG.warn("Getting 'inJeopardy' flag from EOS. Removing txCandidate and stopping watching txCandidate.");
                 watchingEntities.remove(roleContext.getTxEntity());
@@ -232,35 +232,34 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener, Se
             } else {
                 if (!ownershipChange.wasOwner() && ownershipChange.isOwner()) {
                     // SLAVE -> MASTER
-                    LOG.debug("SLAVE to MASTER for node {}", roleContext.getNodeId());
+                    LOG.debug("SLAVE to MASTER for node {}", roleContext.getDeviceInfo().getNodeId());
                     makeDeviceRoleChange(OfpRole.BECOMEMASTER, roleContext, false);
                 } else if (ownershipChange.wasOwner() && !ownershipChange.isOwner()) {
                     // MASTER -> SLAVE
-                    LOG.debug("MASTER to SLAVE for node {}", roleContext.getNodeId());
+                    LOG.debug("MASTER to SLAVE for node {}", roleContext.getDeviceInfo().getNodeId());
                     LOG.warn("Tx-EntityOwnershipRegistration lost leadership entity type {} and node {}",
-                            ownershipChange.getEntity().getType(), roleContext.getNodeId());
+                            ownershipChange.getEntity().getType(), roleContext.getDeviceInfo().getNodeId());
                     watchingEntities.remove(roleContext.getTxEntity(), roleContext);
                     watchingEntities.remove(roleContext.getEntity(), roleContext);
                     roleContext.unregisterCandidate(roleContext.getEntity());
                     roleContext.unregisterCandidate(roleContext.getTxEntity());
                     if (!ownershipChange.hasOwner()) {
-                        LOG.debug("Trying to remove from operational node: {}", roleContext.getNodeId());
-                        removeDeviceFromOperationalDS(roleContext.getNodeId());
+                        LOG.debug("Trying to remove from operational node: {}", roleContext.getDeviceInfo().getNodeId());
+                        removeDeviceFromOperationalDS(roleContext.getDeviceInfo(), MAX_CLEAN_DS_RETRIES);
                     } else {
-                        final NodeId nodeId = roleContext.getNodeId();
-                        contexts.remove(nodeId, roleContext);
+                        final NodeId nodeId = roleContext.getDeviceInfo().getNodeId();
+                        contexts.remove(roleContext.getDeviceInfo(), roleContext);
                         roleContext.close();
-                        conductor.closeConnection(nodeId);
+                        conductor.closeConnection(roleContext.getDeviceInfo());
                     }
                 }
             }
         } else {
-            LOG.debug("Tx-EntityOwnershipRegistration is not active for entity {}", ownershipChange.getEntity().getType());
+            LOG.debug("Tx-EntityOwnershipRegistration is not active for entity type {} and node {}", ownershipChange.getEntity().getType(), roleContext.getDeviceInfo().getNodeId());
             watchingEntities.remove(roleContext.getTxEntity(), roleContext);
-            final NodeId nodeId = roleContext.getNodeId();
-            contexts.remove(nodeId, roleContext);
+            contexts.remove(roleContext.getDeviceInfo(), roleContext);
             roleContext.close();
-            conductor.closeConnection(nodeId);
+            conductor.closeConnection(roleContext.getDeviceInfo());
         }
     }
 
@@ -270,23 +269,23 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener, Se
         Futures.addCallback(roleChangeFuture, new FutureCallback<RpcResult<SetRoleOutput>>() {
             @Override
             public void onSuccess(@Nullable final RpcResult<SetRoleOutput> setRoleOutputRpcResult) {
-                LOG.info("Role {} successfully set on device {}", role, roleContext.getNodeId());
-                notifyListenersRoleChangeOnDevice(roleContext.getNodeId(), true, role, init);
+                LOG.info("Role {} successfully set on device {}", role, roleContext.getDeviceInfo().getNodeId());
+                notifyListenersRoleChangeOnDevice(roleContext.getDeviceInfo(), true, role, init);
             }
 
             @Override
             public void onFailure(@Nonnull final Throwable throwable) {
-                LOG.warn("Unable to set role {} on device {}", role, roleContext.getNodeId());
-                notifyListenersRoleChangeOnDevice(roleContext.getNodeId(), false, role, init);
+                LOG.warn("Unable to set role {} on device {}", role, roleContext.getDeviceInfo().getNodeId());
+                notifyListenersRoleChangeOnDevice(roleContext.getDeviceInfo(), false, role, init);
             }
         });
     }
 
     @VisibleForTesting
     ListenableFuture<RpcResult<SetRoleOutput>> sendRoleChangeToDevice(final OfpRole newRole, final RoleContext roleContext) {
-        LOG.debug("Sending new role {} to device {}", newRole, roleContext.getNodeId());
+        LOG.debug("Sending new role {} to device {}", newRole, roleContext.getDeviceInfo().getNodeId());
         final Future<RpcResult<SetRoleOutput>> setRoleOutputFuture;
-        final Short version = conductor.gainVersionSafely(roleContext.getNodeId());
+        final Short version = roleContext.getDeviceInfo().getVersion();
         if (null == version) {
             LOG.debug("Device version is null");
             return Futures.immediateFuture(null);
@@ -296,16 +295,12 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener, Se
             return Futures.immediateFuture(null);
         } else {
             final SetRoleInput setRoleInput = (new SetRoleInputBuilder()).setControllerRole(newRole)
-                    .setNode(new NodeRef(DeviceStateUtil.createNodeInstanceIdentifier(roleContext.getNodeId()))).build();
+                    .setNode(new NodeRef(DeviceStateUtil.createNodeInstanceIdentifier(roleContext.getDeviceInfo().getNodeId()))).build();
             setRoleOutputFuture = roleContext.getSalRoleService().setRole(setRoleInput);
-            final TimerTask timerTask = new TimerTask() {
-
-                @Override
-                public void run(final Timeout timeout) throws Exception {
-                    if (!setRoleOutputFuture.isDone()) {
-                        LOG.warn("New role {} was not propagated to device {} during 10 sec", newRole, roleContext.getNodeId());
-                        setRoleOutputFuture.cancel(true);
-                    }
+            final TimerTask timerTask = timeout -> {
+                if (!setRoleOutputFuture.isDone()) {
+                    LOG.warn("New role {} was not propagated to device {} during 10 sec", newRole, roleContext.getDeviceInfo().getNodeId());
+                    setRoleOutputFuture.cancel(true);
                 }
             };
             conductor.newTimeout(timerTask, 10, TimeUnit.SECONDS);
@@ -314,17 +309,16 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener, Se
     }
 
     @VisibleForTesting
-    CheckedFuture<Void, TransactionCommitFailedException> removeDeviceFromOperationalDS(final NodeId nodeId) {
-
+    CheckedFuture<Void, TransactionCommitFailedException> removeDeviceFromOperationalDS(final DeviceInfo deviceInfo, final int numRetries) {
         final WriteTransaction delWtx = dataBroker.newWriteOnlyTransaction();
-        delWtx.delete(LogicalDatastoreType.OPERATIONAL, DeviceStateUtil.createNodeInstanceIdentifier(nodeId));
+        delWtx.delete(LogicalDatastoreType.OPERATIONAL, DeviceStateUtil.createNodeInstanceIdentifier(deviceInfo.getNodeId()));
         final CheckedFuture<Void, TransactionCommitFailedException> delFuture = delWtx.submit();
-        Futures.addCallback(delFuture, new FutureCallback<Void>() {
 
+        Futures.addCallback(delFuture, new FutureCallback<Void>() {
             @Override
             public void onSuccess(final Void result) {
-                LOG.debug("Delete Node {} was successful", nodeId);
-                final RoleContext roleContext = contexts.remove(nodeId);
+                LOG.debug("Delete Node {} was successful", deviceInfo);
+                final RoleContext roleContext = contexts.remove(deviceInfo);
                 if (roleContext != null) {
                     roleContext.close();
                 }
@@ -332,14 +326,25 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener, Se
 
             @Override
             public void onFailure(@Nonnull final Throwable t) {
-                LOG.warn("Delete Node {} failed. {}", nodeId, t);
-                contexts.remove(nodeId);
-                final RoleContext roleContext = contexts.remove(nodeId);
+                // If we have any retries left, we will try to clean the datastore again
+                if (numRetries > 0) {
+                    // We "used" one retry here, so decrement it
+                    final int curRetries = numRetries - 1;
+                    LOG.debug("Delete node {} failed with exception {}. Trying again (retries left: {})", deviceInfo.getNodeId(), t, curRetries);
+                    // Recursive call to this method with "one less" retry
+                    removeDeviceFromOperationalDS(deviceInfo, curRetries);
+                    return;
+                }
+
+                // No retries left, so we will just close the role context, and ignore datastore cleanup
+                LOG.warn("Delete node {} failed with exception {}. No retries left, aborting", deviceInfo.getNodeId(), t);
+                final RoleContext roleContext = contexts.remove(deviceInfo);
                 if (roleContext != null) {
                     roleContext.close();
                 }
             }
         });
+
         return delFuture;
     }
 
@@ -349,9 +354,9 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener, Se
     }
 
     @Override
-    public void servicesChangeDone(final NodeId nodeId, final boolean success) {
-        LOG.debug("Services stopping done for node {} as " + (success ? "successful" : "unsuccessful"), nodeId);
-        final RoleContext roleContext = contexts.get(nodeId);
+    public void servicesChangeDone(final DeviceInfo deviceInfo, final boolean success) {
+        LOG.debug("Services stopping done for node {} as " + (success ? "successful" : "unsuccessful"), deviceInfo);
+        final RoleContext roleContext = contexts.get(deviceInfo);
         if (null != roleContext) {
             /* Services stopped or failure */
             roleContext.unregisterCandidate(roleContext.getTxEntity());
@@ -359,17 +364,17 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener, Se
     }
 
     @VisibleForTesting
-    RoleContext getRoleContext(final NodeId nodeId){
-        return contexts.get(nodeId);
+    RoleContext getRoleContext(final DeviceInfo deviceInfo){
+        return contexts.get(deviceInfo);
     }
 
     /**
      * This method is only for testing
      */
     @VisibleForTesting
-    void setRoleContext(NodeId nodeId, RoleContext roleContext){
-        if(!contexts.containsKey(nodeId)) {
-            contexts.put(nodeId, roleContext);
+    void setRoleContext(DeviceInfo deviceInfo, RoleContext roleContext){
+        if(!contexts.containsKey(deviceInfo)) {
+            contexts.put(deviceInfo, roleContext);
         }
     }
 
@@ -380,30 +385,35 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener, Se
 
     /**
      * Invoked when initialization phase is done
-     * @param nodeId node identification
+     * @param deviceInfo node identification
      * @param success true if initialization done ok, false otherwise
      */
     @VisibleForTesting
-    void notifyListenersRoleInitializationDone(final NodeId nodeId, final boolean success){
+    void notifyListenersRoleInitializationDone(final DeviceInfo deviceInfo, final boolean success){
         LOG.debug("Notifying registered listeners for role initialization done, no. of listeners {}", listeners.size());
         for (final RoleChangeListener listener : listeners) {
-            listener.roleInitializationDone(nodeId, success);
+            listener.roleInitializationDone(deviceInfo, success);
         }
     }
 
     /**
      * Notifies registered listener on role change. Role is the new role on device
      * If initialization phase is true, we may skip service starting
+     * @param deviceInfo
      * @param success true if role change on device done ok, false otherwise
      * @param role new role meant to be set on device
      * @param initializationPhase if true, then skipp services start
      */
     @VisibleForTesting
-    void notifyListenersRoleChangeOnDevice(final NodeId nodeId, final boolean success, final OfpRole role, final boolean initializationPhase){
+    void notifyListenersRoleChangeOnDevice(final DeviceInfo deviceInfo, final boolean success, final OfpRole role, final boolean initializationPhase){
         LOG.debug("Notifying registered listeners for role change, no. of listeners {}", listeners.size());
         for (final RoleChangeListener listener : listeners) {
-            listener.roleChangeOnDevice(nodeId, success, role, initializationPhase);
+            listener.roleChangeOnDevice(deviceInfo, success, role, initializationPhase);
         }
     }
 
+    @Override
+    public <T extends OFPContext> T gainContext(DeviceInfo deviceInfo) {
+        return (T) contexts.get(deviceInfo);
+    }
 }
index c5dd4eb03f5e4cce0e83e8d6d88f35fe067d4a12..c91a1346754ff0168e5025fb40bae76f075ddf74 100644 (file)
@@ -17,6 +17,7 @@ import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.Semaphore;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.openflowplugin.api.openflow.OFPContext;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
 import org.opendaylight.openflowplugin.api.openflow.device.XidSequencer;
 import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext;
@@ -29,18 +30,21 @@ import org.opendaylight.yangtools.yang.binding.RpcService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class RpcContextImpl implements RpcContext {
+class RpcContextImpl implements RpcContext {
     private static final Logger LOG = LoggerFactory.getLogger(RpcContextImpl.class);
     private final RpcProviderRegistry rpcProviderRegistry;
     private final MessageSpy messageSpy;
     private final Semaphore tracker;
     private final XidSequencer xidSequencer;
+    private boolean isStatisticsRpcEnabled;
+
+    private volatile CONTEXT_STATE contextState;
 
     // TODO: add private Sal salBroker
     private final ConcurrentMap<Class<?>, RoutedRpcRegistration<?>> rpcRegistrations = new ConcurrentHashMap<>();
     private final KeyedInstanceIdentifier<Node, NodeKey> nodeInstanceIdentifier;
 
-    public RpcContextImpl(final RpcProviderRegistry rpcProviderRegistry,
+    RpcContextImpl(final RpcProviderRegistry rpcProviderRegistry,
                           final XidSequencer xidSequencer,
                           final MessageSpy messageSpy,
                           final int maxRequests,
@@ -51,6 +55,7 @@ public class RpcContextImpl implements RpcContext {
         this.nodeInstanceIdentifier = nodeInstanceIdentifier;
 
         tracker = new Semaphore(maxRequests, true);
+        contextState = CONTEXT_STATE.WORKING;
     }
 
     /**
@@ -83,13 +88,20 @@ public class RpcContextImpl implements RpcContext {
      */
     @Override
     public void close() {
-        for (final Iterator<Entry<Class<?>, RoutedRpcRegistration<?>>> iterator = Iterators
-                .consumingIterator(rpcRegistrations.entrySet().iterator()); iterator.hasNext();) {
-            final RoutedRpcRegistration<?> rpcRegistration = iterator.next().getValue();
-            rpcRegistration.unregisterPath(NodeContext.class, nodeInstanceIdentifier);
-            rpcRegistration.close();
-            LOG.debug("Closing RPC Registration of service {} for device {}.", rpcRegistration.getServiceType(),
-                    nodeInstanceIdentifier);
+        if (CONTEXT_STATE.TERMINATION.equals(contextState)){
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("RpcContext is already in TERMINATION state.");
+            }
+        } else {
+            contextState = CONTEXT_STATE.TERMINATION;
+            for (final Iterator<Entry<Class<?>, RoutedRpcRegistration<?>>> iterator = Iterators
+                    .consumingIterator(rpcRegistrations.entrySet().iterator()); iterator.hasNext(); ) {
+                final RoutedRpcRegistration<?> rpcRegistration = iterator.next().getValue();
+                rpcRegistration.unregisterPath(NodeContext.class, nodeInstanceIdentifier);
+                rpcRegistration.close();
+                LOG.debug("Closing RPC Registration of service {} for device {}.", rpcRegistration.getServiceType(),
+                        nodeInstanceIdentifier);
+            }
         }
     }
 
@@ -132,9 +144,22 @@ public class RpcContextImpl implements RpcContext {
     }
 
     @VisibleForTesting
-    public boolean isEmptyRpcRegistrations() {
+    boolean isEmptyRpcRegistrations() {
         return this.rpcRegistrations.isEmpty();
     }
 
+    @Override
+    public void setStatisticsRpcEnabled(boolean isStatisticsRpcEnabled) {
+        this.isStatisticsRpcEnabled = isStatisticsRpcEnabled;
+    }
+
+    @Override
+    public boolean isStatisticsRpcEnabled() {
+        return isStatisticsRpcEnabled;
+    }
 
+    @Override
+    public CONTEXT_STATE getState() {
+        return contextState;
+    }
 }
index 0180530154532b8414c15fe396c5eea4bc6e4a1d..645409047168083448dd1fe076bf1a99812217fd 100644 (file)
@@ -15,13 +15,14 @@ import java.util.Iterator;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.openflowplugin.api.openflow.OFPContext;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceInitializationPhaseHandler;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceTerminationPhaseHandler;
 import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleConductor;
 import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext;
 import org.opendaylight.openflowplugin.api.openflow.rpc.RpcManager;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -32,7 +33,8 @@ public class RpcManagerImpl implements RpcManager {
     private DeviceInitializationPhaseHandler deviceInitPhaseHandler;
     private DeviceTerminationPhaseHandler deviceTerminPhaseHandler;
     private final int maxRequestsQuota;
-    private final ConcurrentMap<NodeId, RpcContext> contexts = new ConcurrentHashMap<>();
+    private final ConcurrentMap<DeviceInfo, RpcContext> contexts = new ConcurrentHashMap<>();
+    private boolean isStatisticsRpcEnabled;
 
     private final LifecycleConductor conductor;
 
@@ -50,23 +52,23 @@ public class RpcManagerImpl implements RpcManager {
     }
 
     @Override
-    public void onDeviceContextLevelUp(final NodeId nodeId) throws Exception {
+    public void onDeviceContextLevelUp(final DeviceInfo deviceInfo) throws Exception {
 
-        final DeviceContext deviceContext = Preconditions.checkNotNull(conductor.getDeviceContext(nodeId));
+        final DeviceContext deviceContext = Preconditions.checkNotNull(conductor.getDeviceContext(deviceInfo));
 
         final RpcContext rpcContext = new RpcContextImpl(
                 rpcProviderRegistry,
                 deviceContext,
                 deviceContext.getMessageSpy(),
                 maxRequestsQuota,
-                deviceContext.getDeviceState().getNodeInstanceIdentifier());
+                deviceInfo.getNodeInstanceIdentifier());
 
-        deviceContext.setRpcContext(rpcContext);
+        Verify.verify(contexts.putIfAbsent(deviceInfo, rpcContext) == null, "RpcCtx still not closed for node {}", deviceInfo.getNodeId());
 
-        Verify.verify(contexts.putIfAbsent(nodeId, rpcContext) == null, "RpcCtx still not closed for node {}", nodeId);
+        rpcContext.setStatisticsRpcEnabled(isStatisticsRpcEnabled);
 
         // finish device initialization cycle back to DeviceManager
-        deviceInitPhaseHandler.onDeviceContextLevelUp(nodeId);
+        deviceInitPhaseHandler.onDeviceContextLevelUp(deviceInfo);
     }
 
     @Override
@@ -78,13 +80,13 @@ public class RpcManagerImpl implements RpcManager {
     }
 
     @Override
-    public void onDeviceContextLevelDown(final DeviceContext deviceContext) {
-        final RpcContext removedContext = contexts.remove(deviceContext.getDeviceState().getNodeId());
+    public void onDeviceContextLevelDown(final DeviceInfo deviceInfo) {
+        final RpcContext removedContext = contexts.remove(deviceInfo);
         if (removedContext != null) {
             LOG.info("Unregister RPCs services for device context closure");
             removedContext.close();
         }
-        deviceTerminPhaseHandler.onDeviceContextLevelDown(deviceContext);
+        deviceTerminPhaseHandler.onDeviceContextLevelDown(deviceInfo);
     }
 
     @Override
@@ -96,9 +98,20 @@ public class RpcManagerImpl implements RpcManager {
      * This method is only for testing
      */
     @VisibleForTesting
-    void addRecordToContexts(NodeId nodeId, RpcContext rpcContexts) {
-        if(!contexts.containsKey(nodeId)) {
-            this.contexts.put(nodeId,rpcContexts);
+    void addRecordToContexts(DeviceInfo deviceInfo, RpcContext rpcContexts) {
+        if(!contexts.containsKey(deviceInfo)) {
+            this.contexts.put(deviceInfo,rpcContexts);
         }
     }
+
+    @Override
+    public <T extends OFPContext> T gainContext(DeviceInfo deviceInfo) {
+        return (T) contexts.get(deviceInfo);
+    }
+
+
+    @Override
+    public void setStatisticsRpcEnabled(boolean statisticsRpcEnabled) {
+        isStatisticsRpcEnabled = statisticsRpcEnabled;
+    }
 }
index 0d7020030500355cfdb59ed37a07cae73f2b83b7..e20a48dd6ea89d99d372db6be3afc50b2bf115c7 100644 (file)
@@ -24,8 +24,8 @@ public abstract class AbstractMultipartOnTheFlyService<I> extends AbstractServic
     @Override
     protected final FutureCallback<OfHeader> createCallback(final RequestContext<List<MultipartReply>> context, final Class<?> requestType) {
         return new MultipartRequestOnTheFlyCallback(context, requestType,
-                getDeviceContext().getMessageSpy(), getEventIdentifier(), getDeviceContext().getDeviceState(),
-                getDeviceContext().getDeviceFlowRegistry(), getDeviceContext());
+                getMessageSpy(), getEventIdentifier(), getDeviceInfo(),
+                getDeviceContext().getDeviceFlowRegistry(), getTxFacade());
     }
 
 
index f1bdbf116da899234e9f5a02b5c49e90875194a6..73f098da9eb4241931cae4fc64709f503a85e0cc 100644 (file)
@@ -16,14 +16,14 @@ import java.math.BigInteger;
 import javax.annotation.Nonnull;
 import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueue;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceRegistry;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
 import org.opendaylight.openflowplugin.api.openflow.device.Xid;
 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
 import org.opendaylight.yangtools.yang.binding.DataContainer;
 import org.opendaylight.yangtools.yang.common.RpcError;
@@ -42,19 +42,16 @@ abstract class AbstractService<I, O> {
     private final RequestContextStack requestContextStack;
     private final DeviceContext deviceContext;
     private final MessageSpy messageSpy;
-    private final NodeId nodeId;
     private EventIdentifier eventIdentifier;
 
-    public AbstractService(final RequestContextStack requestContextStack, final DeviceContext deviceContext) {
-        final DeviceState deviceState = deviceContext.getDeviceState();
-        final GetFeaturesOutput features = deviceState.getFeatures();
+    AbstractService(final RequestContextStack requestContextStack, final DeviceContext deviceContext) {
+        final DeviceInfo deviceInfo = deviceContext.getDeviceInfo();
 
         this.requestContextStack = requestContextStack;
         this.deviceContext = deviceContext;
-        this.datapathId = features.getDatapathId();
-        this.version = features.getVersion();
+        this.datapathId = deviceInfo.getDatapathId();
+        this.version = deviceInfo.getVersion();
         this.messageSpy = deviceContext.getMessageSpy();
-        this.nodeId = deviceState.getNodeId();
     }
 
     public EventIdentifier getEventIdentifier() {
@@ -73,18 +70,21 @@ abstract class AbstractService<I, O> {
         return datapathId;
     }
 
-    public NodeId getNodeId() {
-        return nodeId;
-    }
-
     public RequestContextStack getRequestContextStack() {
         return requestContextStack;
     }
 
+    @Deprecated
     public DeviceContext getDeviceContext() {
         return deviceContext;
     }
 
+    protected DeviceRegistry getDeviceRegistry() {return deviceContext;}
+
+    public DeviceInfo getDeviceInfo() {return deviceContext.getDeviceInfo();}
+
+    public TxFacade getTxFacade() {return deviceContext;}
+
     public MessageSpy getMessageSpy() {
         return messageSpy;
     }
index c00d092f96273335af1233e70141f3213a3a2ce5..dcb445b11e03db4717fcc91d1ab4f5b865730695 100644 (file)
@@ -12,8 +12,7 @@ import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import java.util.Collections;
 import java.util.List;
-
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
 import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
 import org.opendaylight.openflowplugin.api.openflow.registry.flow.DeviceFlowRegistry;
@@ -36,7 +35,7 @@ import org.slf4j.LoggerFactory;
 final class MultipartRequestOnTheFlyCallback extends AbstractRequestCallback<List<MultipartReply>> {
     private static final Logger LOG = LoggerFactory.getLogger(MultipartRequestOnTheFlyCallback.class);
     private static final SinglePurposeMultipartReplyTranslator MULTIPART_REPLY_TRANSLATOR = new SinglePurposeMultipartReplyTranslator();
-    private final DeviceState deviceState;
+    private final DeviceInfo deviceInfo;
     private final DeviceFlowRegistry registry;
     private boolean virgin = true;
     private boolean finished = false;
@@ -48,17 +47,17 @@ final class MultipartRequestOnTheFlyCallback extends AbstractRequestCallback<Lis
                                             final Class<?> requestType,
                                             final MessageSpy messageSpy,
                                             final EventIdentifier eventIdentifier,
-                                            final DeviceState deviceState,
+                                            final DeviceInfo deviceInfo,
                                             final DeviceFlowRegistry registry,
                                             final TxFacade txFacade) {
         super(context, requestType, messageSpy, eventIdentifier);
 
-        this.deviceState = deviceState;
+        this.deviceInfo = deviceInfo;
         this.registry = registry;
         this.txFacade = txFacade;
 
         //TODO: this is focused on flow stats only - need more general approach if used for more than flow stats
-        doneEventIdentifier = new EventIdentifier(MultipartType.OFPMPFLOW.name(), deviceState.getNodeId().toString());
+        doneEventIdentifier = new EventIdentifier(MultipartType.OFPMPFLOW.name(), deviceInfo.getNodeId().toString());
     }
 
     public EventIdentifier getDoneEventIdentifier() {
@@ -90,13 +89,13 @@ final class MultipartRequestOnTheFlyCallback extends AbstractRequestCallback<Lis
 
             final MultipartReply singleReply = multipartReply;
             final List<? extends DataObject> multipartDataList = MULTIPART_REPLY_TRANSLATOR.translate(
-                    deviceState.getFeatures().getDatapathId(), deviceState.getFeatures().getVersion(), singleReply);
+                    deviceInfo.getDatapathId(), deviceInfo.getVersion(), singleReply);
             final Iterable<? extends DataObject> allMultipartData = multipartDataList;
 
             //TODO: following part is focused on flow stats only - need more general approach if used for more than flow stats
             ListenableFuture<Void> future;
             if (virgin) {
-                future = StatisticsGatheringUtils.deleteAllKnownFlows(deviceState, registry, txFacade);
+                future = StatisticsGatheringUtils.deleteAllKnownFlows(deviceInfo, registry, txFacade);
                 virgin = false;
             } else {
                 future = Futures.immediateFuture(null);
@@ -107,7 +106,7 @@ final class MultipartRequestOnTheFlyCallback extends AbstractRequestCallback<Lis
                 @Override
                 public Void apply(final Void input) {
                     StatisticsGatheringUtils.writeFlowStatistics((Iterable<FlowsStatisticsUpdate>) allMultipartData,
-                            deviceState, registry, txFacade);
+                            deviceInfo, registry, txFacade);
 
                     if (!multipartReply.getFlags().isOFPMPFREQMORE()) {
                         endCollecting();
@@ -123,8 +122,8 @@ final class MultipartRequestOnTheFlyCallback extends AbstractRequestCallback<Lis
         EventsTimeCounter.markEnd(getEventIdentifier());
         final RpcResult<List<MultipartReply>> rpcResult = RpcResultBuilder.success(Collections.<MultipartReply>emptyList()).build();
         spyMessage(MessageSpy.STATISTIC_GROUP.FROM_SWITCH_TRANSLATE_OUT_SUCCESS);
-        setResult(rpcResult);
         txFacade.submitTransaction();
+        setResult(rpcResult);
         finished = true;
     }
 }
index 07b5fadcad2b514f16dc89025d166088d1af5827..c0c0a6544f190c69cae2bb3fc0dd157a95b5b6b6 100644 (file)
@@ -53,7 +53,7 @@ public class RoleService extends AbstractSimpleService<RoleRequestInputBuilder,
     }
 
     public Future<BigInteger> getGenerationIdFromDevice(final Short version) {
-        LOG.info("getGenerationIdFromDevice called for device:{}", getNodeId().getValue());
+        LOG.info("getGenerationIdFromDevice called for device:{}", getDeviceInfo().getNodeId().getValue());
 
         // send a dummy no-change role request to get the generation-id of the switch
         final RoleRequestInputBuilder roleRequestInputBuilder = new RoleRequestInputBuilder();
@@ -73,7 +73,7 @@ public class RoleService extends AbstractSimpleService<RoleRequestInputBuilder,
                         finalFuture.set(roleRequestOutput.getGenerationId());
                     } else {
                         LOG.info("roleRequestOutput is null in getGenerationIdFromDevice");
-                        finalFuture.setException(new RoleChangeException("Exception in getting generationId for device:" + getNodeId().getValue()));
+                        finalFuture.setException(new RoleChangeException("Exception in getting generationId for device:" + getDeviceInfo().getNodeId().getValue()));
                     }
 
                 } else {
@@ -96,7 +96,7 @@ public class RoleService extends AbstractSimpleService<RoleRequestInputBuilder,
 
     public Future<RpcResult<SetRoleOutput>> submitRoleChange(final OfpRole ofpRole, final Short version, final BigInteger generationId) {
         LOG.info("submitRoleChange called for device:{}, role:{}",
-                getNodeId(), ofpRole);
+                getDeviceInfo().getNodeId(), ofpRole);
         final RoleRequestInputBuilder roleRequestInputBuilder = new RoleRequestInputBuilder();
         roleRequestInputBuilder.setRole(toOFJavaRole(ofpRole));
         roleRequestInputBuilder.setVersion(version);
@@ -109,7 +109,7 @@ public class RoleService extends AbstractSimpleService<RoleRequestInputBuilder,
             @Override
             public void onSuccess(final RpcResult<RoleRequestOutput> roleRequestOutputRpcResult) {
                 LOG.info("submitRoleChange onSuccess for device:{}, role:{}",
-                        getNodeId(), ofpRole);
+                        getDeviceInfo().getNodeId(), ofpRole);
                 final RoleRequestOutput roleRequestOutput = roleRequestOutputRpcResult.getResult();
                 final Collection<RpcError> rpcErrors = roleRequestOutputRpcResult.getErrors();
                 if (roleRequestOutput != null) {
@@ -131,7 +131,7 @@ public class RoleService extends AbstractSimpleService<RoleRequestInputBuilder,
             @Override
             public void onFailure(final Throwable throwable) {
                 LOG.error("submitRoleChange onFailure for device:{}, role:{}",
-                        getNodeId(), ofpRole, throwable);
+                        getDeviceInfo().getNodeId(), ofpRole, throwable);
                 finalFuture.setException(throwable);
             }
         });
index c2b3dc122cafb466be890f9850b030b2d5628a11..6baeda6c3a784ead8f9730620a20a841c271389f 100644 (file)
@@ -12,8 +12,8 @@ import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
 import org.opendaylight.openflowplugin.api.openflow.device.Xid;
 import org.opendaylight.openflowplugin.extension.api.ConvertorMessageToOFJava;
-import org.opendaylight.openflowplugin.extension.api.ExtensionConverterProviderKeeper;
 import org.opendaylight.openflowplugin.extension.api.TypeVersionKey;
+import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
 import org.opendaylight.openflowplugin.extension.api.exception.ConversionException;
 import org.opendaylight.openflowplugin.extension.api.exception.ConverterNotFoundException;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.message.service.rev151020.SalExperimenterMessageService;
@@ -27,16 +27,20 @@ import org.opendaylight.yangtools.yang.common.RpcResult;
 
 public class SalExperimenterMessageServiceImpl extends AbstractVoidService<SendExperimenterInput> implements SalExperimenterMessageService {
 
-    public SalExperimenterMessageServiceImpl(final RequestContextStack requestContextStack, final DeviceContext deviceContext) {
+    private final ExtensionConverterProvider extensionConverterProvider;
+
+    public SalExperimenterMessageServiceImpl(final RequestContextStack requestContextStack,
+                                             final DeviceContext deviceContext,
+                                             final ExtensionConverterProvider extensionConverterProvider) {
         super(requestContextStack, deviceContext);
+        this.extensionConverterProvider = extensionConverterProvider;
     }
 
     @Override
     protected OfHeader buildRequest(Xid xid, SendExperimenterInput input) throws ConversionException {
         final TypeVersionKey key = new TypeVersionKey(input.getExperimenterMessageOfChoice().getImplementedInterface(), getVersion());
         final ConvertorMessageToOFJava<ExperimenterMessageOfChoice, ExperimenterDataOfChoice> messageConverter =
-                ((ExtensionConverterProviderKeeper) getDeviceContext())
-                        .getExtensionConverterProvider().getMessageConverter(key);
+                extensionConverterProvider.getMessageConverter(key);
 
         if (messageConverter == null) {
             throw new ConverterNotFoundException(key.toString());
index d89b59781cb53b3e4f6d9655182541062618d11e..cf2a160998321f1077b310cbbf79b142acebecb7 100644 (file)
@@ -97,7 +97,7 @@ public class SalFlowServiceImpl implements SalFlowService, ItemLifeCycleSource {
                     }
                     if (itemLifecycleListener != null) {
                         KeyedInstanceIdentifier<Flow, FlowKey> flowPath = createFlowPath(flowDescriptor,
-                                deviceContext.getDeviceState().getNodeInstanceIdentifier());
+                                deviceContext.getDeviceInfo().getNodeInstanceIdentifier());
                         final FlowBuilder flowBuilder = new FlowBuilder(input).setId(flowDescriptor.getFlowId());
                         itemLifecycleListener.onAdded(flowPath, flowBuilder.build());
                     }
@@ -136,7 +136,7 @@ public class SalFlowServiceImpl implements SalFlowService, ItemLifeCycleSource {
                                 deviceContext.getDeviceFlowRegistry().retrieveIdForFlow(flowRegistryKey);
                         if (flowDescriptor != null) {
                             KeyedInstanceIdentifier<Flow, FlowKey> flowPath = createFlowPath(flowDescriptor,
-                                    deviceContext.getDeviceState().getNodeInstanceIdentifier());
+                                    deviceContext.getDeviceInfo().getNodeInstanceIdentifier());
                             itemLifecycleListener.onRemoved(flowPath);
                         }
                     }
@@ -203,7 +203,7 @@ public class SalFlowServiceImpl implements SalFlowService, ItemLifeCycleSource {
                     final FlowDescriptor flowDescriptor = deviceContext.getDeviceFlowRegistry().retrieveIdForFlow(flowRegistryKey);
                     if (flowDescriptor != null) {
                         KeyedInstanceIdentifier<Flow, FlowKey> flowPath = createFlowPath(flowDescriptor,
-                                deviceContext.getDeviceState().getNodeInstanceIdentifier());
+                                deviceContext.getDeviceInfo().getNodeInstanceIdentifier());
                         itemLifecycleListener.onRemoved(flowPath);
                     }
                 }
@@ -215,7 +215,7 @@ public class SalFlowServiceImpl implements SalFlowService, ItemLifeCycleSource {
 
                     if (itemLifecycleListener != null) {
                         KeyedInstanceIdentifier<Flow, FlowKey> flowPath = createFlowPath(flowDescriptor,
-                                deviceContext.getDeviceState().getNodeInstanceIdentifier());
+                                deviceContext.getDeviceInfo().getNodeInstanceIdentifier());
                         final FlowBuilder flowBuilder = new FlowBuilder(input.getUpdatedFlow()).setId(flowDescriptor.getFlowId());
                         itemLifecycleListener.onAdded(flowPath, flowBuilder.build());
                     }
index 1ebc5d4b5ac461ef00f09877ac892db02bfd0c3f..cdbc10b6f08f0083cf503a734154994c0ca60c6a 100644 (file)
@@ -59,7 +59,7 @@ public class SalGroupServiceImpl implements SalGroupService, ItemLifeCycleSource
 
     @Override
     public Future<RpcResult<AddGroupOutput>> addGroup(final AddGroupInput input) {
-        addGroup.getDeviceContext().getDeviceGroupRegistry().store(input.getGroupId());
+        addGroup.getDeviceRegistry().getDeviceGroupRegistry().store(input.getGroupId());
         final ListenableFuture<RpcResult<AddGroupOutput>> resultFuture = addGroup.handleServiceCall(input);
         Futures.addCallback(resultFuture, new FutureCallback<RpcResult<AddGroupOutput>>() {
             @Override
@@ -115,7 +115,7 @@ public class SalGroupServiceImpl implements SalGroupService, ItemLifeCycleSource
 
     @Override
     public Future<RpcResult<RemoveGroupOutput>> removeGroup(final RemoveGroupInput input) {
-        removeGroup.getDeviceContext().getDeviceGroupRegistry().markToBeremoved(input.getGroupId());
+        removeGroup.getDeviceRegistry().getDeviceGroupRegistry().markToBeremoved(input.getGroupId());
         final ListenableFuture<RpcResult<RemoveGroupOutput>> resultFuture = removeGroup.handleServiceCall(input);
         Futures.addCallback(resultFuture, new FutureCallback<RpcResult<RemoveGroupOutput>>() {
             @Override
@@ -144,7 +144,7 @@ public class SalGroupServiceImpl implements SalGroupService, ItemLifeCycleSource
         if (itemLifecycleListener != null) {
             KeyedInstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group, GroupKey> groupPath
                     = createGroupPath(groupId,
-                    deviceContext.getDeviceState().getNodeInstanceIdentifier());
+                    deviceContext.getDeviceInfo().getNodeInstanceIdentifier());
             itemLifecycleListener.onRemoved(groupPath);
         }
     }
@@ -153,7 +153,7 @@ public class SalGroupServiceImpl implements SalGroupService, ItemLifeCycleSource
         if (itemLifecycleListener != null) {
             KeyedInstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group, GroupKey> groupPath
                     = createGroupPath(groupId,
-                    deviceContext.getDeviceState().getNodeInstanceIdentifier());
+                    deviceContext.getDeviceInfo().getNodeInstanceIdentifier());
             itemLifecycleListener.onAdded(groupPath, new GroupBuilder(data).build());
         }
     }
index ced8aa4d3659fe16f22025523897d8b889ec7540..b053d99cb8fc361361d93ccbebe1d0be955b5f36 100644 (file)
@@ -59,7 +59,7 @@ public class SalMeterServiceImpl implements SalMeterService, ItemLifeCycleSource
 
     @Override
     public Future<RpcResult<AddMeterOutput>> addMeter(final AddMeterInput input) {
-        addMeter.getDeviceContext().getDeviceMeterRegistry().store(input.getMeterId());
+        addMeter.getDeviceRegistry().getDeviceMeterRegistry().store(input.getMeterId());
 
         final ListenableFuture<RpcResult<AddMeterOutput>> resultFuture = addMeter.handleServiceCall(input);
         Futures.addCallback(resultFuture, new FutureCallback<RpcResult<AddMeterOutput>>() {
@@ -119,7 +119,7 @@ public class SalMeterServiceImpl implements SalMeterService, ItemLifeCycleSource
 
     @Override
     public Future<RpcResult<RemoveMeterOutput>> removeMeter(final RemoveMeterInput input) {
-        removeMeter.getDeviceContext().getDeviceMeterRegistry().markToBeremoved(input.getMeterId());
+        removeMeter.getDeviceRegistry().getDeviceMeterRegistry().markToBeremoved(input.getMeterId());
         final ListenableFuture<RpcResult<RemoveMeterOutput>> resultFuture = removeMeter.handleServiceCall(input);
         Futures.addCallback(resultFuture, new FutureCallback<RpcResult<RemoveMeterOutput>>() {
 
@@ -149,7 +149,7 @@ public class SalMeterServiceImpl implements SalMeterService, ItemLifeCycleSource
         if (itemLifecycleListener != null) {
             KeyedInstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter, MeterKey> meterPath
                     = createMeterPath(meterId,
-                    deviceContext.getDeviceState().getNodeInstanceIdentifier());
+                    deviceContext.getDeviceInfo().getNodeInstanceIdentifier());
             itemLifecycleListener.onRemoved(meterPath);
         }
     }
@@ -158,7 +158,7 @@ public class SalMeterServiceImpl implements SalMeterService, ItemLifeCycleSource
         if (itemLifecycleListener != null) {
             KeyedInstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter, MeterKey> groupPath
                     = createMeterPath(meterId,
-                    deviceContext.getDeviceState().getNodeInstanceIdentifier());
+                    deviceContext.getDeviceInfo().getNodeInstanceIdentifier());
             itemLifecycleListener.onAdded(groupPath, new MeterBuilder(data).build());
         }
     }
index c6d15de02fd457be14ab8d7f52c87e7e56f26851..ed500030d018ce42676a32fe9707225ddbfbf03e 100644 (file)
@@ -157,14 +157,14 @@ public final class SalRoleServiceImpl extends AbstractSimpleService<SetRoleInput
     }
 
     private ListenableFuture<RpcResult<SetRoleOutput>> tryToChangeRole(final OfpRole role) {
-        LOG.info("RoleChangeTask called on device:{} OFPRole:{}", getNodeId().getValue(), role);
+        LOG.info("RoleChangeTask called on device:{} OFPRole:{}", getDeviceInfo().getNodeId().getValue(), role);
 
         final Future<BigInteger> generationFuture = roleService.getGenerationIdFromDevice(getVersion());
 
         return Futures.transform(JdkFutureAdapters.listenInPoolThread(generationFuture), (AsyncFunction<BigInteger, RpcResult<SetRoleOutput>>) generationId -> {
-            LOG.debug("RoleChangeTask, GenerationIdFromDevice from device {} is {}", getNodeId().getValue(), generationId);
+            LOG.debug("RoleChangeTask, GenerationIdFromDevice from device {} is {}", getDeviceInfo().getNodeId().getValue(), generationId);
             final BigInteger nextGenerationId = getNextGenerationId(generationId);
-            LOG.debug("nextGenerationId received from device:{} is {}", getNodeId().getValue(), nextGenerationId);
+            LOG.debug("nextGenerationId received from device:{} is {}", getDeviceInfo().getNodeId().getValue(), nextGenerationId);
             final Future<RpcResult<SetRoleOutput>> submitRoleFuture = roleService.submitRoleChange(role, getVersion(), nextGenerationId);
             return JdkFutureAdapters.listenInPoolThread(submitRoleFuture);
         });
index 90d5dc62cf24ad8573559705d5f579023a6355b2..bd38f2836a82402d362a66cac1dd7b137ecec609 100644 (file)
@@ -120,7 +120,7 @@ public final class SalTableServiceImpl extends AbstractMultipartService<UpdateTa
         final List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures> salTableFeatures = convertToSalTableFeatures(multipartReplies);
 
         final InstanceIdentifier<FlowCapableNode> flowCapableNodeII = InstanceIdentifier.create(Nodes.class)
-                .child(Node.class, new NodeKey(getNodeId())).augmentation(FlowCapableNode.class);
+                .child(Node.class, new NodeKey(getDeviceInfo().getNodeId())).augmentation(FlowCapableNode.class);
         for (final org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures tableFeatureData : salTableFeatures) {
             final Short tableId = tableFeatureData.getTableId();
             final KeyedInstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures, TableFeaturesKey> tableFeaturesII = flowCapableNodeII
index eafdc7a4aaf53c144ca115520458f5b870accd3f..362fbb6b1300dddf2777fc56e46cebf5e3ea92e1 100644 (file)
@@ -9,7 +9,6 @@
 package org.opendaylight.openflowplugin.impl.statistics;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterators;
@@ -23,12 +22,15 @@ import java.util.Collection;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Optional;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import javax.annotation.concurrent.GuardedBy;
+import org.opendaylight.openflowplugin.api.openflow.OFPContext;
 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
 import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleConductor;
@@ -39,12 +41,11 @@ import org.opendaylight.openflowplugin.impl.rpc.listener.ItemLifecycleListenerIm
 import org.opendaylight.openflowplugin.impl.services.RequestContextUtil;
 import org.opendaylight.openflowplugin.impl.statistics.services.dedicated.StatisticsGatheringOnTheFlyService;
 import org.opendaylight.openflowplugin.impl.statistics.services.dedicated.StatisticsGatheringService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class StatisticsContextImpl implements StatisticsContext {
+class StatisticsContextImpl implements StatisticsContext {
 
     private static final Logger LOG = LoggerFactory.getLogger(StatisticsContextImpl.class);
     private static final String CONNECTION_CLOSED = "Connection closed.";
@@ -63,12 +64,11 @@ public class StatisticsContextImpl implements StatisticsContext {
     private StatisticsGatheringOnTheFlyService statisticsGatheringOnTheFlyService;
     private Timeout pollTimeout;
 
-    private final LifecycleConductor conductor;
     private volatile boolean schedulingEnabled;
+    private volatile CONTEXT_STATE contextState;
 
-    public StatisticsContextImpl(@CheckForNull final NodeId nodeId, final boolean shuttingDownStatisticsPolling, final LifecycleConductor lifecycleConductor) {
-        this.conductor = lifecycleConductor;
-        this.deviceContext = Preconditions.checkNotNull(conductor.getDeviceContext(nodeId));
+    StatisticsContextImpl(@CheckForNull final DeviceInfo deviceInfo, final boolean shuttingDownStatisticsPolling, final LifecycleConductor lifecycleConductor) {
+        this.deviceContext = Preconditions.checkNotNull(lifecycleConductor.getDeviceContext(deviceInfo));
         this.devState = Preconditions.checkNotNull(deviceContext.getDeviceState());
         this.shuttingDownStatisticsPolling = shuttingDownStatisticsPolling;
         emptyFuture = Futures.immediateFuture(false);
@@ -76,7 +76,7 @@ public class StatisticsContextImpl implements StatisticsContext {
         statisticsGatheringOnTheFlyService = new StatisticsGatheringOnTheFlyService(this, deviceContext);
         itemLifeCycleListener = new ItemLifecycleListenerImpl(deviceContext);
         statListForCollectingInitialization();
-        this.deviceContext.setStatisticsContext(StatisticsContextImpl.this);
+        contextState = CONTEXT_STATE.WORKING;
     }
 
     @Override
@@ -107,10 +107,20 @@ public class StatisticsContextImpl implements StatisticsContext {
         }
     }
 
+
+    @Override
+    public ListenableFuture<Boolean> initialGatherDynamicData() {
+        return gatherDynamicData(true);
+    }
+
     @Override
-    public ListenableFuture<Boolean> gatherDynamicData() {
+    public ListenableFuture<Boolean> gatherDynamicData(){
+        return gatherDynamicData(false);
+    }
+
+    private ListenableFuture<Boolean> gatherDynamicData(final boolean initial) {
         if (shuttingDownStatisticsPolling) {
-            LOG.debug("Statistics for device {} is not enabled.", deviceContext.getDeviceState().getNodeId());
+            LOG.debug("Statistics for device {} is not enabled.", deviceContext.getDeviceInfo().getNodeId());
             return Futures.immediateFuture(Boolean.TRUE);
         }
         final ListenableFuture<Boolean> errorResultFuture = deviceConnectionCheck();
@@ -124,7 +134,7 @@ public class StatisticsContextImpl implements StatisticsContext {
             // write start timestamp to state snapshot container
             StatisticsGatheringUtils.markDeviceStateSnapshotStart(deviceContext);
 
-            statChainFuture(statIterator, settableStatResultFuture);
+            statChainFuture(statIterator, settableStatResultFuture, initial);
 
             // write end timestamp to state snapshot container
             Futures.addCallback(settableStatResultFuture, new FutureCallback<Boolean>() {
@@ -141,10 +151,10 @@ public class StatisticsContextImpl implements StatisticsContext {
         }
     }
 
-    private ListenableFuture<Boolean> chooseStat(final MultipartType multipartType){
+    private ListenableFuture<Boolean> chooseStat(final MultipartType multipartType, final boolean initial){
         switch (multipartType) {
             case OFPMPFLOW:
-                return collectFlowStatistics(multipartType);
+                return collectFlowStatistics(multipartType, initial);
             case OFPMPTABLE:
                 return collectTableStatistics(multipartType);
             case OFPMPPORTSTATS:
@@ -180,13 +190,20 @@ public class StatisticsContextImpl implements StatisticsContext {
 
     @Override
     public void close() {
-        schedulingEnabled = false;
-        for (final Iterator<RequestContext<?>> iterator = Iterators.consumingIterator(requestContexts.iterator());
-                iterator.hasNext();) {
-            RequestContextUtil.closeRequestContextWithRpcError(iterator.next(), CONNECTION_CLOSED);
-        }
-        if (null != pollTimeout && !pollTimeout.isExpired()) {
-            pollTimeout.cancel();
+        if (CONTEXT_STATE.TERMINATION.equals(contextState)) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Statistics context is already in state TERMINATION.");
+            }
+        } else {
+            contextState = CONTEXT_STATE.TERMINATION;
+            schedulingEnabled = false;
+            for (final Iterator<RequestContext<?>> iterator = Iterators.consumingIterator(requestContexts.iterator());
+                 iterator.hasNext(); ) {
+                RequestContextUtil.closeRequestContextWithRpcError(iterator.next(), CONNECTION_CLOSED);
+            }
+            if (null != pollTimeout && !pollTimeout.isExpired()) {
+                pollTimeout.cancel();
+            }
         }
     }
 
@@ -207,31 +224,31 @@ public class StatisticsContextImpl implements StatisticsContext {
 
     @Override
     public Optional<Timeout> getPollTimeout() {
-        return Optional.fromNullable(pollTimeout);
+        return Optional.ofNullable(pollTimeout);
     }
 
-    private void statChainFuture(final Iterator<MultipartType> iterator, final SettableFuture<Boolean> resultFuture) {
+    private void statChainFuture(final Iterator<MultipartType> iterator, final SettableFuture<Boolean> resultFuture, final boolean initial) {
         if (ConnectionContext.CONNECTION_STATE.RIP.equals(deviceContext.getPrimaryConnectionContext().getConnectionState())) {
             final String errMsg = String.format("Device connection is closed for Node : %s.",
-                    deviceContext.getDeviceState().getNodeId());
+                    deviceContext.getDeviceInfo().getNodeId());
             LOG.debug(errMsg);
             resultFuture.setException(new IllegalStateException(errMsg));
             return;
         }
         if ( ! iterator.hasNext()) {
             resultFuture.set(Boolean.TRUE);
-            LOG.debug("Stats collection successfully finished for node {}", deviceContext.getDeviceState().getNodeId());
+            LOG.debug("Stats collection successfully finished for node {}", deviceContext.getDeviceInfo().getNodeId());
             return;
         }
 
         final MultipartType nextType = iterator.next();
-        LOG.debug("Stats iterating to next type for node {} of type {}", deviceContext.getDeviceState().getNodeId(), nextType);
+        LOG.debug("Stats iterating to next type for node {} of type {}", deviceContext.getDeviceInfo().getNodeId(), nextType);
 
-        final ListenableFuture<Boolean> deviceStatisticsCollectionFuture = chooseStat(nextType);
+        final ListenableFuture<Boolean> deviceStatisticsCollectionFuture = chooseStat(nextType, initial);
         Futures.addCallback(deviceStatisticsCollectionFuture, new FutureCallback<Boolean>() {
             @Override
             public void onSuccess(final Boolean result) {
-                statChainFuture(iterator, resultFuture);
+                statChainFuture(iterator, resultFuture, initial);
             }
             @Override
             public void onFailure(@Nonnull final Throwable t) {
@@ -249,7 +266,7 @@ public class StatisticsContextImpl implements StatisticsContext {
     @VisibleForTesting
     ListenableFuture<Boolean> deviceConnectionCheck() {
         if (!ConnectionContext.CONNECTION_STATE.WORKING.equals(deviceContext.getPrimaryConnectionContext().getConnectionState())) {
-            ListenableFuture<Boolean> resultingFuture = SettableFuture.create();
+            ListenableFuture<Boolean> resultingFuture;
             switch (deviceContext.getPrimaryConnectionContext().getConnectionState()) {
                 case RIP:
                     final String errMsg = String.format("Device connection doesn't exist anymore. Primary connection status : %s",
@@ -265,44 +282,85 @@ public class StatisticsContextImpl implements StatisticsContext {
         return null;
     }
 
-    private ListenableFuture<Boolean> collectFlowStatistics(final MultipartType multipartType) {
+    //TODO: Refactor twice sending deviceContext into gatheringStatistics
+    private ListenableFuture<Boolean> collectFlowStatistics(final MultipartType multipartType, final boolean initial) {
         return devState.isFlowStatisticsAvailable() ? StatisticsGatheringUtils.gatherStatistics(
-                statisticsGatheringOnTheFlyService, deviceContext, /*MultipartType.OFPMPFLOW*/ multipartType) : emptyFuture;
+                statisticsGatheringOnTheFlyService,
+                deviceContext.getDeviceInfo(),
+                /*MultipartType.OFPMPFLOW*/ multipartType,
+                deviceContext,
+                deviceContext,
+                initial) : emptyFuture;
     }
 
     private ListenableFuture<Boolean> collectTableStatistics(final MultipartType multipartType) {
         return devState.isTableStatisticsAvailable() ? StatisticsGatheringUtils.gatherStatistics(
-                statisticsGatheringService, deviceContext, /*MultipartType.OFPMPTABLE*/ multipartType) : emptyFuture;
+                statisticsGatheringService,
+                deviceContext.getDeviceInfo(),
+                /*MultipartType.OFPMPTABLE*/ multipartType,
+                deviceContext,
+                deviceContext,
+                false) : emptyFuture;
     }
 
     private ListenableFuture<Boolean> collectPortStatistics(final MultipartType multipartType) {
         return devState.isPortStatisticsAvailable() ? StatisticsGatheringUtils.gatherStatistics(
-                statisticsGatheringService, deviceContext, /*MultipartType.OFPMPPORTSTATS*/ multipartType) : emptyFuture;
+                statisticsGatheringService,
+                deviceContext.getDeviceInfo(),
+                /*MultipartType.OFPMPPORTSTATS*/ multipartType,
+                deviceContext,
+                deviceContext,
+                false) : emptyFuture;
     }
 
     private ListenableFuture<Boolean> collectQueueStatistics(final MultipartType multipartType) {
-        return devState.isQueueStatisticsAvailable() ? StatisticsGatheringUtils.gatherStatistics(
-                statisticsGatheringService, deviceContext, /*MultipartType.OFPMPQUEUE*/ multipartType) : emptyFuture;
+        return !devState.isQueueStatisticsAvailable() ? emptyFuture : StatisticsGatheringUtils.gatherStatistics(
+                statisticsGatheringService,
+                deviceContext.getDeviceInfo(),
+                /*MultipartType.OFPMPQUEUE*/ multipartType,
+                deviceContext,
+                deviceContext,
+                false);
     }
 
     private ListenableFuture<Boolean> collectGroupDescStatistics(final MultipartType multipartType) {
         return devState.isGroupAvailable() ? StatisticsGatheringUtils.gatherStatistics(
-                statisticsGatheringService, deviceContext, /*MultipartType.OFPMPGROUPDESC*/ multipartType) : emptyFuture;
+                statisticsGatheringService,
+                deviceContext.getDeviceInfo(),
+                /*MultipartType.OFPMPGROUPDESC*/ multipartType,
+                deviceContext,
+                deviceContext,
+                false) : emptyFuture;
     }
 
     private ListenableFuture<Boolean> collectGroupStatistics(final MultipartType multipartType) {
         return devState.isGroupAvailable() ? StatisticsGatheringUtils.gatherStatistics(
-                statisticsGatheringService, deviceContext, /*MultipartType.OFPMPGROUP*/ multipartType) : emptyFuture;
+                statisticsGatheringService,
+                deviceContext.getDeviceInfo(),
+                /*MultipartType.OFPMPGROUP*/ multipartType,
+                deviceContext,
+                deviceContext,
+                false) : emptyFuture;
     }
 
     private ListenableFuture<Boolean> collectMeterConfigStatistics(final MultipartType multipartType) {
         return devState.isMetersAvailable() ? StatisticsGatheringUtils.gatherStatistics(
-                statisticsGatheringService, deviceContext, /*MultipartType.OFPMPMETERCONFIG*/ multipartType) : emptyFuture;
+                statisticsGatheringService,
+                deviceContext.getDeviceInfo(),
+                /*MultipartType.OFPMPMETERCONFIG*/ multipartType,
+                deviceContext,
+                deviceContext,
+                false) : emptyFuture;
     }
 
     private ListenableFuture<Boolean> collectMeterStatistics(final MultipartType multipartType) {
         return devState.isMetersAvailable() ? StatisticsGatheringUtils.gatherStatistics(
-                statisticsGatheringService, deviceContext, /*MultipartType.OFPMPMETER*/ multipartType) : emptyFuture;
+                statisticsGatheringService,
+                deviceContext.getDeviceInfo(),
+                /*MultipartType.OFPMPMETER*/ multipartType,
+                deviceContext,
+                deviceContext,
+                false) : emptyFuture;
     }
 
     @VisibleForTesting
@@ -321,9 +379,8 @@ public class StatisticsContextImpl implements StatisticsContext {
         return itemLifeCycleListener;
     }
 
-
     @Override
-    public DeviceContext getDeviceContext() {
-        return deviceContext;
+    public CONTEXT_STATE getState() {
+        return contextState;
     }
 }
index 4933f28374008e089049c67978ba84ae55fe0756..afe4d0085a704ae165c3c870da2ee33f424c7c2d 100644 (file)
@@ -26,10 +26,13 @@ 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.openflowplugin.api.openflow.device.DeviceContext;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
+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.FlowRegistryKey;
+import org.opendaylight.openflowplugin.api.openflow.registry.group.DeviceGroupRegistry;
+import org.opendaylight.openflowplugin.api.openflow.registry.meter.DeviceMeterRegistry;
 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.StatisticsGatherer;
 import org.opendaylight.openflowplugin.impl.registry.flow.FlowRegistryKeyFactory;
@@ -109,47 +112,53 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * Created by Martin Bobak &lt;mbobak@cisco.com&gt; on 2.4.2015.
+ * Utils for gatherig statistics
  */
 public final class StatisticsGatheringUtils {
 
-    public static String DATE_AND_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
+    private static String DATE_AND_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
 
     private static final Logger LOG = LoggerFactory.getLogger(StatisticsGatheringUtils.class);
     private static final SinglePurposeMultipartReplyTranslator MULTIPART_REPLY_TRANSLATOR = new SinglePurposeMultipartReplyTranslator();
-    public static final String QUEUE2_REQCTX = "QUEUE2REQCTX-";
+    private static final String QUEUE2_REQCTX = "QUEUE2REQCTX-";
 
     private StatisticsGatheringUtils() {
         throw new IllegalStateException("This class should not be instantiated.");
     }
 
-
-    public static ListenableFuture<Boolean> gatherStatistics(final StatisticsGatherer statisticsGatheringService,
-                                                             final DeviceContext deviceContext,
-                                                             final MultipartType type) {
-        final String deviceId = deviceContext.getPrimaryConnectionContext().getNodeId().toString();
+    //TODO: Flow-,Group- and Meter- registry should be not in device context, consider move it in separate class
+    static ListenableFuture<Boolean> gatherStatistics(final StatisticsGatherer statisticsGatheringService,
+                                                      final DeviceInfo deviceInfo,
+                                                      final MultipartType type,
+                                                      final TxFacade txFacade,
+                                                      final DeviceRegistry registry,
+                                                      final Boolean initial) {
         EventIdentifier wholeProcessEventIdentifier = null;
         if (MultipartType.OFPMPFLOW.equals(type)) {
-            wholeProcessEventIdentifier = new EventIdentifier(type.toString(), deviceId);
+            wholeProcessEventIdentifier = new EventIdentifier(type.toString(), deviceInfo.getNodeId().getValue());
             EventsTimeCounter.markStart(wholeProcessEventIdentifier);
         }
-        final EventIdentifier ofpQueuToRequestContextEventIdentifier = new EventIdentifier(QUEUE2_REQCTX + type.toString(), deviceId);
+        final EventIdentifier ofpQueuToRequestContextEventIdentifier = new EventIdentifier(QUEUE2_REQCTX + type.toString(), deviceInfo.getNodeId().toString());
         final ListenableFuture<RpcResult<List<MultipartReply>>> statisticsDataInFuture =
                 JdkFutureAdapters.listenInPoolThread(statisticsGatheringService.getStatisticsOfType(
                         ofpQueuToRequestContextEventIdentifier, type));
-        return transformAndStoreStatisticsData(statisticsDataInFuture, deviceContext, wholeProcessEventIdentifier, type);
+        return transformAndStoreStatisticsData(statisticsDataInFuture, deviceInfo, wholeProcessEventIdentifier, type, txFacade, registry, initial);
     }
 
     private static ListenableFuture<Boolean> transformAndStoreStatisticsData(final ListenableFuture<RpcResult<List<MultipartReply>>> statisticsDataInFuture,
-                                                                             final DeviceContext deviceContext,
-                                                                             final EventIdentifier eventIdentifier, final MultipartType type) {
+                                                                             final DeviceInfo deviceInfo,
+                                                                             final EventIdentifier eventIdentifier,
+                                                                             final MultipartType type,
+                                                                             final TxFacade txFacade,
+                                                                             final DeviceRegistry registry,
+                                                                             final boolean initial) {
         return Futures.transform(statisticsDataInFuture, new AsyncFunction<RpcResult<List<MultipartReply>>, Boolean>() {
             @Nullable
             @Override
             public ListenableFuture<Boolean> apply(final RpcResult<List<MultipartReply>> rpcResult) {
                 boolean isMultipartProcessed = Boolean.TRUE;
                 if (rpcResult.isSuccessful()) {
-                    LOG.debug("Stats reply successfully received for node {} of type {}", deviceContext.getDeviceState().getNodeId(), type);
+                    LOG.debug("Stats reply successfully received for node {} of type {}", deviceInfo.getNodeId(), type);
 
                     // TODO: in case the result value is null then multipart data probably got processed on the fly -
                     // TODO: this contract should by clearly stated and enforced - now simple true value is returned
@@ -161,56 +170,56 @@ public final class StatisticsGatheringUtils {
                         try {
                             for (final MultipartReply singleReply : rpcResult.getResult()) {
                                 final List<? extends DataObject> multipartDataList = MULTIPART_REPLY_TRANSLATOR.translate(
-                                        deviceContext.getPrimaryConnectionContext().getFeatures().getDatapathId(),
-                                        deviceContext.getPrimaryConnectionContext().getFeatures().getVersion(), singleReply);
+                                        deviceInfo.getDatapathId(),
+                                        deviceInfo.getVersion(), singleReply);
                                 multipartData = multipartDataList.get(0);
                                 allMultipartData = Iterables.concat(allMultipartData, multipartDataList);
                             }
                         } catch (final Exception e) {
                             LOG.warn("stats processing of type {} for node {} failed during transfomation step",
-                                    type, deviceContext.getDeviceState().getNodeId(), e);
+                                    type, deviceInfo.getNodeId(), e);
                             return Futures.immediateFailedFuture(e);
                         }
 
 
                         try {
                             if (multipartData instanceof GroupStatisticsUpdated) {
-                                processGroupStatistics((Iterable<GroupStatisticsUpdated>) allMultipartData, deviceContext);
+                                processGroupStatistics((Iterable<GroupStatisticsUpdated>) allMultipartData, deviceInfo, txFacade);
                             } else if (multipartData instanceof MeterStatisticsUpdated) {
-                                processMetersStatistics((Iterable<MeterStatisticsUpdated>) allMultipartData, deviceContext);
+                                processMetersStatistics((Iterable<MeterStatisticsUpdated>) allMultipartData, deviceInfo, txFacade);
                             } else if (multipartData instanceof NodeConnectorStatisticsUpdate) {
-                                processNodeConnectorStatistics((Iterable<NodeConnectorStatisticsUpdate>) allMultipartData, deviceContext);
+                                processNodeConnectorStatistics((Iterable<NodeConnectorStatisticsUpdate>) allMultipartData, deviceInfo, txFacade);
                             } else if (multipartData instanceof FlowTableStatisticsUpdate) {
-                                processFlowTableStatistics((Iterable<FlowTableStatisticsUpdate>) allMultipartData, deviceContext);
+                                processFlowTableStatistics((Iterable<FlowTableStatisticsUpdate>) allMultipartData, deviceInfo, txFacade);
                             } else if (multipartData instanceof QueueStatisticsUpdate) {
-                                processQueueStatistics((Iterable<QueueStatisticsUpdate>) allMultipartData, deviceContext);
+                                processQueueStatistics((Iterable<QueueStatisticsUpdate>) allMultipartData, deviceInfo, txFacade);
                             } else if (multipartData instanceof FlowsStatisticsUpdate) {
                                 /* FlowStat Processing is realized by NettyThread only by initPhase, otherwise it is realized
                                  * by MD-SAL thread */
-                                return processFlowStatistics((Iterable<FlowsStatisticsUpdate>) allMultipartData, deviceContext, eventIdentifier);
+                                return processFlowStatistics((Iterable<FlowsStatisticsUpdate>) allMultipartData, deviceInfo, txFacade, registry.getDeviceFlowRegistry(), initial, eventIdentifier);
 
                             } else if (multipartData instanceof GroupDescStatsUpdated) {
-                                processGroupDescStats((Iterable<GroupDescStatsUpdated>) allMultipartData, deviceContext);
+                                processGroupDescStats((Iterable<GroupDescStatsUpdated>) allMultipartData, deviceInfo, txFacade, registry.getDeviceGroupRegistry());
                             } else if (multipartData instanceof MeterConfigStatsUpdated) {
-                                processMeterConfigStatsUpdated((Iterable<MeterConfigStatsUpdated>) allMultipartData, deviceContext);
+                                processMeterConfigStatsUpdated((Iterable<MeterConfigStatsUpdated>) allMultipartData, deviceInfo, txFacade, registry.getDeviceMeterRegistry());
                             } else {
                                 isMultipartProcessed = Boolean.FALSE;
                             }
                         } catch (final Exception e) {
                             LOG.warn("stats processing of type {} for node {} failed during write-to-tx step",
-                                    type, deviceContext.getDeviceState().getNodeId(), e);
+                                    type, deviceInfo.getNodeId(), e);
                             return Futures.immediateFailedFuture(e);
                         }
 
-                        LOG.debug("Stats reply added to transaction for node {} of type {}", deviceContext.getDeviceState().getNodeId(), type);
+                        LOG.debug("Stats reply added to transaction for node {} of type {}", deviceInfo.getNodeId(), type);
 
                         //TODO : implement experimenter
                     } else {
-                        LOG.debug("Stats reply was empty for node {} of type {}", deviceContext.getDeviceState().getNodeId(), type);
+                        LOG.debug("Stats reply was empty for node {} of type {}", deviceInfo.getNodeId(), type);
                     }
 
                 } else {
-                    LOG.debug("Stats reply FAILED for node {} of type {}: {}", deviceContext.getDeviceState().getNodeId(), type, rpcResult.getErrors());
+                    LOG.debug("Stats reply FAILED for node {} of type {}: {}", deviceInfo.getNodeId(), type, rpcResult.getErrors());
                     isMultipartProcessed = Boolean.FALSE;
                 }
                 return Futures.immediateFuture(isMultipartProcessed);
@@ -218,9 +227,12 @@ public final class StatisticsGatheringUtils {
         });
     }
 
-    private static void processMeterConfigStatsUpdated(final Iterable<MeterConfigStatsUpdated> data, final DeviceContext deviceContext) throws Exception {
-        final InstanceIdentifier<FlowCapableNode> fNodeIdent = assembleFlowCapableNodeInstanceIdentifier(deviceContext.getDeviceState());
-        deleteAllKnownMeters(deviceContext, fNodeIdent);
+    private static void processMeterConfigStatsUpdated(final Iterable<MeterConfigStatsUpdated> data,
+                                                       final DeviceInfo deviceInfo,
+                                                       final TxFacade txFacade,
+                                                       final DeviceMeterRegistry meterRegistry) throws Exception {
+        final InstanceIdentifier<FlowCapableNode> fNodeIdent = assembleFlowCapableNodeInstanceIdentifier(deviceInfo);
+        deleteAllKnownMeters(meterRegistry, fNodeIdent, txFacade);
         for (final MeterConfigStatsUpdated meterConfigStatsUpdated : data) {
             for (final MeterConfigStats meterConfigStats : meterConfigStatsUpdated.getMeterConfigStats()) {
                 final MeterId meterId = meterConfigStats.getMeterId();
@@ -229,24 +241,27 @@ public final class StatisticsGatheringUtils {
                 final MeterBuilder meterBuilder = new MeterBuilder(meterConfigStats);
                 meterBuilder.setKey(new MeterKey(meterId));
                 meterBuilder.addAugmentation(NodeMeterStatistics.class, new NodeMeterStatisticsBuilder().build());
-                deviceContext.getDeviceMeterRegistry().store(meterId);
-                deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, meterInstanceIdentifier, meterBuilder.build());
+                meterRegistry.store(meterId);
+                txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, meterInstanceIdentifier, meterBuilder.build());
             }
         }
-        deviceContext.submitTransaction();
+        txFacade.submitTransaction();
     }
 
     private static ListenableFuture<Boolean> processFlowStatistics(final Iterable<FlowsStatisticsUpdate> data,
-                                                                   final DeviceContext deviceContext, final EventIdentifier eventIdentifier) {
-        final ListenableFuture<Void> deleFuture = deleteAllKnownFlows(deviceContext.getDeviceState(),
-                deviceContext.getDeviceFlowRegistry(), deviceContext);
-        return Futures.transform(deleFuture, new Function<Void, Boolean>() {
+                                                                   final DeviceInfo deviceInfo,
+                                                                   final TxFacade txFacade,
+                                                                   final DeviceFlowRegistry flowRegistry,
+                                                                   final boolean initial,
+                                                                   final EventIdentifier eventIdentifier) {
+        final ListenableFuture<Void> deleteFuture = initial ? Futures.immediateFuture(null) : deleteAllKnownFlows(deviceInfo,
+                flowRegistry, txFacade);
+        return Futures.transform(deleteFuture, new Function<Void, Boolean>() {
 
             @Override
             public Boolean apply(final Void input) {
-                writeFlowStatistics(data, deviceContext.getDeviceState(), deviceContext.getDeviceFlowRegistry(),
-                        deviceContext);
-                deviceContext.submitTransaction();
+                writeFlowStatistics(data, deviceInfo, flowRegistry, txFacade);
+                txFacade.submitTransaction();
                 EventsTimeCounter.markEnd(eventIdentifier);
                 return Boolean.TRUE;
             }
@@ -254,10 +269,10 @@ public final class StatisticsGatheringUtils {
     }
 
     public static void writeFlowStatistics(final Iterable<FlowsStatisticsUpdate> data,
-                                           final DeviceState deviceState,
+                                           final DeviceInfo deviceInfo,
                                            final DeviceFlowRegistry registry,
                                            final TxFacade txFacade) {
-        final InstanceIdentifier<FlowCapableNode> fNodeIdent = assembleFlowCapableNodeInstanceIdentifier(deviceState);
+        final InstanceIdentifier<FlowCapableNode> fNodeIdent = assembleFlowCapableNodeInstanceIdentifier(deviceInfo);
         try {
             for (final FlowsStatisticsUpdate flowsStatistics : data) {
                 for (final FlowAndStatisticsMapList flowStat : flowsStatistics.getFlowAndStatisticsMapList()) {
@@ -292,53 +307,49 @@ public final class StatisticsGatheringUtils {
         return flowStatisticsDataBld;
     }
 
-    public static ListenableFuture<Void> deleteAllKnownFlows(final DeviceState deviceState,
+    public static ListenableFuture<Void> deleteAllKnownFlows(final DeviceInfo deviceInfo,
                                                              final DeviceFlowRegistry registry,
                                                              final TxFacade txFacade) {
-        /* DeviceState.deviceSynchronized is a marker for actual phase - false means initPhase, true means noInitPhase */
-        if (deviceState.deviceSynchronized()) {
-            final InstanceIdentifier<FlowCapableNode> flowCapableNodePath = assembleFlowCapableNodeInstanceIdentifier(deviceState);
-            final ReadOnlyTransaction readTx = txFacade.getReadTransaction();
-            final CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> flowCapableNodeFuture = readTx.read(
-                    LogicalDatastoreType.OPERATIONAL, flowCapableNodePath);
-
-            /* we wish to close readTx for fallBack */
-            Futures.withFallback(flowCapableNodeFuture, new FutureFallback<Optional<FlowCapableNode>>() {
-
-                @Override
-                public ListenableFuture<Optional<FlowCapableNode>> create(final Throwable t) throws Exception {
-                    readTx.close();
-                    return Futures.immediateFailedFuture(t);
-                }
-            });
-            /*
-             * we have to read actual tables with all information before we set empty Flow list, merge is expensive and
-             * not applicable for lists
-             */
-            return Futures.transform(flowCapableNodeFuture, new AsyncFunction<Optional<FlowCapableNode>, Void>() {
-
-                @Override
-                public ListenableFuture<Void> apply(final Optional<FlowCapableNode> flowCapNodeOpt) throws Exception {
-                    if (flowCapNodeOpt.isPresent()) {
-                        for (final Table tableData : flowCapNodeOpt.get().getTable()) {
-                            final Table table = new TableBuilder(tableData).setFlow(Collections.<Flow>emptyList()).build();
-                            final InstanceIdentifier<Table> iiToTable = flowCapableNodePath.child(Table.class, tableData.getKey());
-                            txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, iiToTable, table);
-                        }
+        final InstanceIdentifier<FlowCapableNode> flowCapableNodePath = assembleFlowCapableNodeInstanceIdentifier(deviceInfo);
+        final ReadOnlyTransaction readTx = txFacade.getReadTransaction();
+        final CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> flowCapableNodeFuture = readTx.read(
+                LogicalDatastoreType.OPERATIONAL, flowCapableNodePath);
+
+        /* we wish to close readTx for fallBack */
+        Futures.withFallback(flowCapableNodeFuture, new FutureFallback<Optional<FlowCapableNode>>() {
+
+            @Override
+            public ListenableFuture<Optional<FlowCapableNode>> create(final Throwable t) throws Exception {
+                readTx.close();
+                return Futures.immediateFailedFuture(t);
+            }
+        });
+        /*
+         * we have to read actual tables with all information before we set empty Flow list, merge is expensive and
+         * not applicable for lists
+         */
+        return Futures.transform(flowCapableNodeFuture, new AsyncFunction<Optional<FlowCapableNode>, Void>() {
+
+            @Override
+            public ListenableFuture<Void> apply(final Optional<FlowCapableNode> flowCapNodeOpt) throws Exception {
+                if (flowCapNodeOpt.isPresent()) {
+                    for (final Table tableData : flowCapNodeOpt.get().getTable()) {
+                        final Table table = new TableBuilder(tableData).setFlow(Collections.<Flow>emptyList()).build();
+                        final InstanceIdentifier<Table> iiToTable = flowCapableNodePath.child(Table.class, tableData.getKey());
+                        txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, iiToTable, table);
                     }
-                    registry.removeMarked();
-                    readTx.close();
-                    return Futures.immediateFuture(null);
                 }
+                registry.removeMarked();
+                readTx.close();
+                return Futures.immediateFuture(null);
+            }
 
-            });
-        }
-        return Futures.immediateFuture(null);
+        });
     }
 
-    private static void processQueueStatistics(final Iterable<QueueStatisticsUpdate> data, final DeviceContext deviceContext) throws Exception {
+    private static void processQueueStatistics(final Iterable<QueueStatisticsUpdate> data, final DeviceInfo deviceInfo, final TxFacade txFacade) throws Exception {
         // TODO: clean all queues of all node-connectors before writing up-to-date stats
-        final InstanceIdentifier<Node> nodeIdent = deviceContext.getDeviceState().getNodeInstanceIdentifier();
+        final InstanceIdentifier<Node> nodeIdent = deviceInfo.getNodeInstanceIdentifier();
         for (final QueueStatisticsUpdate queueStatisticsUpdate : data) {
             for (final QueueIdAndStatisticsMap queueStat : queueStatisticsUpdate.getQueueIdAndStatisticsMap()) {
                 if (queueStat.getQueueId() != null) {
@@ -357,29 +368,29 @@ public final class StatisticsGatheringUtils {
                             .setQueueId(queueStat.getQueueId())
                             // node-connector-id is already contained in parent node and the port-id here is of incompatible format
                             .addAugmentation(FlowCapableNodeConnectorQueueStatisticsData.class, statBuild.build());
-                    deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, queueIdent, queueBuilder.build());
+                    txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, queueIdent, queueBuilder.build());
                 }
             }
         }
-        deviceContext.submitTransaction();
+        txFacade.submitTransaction();
     }
 
-    private static void processFlowTableStatistics(final Iterable<FlowTableStatisticsUpdate> data, final DeviceContext deviceContext) throws Exception {
-        final InstanceIdentifier<FlowCapableNode> fNodeIdent = assembleFlowCapableNodeInstanceIdentifier(deviceContext.getDeviceState());
+    private static void processFlowTableStatistics(final Iterable<FlowTableStatisticsUpdate> data, final DeviceInfo deviceInfo, final TxFacade txFacade) throws Exception {
+        final InstanceIdentifier<FlowCapableNode> fNodeIdent = assembleFlowCapableNodeInstanceIdentifier(deviceInfo);
         for (final FlowTableStatisticsUpdate flowTableStatisticsUpdate : data) {
 
             for (final FlowTableAndStatisticsMap tableStat : flowTableStatisticsUpdate.getFlowTableAndStatisticsMap()) {
                 final InstanceIdentifier<FlowTableStatistics> tStatIdent = fNodeIdent.child(Table.class, new TableKey(tableStat.getTableId().getValue()))
                         .augmentation(FlowTableStatisticsData.class).child(FlowTableStatistics.class);
                 final FlowTableStatistics stats = new FlowTableStatisticsBuilder(tableStat).build();
-                deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, tStatIdent, stats);
+                txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, tStatIdent, stats);
             }
         }
-        deviceContext.submitTransaction();
+        txFacade.submitTransaction();
     }
 
-    private static void processNodeConnectorStatistics(final Iterable<NodeConnectorStatisticsUpdate> data, final DeviceContext deviceContext) throws Exception {
-        final InstanceIdentifier<Node> nodeIdent = deviceContext.getDeviceState().getNodeInstanceIdentifier();
+    private static void processNodeConnectorStatistics(final Iterable<NodeConnectorStatisticsUpdate> data, final DeviceInfo deviceInfo, final TxFacade txFacade) throws Exception {
+        final InstanceIdentifier<Node> nodeIdent = deviceInfo.getNodeInstanceIdentifier();
         for (final NodeConnectorStatisticsUpdate nodeConnectorStatisticsUpdate : data) {
             for (final NodeConnectorStatisticsAndPortNumberMap nConnectPort : nodeConnectorStatisticsUpdate.getNodeConnectorStatisticsAndPortNumberMap()) {
                 final FlowCapableNodeConnectorStatistics stats = new FlowCapableNodeConnectorStatisticsBuilder(nConnectPort).build();
@@ -389,15 +400,16 @@ public final class StatisticsGatheringUtils {
                         .augmentation(FlowCapableNodeConnectorStatisticsData.class);
                 final InstanceIdentifier<FlowCapableNodeConnectorStatistics> flowCapNodeConnStatIdent =
                         nodeConnStatIdent.child(FlowCapableNodeConnectorStatistics.class);
-                deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, flowCapNodeConnStatIdent, stats);
+                txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, flowCapNodeConnStatIdent, stats);
             }
         }
-        deviceContext.submitTransaction();
+        txFacade.submitTransaction();
     }
 
     private static void processMetersStatistics(final Iterable<MeterStatisticsUpdated> data,
-                                                final DeviceContext deviceContext) throws Exception {
-        final InstanceIdentifier<FlowCapableNode> fNodeIdent = assembleFlowCapableNodeInstanceIdentifier(deviceContext.getDeviceState());
+                                                final DeviceInfo deviceInfo,
+                                                final TxFacade txFacade) throws Exception {
+        final InstanceIdentifier<FlowCapableNode> fNodeIdent = assembleFlowCapableNodeInstanceIdentifier(deviceInfo);
         for (final MeterStatisticsUpdated meterStatisticsUpdated : data) {
             for (final MeterStats mStat : meterStatisticsUpdated.getMeterStats()) {
                 final MeterStatistics stats = new MeterStatisticsBuilder(mStat).build();
@@ -406,24 +418,23 @@ public final class StatisticsGatheringUtils {
                 final InstanceIdentifier<NodeMeterStatistics> nodeMeterStatIdent = meterIdent
                         .augmentation(NodeMeterStatistics.class);
                 final InstanceIdentifier<MeterStatistics> msIdent = nodeMeterStatIdent.child(MeterStatistics.class);
-                deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, msIdent, stats);
+                txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, msIdent, stats);
             }
         }
-        deviceContext.submitTransaction();
+        txFacade.submitTransaction();
     }
 
-    private static void deleteAllKnownMeters(final DeviceContext deviceContext, final InstanceIdentifier<FlowCapableNode> fNodeIdent) throws Exception {
-        for (final MeterId meterId : deviceContext.getDeviceMeterRegistry().getAllMeterIds()) {
+    private static void deleteAllKnownMeters(final DeviceMeterRegistry meterRegistry, final InstanceIdentifier<FlowCapableNode> fNodeIdent, final TxFacade txFacade) throws Exception {
+        for (final MeterId meterId : meterRegistry.getAllMeterIds()) {
             final InstanceIdentifier<Meter> meterIdent = fNodeIdent.child(Meter.class, new MeterKey(meterId));
-            deviceContext.addDeleteToTxChain(LogicalDatastoreType.OPERATIONAL, meterIdent);
+            txFacade.addDeleteToTxChain(LogicalDatastoreType.OPERATIONAL, meterIdent);
         }
-        deviceContext.getDeviceMeterRegistry().removeMarked();
+        meterRegistry.removeMarked();
     }
 
-    private static void processGroupDescStats(final Iterable<GroupDescStatsUpdated> data, final DeviceContext deviceContext) throws Exception {
-        final InstanceIdentifier<FlowCapableNode> fNodeIdent =
-                deviceContext.getDeviceState().getNodeInstanceIdentifier().augmentation(FlowCapableNode.class);
-        deleteAllKnownGroups(deviceContext, fNodeIdent);
+    private static void processGroupDescStats(final Iterable<GroupDescStatsUpdated> data, final DeviceInfo deviceInfo, final TxFacade txFacade, final DeviceGroupRegistry groupRegistry) throws Exception {
+        final InstanceIdentifier<FlowCapableNode> fNodeIdent = assembleFlowCapableNodeInstanceIdentifier(deviceInfo);
+        deleteAllKnownGroups(txFacade, fNodeIdent, groupRegistry);
 
         for (final GroupDescStatsUpdated groupDescStatsUpdated : data) {
             for (final GroupDescStats groupDescStats : groupDescStatsUpdated.getGroupDescStats()) {
@@ -435,23 +446,23 @@ public final class StatisticsGatheringUtils {
 
                 final InstanceIdentifier<Group> groupIdent = fNodeIdent.child(Group.class, new GroupKey(groupId));
 
-                deviceContext.getDeviceGroupRegistry().store(groupId);
-                deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, groupIdent, groupBuilder.build());
+                groupRegistry.store(groupId);
+                txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, groupIdent, groupBuilder.build());
             }
         }
-        deviceContext.submitTransaction();
+        txFacade.submitTransaction();
     }
 
-    private static void deleteAllKnownGroups(final DeviceContext deviceContext, final InstanceIdentifier<FlowCapableNode> fNodeIdent) throws Exception {
-        for (final GroupId groupId : deviceContext.getDeviceGroupRegistry().getAllGroupIds()) {
+    private static void deleteAllKnownGroups(final TxFacade txFacade, final InstanceIdentifier<FlowCapableNode> fNodeIdent, final DeviceGroupRegistry groupRegistry) throws Exception {
+        for (final GroupId groupId : groupRegistry.getAllGroupIds()) {
             final InstanceIdentifier<Group> groupIdent = fNodeIdent.child(Group.class, new GroupKey(groupId));
-            deviceContext.addDeleteToTxChain(LogicalDatastoreType.OPERATIONAL, groupIdent);
+            txFacade.addDeleteToTxChain(LogicalDatastoreType.OPERATIONAL, groupIdent);
         }
-        deviceContext.getDeviceGroupRegistry().removeMarked();
+        groupRegistry.removeMarked();
     }
 
-    private static void processGroupStatistics(final Iterable<GroupStatisticsUpdated> data, final DeviceContext deviceContext) throws Exception {
-        final InstanceIdentifier<FlowCapableNode> fNodeIdent = assembleFlowCapableNodeInstanceIdentifier(deviceContext.getDeviceState());
+    private static void processGroupStatistics(final Iterable<GroupStatisticsUpdated> data, final DeviceInfo deviceInfo, final TxFacade txFacade) throws Exception {
+        final InstanceIdentifier<FlowCapableNode> fNodeIdent = assembleFlowCapableNodeInstanceIdentifier(deviceInfo);
         for (final GroupStatisticsUpdated groupStatistics : data) {
             for (final GroupStats groupStats : groupStatistics.getGroupStats()) {
 
@@ -461,14 +472,14 @@ public final class StatisticsGatheringUtils {
 
                 final InstanceIdentifier<GroupStatistics> gsIdent = nGroupStatIdent.child(GroupStatistics.class);
                 final GroupStatistics stats = new GroupStatisticsBuilder(groupStats).build();
-                deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, gsIdent, stats);
+                txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, gsIdent, stats);
             }
         }
-        deviceContext.submitTransaction();
+        txFacade.submitTransaction();
     }
 
-    private static InstanceIdentifier<FlowCapableNode> assembleFlowCapableNodeInstanceIdentifier(final DeviceState deviceState) {
-        return deviceState.getNodeInstanceIdentifier().augmentation(FlowCapableNode.class);
+    private static InstanceIdentifier<FlowCapableNode> assembleFlowCapableNodeInstanceIdentifier(final DeviceInfo deviceInfo) {
+        return deviceInfo.getNodeInstanceIdentifier().augmentation(FlowCapableNode.class);
     }
 
     /**
@@ -477,7 +488,7 @@ public final class StatisticsGatheringUtils {
      * @param deviceContext txManager + node path keeper
      */
     static void markDeviceStateSnapshotStart(final DeviceContext deviceContext) {
-        final InstanceIdentifier<FlowCapableStatisticsGatheringStatus> statusPath = deviceContext.getDeviceState()
+        final InstanceIdentifier<FlowCapableStatisticsGatheringStatus> statusPath = deviceContext.getDeviceInfo()
                 .getNodeInstanceIdentifier().augmentation(FlowCapableStatisticsGatheringStatus.class);
 
         final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_AND_TIME_FORMAT);
@@ -503,7 +514,7 @@ public final class StatisticsGatheringUtils {
      * @param succeeded     outcome of currently finished gathering
      */
     static void markDeviceStateSnapshotEnd(final DeviceContext deviceContext, final boolean succeeded) {
-        final InstanceIdentifier<SnapshotGatheringStatusEnd> statusEndPath = deviceContext.getDeviceState()
+        final InstanceIdentifier<SnapshotGatheringStatusEnd> statusEndPath = deviceContext.getDeviceInfo()
                 .getNodeInstanceIdentifier().augmentation(FlowCapableStatisticsGatheringStatus.class)
                 .child(SnapshotGatheringStatusEnd.class);
 
index ca217555cf0e4699935c1bbdcad9433b4e0c000d..8aa3c7aa537d248bc8b58a1cb78991f180fc450b 100644 (file)
@@ -9,7 +9,6 @@
 package org.opendaylight.openflowplugin.impl.statistics;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Verify;
 import com.google.common.collect.Iterators;
@@ -18,16 +17,29 @@ import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import io.netty.util.Timeout;
 import io.netty.util.TimerTask;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.Future;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.openflowplugin.api.openflow.OFPContext;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceInitializationPhaseHandler;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceTerminationPhaseHandler;
 import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleConductor;
 import org.opendaylight.openflowplugin.api.openflow.rpc.ItemLifeCycleSource;
 import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsContext;
 import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsManager;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.sm.control.rev150812.ChangeStatisticsWorkModeInput;
 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.GetStatisticsWorkModeOutputBuilder;
@@ -39,16 +51,6 @@ import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.annotation.CheckForNull;
-import javax.annotation.Nonnull;
-import java.util.Iterator;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.Future;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-
 public class StatisticsManagerImpl implements StatisticsManager, StatisticsManagerControlService {
 
     private static final Logger LOG = LoggerFactory.getLogger(StatisticsManagerImpl.class);
@@ -58,7 +60,7 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag
     private DeviceInitializationPhaseHandler deviceInitPhaseHandler;
     private DeviceTerminationPhaseHandler deviceTerminPhaseHandler;
 
-    private final ConcurrentMap<NodeId, StatisticsContext> contexts = new ConcurrentHashMap<>();
+    private final ConcurrentMap<DeviceInfo, StatisticsContext> contexts = new ConcurrentHashMap<>();
 
     private static final long basicTimerDelay = 3000;
     private static long currentTimerDelay = basicTimerDelay;
@@ -87,41 +89,39 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag
     }
 
     @Override
-    public void onDeviceContextLevelUp(final NodeId nodeId) throws Exception {
+    public void onDeviceContextLevelUp(final DeviceInfo deviceInfo) throws Exception {
 
-        final DeviceContext deviceContext = Preconditions.checkNotNull(conductor.getDeviceContext(nodeId));
+        final DeviceContext deviceContext = Preconditions.checkNotNull(conductor.getDeviceContext(deviceInfo));
 
-        final StatisticsContext statisticsContext = new StatisticsContextImpl(nodeId, shuttingDownStatisticsPolling, conductor);
-        Verify.verify(contexts.putIfAbsent(nodeId, statisticsContext) == null, "StatisticsCtx still not closed for Node {}", nodeId);
+        final StatisticsContext statisticsContext = new StatisticsContextImpl(deviceInfo, shuttingDownStatisticsPolling, conductor);
+        Verify.verify(contexts.putIfAbsent(deviceInfo, statisticsContext) == null, "StatisticsCtx still not closed for Node {}", deviceInfo.getNodeId());
 
-        deviceContext.getDeviceState().setDeviceSynchronized(true);
-        deviceInitPhaseHandler.onDeviceContextLevelUp(nodeId);
+        deviceInitPhaseHandler.onDeviceContextLevelUp(deviceInfo);
     }
 
     @VisibleForTesting
-    void pollStatistics(final DeviceContext deviceContext,
-                                final StatisticsContext statisticsContext,
-                                final TimeCounter timeCounter) {
-
-        final NodeId nodeId = deviceContext.getDeviceState().getNodeId();
+    void pollStatistics(final DeviceState deviceState,
+                        final StatisticsContext statisticsContext,
+                        final TimeCounter timeCounter,
+                        final DeviceInfo deviceInfo) {
 
         if (!statisticsContext.isSchedulingEnabled()) {
-            LOG.debug("Disabling statistics scheduling for device: {}", nodeId);
+            LOG.debug("Disabling statistics scheduling for device: {}", deviceInfo.getNodeId());
             return;
         }
         
-        if (!deviceContext.getDeviceState().isValid()) {
-            LOG.debug("Session is not valid for device: {}", nodeId);
+        if (!deviceState.isValid()) {
+            LOG.debug("Session is not valid for device: {}", deviceInfo.getNodeId());
             return;
         }
 
-        if (!deviceContext.getDeviceState().isStatisticsPollingEnabled()) {
-            LOG.debug("Statistics polling is currently disabled for device: {}", nodeId);
-            scheduleNextPolling(deviceContext, statisticsContext, timeCounter);
+        if (!deviceState.isStatisticsPollingEnabled()) {
+            LOG.debug("Statistics polling is currently disabled for device: {}", deviceInfo.getNodeId());
+            scheduleNextPolling(deviceState, deviceInfo, statisticsContext, timeCounter);
             return;
         }
 
-        LOG.debug("POLLING ALL STATISTICS for device: {}", nodeId);
+        LOG.debug("POLLING ALL STATISTICS for device: {}", deviceInfo.getNodeId());
         timeCounter.markStart();
         final ListenableFuture<Boolean> deviceStatisticsCollectionFuture = statisticsContext.gatherDynamicData();
         Futures.addCallback(deviceStatisticsCollectionFuture, new FutureCallback<Boolean>() {
@@ -129,7 +129,7 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag
             public void onSuccess(final Boolean o) {
                 timeCounter.addTimeMark();
                 calculateTimerDelay(timeCounter);
-                scheduleNextPolling(deviceContext, statisticsContext, timeCounter);
+                scheduleNextPolling(deviceState, deviceInfo, statisticsContext, timeCounter);
             }
 
             @Override
@@ -140,40 +140,32 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag
                 calculateTimerDelay(timeCounter);
                 if (throwable instanceof CancellationException) {
                     /** This often happens when something wrong with akka or DS, so closing connection will help to restart device **/
-                    conductor.closeConnection(deviceContext.getDeviceState().getNodeId());
+                    conductor.closeConnection(deviceInfo);
                 } else {
-                    scheduleNextPolling(deviceContext, statisticsContext, timeCounter);
+                    scheduleNextPolling(deviceState, deviceInfo, statisticsContext, timeCounter);
                 }
             }
         });
 
         final long averageTime = TimeUnit.MILLISECONDS.toSeconds(timeCounter.getAverageTimeBetweenMarks());
         final long STATS_TIMEOUT_SEC = averageTime > 0 ? 3 * averageTime : DEFAULT_STATS_TIMEOUT_SEC;
-        final TimerTask timerTask = new TimerTask() {
-
-            @Override
-            public void run(final Timeout timeout) throws Exception {
-                if (!deviceStatisticsCollectionFuture.isDone()) {
-                    LOG.info("Statistics collection for node {} still in progress even after {} secs", nodeId, STATS_TIMEOUT_SEC);
-                    deviceStatisticsCollectionFuture.cancel(true);
-                }
+        final TimerTask timerTask = timeout -> {
+            if (!deviceStatisticsCollectionFuture.isDone()) {
+                LOG.info("Statistics collection for node {} still in progress even after {} secs", deviceInfo.getNodeId(), STATS_TIMEOUT_SEC);
+                deviceStatisticsCollectionFuture.cancel(true);
             }
         };
 
         conductor.newTimeout(timerTask, STATS_TIMEOUT_SEC, TimeUnit.SECONDS);
     }
 
-    private void scheduleNextPolling(final DeviceContext deviceContext,
+    private void scheduleNextPolling(final DeviceState deviceState,
+                                     final DeviceInfo deviceInfo,
                                      final StatisticsContext statisticsContext,
                                      final TimeCounter timeCounter) {
-        LOG.debug("SCHEDULING NEXT STATISTICS POLLING for device: {}", deviceContext.getDeviceState().getNodeId());
+        LOG.debug("SCHEDULING NEXT STATISTICS POLLING for device: {}", deviceInfo.getNodeId());
         if (!shuttingDownStatisticsPolling) {
-            final Timeout pollTimeout = conductor.newTimeout(new TimerTask() {
-                @Override
-                public void run(final Timeout timeout) throws Exception {
-                    pollStatistics(deviceContext, statisticsContext, timeCounter);
-                }
-            }, currentTimerDelay, TimeUnit.MILLISECONDS);
+            final Timeout pollTimeout = conductor.newTimeout(timeout -> pollStatistics(deviceState, statisticsContext, timeCounter, deviceInfo), currentTimerDelay, TimeUnit.MILLISECONDS);
             statisticsContext.setPollTimeout(pollTimeout);
         }
     }
@@ -201,13 +193,13 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag
     }
 
     @Override
-    public void onDeviceContextLevelDown(final DeviceContext deviceContext) {
-        final StatisticsContext statisticsContext = contexts.remove(deviceContext.getDeviceState().getNodeId());
+    public void onDeviceContextLevelDown(final DeviceInfo deviceInfo) {
+        final StatisticsContext statisticsContext = contexts.remove(deviceInfo);
         if (null != statisticsContext) {
-            LOG.trace("Removing device context from stack. No more statistics gathering for device: {}", deviceContext.getDeviceState().getNodeId());
+            LOG.trace("Removing device context from stack. No more statistics gathering for device: {}", deviceInfo.getNodeId());
             statisticsContext.close();
         }
-        deviceTerminPhaseHandler.onDeviceContextLevelDown(deviceContext);
+        deviceTerminPhaseHandler.onDeviceContextLevelDown(deviceInfo);
     }
 
     @Override
@@ -226,22 +218,21 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag
             if (!workMode.equals(targetWorkMode)) {
                 shuttingDownStatisticsPolling = StatisticsWorkMode.FULLYDISABLED.equals(targetWorkMode);
                 // iterate through stats-ctx: propagate mode
-                for (final StatisticsContext statisticsContext : contexts.values()) {
-                    final DeviceContext deviceContext = statisticsContext.getDeviceContext();
+                for (Map.Entry<DeviceInfo, StatisticsContext> entry : contexts.entrySet()) {
                     switch (targetWorkMode) {
                         case COLLECTALL:
-                            scheduleNextPolling(deviceContext, statisticsContext, new TimeCounter());
-                            for (final ItemLifeCycleSource lifeCycleSource : deviceContext.getItemLifeCycleSourceRegistry().getLifeCycleSources()) {
+                            scheduleNextPolling(conductor.getDeviceContext(entry.getKey()).getDeviceState(), entry.getKey(), entry.getValue(), new TimeCounter());
+                            for (final ItemLifeCycleSource lifeCycleSource : conductor.getDeviceContext(entry.getKey()).getItemLifeCycleSourceRegistry().getLifeCycleSources()) {
                                 lifeCycleSource.setItemLifecycleListener(null);
                             }
                             break;
                         case FULLYDISABLED:
-                            final Optional<Timeout> pollTimeout = statisticsContext.getPollTimeout();
+                            final Optional<Timeout> pollTimeout = entry.getValue().getPollTimeout();
                             if (pollTimeout.isPresent()) {
                                 pollTimeout.get().cancel();
                             }
-                            for (final ItemLifeCycleSource lifeCycleSource : deviceContext.getItemLifeCycleSourceRegistry().getLifeCycleSources()) {
-                                lifeCycleSource.setItemLifecycleListener(statisticsContext.getItemLifeCycleListener());
+                            for (final ItemLifeCycleSource lifeCycleSource : conductor.getDeviceContext(entry.getKey()).getItemLifeCycleSourceRegistry().getLifeCycleSources()) {
+                                lifeCycleSource.setItemLifecycleListener(entry.getValue().getItemLifeCycleListener());
                             }
                             break;
                         default:
@@ -261,43 +252,37 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag
     }
 
     @Override
-    public void startScheduling(final NodeId nodeId) {
+    public void startScheduling(final DeviceInfo deviceInfo) {
         if (shuttingDownStatisticsPolling) {
-            LOG.info("Statistics are shut down for device: {}", nodeId);
+            LOG.info("Statistics are shut down for device: {}", deviceInfo.getNodeId());
             return;
         }
 
-        final StatisticsContext statisticsContext = contexts.get(nodeId);
+        final StatisticsContext statisticsContext = contexts.get(deviceInfo);
 
         if (statisticsContext == null) {
-            LOG.warn("Statistics context not found for device: {}", nodeId);
+            LOG.warn("Statistics context not found for device: {}", deviceInfo.getNodeId());
             return;
         }
 
         if (statisticsContext.isSchedulingEnabled()) {
-            LOG.debug("Statistics scheduling is already enabled for device: {}", nodeId);
+            LOG.debug("Statistics scheduling is already enabled for device: {}", deviceInfo.getNodeId());
             return;
         }
 
-        LOG.info("Scheduling statistics poll for device: {}", nodeId);
-        final DeviceContext deviceContext = conductor.getDeviceContext(nodeId);
-
-        if (deviceContext == null) {
-            LOG.warn("Device context not found for device: {}", nodeId);
-            return;
-        }
+        LOG.info("Scheduling statistics poll for device: {}", deviceInfo.getNodeId());
 
         statisticsContext.setSchedulingEnabled(true);
-        scheduleNextPolling(deviceContext, statisticsContext, new TimeCounter());
+        scheduleNextPolling(conductor.getDeviceContext(deviceInfo).getDeviceState(), deviceInfo, statisticsContext, new TimeCounter());
     }
 
     @Override
-    public void stopScheduling(final NodeId nodeId) {
-        LOG.debug("Stopping statistics scheduling for device: {}", nodeId);
-        final StatisticsContext statisticsContext = contexts.get(nodeId);
+    public void stopScheduling(final DeviceInfo deviceInfo) {
+        LOG.debug("Stopping statistics scheduling for device: {}", deviceInfo.getNodeId());
+        final StatisticsContext statisticsContext = contexts.get(deviceInfo);
 
         if (statisticsContext == null) {
-            LOG.warn("Statistics context not found for device: {}", nodeId);
+            LOG.warn("Statistics context not found for device: {}", deviceInfo.getNodeId());
             return;
         }
 
@@ -320,4 +305,9 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag
     public void setDeviceTerminationPhaseHandler(final DeviceTerminationPhaseHandler handler) {
         this.deviceTerminPhaseHandler = handler;
     }
+
+    @Override
+    public <T extends OFPContext> T gainContext(DeviceInfo deviceInfo) {
+        return (T) contexts.get(deviceInfo);
+    }
 }
index af49302a778ed1c4fe1d69aae8d01050ec8fcfb3..45a19e1ae56add3299a60952f6b4e908655757d1 100644 (file)
@@ -91,9 +91,9 @@ public final class AggregateFlowsInTableService extends AbstractCompatibleStatSe
         final TranslatorKey translatorKey = new TranslatorKey(mpReply.getVersion(), MultipartReplyAggregateCase.class.getName());
         final MessageTranslator<MultipartReply, AggregatedFlowStatistics> messageTranslator = translatorLibrary.lookupTranslator(translatorKey);
 
-        final AggregatedFlowStatistics flowStatistics = messageTranslator.translate(mpReply, getDeviceContext().getDeviceState(), null);
+        final AggregatedFlowStatistics flowStatistics = messageTranslator.translate(mpReply, getDeviceInfo(), null);
         final AggregateFlowStatisticsUpdateBuilder notification = new AggregateFlowStatisticsUpdateBuilder(flowStatistics)
-                .setId(getDeviceContext().getDeviceState().getNodeId())
+                .setId(getDeviceInfo().getNodeId())
                 .setMoreReplies(Boolean.FALSE)
                 .setTransactionId(emulatedTxId);
 
index 5801f43a6145e152e753b873b7f74784393d16a4..d49c00b6966fe3b60935089b2ae5602f6925da8b 100644 (file)
@@ -67,6 +67,6 @@ public final class AllFlowsInAllTablesService extends AbstractCompatibleStatServ
 
     @Override
     public FlowsStatisticsUpdate transformToNotification(List<MultipartReply> result, TransactionId emulatedTxId) {
-        return FlowStatisticsToNotificationTransformer.transformToNotification(result, getDeviceContext().getDeviceState(), getOfVersion(), emulatedTxId);
+        return FlowStatisticsToNotificationTransformer.transformToNotification(result, getDeviceInfo(), getOfVersion(), emulatedTxId);
     }
 }
index 8c9262f3996e503a693f23a9e9d56de5e4e58d98..cdd22569049220317bedb11bf974bbbdf9eea2b3 100644 (file)
@@ -72,6 +72,6 @@ public class AllFlowsInTableService extends AbstractCompatibleStatService<GetAll
 
     @Override
     public FlowsStatisticsUpdate transformToNotification(List<MultipartReply> mpResult, TransactionId emulatedTxId) {
-        return FlowStatisticsToNotificationTransformer.transformToNotification(mpResult, getDeviceContext().getDeviceState(), getOfVersion(), emulatedTxId);
+        return FlowStatisticsToNotificationTransformer.transformToNotification(mpResult, getDeviceInfo(), getOfVersion(), emulatedTxId);
     }
 }
index e33c2100562fc1b14ee0f3187480c07d27c42726..5cf5db31ef1f61fb106178fa1185ffdf59181234 100644 (file)
@@ -71,6 +71,6 @@ final class AllGroupsStatsService extends
 
     @Override
     public GroupStatisticsUpdated transformToNotification(List<MultipartReply> result, TransactionId emulatedTxId) {
-        return GroupStatisticsToNotificationTransformer.transformToNotification(result, getDeviceContext().getDeviceState(), getOfVersion(), emulatedTxId);
+        return GroupStatisticsToNotificationTransformer.transformToNotification(result, getDeviceInfo(), emulatedTxId);
     }
 }
index f7667e8116432c84efc4228767f1b7d4ba273846..1fc57caca09c4873ada8a46c069e2dfc8f819405 100644 (file)
@@ -73,7 +73,7 @@ final class AllMeterConfigStatsService
     @Override
     public MeterConfigStatsUpdated transformToNotification(List<MultipartReply> result, TransactionId emulatedTxId) {
         MeterConfigStatsUpdatedBuilder message = new MeterConfigStatsUpdatedBuilder();
-        message.setId(getDeviceContext().getDeviceState().getNodeId());
+        message.setId(getDeviceInfo().getNodeId());
         message.setMoreReplies(Boolean.FALSE);
         message.setTransactionId(emulatedTxId);
 
index fb3b2d90fa6641533e65345224b2c24abc3f54ce..aae79faed6afe89965b3c65df720cd0fad6d2af2 100644 (file)
@@ -65,6 +65,6 @@ final class AllMeterStatsService
 
     @Override
     public MeterStatisticsUpdated transformToNotification(List<MultipartReply> result, TransactionId emulatedTxId) {
-        return MeterStatisticsToNotificationTransformer.transformToNotification(result, getDeviceContext().getDeviceState(), getOfVersion(), emulatedTxId);
+        return MeterStatisticsToNotificationTransformer.transformToNotification(result, getDeviceInfo(), getOfVersion(), emulatedTxId);
     }
 }
index d2ca4400443c908e06abff59a4053d4ebeee3d70..20be7f9433deefcd7e451bcc20a8e34e54089687 100644 (file)
@@ -65,6 +65,6 @@ final class AllPortStatsService
 
     @Override
     public NodeConnectorStatisticsUpdate transformToNotification(List<MultipartReply> result, TransactionId emulatedTxId) {
-        return NodeConnectorStatisticsToNotificationTransformer.transformToNotification(result, getDeviceContext(), getOfVersion(), emulatedTxId);
+        return NodeConnectorStatisticsToNotificationTransformer.transformToNotification(result, getDeviceInfo(), getOfVersion(), emulatedTxId);
     }
 }
index b9da4288af81f7c1f54004435c9eeba86d5e4e72..ca34feb4c5dbecbcaf51ad09652ef1c176269564 100644 (file)
@@ -66,6 +66,6 @@ final class AllQueuesAllPortsService
 
     @Override
     public QueueStatisticsUpdate transformToNotification(List<MultipartReply> result, TransactionId emulatedTxId) {
-        return QueueStatisticsToNotificationTransformer.transformToNotification(result, getDeviceContext().getDeviceState(), getOfVersion(), emulatedTxId);
+        return QueueStatisticsToNotificationTransformer.transformToNotification(result, getDeviceInfo(), getOfVersion(), emulatedTxId);
     }
 }
index 1f6f6b3232d4bf2dd08853f9facb7f68b6b15e5e..697edecaa01525037769cc80bf430cd323ac8ec7 100644 (file)
@@ -65,6 +65,6 @@ final class AllQueuesOnePortService
 
     @Override
     public QueueStatisticsUpdate transformToNotification(List<MultipartReply> result, TransactionId emulatedTxId) {
-        return QueueStatisticsToNotificationTransformer.transformToNotification(result, getDeviceContext().getDeviceState(), getOfVersion(), emulatedTxId);
+        return QueueStatisticsToNotificationTransformer.transformToNotification(result, getDeviceInfo(), getOfVersion(), emulatedTxId);
     }
 }
index f063b2ef51d69511fc26f61ba722e84eabb3e2a6..70b458daaa3084d42b8e6c87564aaf6a9f2d8ca5 100644 (file)
@@ -73,9 +73,8 @@ public final class FlowsInTableService extends AbstractCompatibleStatService<Get
 
         // convert and inject match
         final short version = getVersion();
-        final DeviceContext deviceContext = getDeviceContext();
         MatchReactor.getInstance().convert(input.getMatch(), version, mprFlowRequestBuilder,
-                deviceContext.getPrimaryConnectionContext().getFeatures().getDatapathId());
+                getDeviceInfo().getDatapathId());
 
         // Set request body to main multipart request
         multipartRequestFlowCaseBuilder.setMultipartRequestFlow(mprFlowRequestBuilder.build());
@@ -93,6 +92,6 @@ public final class FlowsInTableService extends AbstractCompatibleStatService<Get
 
     @Override
     public FlowsStatisticsUpdate transformToNotification(List<MultipartReply> result, TransactionId emulatedTxId) {
-        return FlowStatisticsToNotificationTransformer.transformToNotification(result, getDeviceContext().getDeviceState(), getOfVersion(), emulatedTxId);
+        return FlowStatisticsToNotificationTransformer.transformToNotification(result, getDeviceInfo(), getOfVersion(), emulatedTxId);
     }
 }
index 46e2588be17e56b501b7d3707f8291862354938c..bb6c9f7b5318d9bd466e58ffc1180a2ef4ce3fb6 100644 (file)
@@ -58,7 +58,7 @@ final class GroupDescriptionService
     @Override
     public GroupDescStatsUpdated transformToNotification(List<MultipartReply> result, TransactionId emulatedTxId) {
         GroupDescStatsUpdatedBuilder notification = new GroupDescStatsUpdatedBuilder();
-        notification.setId(getDeviceContext().getDeviceState().getNodeId());
+        notification.setId(getDeviceInfo().getNodeId());
         notification.setMoreReplies(Boolean.FALSE);
         notification.setTransactionId(emulatedTxId);
 
index 22c8d6d465c3e8c07031ed15c1a5840e199839a5..008429797eff41b0cb774dee8f2cc4c7cc71face 100644 (file)
@@ -74,7 +74,7 @@ final class GroupFeaturesService
         Preconditions.checkArgument(mpSize == 1, "unexpected (!=1) mp-reply size received: {}", mpSize);
 
         GroupFeaturesUpdatedBuilder notification = new GroupFeaturesUpdatedBuilder();
-        notification.setId(getDeviceContext().getDeviceState().getNodeId());
+        notification.setId(getDeviceInfo().getNodeId());
         notification.setMoreReplies(Boolean.FALSE);
         notification.setTransactionId(emulatedTxId);
 
index e0e04f95c92df1b534b9451ae9c1b105e2885cd2..77ec5014cc1ff689413de02781d333f9eaae81d0 100644 (file)
@@ -56,6 +56,6 @@ final class GroupStatsService
 
     @Override
     public GroupStatisticsUpdated transformToNotification(List<MultipartReply> result, TransactionId emulatedTxId) {
-        return GroupStatisticsToNotificationTransformer.transformToNotification(result, getDeviceContext().getDeviceState(), getOfVersion(), emulatedTxId);
+        return GroupStatisticsToNotificationTransformer.transformToNotification(result, getDeviceInfo(), emulatedTxId);
     }
 }
index 3de2abdba19144abd0289e9ca620cd206f7191d5..6456c89fad3b0bcc0d6731a984766f1063f9769a 100644 (file)
@@ -31,7 +31,6 @@ final class MatchingFlowsInTableService extends AbstractMultipartService<GetAggr
 
     @Override
     protected OfHeader buildRequest(final Xid xid, final GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input) {
-        final DeviceContext deviceContext = getDeviceContext();
         final MultipartRequestAggregateCaseBuilder multipartRequestAggregateCaseBuilder = new MultipartRequestAggregateCaseBuilder();
         final MultipartRequestAggregateBuilder mprAggregateRequestBuilder = new MultipartRequestAggregateBuilder();
         final short tableId = MoreObjects.firstNonNull(input.getTableId(), OFConstants.OFPTT_ALL).shortValue();
index 142b3c0c85f6859c05b256e202a285966c3bc8bb..e3f2d3149f4202b41dffbfdb62181d4ffb07acea 100644 (file)
@@ -70,7 +70,7 @@ final class MeterFeaturesService
         Preconditions.checkArgument(mpSize == 1, "unexpected (!=1) mp-reply size received: {}", mpSize);
 
         MeterFeaturesUpdatedBuilder notification = new MeterFeaturesUpdatedBuilder();
-        notification.setId(getDeviceContext().getDeviceState().getNodeId());
+        notification.setId(getDeviceInfo().getNodeId());
         notification.setMoreReplies(Boolean.FALSE);
         notification.setTransactionId(emulatedTxId);
 
index 33d36ffbba9f9ef21cd62865e3d7c336202b9365..841adf203903edf7c5bceb7df119f0c193bd8544 100644 (file)
@@ -57,6 +57,6 @@ final class MeterStatsService
 
     @Override
     public MeterStatisticsUpdated transformToNotification(List<MultipartReply> result, TransactionId emulatedTxId) {
-        return MeterStatisticsToNotificationTransformer.transformToNotification(result, getDeviceContext().getDeviceState(), getOfVersion(), emulatedTxId);
+        return MeterStatisticsToNotificationTransformer.transformToNotification(result, getDeviceInfo(), getOfVersion(), emulatedTxId);
     }
 }
index 867d10b79307e589eaa165ec201d3c9750162dac..469c91362e5dabba9e1a9763a0b987c6a1e63610 100644 (file)
@@ -62,6 +62,6 @@ final class OneQueueOnePortService
 
     @Override
     public QueueStatisticsUpdate transformToNotification(List<MultipartReply> result, TransactionId emulatedTxId) {
-        return QueueStatisticsToNotificationTransformer.transformToNotification(result, getDeviceContext().getDeviceState(), getOfVersion(), emulatedTxId);
+        return QueueStatisticsToNotificationTransformer.transformToNotification(result, getDeviceInfo(), getOfVersion(), emulatedTxId);
     }
 }
index cabe1cffa40ced08d7025e5d7264d39d285a590f..d028ad976cb9734697e9ca1be0edd8f0eb34d1f6 100644 (file)
@@ -13,6 +13,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.Future;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
 import org.opendaylight.openflowplugin.api.openflow.device.TranslatorLibrary;
@@ -49,7 +50,7 @@ public class OpendaylightFlowStatisticsServiceImpl implements OpendaylightFlowSt
             new Function<RpcResult<List<MultipartReply>>, RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>>() {
                 @Override
                 public RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput> apply(final RpcResult<List<MultipartReply>> input) {
-                    final DeviceContext deviceContext = matchingFlowsInTable.getDeviceContext();
+                    final DeviceInfo deviceInfo = matchingFlowsInTable.getDeviceInfo();
                     final RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput> rpcResult;
                     if (input.isSuccessful()) {
                         MultipartReply reply = input.getResult().get(0);
@@ -58,7 +59,7 @@ public class OpendaylightFlowStatisticsServiceImpl implements OpendaylightFlowSt
                         List<AggregatedFlowStatistics> aggregStats = new ArrayList<AggregatedFlowStatistics>();
 
                         for (MultipartReply multipartReply : input.getResult()) {
-                            aggregStats.add(messageTranslator.translate(multipartReply, deviceContext.getDeviceState(), null));
+                            aggregStats.add(messageTranslator.translate(multipartReply, deviceInfo, null));
                         }
 
                         GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder getAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder =
index a6f6b2b197455ea1f8fbdb9748f5541553966e6f..2f4483b7e0953fabe2a2ebd5dfd3b35dd9ed5087 100644 (file)
@@ -85,7 +85,7 @@ public final class OpendaylightFlowTableStatisticsServiceImpl extends
     @Override
     public FlowTableStatisticsUpdate transformToNotification(List<MultipartReply> mpReplyList, TransactionId emulatedTxId) {
         FlowTableStatisticsUpdateBuilder notification = new FlowTableStatisticsUpdateBuilder();
-        notification.setId(getDeviceContext().getDeviceState().getNodeId());
+        notification.setId(getDeviceInfo().getNodeId());
         notification.setMoreReplies(Boolean.FALSE);
         notification.setTransactionId(emulatedTxId);
 
index ed8caa2c6525325359518da4530e3159e2b631f2..8354c3df762237e089208818159c10c9174fd617 100644 (file)
@@ -64,6 +64,6 @@ final class PortStatsService
 
     @Override
     public NodeConnectorStatisticsUpdate transformToNotification(List<MultipartReply> result, TransactionId emulatedTxId) {
-        return NodeConnectorStatisticsToNotificationTransformer.transformToNotification(result, getDeviceContext(), getOfVersion(), emulatedTxId);
+        return NodeConnectorStatisticsToNotificationTransformer.transformToNotification(result, getDeviceInfo(), getOfVersion(), emulatedTxId);
     }
 }
index 6ba60dcbb661fce089eedb11ec65c7f269133a63..c3e2a91c828995e311f8c71cf52fc3f4915749b0 100644 (file)
@@ -11,7 +11,7 @@ package org.opendaylight.openflowplugin.impl.statistics.services.compatibility;
 import com.google.common.base.Preconditions;
 import java.util.ArrayList;
 import java.util.List;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.FlowStatsResponseConvertor;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate;
@@ -32,18 +32,18 @@ public class FlowStatisticsToNotificationTransformer {
 
     /**
      * @param mpResult      raw multipart response from device
-     * @param deviceState   device state
+     * @param deviceInfo   device state
      * @param ofVersion     device version
      * @param emulatedTxId
      * @return notification containing flow stats
      */
     public static FlowsStatisticsUpdate transformToNotification(final List<MultipartReply> mpResult,
-                                                                final DeviceState deviceState,
+                                                                final DeviceInfo deviceInfo,
                                                                 final OpenflowVersion ofVersion,
                                                                 final TransactionId emulatedTxId) {
         final FlowsStatisticsUpdateBuilder notification = new FlowsStatisticsUpdateBuilder();
         final List<FlowAndStatisticsMapList> statsList = new ArrayList<>();
-        notification.setId(deviceState.getNodeId());
+        notification.setId(deviceInfo.getNodeId());
         notification.setFlowAndStatisticsMapList(statsList);
         notification.setMoreReplies(Boolean.FALSE);
         notification.setTransactionId(emulatedTxId);
@@ -55,7 +55,7 @@ public class FlowStatisticsToNotificationTransformer {
             MultipartReplyFlow replyBody = caseBody.getMultipartReplyFlow();
             List<FlowAndStatisticsMapList> outStatsItem = flowStatsConvertor.toSALFlowStatsList(
                     replyBody.getFlowStats(),
-                    deviceState.getFeatures().getDatapathId(),
+                    deviceInfo.getDatapathId(),
                     ofVersion);
             statsList.addAll(outStatsItem);
         }
index 2dcef59d0ff855fe0086a6348cb652c44f870fe7..5df1440ec25dbc89c66741d593d661ad94735c55 100644 (file)
@@ -10,8 +10,7 @@ package org.opendaylight.openflowplugin.impl.statistics.services.compatibility;
 
 import java.util.ArrayList;
 import java.util.List;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
-import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.GroupStatsResponseConvertor;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupStatisticsUpdated;
@@ -30,18 +29,16 @@ public class GroupStatisticsToNotificationTransformer {
 
     /**
      * @param mpReplyList   raw multipart response from device
-     * @param deviceState   device state
-     * @param ofVersion     device version
+     * @param deviceInfo   device state
      * @param emulatedTxId
      * @return notification containing flow stats
      */
     public static GroupStatisticsUpdated transformToNotification(final List<MultipartReply> mpReplyList,
-                                                                 final DeviceState deviceState,
-                                                                 final OpenflowVersion ofVersion,
+                                                                 final DeviceInfo deviceInfo,
                                                                  final TransactionId emulatedTxId) {
 
         GroupStatisticsUpdatedBuilder notification = new GroupStatisticsUpdatedBuilder();
-        notification.setId(deviceState.getNodeId());
+        notification.setId(deviceInfo.getNodeId());
         notification.setMoreReplies(Boolean.FALSE);
         notification.setTransactionId(emulatedTxId);
 
index 4bf30e29cebfbd197cab9d03b2ff17d3195b1125..f4f09234fb4b7a08e311145e5cd151a76b18af1d 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.openflowplugin.impl.statistics.services.compatibility;
 
 import java.util.ArrayList;
 import java.util.List;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.MeterStatsResponseConvertor;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
@@ -30,18 +30,18 @@ public class MeterStatisticsToNotificationTransformer {
 
     /**
      * @param mpReplyList   raw multipart response from device
-     * @param deviceState   device state
+     * @param deviceInfo   device state
      * @param ofVersion     device version
      * @param emulatedTxId
      * @return notification containing flow stats
      */
     public static MeterStatisticsUpdated transformToNotification(final List<MultipartReply> mpReplyList,
-                                                                 final DeviceState deviceState,
+                                                                 final DeviceInfo deviceInfo,
                                                                  final OpenflowVersion ofVersion,
                                                                  final TransactionId emulatedTxId) {
 
         MeterStatisticsUpdatedBuilder notification = new MeterStatisticsUpdatedBuilder();
-        notification.setId(deviceState.getNodeId());
+        notification.setId(deviceInfo.getNodeId());
         notification.setMoreReplies(Boolean.FALSE);
         notification.setTransactionId(emulatedTxId);
 
index 3649a252988567560be1b328f9da4cfc11e61934..4b1c398b1838328401385f9eb2a476201d481463 100644 (file)
@@ -11,7 +11,7 @@ package org.opendaylight.openflowplugin.impl.statistics.services.compatibility;
 import com.google.common.annotations.VisibleForTesting;
 import java.util.ArrayList;
 import java.util.List;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
 import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.Counter32;
@@ -36,18 +36,18 @@ public class NodeConnectorStatisticsToNotificationTransformer {
 
     /**
      * @param mpReplyList   raw multipart response from device
-     * @param deviceContext device context
+     * @param deviceInfo    device basic info
      * @param ofVersion     device version
      * @param emulatedTxId
      * @return notification containing flow stats
      */
     public static NodeConnectorStatisticsUpdate transformToNotification(final List<MultipartReply> mpReplyList,
-                                                                        final DeviceContext deviceContext,
+                                                                        final DeviceInfo deviceInfo,
                                                                         final OpenflowVersion ofVersion,
                                                                         final TransactionId emulatedTxId) {
 
         NodeConnectorStatisticsUpdateBuilder notification = new NodeConnectorStatisticsUpdateBuilder();
-        notification.setId(deviceContext.getDeviceState().getNodeId());
+        notification.setId(deviceInfo.getNodeId());
         notification.setMoreReplies(Boolean.FALSE);
         notification.setTransactionId(emulatedTxId);
 
@@ -58,7 +58,7 @@ public class NodeConnectorStatisticsToNotificationTransformer {
             MultipartReplyPortStats replyBody = caseBody.getMultipartReplyPortStats();
             for (PortStats portStats : replyBody.getPortStats()) {
                 NodeConnectorStatisticsAndPortNumberMapBuilder statsBuilder =
-                        processSingleNodeConnectorStats(deviceContext, ofVersion, portStats);
+                        processSingleNodeConnectorStats(deviceInfo, ofVersion, portStats);
                 notification.getNodeConnectorStatisticsAndPortNumberMap().add(statsBuilder.build());
             }
         }
@@ -66,12 +66,12 @@ public class NodeConnectorStatisticsToNotificationTransformer {
     }
 
     @VisibleForTesting
-    static NodeConnectorStatisticsAndPortNumberMapBuilder processSingleNodeConnectorStats(DeviceContext deviceContext, OpenflowVersion ofVersion, PortStats portStats) {
+    static NodeConnectorStatisticsAndPortNumberMapBuilder processSingleNodeConnectorStats(DeviceInfo deviceInfo, OpenflowVersion ofVersion, PortStats portStats) {
         NodeConnectorStatisticsAndPortNumberMapBuilder statsBuilder =
                 new NodeConnectorStatisticsAndPortNumberMapBuilder();
         statsBuilder.setNodeConnectorId(
                 InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(
-                        deviceContext.getDeviceState().getFeatures().getDatapathId(),
+                        deviceInfo.getDatapathId(),
                         portStats.getPortNo(), ofVersion));
 
         BytesBuilder bytesBuilder = new BytesBuilder();
index fc4f6c08e11b5056d7a9ee327146b168cc7d9f8e..fe94327f6da2cfffae196d9fdfc4ed123a983095 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.openflowplugin.impl.statistics.services.compatibility;
 
 import java.util.ArrayList;
 import java.util.List;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
 import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.Counter32;
@@ -34,18 +34,18 @@ public class QueueStatisticsToNotificationTransformer {
 
     /**
      * @param mpReplyList   raw multipart response from device
-     * @param deviceState   device state
+     * @param deviceInfo   device state
      * @param ofVersion     device version
      * @param emulatedTxId
      * @return notification containing flow stats
      */
     public static QueueStatisticsUpdate transformToNotification(final List<MultipartReply> mpReplyList,
-                                                                final DeviceState deviceState,
+                                                                final DeviceInfo deviceInfo,
                                                                 final OpenflowVersion ofVersion,
                                                                 final TransactionId emulatedTxId) {
 
         QueueStatisticsUpdateBuilder notification = new QueueStatisticsUpdateBuilder();
-        notification.setId(deviceState.getNodeId());
+        notification.setId(deviceInfo.getNodeId());
         notification.setMoreReplies(Boolean.FALSE);
         notification.setTransactionId(emulatedTxId);
 
@@ -61,7 +61,7 @@ public class QueueStatisticsToNotificationTransformer {
                         new QueueIdAndStatisticsMapBuilder();
                 statsBuilder.setNodeConnectorId(
                         InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(
-                                deviceState.getFeatures().getDatapathId(),
+                                deviceInfo.getDatapathId(),
                                 queueStats.getPortNo(), ofVersion));
                 statsBuilder.setTransmissionErrors(new Counter64(queueStats.getTxErrors()));
                 statsBuilder.setTransmittedBytes(new Counter64(queueStats.getTxBytes()));
index 6dfcfa05405cccad2982993b662de6a5a6777185..60f7b03f29dcfcd03314392bcfbeae6534f7e372 100644 (file)
@@ -38,7 +38,7 @@ public class StatisticsGatheringOnTheFlyService extends AbstractMultipartOnTheFl
 
     @Override
     public Future<RpcResult<List<MultipartReply>>> getStatisticsOfType(final EventIdentifier eventIdentifier, final MultipartType type) {
-        LOG.debug("Getting statistics (onTheFly) for node {} of type {}", getNodeId(), type);
+        LOG.debug("Getting statistics (onTheFly) for node {} of type {}", getDeviceInfo().getNodeId(), type);
         EventsTimeCounter.markStart(eventIdentifier);
         setEventIdentifier(eventIdentifier);
         return handleServiceCall(type);
index c43ae604fc8af3fee422d8b2e9ef5d61055285ba..b6f1b10f33c0c102ac85f5741d45a40616fc6e43 100644 (file)
@@ -38,7 +38,7 @@ public class StatisticsGatheringService extends AbstractMultipartService<Multipa
 
     @Override
     public Future<RpcResult<List<MultipartReply>>> getStatisticsOfType(final EventIdentifier eventIdentifier, final MultipartType type) {
-        LOG.debug("Getting statistics for node {} of type {}", getNodeId(), type);
+        LOG.debug("Getting statistics for node {} of type {}", getDeviceInfo().getNodeId(), type);
         EventsTimeCounter.markStart(eventIdentifier);
         setEventIdentifier(eventIdentifier);
         return handleServiceCall(type);
index e809ebf9a05b759d250fafcfddbeba1533893124..9c200a990a90e0277ed149f0fad0ce1eba8ad837 100644 (file)
@@ -13,6 +13,9 @@ import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.AsyncFunction;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
+import java.util.List;
+import java.util.concurrent.Future;
+import javax.annotation.Nullable;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
 import org.opendaylight.openflowplugin.api.openflow.device.Xid;
@@ -27,10 +30,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 
-import javax.annotation.Nullable;
-import java.util.List;
-import java.util.concurrent.Future;
-
 /**
  * The abstract direct statistics service.
  * This abstract service provides wrappers and tools for all other derived statistics services.
@@ -60,7 +59,7 @@ public abstract class AbstractDirectStatisticsService<I extends StoreStatsGroupi
 
                     if (input.isSuccessful()) {
                         storeStatistics(input.getResult());
-                        getDeviceContext().submitTransaction(); // TODO: If submitTransaction will ever return future, chain it
+                        getTxFacade().submitTransaction(); // TODO: If submitTransaction will ever return future, chain it
                     }
 
                     return Futures.immediateFuture(input);
index 72066b0395f578dc3f72600e121d2b347f04ba93..edfede1aef7d0df584a168d6177ec7db3242db2d 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.openflowplugin.impl.statistics.services.direct;
 
+import java.util.ArrayList;
+import java.util.List;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.openflowplugin.api.OFConstants;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
@@ -41,9 +43,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.flow._case.MultipartRequestFlowBuilder;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * The Flow direct statistics service.
  */
@@ -131,8 +130,7 @@ public class FlowDirectStatisticsService extends AbstractDirectStatisticsService
 
     @Override
     protected void storeStatistics(GetFlowStatisticsOutput output) throws Exception {
-        final InstanceIdentifier<FlowCapableNode> nodePath = getDeviceContext()
-                .getDeviceState().getNodeInstanceIdentifier().augmentation(FlowCapableNode.class);
+        final InstanceIdentifier<FlowCapableNode> nodePath = getDeviceInfo().getNodeInstanceIdentifier().augmentation(FlowCapableNode.class);
 
         for (final FlowAndStatisticsMapList flowStatistics : output.getFlowAndStatisticsMapList()) {
             final FlowId flowId = generateFlowId(flowStatistics);
@@ -149,7 +147,7 @@ public class FlowDirectStatisticsService extends AbstractDirectStatisticsService
                     .child(Table.class, new TableKey(flowStatistics.getTableId()))
                     .child(Flow.class, flowKey);
 
-            getDeviceContext().writeToTransactionWithParentsSlow(LogicalDatastoreType.OPERATIONAL, flowStatisticsPath, flowBuilder.build());
+            getTxFacade().writeToTransactionWithParentsSlow(LogicalDatastoreType.OPERATIONAL, flowStatisticsPath, flowBuilder.build());
         }
     }
 
@@ -162,6 +160,6 @@ public class FlowDirectStatisticsService extends AbstractDirectStatisticsService
 
         final short tableId = flowStatistics.getTableId();
         final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(flowBuilder.build());
-        return getDeviceContext().getDeviceFlowRegistry().storeIfNecessary(flowRegistryKey, tableId);
+        return getDeviceRegistry().getDeviceFlowRegistry().storeIfNecessary(flowRegistryKey, tableId);
     }
 }
index b7c650a03a4d8e4e91934aca7b7af3a4d4f96a2a..75579a18c0ac606a678083ad6b5f6df50e3a12cc 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.openflowplugin.impl.statistics.services.direct;
 
+import java.util.ArrayList;
+import java.util.List;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.openflowplugin.api.OFConstants;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
@@ -33,9 +35,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.group._case.MultipartRequestGroupBuilder;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * The Group direct statistics service.
  */
@@ -86,8 +85,7 @@ public class GroupDirectStatisticsService extends AbstractDirectStatisticsServic
 
     @Override
     protected void storeStatistics(GetGroupStatisticsOutput output) throws Exception {
-        final InstanceIdentifier<FlowCapableNode> nodePath = getDeviceContext()
-                .getDeviceState().getNodeInstanceIdentifier().augmentation(FlowCapableNode.class);
+        final InstanceIdentifier<FlowCapableNode> nodePath = getDeviceInfo().getNodeInstanceIdentifier().augmentation(FlowCapableNode.class);
 
         for (final GroupStats groupStatistics : output.getGroupStats()) {
             final InstanceIdentifier<GroupStatistics> groupStatisticsPath = nodePath
@@ -96,7 +94,7 @@ public class GroupDirectStatisticsService extends AbstractDirectStatisticsServic
                     .child(GroupStatistics.class);
 
             final GroupStatistics stats = new GroupStatisticsBuilder(groupStatistics).build();
-            getDeviceContext().writeToTransactionWithParentsSlow(LogicalDatastoreType.OPERATIONAL, groupStatisticsPath, stats);
+            getTxFacade().writeToTransactionWithParentsSlow(LogicalDatastoreType.OPERATIONAL, groupStatisticsPath, stats);
         }
     }
 }
index da6475ec5ce32e26096bc6c9471eaafd310bf6fe..55e0fab0cc7bddfa8483901168506c97d9693cf2 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.openflowplugin.impl.statistics.services.direct;
 
+import java.util.ArrayList;
+import java.util.List;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.openflowplugin.api.OFConstants;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
@@ -33,9 +35,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter._case.MultipartRequestMeterBuilder;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * The Meter direct statistics service.
  */
@@ -86,8 +85,7 @@ public class MeterDirectStatisticsService extends AbstractDirectStatisticsServic
 
     @Override
     protected void storeStatistics(GetMeterStatisticsOutput output) throws Exception {
-        final InstanceIdentifier<FlowCapableNode> nodePath = getDeviceContext()
-                .getDeviceState().getNodeInstanceIdentifier().augmentation(FlowCapableNode.class);
+        final InstanceIdentifier<FlowCapableNode> nodePath = getDeviceInfo().getNodeInstanceIdentifier().augmentation(FlowCapableNode.class);
 
         for (final MeterStats meterStatistics : output.getMeterStats()) {
             final InstanceIdentifier<MeterStatistics> meterPath = nodePath
@@ -96,7 +94,7 @@ public class MeterDirectStatisticsService extends AbstractDirectStatisticsServic
                     .child(MeterStatistics.class);
 
             final MeterStatistics stats = new MeterStatisticsBuilder(meterStatistics).build();
-            getDeviceContext().writeToTransactionWithParentsSlow(LogicalDatastoreType.OPERATIONAL, meterPath, stats);
+            getTxFacade().writeToTransactionWithParentsSlow(LogicalDatastoreType.OPERATIONAL, meterPath, stats);
         }
     }
 }
index 6f6f496cbe66283a939843aa2340986c9a546bfa..f38600ca8e184098288f5570062263f1c50172e9 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.openflowplugin.impl.statistics.services.direct;
 
+import java.util.ArrayList;
+import java.util.List;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.openflowplugin.api.OFConstants;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
@@ -40,9 +42,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.n
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * The Node connector direct statistics service.
  */
@@ -130,7 +129,7 @@ public class NodeConnectorDirectStatisticsService extends AbstractDirectStatisti
 
     @Override
     protected void storeStatistics(GetNodeConnectorStatisticsOutput output) throws Exception {
-        final InstanceIdentifier<Node> nodePath = getDeviceContext().getDeviceState().getNodeInstanceIdentifier();
+        final InstanceIdentifier<Node> nodePath = getDeviceInfo().getNodeInstanceIdentifier();
 
         for (final NodeConnectorStatisticsAndPortNumberMap nodeConnectorStatistics : output.getNodeConnectorStatisticsAndPortNumberMap()) {
             final InstanceIdentifier<FlowCapableNodeConnectorStatistics> nodeConnectorPath = nodePath
@@ -139,7 +138,7 @@ public class NodeConnectorDirectStatisticsService extends AbstractDirectStatisti
                     .child(FlowCapableNodeConnectorStatistics.class);
 
             final FlowCapableNodeConnectorStatistics stats = new FlowCapableNodeConnectorStatisticsBuilder(nodeConnectorStatistics).build();
-            getDeviceContext().writeToTransactionWithParentsSlow(LogicalDatastoreType.OPERATIONAL, nodeConnectorPath, stats);
+            getTxFacade().writeToTransactionWithParentsSlow(LogicalDatastoreType.OPERATIONAL, nodeConnectorPath, stats);
         }
     }
 }
index b96ae21ec102bc81bc997823ff2a73253f134ff8..3f5af2f8e6edf9ffd4bad53a2288a5c1ba2d2802 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.openflowplugin.impl.statistics.services.direct;
 
+import java.util.Optional;
+import java.util.concurrent.Future;
 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.direct.statistics.rev160511.GetGroupStatisticsInput;
@@ -24,9 +26,6 @@ import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 
-import java.util.Optional;
-import java.util.concurrent.Future;
-
 /**
  * The Opendaylight direct statistics service.
  * This service handles RPC requests, sends them to registered handlers and returns their replies.
index 88f97dcbabcf65c7e410e368bb88d4de4442e7f2..0d2805b05cf29e42bc85d1923516a7195898297c 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.openflowplugin.impl.statistics.services.direct;
 
+import java.util.ArrayList;
+import java.util.List;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.openflowplugin.api.OFConstants;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
@@ -43,9 +45,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMapBuilder;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * The Queue direct statistics service.
  */
@@ -116,7 +115,7 @@ public class QueueDirectStatisticsService extends AbstractDirectStatisticsServic
 
     @Override
     protected void storeStatistics(GetQueueStatisticsOutput output) throws Exception {
-        final InstanceIdentifier<Node> nodePath = getDeviceContext().getDeviceState().getNodeInstanceIdentifier();
+        final InstanceIdentifier<Node> nodePath = getDeviceInfo().getNodeInstanceIdentifier();
 
         for (final QueueIdAndStatisticsMap queueStatistics : output.getQueueIdAndStatisticsMap()) {
             if (queueStatistics.getQueueId() != null) {
@@ -139,7 +138,7 @@ public class QueueDirectStatisticsService extends AbstractDirectStatisticsServic
                         .setQueueId(queueStatistics.getQueueId())
                         .addAugmentation(FlowCapableNodeConnectorQueueStatisticsData.class, statBuild.build()).build();
 
-                getDeviceContext().writeToTransactionWithParentsSlow(LogicalDatastoreType.OPERATIONAL, queueStatisticsPath, stats);
+                getTxFacade().writeToTransactionWithParentsSlow(LogicalDatastoreType.OPERATIONAL, queueStatisticsPath, stats);
             }
         }
     }
index 6e7626d4954a3c2855b3f860e551c81455de2e12..c00e01bcd3fb7f6b777a2f4f559882fe20274a29 100644 (file)
@@ -8,7 +8,7 @@
 
 package org.opendaylight.openflowplugin.impl.translator;
 
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.Counter32;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.Counter64;
@@ -23,7 +23,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
  */
 public class AggregatedFlowStatisticsTranslator implements MessageTranslator<MultipartReply, AggregatedFlowStatistics> {
     @Override
-    public AggregatedFlowStatistics translate(final MultipartReply input, final DeviceState deviceState, final Object connectionDistinguisher) {
+    public AggregatedFlowStatistics translate(final MultipartReply input, final DeviceInfo deviceInfo, final Object connectionDistinguisher) {
         AggregatedFlowStatisticsBuilder aggregatedFlowStatisticsBuilder = new AggregatedFlowStatisticsBuilder();
 
         MultipartReplyAggregateCase caseBody = (MultipartReplyAggregateCase)input.getMultipartReplyBody();
index 4aa08b00288f215fe1ec111544d5600e9e025941..c5683d2ebc171a071b446bbae668efa65be1a9e5 100644 (file)
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.openflowplugin.impl.translator;
 
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator;
 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchConvertorImpl;
@@ -23,20 +23,20 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 public class FlowRemovedTranslator implements MessageTranslator<FlowRemoved, org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved> {
 
     @Override
-    public org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved translate(FlowRemoved input, DeviceState deviceState, Object connectionDistinguisher) {
+    public org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved translate(FlowRemoved input, DeviceInfo deviceInfo, Object connectionDistinguisher) {
         FlowRemovedBuilder flowRemovedBld = new FlowRemovedBuilder()
-                .setMatch(translateMatch(input, deviceState).build())
+                .setMatch(translateMatch(input, deviceInfo).build())
                 .setCookie(new FlowCookie(input.getCookie()))
-                .setNode(new NodeRef(deviceState.getNodeInstanceIdentifier()))
+                .setNode(new NodeRef(deviceInfo.getNodeInstanceIdentifier()))
                 .setPriority(input.getPriority())
                 .setTableId(translateTableId(input));
 
         return flowRemovedBld.build();
     }
 
-    protected MatchBuilder translateMatch(FlowRemoved flowRemoved, DeviceState deviceState) {
+    protected MatchBuilder translateMatch(FlowRemoved flowRemoved, DeviceInfo deviceInfo) {
         return MatchConvertorImpl.fromOFMatchToSALMatch(flowRemoved.getMatch(),
-                deviceState.getFeatures().getDatapathId(), OpenflowVersion.OF13);
+                deviceInfo.getDatapathId(), OpenflowVersion.OF13);
     }
 
     /**
index 23efec2ed636a1c5f06feb76987e7b5278c901e1..e5904310c5288618b29f0a8529834a91d5391fd0 100644 (file)
@@ -8,7 +8,7 @@
 
 package org.opendaylight.openflowplugin.impl.translator;
 
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchConvertorImpl;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
@@ -20,9 +20,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 public class FlowRemovedV10Translator extends FlowRemovedTranslator {
 
     @Override
-    protected MatchBuilder translateMatch(FlowRemoved flowRemoved, DeviceState deviceState) {
+    protected MatchBuilder translateMatch(FlowRemoved flowRemoved, DeviceInfo deviceInfo) {
         return MatchConvertorImpl.fromOFMatchV10ToSALMatch(flowRemoved.getMatchV10(),
-                deviceState.getFeatures().getDatapathId(), OpenflowVersion.OF10);
+                deviceInfo.getDatapathId(), OpenflowVersion.OF10);
     }
 
     /**
index 08862300d76327896cc993a80abbb34882a90b04..9b5f76069f1d38d303bf27c4365ad7d6335be526 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.openflowplugin.impl.translator;
 
 import com.google.common.annotations.VisibleForTesting;
 import java.math.BigInteger;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator;
 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
 import org.opendaylight.openflowplugin.extension.api.AugmentTuple;
@@ -33,10 +33,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.Table
  */
 public class PacketReceivedTranslator implements MessageTranslator<PacketInMessage, PacketReceived> {
     @Override
-    public PacketReceived translate(final PacketInMessage input, final DeviceState deviceState, final Object connectionDistinguisher) {
+    public PacketReceived translate(final PacketInMessage input, final DeviceInfo deviceInfo, final Object connectionDistinguisher) {
 
         PacketReceivedBuilder packetReceivedBuilder = new PacketReceivedBuilder();
-        BigInteger datapathId = deviceState.getFeatures().getDatapathId();
+        BigInteger datapathId = deviceInfo.getDatapathId();
 
         // TODO: connection cookie from connection distinguisher
         // packetReceivedBuilder.setConnectionCookie(new ConnectionCookie(input.getCookie().longValue()));
@@ -49,7 +49,7 @@ public class PacketReceivedTranslator implements MessageTranslator<PacketInMessa
         }
 
         // Try to create the NodeConnectorRef
-        BigInteger dataPathId = deviceState.getFeatures().getDatapathId();
+        BigInteger dataPathId = deviceInfo.getDatapathId();
         NodeConnectorRef nodeConnectorRef = NodeConnectorRefToPortTranslator.toNodeConnectorRef(input, dataPathId);
 
         // If we was able to create NodeConnectorRef, use it
index 54a2b4c8d6e2baf25899d40e754bb82bda946dd2..61ef3344851a38b1fc5a5658003a26f699989064 100644 (file)
@@ -9,7 +9,7 @@ package org.opendaylight.openflowplugin.impl.translator;
 
 import java.util.Collections;
 import org.opendaylight.openflowplugin.api.OFConstants;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator;
 import org.opendaylight.openflowplugin.openflow.md.util.PortTranslatorUtil;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
@@ -24,17 +24,17 @@ public class PortUpdateTranslator implements MessageTranslator<PortGrouping, Flo
 
     @Override
     public FlowCapableNodeConnector translate(final PortGrouping input,
-                                              final DeviceState deviceState, final Object connectionDistinguisher) {
+                                              final DeviceInfo deviceInfo, final Object connectionDistinguisher) {
         final FlowCapableNodeConnectorBuilder builder = new FlowCapableNodeConnectorBuilder();
         //OF1.0
-        if (deviceState.getVersion() == OFConstants.OFP_VERSION_1_0) {
+        if (deviceInfo.getVersion() == OFConstants.OFP_VERSION_1_0) {
             builder.setAdvertisedFeatures(PortTranslatorUtil.translatePortFeatures(input.getAdvertisedFeaturesV10()));
             builder.setConfiguration(PortTranslatorUtil.translatePortConfig(input.getConfigV10()));
             builder.setCurrentFeature(PortTranslatorUtil.translatePortFeatures(input.getCurrentFeaturesV10()));
             builder.setPeerFeatures(PortTranslatorUtil.translatePortFeatures(input.getPeerFeaturesV10()));
             builder.setState(PortTranslatorUtil.translatePortState(input.getStateV10()));
             builder.setSupported(PortTranslatorUtil.translatePortFeatures(input.getSupportedFeaturesV10()));
-        } else if (deviceState.getVersion() == OFConstants.OFP_VERSION_1_3) {
+        } else if (deviceInfo.getVersion() == OFConstants.OFP_VERSION_1_3) {
             builder.setAdvertisedFeatures(PortTranslatorUtil.translatePortFeatures(input.getAdvertisedFeatures()));
             builder.setConfiguration(PortTranslatorUtil.translatePortConfig(input.getConfig()));
             builder.setCurrentFeature(PortTranslatorUtil.translatePortFeatures(input.getCurrentFeatures()));
index a9a6e190af485f630958d0df2fd1cf479767f1fc..3543a692b24dd33449f3b08da476aaf3d775b310 100644 (file)
@@ -27,6 +27,7 @@ import org.opendaylight.openflowplugin.api.ConnectionException;
 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;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
@@ -97,9 +98,10 @@ public class DeviceInitializationUtils {
     public static ListenableFuture<Void> initializeNodeInformation(final DeviceContext deviceContext, final boolean switchFeaturesMandatory) {
         Preconditions.checkArgument(deviceContext != null);
         final DeviceState deviceState = Preconditions.checkNotNull(deviceContext.getDeviceState());
+        final DeviceInfo deviceInfo = deviceContext.getDeviceInfo();
         final ConnectionContext connectionContext = Preconditions.checkNotNull(deviceContext.getPrimaryConnectionContext());
-        final short version = deviceState.getVersion();
-        LOG.trace("initalizeNodeInformation for node {}", deviceState.getNodeId());
+        final short version = deviceInfo.getVersion();
+        LOG.trace("initalizeNodeInformation for node {}", deviceInfo.getNodeId());
         final SettableFuture<Void> returnFuture = SettableFuture.<Void>create();
         addNodeToOperDS(deviceContext, returnFuture);
         final ListenableFuture<List<RpcResult<List<MultipartReply>>>> deviceFeaturesFuture;
@@ -112,14 +114,14 @@ public class DeviceInitializationUtils {
             // create empty tables after device description is processed
             chainTableTrunkWriteOF10(deviceContext, deviceFeaturesFuture);
 
-            final short ofVersion = deviceContext.getDeviceState().getVersion();
+            final short ofVersion = deviceInfo.getVersion();
             final TranslatorKey translatorKey = new TranslatorKey(ofVersion, PortGrouping.class.getName());
             final MessageTranslator<PortGrouping, FlowCapableNodeConnector> translator = deviceContext.oook()
                     .lookupTranslator(translatorKey);
-            final BigInteger dataPathId = deviceContext.getPrimaryConnectionContext().getFeatures().getDatapathId();
+            final BigInteger dataPathId = deviceContext.getDeviceInfo().getDatapathId();
 
             for (final PortGrouping port : connectionContext.getFeatures().getPhyPort()) {
-                final FlowCapableNodeConnector fcNodeConnector = translator.translate(port, deviceContext.getDeviceState(), null);
+                final FlowCapableNodeConnector fcNodeConnector = translator.translate(port, deviceContext.getDeviceInfo(), null);
 
                 final NodeConnectorId nodeConnectorId = NodeStaticReplyTranslatorUtil.nodeConnectorId(
                         dataPathId.toString(), port.getPortNo(), ofVersion);
@@ -128,19 +130,19 @@ public class DeviceInitializationUtils {
                 ncBuilder.addAugmentation(FlowCapableNodeConnectorStatisticsData.class,
                         new FlowCapableNodeConnectorStatisticsDataBuilder().build());
                 final NodeConnector connector = ncBuilder.build();
-                final InstanceIdentifier<NodeConnector> connectorII = deviceState.getNodeInstanceIdentifier().child(
+                final InstanceIdentifier<NodeConnector> connectorII = deviceInfo.getNodeInstanceIdentifier().child(
                         NodeConnector.class, connector.getKey());
                 try {
                     deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, connectorII, connector);
                 } catch (final Exception e) {
-                    LOG.debug("Failed to write node {} to DS ", deviceContext.getDeviceState().getNodeId().toString(),
+                    LOG.debug("Failed to write node {} to DS ", deviceInfo.getNodeId().toString(),
                             e);
                 }
 
             }
         } else if (OFConstants.OFP_VERSION_1_3 == version) {
             final Capabilities capabilities = connectionContext.getFeatures().getCapabilities();
-            LOG.debug("Setting capabilities for device {}", deviceContext.getDeviceState().getNodeId());
+            LOG.debug("Setting capabilities for device {}", deviceInfo.getNodeId());
             DeviceStateUtil.setDeviceStateBasedOnV13Capabilities(deviceState, capabilities);
             deviceFeaturesFuture = createDeviceFeaturesForOF13(deviceContext, deviceState, switchFeaturesMandatory);
         } else {
@@ -151,7 +153,7 @@ public class DeviceInitializationUtils {
         Futures.addCallback(deviceFeaturesFuture, new FutureCallback<List<RpcResult<List<MultipartReply>>>>() {
             @Override
             public void onSuccess(final List<RpcResult<List<MultipartReply>>> result) {
-                LOG.debug("All init data for node {} is in submited.", deviceState.getNodeId());
+                LOG.debug("All init data for node {} is in submited.", deviceInfo.getNodeId());
                 returnFuture.set(null);
             }
 
@@ -160,7 +162,7 @@ public class DeviceInitializationUtils {
                 // FIXME : remove session
                 LOG.trace("Device capabilities gathering future failed.");
                 LOG.trace("more info in exploration failure..", t);
-                LOG.debug("All init data for node {} was not submited correctly - connection has to go down.", deviceState.getNodeId());
+                LOG.debug("All init data for node {} was not submited correctly - connection has to go down.", deviceInfo.getNodeId());
                 returnFuture.setException(t);
             }
         });
@@ -170,13 +172,13 @@ public class DeviceInitializationUtils {
     private static void addNodeToOperDS(final DeviceContext deviceContext, final SettableFuture<Void> future) {
         Preconditions.checkArgument(deviceContext != null);
         final DeviceState deviceState = deviceContext.getDeviceState();
-        final NodeBuilder nodeBuilder = new NodeBuilder().setId(deviceState.getNodeId()).setNodeConnector(
+        final NodeBuilder nodeBuilder = new NodeBuilder().setId(deviceContext.getDeviceInfo().getNodeId()).setNodeConnector(
                 Collections.<NodeConnector>emptyList());
         try {
-            deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, deviceState.getNodeInstanceIdentifier(),
+            deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, deviceContext.getDeviceInfo().getNodeInstanceIdentifier(),
                     nodeBuilder.build());
         } catch (final Exception e) {
-            LOG.warn("Failed to write node {} to DS ", deviceState.getNodeId(), e);
+            LOG.warn("Failed to write node {} to DS ", deviceContext.getDeviceInfo().getNodeId(), e);
             future.cancel(true);
         }
     }
@@ -184,7 +186,7 @@ public class DeviceInitializationUtils {
     private static ListenableFuture<List<RpcResult<List<MultipartReply>>>> createDeviceFeaturesForOF10(
             final DeviceContext deviceContext, final DeviceState deviceState) {
         final ListenableFuture<RpcResult<List<MultipartReply>>> replyDesc = getNodeStaticInfo(MultipartType.OFPMPDESC,
-                deviceContext, deviceState.getNodeInstanceIdentifier(), deviceState.getVersion());
+                deviceContext, deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), deviceContext.getDeviceInfo().getVersion());
 
         return Futures.allAsList(Arrays.asList(replyDesc));
     }
@@ -193,7 +195,7 @@ public class DeviceInitializationUtils {
             final DeviceContext deviceContext, final DeviceState deviceState, final boolean switchFeaturesMandatory) {
 
         final ListenableFuture<RpcResult<List<MultipartReply>>> replyDesc = getNodeStaticInfo(MultipartType.OFPMPDESC,
-                deviceContext, deviceState.getNodeInstanceIdentifier(), deviceState.getVersion());
+                deviceContext, deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), deviceContext.getDeviceInfo().getVersion());
 
         //first process description reply, write data to DS and write consequent data if successful
         return Futures.transform(replyDesc,
@@ -203,32 +205,32 @@ public class DeviceInitializationUtils {
                             final RpcResult<List<MultipartReply>> rpcResult) throws Exception {
 
                         translateAndWriteReply(MultipartType.OFPMPDESC, deviceContext,
-                                deviceState.getNodeInstanceIdentifier(), rpcResult.getResult());
+                                deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), rpcResult.getResult());
 
                         final ListenableFuture<RpcResult<List<MultipartReply>>> replyMeterFeature = getNodeStaticInfo(
                                 MultipartType.OFPMPMETERFEATURES, deviceContext,
-                                deviceState.getNodeInstanceIdentifier(), deviceState.getVersion());
+                                deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), deviceContext.getDeviceInfo().getVersion());
 
                         createSuccessProcessingCallback(MultipartType.OFPMPMETERFEATURES, deviceContext,
-                                deviceState.getNodeInstanceIdentifier(), replyMeterFeature);
+                                deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), replyMeterFeature);
 
                         final ListenableFuture<RpcResult<List<MultipartReply>>> replyGroupFeatures = getNodeStaticInfo(
                                 MultipartType.OFPMPGROUPFEATURES, deviceContext,
-                                deviceState.getNodeInstanceIdentifier(), deviceState.getVersion());
+                                deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), deviceContext.getDeviceInfo().getVersion());
                         createSuccessProcessingCallback(MultipartType.OFPMPGROUPFEATURES, deviceContext,
-                                deviceState.getNodeInstanceIdentifier(), replyGroupFeatures);
+                                deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), replyGroupFeatures);
 
                         final ListenableFuture<RpcResult<List<MultipartReply>>> replyTableFeatures = getNodeStaticInfo(
                                 MultipartType.OFPMPTABLEFEATURES, deviceContext,
-                                deviceState.getNodeInstanceIdentifier(), deviceState.getVersion());
+                                deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), deviceContext.getDeviceInfo().getVersion());
                         createSuccessProcessingCallback(MultipartType.OFPMPTABLEFEATURES, deviceContext,
-                                deviceState.getNodeInstanceIdentifier(), replyTableFeatures);
+                                deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), replyTableFeatures);
 
                         final ListenableFuture<RpcResult<List<MultipartReply>>> replyPortDescription = getNodeStaticInfo(
-                                MultipartType.OFPMPPORTDESC, deviceContext, deviceState.getNodeInstanceIdentifier(),
-                                deviceState.getVersion());
+                                MultipartType.OFPMPPORTDESC, deviceContext, deviceContext.getDeviceInfo().getNodeInstanceIdentifier(),
+                                deviceContext.getDeviceInfo().getVersion());
                         createSuccessProcessingCallback(MultipartType.OFPMPPORTDESC, deviceContext,
-                                deviceState.getNodeInstanceIdentifier(), replyPortDescription);
+                                deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), replyPortDescription);
                         if (switchFeaturesMandatory) {
                             return Futures.allAsList(Arrays.asList(replyMeterFeature, replyGroupFeatures,
                                     replyTableFeatures, replyPortDescription));
@@ -311,11 +313,11 @@ public class DeviceInitializationUtils {
                         final MultipartReplyPortDesc portDesc = ((MultipartReplyPortDescCase) body)
                                 .getMultipartReplyPortDesc();
                         for (final PortGrouping port : portDesc.getPorts()) {
-                            final short ofVersion = dContext.getDeviceState().getVersion();
+                            final short ofVersion = dContext.getDeviceInfo().getVersion();
                             final TranslatorKey translatorKey = new TranslatorKey(ofVersion, PortGrouping.class.getName());
                             final MessageTranslator<PortGrouping, FlowCapableNodeConnector> translator = dContext.oook()
                                     .lookupTranslator(translatorKey);
-                            final FlowCapableNodeConnector fcNodeConnector = translator.translate(port, dContext.getDeviceState(), null);
+                            final FlowCapableNodeConnector fcNodeConnector = translator.translate(port, dContext.getDeviceInfo(), null);
 
                             final BigInteger dataPathId = dContext.getPrimaryConnectionContext().getFeatures()
                                     .getDatapathId();
@@ -340,18 +342,18 @@ public class DeviceInitializationUtils {
                 }
             }
         } catch (final Exception e) {
-            LOG.debug("Failed to write node {} to DS ", dContext.getDeviceState().getNodeId().toString(), e);
+            LOG.debug("Failed to write node {} to DS ", dContext.getDeviceInfo().getNodeId().toString(), e);
         }
     }
 
     private static void createEmptyFlowCapableNodeInDs(final DeviceContext deviceContext) {
         final FlowCapableNodeBuilder flowCapableNodeBuilder = new FlowCapableNodeBuilder();
-        final InstanceIdentifier<FlowCapableNode> fNodeII = deviceContext.getDeviceState().getNodeInstanceIdentifier()
+        final InstanceIdentifier<FlowCapableNode> fNodeII = deviceContext.getDeviceInfo().getNodeInstanceIdentifier()
                 .augmentation(FlowCapableNode.class);
         try {
             deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, fNodeII, flowCapableNodeBuilder.build());
         } catch (final Exception e) {
-            LOG.debug("Failed to write node {} to DS ", deviceContext.getDeviceState().getNodeId().toString(), e);
+            LOG.debug("Failed to write node {} to DS ", deviceContext.getDeviceInfo().getNodeId().toString(), e);
         }
     }
 
@@ -362,7 +364,7 @@ public class DeviceInitializationUtils {
 
         if (remoteAddress == null) {
             LOG.warn("IP address of the node {} cannot be obtained. No connection with switch.", deviceContext
-                    .getDeviceState().getNodeId());
+                    .getDeviceInfo().getNodeId());
             return null;
         }
         LOG.info("IP address of switch is: {}", remoteAddress);
@@ -384,7 +386,7 @@ public class DeviceInitializationUtils {
             try {
                 dContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, tableII, tableBuilder.build());
             } catch (final Exception e) {
-                LOG.debug("Failed to write node {} to DS ", dContext.getDeviceState().getNodeId().toString(), e);
+                LOG.debug("Failed to write node {} to DS ", dContext.getDeviceInfo().getNodeId().toString(), e);
             }
 
         }
@@ -398,7 +400,7 @@ public class DeviceInitializationUtils {
             public void onSuccess(final RpcResult<List<MultipartReply>> rpcResult) {
                 final List<MultipartReply> result = rpcResult.getResult();
                 if (result != null) {
-                    LOG.info("Static node {} info: {} collected", deviceContext.getDeviceState().getNodeId(), type);
+                    LOG.info("Static node {} info: {} collected", deviceContext.getDeviceInfo().getNodeId(), type);
                     translateAndWriteReply(type, deviceContext, nodeII, result);
                 } else {
                     final Iterator<RpcError> rpcErrorIterator = rpcResult.getErrors().iterator();
@@ -486,8 +488,8 @@ public class DeviceInitializationUtils {
                 }
                 if (allSucceeded) {
                     createEmptyFlowCapableNodeInDs(deviceContext);
-                    makeEmptyTables(deviceContext, deviceContext.getDeviceState().getNodeInstanceIdentifier(),
-                            deviceContext.getDeviceState().getFeatures().getTables());
+                    makeEmptyTables(deviceContext, deviceContext.getDeviceInfo().getNodeInstanceIdentifier(),
+                            deviceContext.getPrimaryConnectionContext().getFeatures().getTables());
                 }
             }
 
index 05806e9b9a120077b26bfd59ab8a2572e43e2602..3dd74d15e5928a6b02812a572d0dc2e33b15c9b6 100644 (file)
@@ -16,6 +16,7 @@ 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;
 import org.opendaylight.openflowplugin.api.openflow.statistics.compatibility.Delegator;
+import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
 import org.opendaylight.openflowplugin.impl.services.FlowCapableTransactionServiceImpl;
 import org.opendaylight.openflowplugin.impl.services.NodeConfigServiceImpl;
 import org.opendaylight.openflowplugin.impl.services.PacketProcessingServiceImpl;
@@ -85,7 +86,9 @@ public class MdSalRegistrationUtils {
      * @param newRole       - role validation for {@link OfpRole#BECOMEMASTER}
      */
     public static void registerMasterServices(@CheckForNull final RpcContext rpcContext,
-                                              @CheckForNull final DeviceContext deviceContext, @CheckForNull final OfpRole newRole) {
+                                              @CheckForNull final DeviceContext deviceContext,
+                                              @CheckForNull final OfpRole newRole,
+                                              final ExtensionConverterProvider extensionConverterProvider) {
         Preconditions.checkArgument(rpcContext != null);
         Preconditions.checkArgument(deviceContext != null);
         Preconditions.checkArgument(newRole != null);
@@ -127,7 +130,8 @@ public class MdSalRegistrationUtils {
         rpcContext.registerRpcServiceImplementation(SalFlatBatchService.class, salFlatBatchService);
 
         // TODO: experimenter symmetric and multipart message services
-        rpcContext.registerRpcServiceImplementation(SalExperimenterMessageService.class, new SalExperimenterMessageServiceImpl(rpcContext, deviceContext));
+        rpcContext.registerRpcServiceImplementation(SalExperimenterMessageService.class,
+                new SalExperimenterMessageServiceImpl(rpcContext, deviceContext, extensionConverterProvider));
     }
 
     /**
index 1738fe3b130182afb60d6ce5b48383f3dff69df9..39d4e4c917c279e9819fa23bac850d7777636226 100644 (file)
@@ -12,21 +12,27 @@ import static org.junit.Assert.assertNull;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
+
 import com.google.common.util.concurrent.ListenableFuture;
 import io.netty.util.HashedWheelTimer;
 import io.netty.util.TimerTask;
+import java.math.BigInteger;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.TimeUnit;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceManager;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.api.openflow.lifecycle.ServiceChangeListener;
+import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext;
+import org.opendaylight.openflowplugin.api.openflow.rpc.RpcManager;
 import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsManager;
 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageIntelligenceAgency;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
@@ -43,7 +49,7 @@ public class LifecycleConductorImplTest {
     @Mock
     private ServiceChangeListener serviceChangeListener;
     @Mock
-    private ConcurrentHashMap<NodeId, ServiceChangeListener> serviceChangeListeners;
+    private ConcurrentHashMap<DeviceInfo, ServiceChangeListener> serviceChangeListeners;
     @Mock
     private DeviceContext deviceContext;
     @Mock
@@ -64,6 +70,12 @@ public class LifecycleConductorImplTest {
     private ListenableFuture<Void> listenableFuture;
     @Mock
     private StatisticsManager statisticsManager;
+    @Mock
+    private RpcManager rpcManager;
+    @Mock
+    private RpcContext rpcContext;
+    @Mock
+    private DeviceInfo deviceInfo;
 
     private NodeId nodeId = new NodeId("openflow-junit:1");
     private OfpRole ofpRole = OfpRole.NOCHANGE;
@@ -71,21 +83,27 @@ public class LifecycleConductorImplTest {
 
     @Before
     public void setUp() {
-        when(deviceManager.getDeviceContextFromNodeId(nodeId)).thenReturn(deviceContext);
-        when(deviceContext.getPrimaryConnectionContext()).thenReturn(connectionContext);
 
         lifecycleConductor = new LifecycleConductorImpl(messageIntelligenceAgency);
-        lifecycleConductor.setSafelyDeviceManager(deviceManager);
-        lifecycleConductor.setSafelyStatisticsManager(statisticsManager);
+        lifecycleConductor.setSafelyManager(deviceManager);
+        lifecycleConductor.setSafelyManager(statisticsManager);
+        lifecycleConductor.setSafelyManager(rpcManager);
 
-        when(connectionContext.getFeatures()).thenReturn(featuresReply);
+        when(deviceManager.gainContext(Mockito.<DeviceInfo>any())).thenReturn(deviceContext);
+        when(deviceContext.getPrimaryConnectionContext()).thenReturn(connectionContext);
+        when(deviceContext.getDeviceInfo()).thenReturn(deviceInfo);
+        when(rpcManager.gainContext(Mockito.<DeviceInfo>any())).thenReturn(rpcContext);
+        when(deviceInfo.getNodeId()).thenReturn(nodeId);
+        when(deviceInfo.getDatapathId()).thenReturn(BigInteger.TEN);
+        when(deviceContext.getDeviceInfo()).thenReturn(deviceInfo);
+        when(rpcManager.gainContext(Mockito.<DeviceInfo>any())).thenReturn(rpcContext);
     }
 
 
 
     @Test
     public void addOneTimeListenerWhenServicesChangesDoneTest() {
-        lifecycleConductor.addOneTimeListenerWhenServicesChangesDone(serviceChangeListener, nodeId);
+        lifecycleConductor.addOneTimeListenerWhenServicesChangesDone(serviceChangeListener, deviceInfo);
         assertEquals(false,lifecycleConductor.isServiceChangeListenersEmpty());
     }
 
@@ -95,9 +113,9 @@ public class LifecycleConductorImplTest {
      */
     @Test
     public void notifyServiceChangeListenersTest1() {
-        lifecycleConductor.notifyServiceChangeListeners(nodeId,true);
+        lifecycleConductor.notifyServiceChangeListeners(deviceInfo,true);
         when(serviceChangeListeners.size()).thenReturn(0);
-        verify(serviceChangeListeners,times(0)).remove(nodeId);
+        verify(serviceChangeListeners,times(0)).remove(deviceInfo);
     }
 
     /**
@@ -105,9 +123,9 @@ public class LifecycleConductorImplTest {
      */
     @Test
     public void notifyServiceChangeListenersTest2() {
-        lifecycleConductor.addOneTimeListenerWhenServicesChangesDone(serviceChangeListener, nodeId);
+        lifecycleConductor.addOneTimeListenerWhenServicesChangesDone(serviceChangeListener, deviceInfo);
         assertEquals(false,lifecycleConductor.isServiceChangeListenersEmpty());
-        lifecycleConductor.notifyServiceChangeListeners(nodeId,true);
+        lifecycleConductor.notifyServiceChangeListeners(deviceInfo,true);
         assertEquals(true,lifecycleConductor.isServiceChangeListenersEmpty());
     }
 
@@ -117,8 +135,8 @@ public class LifecycleConductorImplTest {
      */
     @Test
     public void roleInitializationDoneTest1() {
-        lifecycleConductor.addOneTimeListenerWhenServicesChangesDone(serviceChangeListener, nodeId);
-        lifecycleConductor.roleInitializationDone(nodeId,false);
+        lifecycleConductor.addOneTimeListenerWhenServicesChangesDone(serviceChangeListener, deviceInfo);
+        lifecycleConductor.roleInitializationDone(deviceInfo,false);
         verify(deviceContext,times(1)).shutdownConnection();
     }
 
@@ -127,8 +145,8 @@ public class LifecycleConductorImplTest {
      */
     @Test
     public void roleInitializationDoneTest2() {
-        lifecycleConductor.addOneTimeListenerWhenServicesChangesDone(serviceChangeListener, nodeId);
-        lifecycleConductor.roleInitializationDone(nodeId,true);
+        lifecycleConductor.addOneTimeListenerWhenServicesChangesDone(serviceChangeListener, deviceInfo);
+        lifecycleConductor.roleInitializationDone(deviceInfo,true);
         verify(deviceContext,times(0)).shutdownConnection();
     }
 
@@ -137,10 +155,10 @@ public class LifecycleConductorImplTest {
      */
     @Test
     public void roleChangeOnDeviceTest1() {
-        when(deviceManager.getDeviceContextFromNodeId(nodeId)).thenReturn(null);
-        lifecycleConductor.roleChangeOnDevice(nodeId,true,ofpRole,false);
+        when(deviceManager.gainContext(deviceInfo)).thenReturn(null);
+        lifecycleConductor.roleChangeOnDevice(deviceInfo,true,ofpRole,false);
         verify(deviceContext,times(0)).shutdownConnection();
-        lifecycleConductor.roleChangeOnDevice(nodeId,false,ofpRole,false);
+        lifecycleConductor.roleChangeOnDevice(deviceInfo,false,ofpRole,false);
         verify(deviceContext,times(0)).shutdownConnection();
     }
 
@@ -149,8 +167,8 @@ public class LifecycleConductorImplTest {
      */
     @Test
     public void roleChangeOnDeviceTest2() {
-        when(deviceManager.getDeviceContextFromNodeId(nodeId)).thenReturn(deviceContext);
-        lifecycleConductor.roleChangeOnDevice(nodeId,false,ofpRole,false);
+        when(deviceManager.gainContext(deviceInfo)).thenReturn(deviceContext);
+        lifecycleConductor.roleChangeOnDevice(deviceInfo,false,ofpRole,false);
         verify(deviceContext,times(1)).shutdownConnection();
     }
 
@@ -160,8 +178,8 @@ public class LifecycleConductorImplTest {
      */
     @Test
     public void roleChangeOnDeviceTest3() {
-        when(deviceManager.getDeviceContextFromNodeId(nodeId)).thenReturn(deviceContext);
-        lifecycleConductor.roleChangeOnDevice(nodeId,true,ofpRole,true);
+        when(deviceManager.gainContext(deviceInfo)).thenReturn(deviceContext);
+        lifecycleConductor.roleChangeOnDevice(deviceInfo,true,ofpRole,true);
         verify(deviceContext,times(0)).shutdownConnection();
     }
 
@@ -171,10 +189,10 @@ public class LifecycleConductorImplTest {
     @Test
     public void roleChangeOnDeviceTest4() {
         when(deviceContext.getDeviceState()).thenReturn(deviceState);
-        when(deviceManager.getDeviceContextFromNodeId(nodeId)).thenReturn(deviceContext);
-        when(deviceContext.onClusterRoleChange(null, OfpRole.BECOMEMASTER)).thenReturn(listenableFuture);
-        lifecycleConductor.roleChangeOnDevice(nodeId,true,OfpRole.BECOMEMASTER,false);
-        verify(statisticsManager).startScheduling(nodeId);
+        when(deviceManager.gainContext(deviceInfo)).thenReturn(deviceContext);
+        when(deviceManager.onClusterRoleChange(deviceInfo, OfpRole.BECOMEMASTER)).thenReturn(listenableFuture);
+        lifecycleConductor.roleChangeOnDevice(deviceInfo,true,OfpRole.BECOMEMASTER,false);
+        verify(statisticsManager).startScheduling(Mockito.<DeviceInfo>any());
     }
 
     /**
@@ -183,29 +201,10 @@ public class LifecycleConductorImplTest {
     @Test
     public void roleChangeOnDeviceTest5() {
         when(deviceContext.getDeviceState()).thenReturn(deviceState);
-        when(deviceManager.getDeviceContextFromNodeId(nodeId)).thenReturn(deviceContext);
-        when(deviceContext.onClusterRoleChange(null, OfpRole.BECOMESLAVE)).thenReturn(listenableFuture);
-        lifecycleConductor.roleChangeOnDevice(nodeId,true,OfpRole.BECOMESLAVE,false);
-        verify(statisticsManager).stopScheduling(nodeId);
-    }
-
-    /**
-     * If getDeviceContext returns null nothing should happen
-     */
-    @Test
-    public void gainVersionSafelyTest1() {
-        when(deviceManager.getDeviceContextFromNodeId(nodeId)).thenReturn(null);
-        assertNull(lifecycleConductor.gainVersionSafely(nodeId));
-    }
-
-    /**
-     * If getDeviceContext returns deviceContext getPrimaryConnectionContext() should be called
-     */
-    @Test
-    public void gainVersionSafelyTest2() {
-        when(deviceManager.getDeviceContextFromNodeId(nodeId)).thenReturn(deviceContext);
-        lifecycleConductor.gainVersionSafely(nodeId);
-        verify(deviceContext,times(1)).getPrimaryConnectionContext();
+        when(deviceManager.gainContext(deviceInfo)).thenReturn(deviceContext);
+        when(deviceManager.onClusterRoleChange(deviceInfo, OfpRole.BECOMESLAVE)).thenReturn(listenableFuture);
+        lifecycleConductor.roleChangeOnDevice(deviceInfo,true,OfpRole.BECOMESLAVE,false);
+        verify(statisticsManager).stopScheduling(Mockito.<DeviceInfo>any());
     }
 
     /**
@@ -213,8 +212,8 @@ public class LifecycleConductorImplTest {
      */
     @Test
     public void gainConnectionStateSafelyTest1() {
-        when(deviceManager.getDeviceContextFromNodeId(nodeId)).thenReturn(null);
-        assertNull(lifecycleConductor.gainConnectionStateSafely(nodeId));
+        when(deviceManager.gainContext(deviceInfo)).thenReturn(null);
+        assertNull(lifecycleConductor.gainConnectionStateSafely(deviceInfo));
     }
 
     /**
@@ -222,8 +221,7 @@ public class LifecycleConductorImplTest {
      */
     @Test
     public void gainConnectionStateSafelyTest2() {
-        when(deviceManager.getDeviceContextFromNodeId(nodeId)).thenReturn(deviceContext);
-        lifecycleConductor.gainConnectionStateSafely(nodeId);
+        lifecycleConductor.gainConnectionStateSafely(deviceInfo);
         verify(deviceContext,times(1)).getPrimaryConnectionContext();
     }
 
@@ -232,8 +230,8 @@ public class LifecycleConductorImplTest {
      */
     @Test
     public void reserveXidForDeviceMessageTest1() {
-        when(deviceManager.getDeviceContextFromNodeId(nodeId)).thenReturn(null);
-        assertNull(lifecycleConductor.reserveXidForDeviceMessage(nodeId));
+        when(deviceManager.gainContext(deviceInfo)).thenReturn(null);
+        assertNull(lifecycleConductor.reserveXidForDeviceMessage(deviceInfo));
     }
 
     /**
@@ -241,8 +239,7 @@ public class LifecycleConductorImplTest {
      */
     @Test
     public void reserveXidForDeviceMessageTest2() {
-        when(deviceManager.getDeviceContextFromNodeId(nodeId)).thenReturn(deviceContext);
-        lifecycleConductor.reserveXidForDeviceMessage(nodeId);
+        lifecycleConductor.reserveXidForDeviceMessage(deviceInfo);
         verify(deviceContext,times(1)).reserveXidForDeviceMessage();
     }
 
@@ -251,7 +248,7 @@ public class LifecycleConductorImplTest {
      */
     @Test
     public void deviceStartInitializationDoneTest() {
-        lifecycleConductor.deviceStartInitializationDone(nodeId, false);
+        lifecycleConductor.deviceStartInitializationDone(deviceInfo, false);
         verify(deviceContext,times(1)).shutdownConnection();
     }
 
@@ -260,7 +257,7 @@ public class LifecycleConductorImplTest {
      */
     @Test
     public void deviceInitializationDoneTest() {
-        lifecycleConductor.deviceInitializationDone(nodeId, false);
+        lifecycleConductor.deviceInitializationDone(deviceInfo, false);
         verify(deviceContext,times(1)).shutdownConnection();
     }
 }
index c32fdc8aab54cbde124a6d2ebcc4ab98e5743007..cb7c958b5c239f34926e5eb6fb5b54e112c69183 100644 (file)
@@ -13,6 +13,7 @@ import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
+
 import com.google.common.collect.Lists;
 import com.google.common.util.concurrent.Futures;
 import org.junit.After;
@@ -60,6 +61,9 @@ public class OpenFlowPluginProviderImplTest {
 
     private static final long RPC_REQUESTS_QUOTA = 500;
     private static final long GLOBAL_NOTIFICATION_QUOTA = 131072;
+    private static final int THREAD_POOL_MIN_THREADS = 1;
+    private static final int THREAD_POOL_MAX_THREADS = 32000;
+    private static final long THREAD_POOL_TIMEOUT = 60;
 
     private OpenFlowPluginProviderImpl provider;
 
@@ -71,7 +75,13 @@ public class OpenFlowPluginProviderImplTest {
         when(rpcProviderRegistry.addRpcImplementation(eq(StatisticsManagerControlService.class), any())).thenReturn(controlServiceRegistration);
         when(switchConnectionProvider.startup()).thenReturn(Futures.immediateCheckedFuture(null));
 
-        provider = new OpenFlowPluginProviderImpl(RPC_REQUESTS_QUOTA, GLOBAL_NOTIFICATION_QUOTA);
+        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);
index 813c1bd372a04084d63bc47ff05d8e098847a437..9a4338ea621c0d1b01336bbe72697f051c2f0531 100644 (file)
@@ -9,7 +9,11 @@ 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;
@@ -25,6 +29,7 @@ import org.opendaylight.openflowjava.protocol.api.connection.ConnectionReadyList
 import org.opendaylight.openflowplugin.api.OFConstants;
 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceConnectedHandler;
+import org.opendaylight.openflowplugin.openflow.md.core.ThreadPoolLoggingExecutor;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInput;
@@ -62,7 +67,11 @@ public class ConnectionManagerImplTest {
      */
     @Before
     public void setUp() {
-        connectionManagerImpl = new ConnectionManagerImpl(ECHO_REPLY_TIMEOUT);
+        final ThreadPoolLoggingExecutor threadPool = new ThreadPoolLoggingExecutor(0, Integer.MAX_VALUE,
+                60L, TimeUnit.SECONDS,
+                new SynchronousQueue<>(), "ofppool");
+
+        connectionManagerImpl = new ConnectionManagerImpl(ECHO_REPLY_TIMEOUT, threadPool);
         connectionManagerImpl.setDeviceConnectedHandler(deviceConnectedHandler);
         final InetSocketAddress deviceAddress = InetSocketAddress.createUnresolved("yahoo", 42);
         Mockito.when(connection.getRemoteAddress()).thenReturn(deviceAddress);
index 7a2764be510d40bd3ea220eb9a59c3538bbc9937..ef5aa3063f41edbf41b909fead6f7d6cbd97771a 100644 (file)
@@ -1,14 +1,14 @@
 package org.opendaylight.openflowplugin.impl.connection;
 
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import junit.framework.TestCase;
 import org.junit.Test;
 import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueue;
 import org.opendaylight.openflowplugin.api.OFConstants;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput;
 
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
 public class OutboundQueueProviderImplTest extends TestCase {
 
     private static final Long DUMMY_ENTRY_NUMBER = 44L;
index 90d908b6b460ccf609c6ed3ec34107f0b13c3b66..b20a4f999e6b915a71e22e681c486e91844afa9a 100644 (file)
@@ -63,6 +63,7 @@ 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);
     }
@@ -78,6 +79,7 @@ public class HandshakeListenerImplTest {
         Mockito.verify(connectionContextSpy).changeStateToWorking();
         Mockito.verify(connectionContextSpy).setFeatures(Matchers.any(FeaturesReply.class));
         Mockito.verify(connectionContextSpy).setNodeId(nodeIdCaptor.capture());
+        Mockito.verify(connectionContextSpy).handshakeSuccessful();
         Mockito.verify(deviceConnectedHandler).deviceConnected(connectionContextSpy);
         Mockito.verify(handshakeContext).close();
 
index a361d61ac9ca60eeda8a1d0ea438a5ec88f60382..3b051fc25e2b5d9f3d61dbdd72c521ec08d9494a 100644 (file)
@@ -11,6 +11,9 @@ package org.opendaylight.openflowplugin.impl.connection.listener;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.SettableFuture;
 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;
@@ -21,6 +24,7 @@ import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
 import org.opendaylight.openflowplugin.impl.connection.ConnectionContextImpl;
+import org.opendaylight.openflowplugin.openflow.md.core.ThreadPoolLoggingExecutor;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutput;
@@ -66,7 +70,11 @@ public class SystemNotificationsListenerImplTest {
         Mockito.when(connectionContext.getConnectionAdapter()).thenReturn(connectionAdapter);
         Mockito.when(connectionContext.getFeatures()).thenReturn(features);
 
-        systemNotificationsListener = new SystemNotificationsListenerImpl(connectionContext, ECHO_REPLY_TIMEOUT);
+        final ThreadPoolLoggingExecutor threadPool = new ThreadPoolLoggingExecutor(0, Integer.MAX_VALUE,
+                60L, TimeUnit.SECONDS,
+                new SynchronousQueue<>(), "opfpool");
+
+        systemNotificationsListener = new SystemNotificationsListenerImpl(connectionContext, ECHO_REPLY_TIMEOUT, threadPool);
     }
 
     @After
index 07e345168a52e4d77b538a2b47bf6a9f0e84cdda..f6298433c6b7afbd7aab4c60a029c3acee5c8237 100644 (file)
@@ -29,16 +29,13 @@ import io.netty.util.Timeout;
 import java.math.BigInteger;
 import java.net.InetSocketAddress;
 import java.util.concurrent.atomic.AtomicLong;
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.InOrder;
 import org.mockito.Mock;
 import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
 import org.mockito.runners.MockitoJUnitRunner;
-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.NotificationPublishService;
@@ -53,6 +50,7 @@ import org.opendaylight.openflowplugin.api.OFConstants;
 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
 import org.opendaylight.openflowplugin.api.openflow.connection.OutboundQueueProvider;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
@@ -67,9 +65,7 @@ import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKe
 import org.opendaylight.openflowplugin.api.openflow.registry.group.DeviceGroupRegistry;
 import org.opendaylight.openflowplugin.api.openflow.registry.meter.DeviceMeterRegistry;
 import org.opendaylight.openflowplugin.api.openflow.rpc.ItemLifeCycleSource;
-import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext;
 import org.opendaylight.openflowplugin.api.openflow.rpc.listener.ItemLifecycleListener;
-import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsContext;
 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageIntelligenceAgency;
 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
 import org.opendaylight.openflowplugin.extension.api.ConvertorMessageFromOFJava;
@@ -89,18 +85,27 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.ta
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemovedBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
 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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Capabilities;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortReason;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.*;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.Error;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FeaturesReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncReply;
+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.OfHeader;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketIn;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortGrouping;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.OfpRole;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
@@ -119,14 +124,14 @@ public class DeviceContextImplTest {
     private static final BigInteger DUMMY_DATAPATH_ID = new BigInteger("55");
     Xid xid;
     Xid xidMulti;
-    DeviceContextImpl deviceContext;
+
+    DeviceContext deviceContext;
     @Mock
     TransactionChainManager txChainManager;
     @Mock
     RequestContext<GetAsyncReply> requestContext;
     @Mock
     RequestContext<MultipartReply> requestContextMultiReply;
-
     @Mock
     ConnectionContext connectionContext;
     @Mock
@@ -163,6 +168,8 @@ public class DeviceContextImplTest {
     private MessageTranslator<Object, Object> messageTranslatorFlowRemoved;
     @Mock
     private LifecycleConductor lifecycleConductor;
+    @Mock
+    private DeviceInfo deviceInfo;
 
     private InOrder inOrderDevState;
 
@@ -171,49 +178,41 @@ public class DeviceContextImplTest {
     private DeviceContext deviceContextSpy;
 
     @Before
-    public void setUp() {
+    public void setUp() throws Exception{
         final CheckedFuture<Optional<Node>, ReadFailedException> noExistNodeFuture = Futures.immediateCheckedFuture(Optional.<Node>absent());
         Mockito.when(rTx.read(LogicalDatastoreType.OPERATIONAL, nodeKeyIdent)).thenReturn(noExistNodeFuture);
         Mockito.when(dataBroker.newReadOnlyTransaction()).thenReturn(rTx);
         Mockito.when(dataBroker.createTransactionChain(Mockito.any(TransactionChainManager.class))).thenReturn(txChainFactory);
-        Mockito.when(deviceState.getNodeInstanceIdentifier()).thenReturn(nodeKeyIdent);
-        Mockito.when(deviceState.getNodeId()).thenReturn(nodeId);
-//        txChainManager = new TransactionChainManager(dataBroker, deviceState);
+        Mockito.when(deviceInfo.getNodeInstanceIdentifier()).thenReturn(nodeKeyIdent);
+        Mockito.when(deviceInfo.getNodeId()).thenReturn(nodeId);
+        Mockito.when(deviceInfo.getDatapathId()).thenReturn(BigInteger.ONE);
         final SettableFuture<RpcResult<GetAsyncReply>> settableFuture = SettableFuture.create();
         final SettableFuture<RpcResult<MultipartReply>> settableFutureMultiReply = SettableFuture.create();
         Mockito.when(requestContext.getFuture()).thenReturn(settableFuture);
-        Mockito.doAnswer(new Answer<Object>() {
-            @SuppressWarnings("unchecked")
-            @Override
-            public Object answer(final InvocationOnMock invocation) {
-                settableFuture.set((RpcResult<GetAsyncReply>) invocation.getArguments()[0]);
-                return null;
-            }
+        Mockito.doAnswer(invocation -> {
+            settableFuture.set((RpcResult<GetAsyncReply>) invocation.getArguments()[0]);
+            return null;
         }).when(requestContext).setResult(any(RpcResult.class));
 
         Mockito.when(requestContextMultiReply.getFuture()).thenReturn(settableFutureMultiReply);
-        Mockito.doAnswer(new Answer<Object>() {
-            @SuppressWarnings("unchecked")
-            @Override
-            public Object answer(final InvocationOnMock invocation) {
-                settableFutureMultiReply.set((RpcResult<MultipartReply>) invocation.getArguments()[0]);
-                return null;
-            }
+        Mockito.doAnswer(invocation -> {
+            settableFutureMultiReply.set((RpcResult<MultipartReply>) invocation.getArguments()[0]);
+            return null;
         }).when(requestContextMultiReply).setResult(any(RpcResult.class));
         Mockito.when(txChainFactory.newWriteOnlyTransaction()).thenReturn(wTx);
         Mockito.when(dataBroker.newReadOnlyTransaction()).thenReturn(rTx);
         Mockito.when(connectionContext.getOutboundQueueProvider()).thenReturn(outboundQueueProvider);
         Mockito.when(connectionContext.getConnectionAdapter()).thenReturn(connectionAdapter);
+        Mockito.when(connectionContext.getDeviceInfo()).thenReturn(deviceInfo);
         final FeaturesReply mockedFeaturesReply = mock(FeaturesReply.class);
         when(connectionContext.getFeatures()).thenReturn(mockedFeaturesReply);
         when(connectionContext.getFeatures().getCapabilities()).thenReturn(mock(Capabilities.class));
 
-        Mockito.when(deviceState.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
+        Mockito.when(deviceInfo.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
         Mockito.when(featuresOutput.getDatapathId()).thenReturn(DUMMY_DATAPATH_ID);
         Mockito.when(featuresOutput.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
-        Mockito.when(deviceState.getFeatures()).thenReturn(featuresOutput);
-        Mockito.when(messageTranslatorPacketReceived.translate(any(Object.class), any(DeviceState.class), any(Object.class))).thenReturn(mock(PacketReceived.class));
-        Mockito.when(messageTranslatorFlowCapableNodeConnector.translate(any(Object.class), any(DeviceState.class), any(Object.class))).thenReturn(mock(FlowCapableNodeConnector.class));
+        Mockito.when(messageTranslatorPacketReceived.translate(any(Object.class), any(DeviceInfo.class), any(Object.class))).thenReturn(mock(PacketReceived.class));
+        Mockito.when(messageTranslatorFlowCapableNodeConnector.translate(any(Object.class), any(DeviceInfo.class), any(Object.class))).thenReturn(mock(FlowCapableNodeConnector.class));
         Mockito.when(translatorLibrary.lookupTranslator(eq(new TranslatorKey(OFConstants.OFP_VERSION_1_3, PacketIn.class.getName())))).thenReturn(messageTranslatorPacketReceived);
         Mockito.when(translatorLibrary.lookupTranslator(eq(new TranslatorKey(OFConstants.OFP_VERSION_1_3, PortGrouping.class.getName())))).thenReturn(messageTranslatorFlowCapableNodeConnector);
         Mockito.when(translatorLibrary.lookupTranslator(eq(new TranslatorKey(OFConstants.OFP_VERSION_1_3,
@@ -221,27 +220,28 @@ public class DeviceContextImplTest {
                 .thenReturn(messageTranslatorFlowRemoved);
         Mockito.when(lifecycleConductor.getMessageIntelligenceAgency()).thenReturn(messageIntelligenceAgency);
 
-        deviceContext = new DeviceContextImpl(connectionContext, deviceState, dataBroker, lifecycleConductor, outboundQueueProvider, translatorLibrary, false);
-
+        deviceContext = new DeviceContextImpl(connectionContext, deviceState, dataBroker, lifecycleConductor, outboundQueueProvider, translatorLibrary);
         deviceContextSpy = Mockito.spy(deviceContext);
 
         xid = new Xid(atomicLong.incrementAndGet());
         xidMulti = new Xid(atomicLong.incrementAndGet());
+
+        Mockito.doNothing().when(deviceContextSpy).writeToTransaction(Mockito.<LogicalDatastoreType>any(), Mockito.<InstanceIdentifier>any(), any());
     }
 
     @Test(expected = NullPointerException.class)
     public void testDeviceContextImplConstructorNullDataBroker() throws Exception {
-        new DeviceContextImpl(connectionContext, deviceState, null, lifecycleConductor, outboundQueueProvider, translatorLibrary, false).close();
+        new DeviceContextImpl(connectionContext, deviceState, null, lifecycleConductor, outboundQueueProvider, translatorLibrary).close();
     }
 
     @Test(expected = NullPointerException.class)
     public void testDeviceContextImplConstructorNullDeviceState() throws Exception {
-        new DeviceContextImpl(connectionContext, null, dataBroker, lifecycleConductor, outboundQueueProvider, translatorLibrary, false).close();
+        new DeviceContextImpl(connectionContext, null, dataBroker, lifecycleConductor, outboundQueueProvider, translatorLibrary).close();
     }
 
     @Test(expected = NullPointerException.class)
     public void testDeviceContextImplConstructorNullTimer() throws Exception {
-        new DeviceContextImpl(null, deviceState, dataBroker, lifecycleConductor, outboundQueueProvider, translatorLibrary, false).close();
+        new DeviceContextImpl(null, deviceState, dataBroker, lifecycleConductor, outboundQueueProvider, translatorLibrary).close();
     }
 
     @Test
@@ -265,10 +265,10 @@ public class DeviceContextImplTest {
     public void testInitialSubmitTransaction() throws Exception {
         Mockito.when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null));
         final InstanceIdentifier<Nodes> dummyII = InstanceIdentifier.create(Nodes.class);
-        deviceContext.getTransactionChainManager().activateTransactionManager() ;
-        deviceContext.getTransactionChainManager().enableSubmit();
+        ((DeviceContextImpl) deviceContext).getTransactionChainManager().activateTransactionManager() ;
+        ((DeviceContextImpl) deviceContext).getTransactionChainManager().enableSubmit();
         deviceContext.addDeleteToTxChain(LogicalDatastoreType.CONFIGURATION, dummyII);
-        deviceContext.initialSubmitTransaction();
+        ((DeviceContextImpl) deviceContext).initialSubmitTransaction();
         verify(wTx).submit();
     }
 
@@ -316,8 +316,8 @@ public class DeviceContextImplTest {
     @Test
     public void testAddDeleteToTxChain() throws Exception{
         final InstanceIdentifier<Nodes> dummyII = InstanceIdentifier.create(Nodes.class);
-        deviceContext.getTransactionChainManager().activateTransactionManager() ;
-        deviceContext.getTransactionChainManager().enableSubmit();
+        ((DeviceContextImpl) deviceContext).getTransactionChainManager().activateTransactionManager() ;
+        ((DeviceContextImpl) deviceContext).getTransactionChainManager().enableSubmit();
         deviceContext.addDeleteToTxChain(LogicalDatastoreType.CONFIGURATION, dummyII);
         verify(wTx).delete(eq(LogicalDatastoreType.CONFIGURATION), eq(dummyII));
     }
@@ -327,8 +327,8 @@ public class DeviceContextImplTest {
      */
     @Test
     public void testSubmitTransaction() throws Exception {
-        deviceContext.getTransactionChainManager().activateTransactionManager() ;
-        deviceContext.getTransactionChainManager().enableSubmit();
+        ((DeviceContextImpl) deviceContext).getTransactionChainManager().activateTransactionManager() ;
+        ((DeviceContextImpl) deviceContext).getTransactionChainManager().enableSubmit();
         assertTrue(deviceContext.submitTransaction());
     }
 
@@ -356,13 +356,6 @@ public class DeviceContextImplTest {
         assertNotNull(deviceMeterRegistry);
     }
 
-    @Test
-    public void testGetRpcContext() {
-        final RpcContext rpcContext = mock(RpcContext.class);
-        deviceContext.setRpcContext(rpcContext);
-        assertNotNull(deviceContext.getRpcContext());
-    }
-
     @Test
     public void testProcessReply() {
         final Error mockedError = mock(Error.class);
@@ -419,7 +412,7 @@ public class DeviceContextImplTest {
         when(connectionContext.getConnectionAdapter()).thenReturn(mockedConnectionAdapter);
 
         final NodeId dummyNodeId = new NodeId("dummyNodeId");
-        when(deviceState.getNodeId()).thenReturn(dummyNodeId);
+        when(deviceInfo.getNodeId()).thenReturn(dummyNodeId);
 
         final ConnectionContext mockedAuxiliaryConnectionContext = prepareConnectionContext();
         deviceContext.addAuxiliaryConnectionContext(mockedAuxiliaryConnectionContext);
@@ -443,15 +436,6 @@ public class DeviceContextImplTest {
         assertEquals(messageIntelligenceAgency, pickedMessageSpy);
     }
 
-    @Test
-    public void testNodeConnector() {
-        final NodeConnectorRef mockedNodeConnectorRef = mock(NodeConnectorRef.class);
-        deviceContext.storeNodeConnectorRef(DUMMY_PORT_NUMBER, mockedNodeConnectorRef);
-        final NodeConnectorRef nodeConnectorRef = deviceContext.lookupNodeConnectorRef(DUMMY_PORT_NUMBER);
-        assertEquals(mockedNodeConnectorRef, nodeConnectorRef);
-
-    }
-
     @Test
     public void testOnPublished() {
         final ConnectionContext auxiliaryConnectionContext = addDummyAuxiliaryConnectionContext();
@@ -468,7 +452,7 @@ public class DeviceContextImplTest {
     }
 
     @Test
-    public void testPortStatusMessage() {
+    public void testPortStatusMessage() throws Exception{
         final PortStatusMessage mockedPortStatusMessage = mock(PortStatusMessage.class);
         final Class dummyClass = Class.class;
         when(mockedPortStatusMessage.getImplementedInterface()).thenReturn(dummyClass);
@@ -476,14 +460,15 @@ public class DeviceContextImplTest {
 
         final GetFeaturesOutput mockedFeature = mock(GetFeaturesOutput.class);
         when(mockedFeature.getDatapathId()).thenReturn(DUMMY_DATAPATH_ID);
-        when(deviceState.getFeatures()).thenReturn(mockedFeature);
 
         when(mockedPortStatusMessage.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
         when(mockedPortStatusMessage.getReason()).thenReturn(PortReason.OFPPRADD);
+        when(mockedPortStatusMessage.getPortNo()).thenReturn(42L);
 
         OpenflowPortsUtil.init();
-        deviceContext.processPortStatusMessage(mockedPortStatusMessage);
-//        verify(txChainManager).writeToTransaction(eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class), any(DataObject.class));
+        deviceContextSpy.processPortStatusMessage(mockedPortStatusMessage);
+        verify(deviceContextSpy).writeToTransaction(Mockito.<LogicalDatastoreType>any(), Mockito.<InstanceIdentifier>any(), any());
+        verify(deviceContextSpy).submitTransaction();
     }
 
     @Test
@@ -496,7 +481,7 @@ public class DeviceContextImplTest {
                 .setMatch(new MatchBuilder().build());
         final NotificationPublishService mockedNotificationPublishService = mock(NotificationPublishService.class);
 
-        Mockito.when(messageTranslatorFlowRemoved.translate(any(Object.class), any(DeviceState.class), any(Object.class)))
+        Mockito.when(messageTranslatorFlowRemoved.translate(any(Object.class), any(DeviceInfo.class), any(Object.class)))
                 .thenReturn(flowRemovedMdsalBld.build());
 
         // insert flow+flowId into local registry
@@ -537,7 +522,7 @@ public class DeviceContextImplTest {
         final NotificationPublishService mockedNotificationPublishService = mock(NotificationPublishService.class);
 
         deviceContext.setNotificationPublishService(mockedNotificationPublishService);
-        deviceContext.setExtensionConverterProvider(mockedExtensionConverterProvider);
+        ((DeviceContextImpl) deviceContext).setExtensionConverterProvider(mockedExtensionConverterProvider);
         deviceContext.processExperimenterMessage(experimenterMessage);
 
         verify(mockedNotificationPublishService).offerNotification(any(ExperimenterMessageFromDev.class));
@@ -552,28 +537,4 @@ public class DeviceContextImplTest {
         assertEquals(0, deviceContext.getDeviceMeterRegistry().getAllMeterIds().size());
 
     }
-
-    @Test
-    public void testOnClusterRoleChange() throws Exception {
-        // test role.equals(oldRole)
-        Assert.assertNull(deviceContextSpy.onClusterRoleChange(OfpRole.BECOMEMASTER, OfpRole.BECOMEMASTER).get());
-
-        // test call transactionChainManager.deactivateTransactionManager()
-        Assert.assertNull(deviceContextSpy.onClusterRoleChange(OfpRole.BECOMESLAVE, OfpRole.NOCHANGE).get());
-
-        // test call MdSalRegistrationUtils.unregisterServices(rpcContext)
-        final RpcContext rpcContext = mock(RpcContext.class);
-        deviceContextSpy.setRpcContext(rpcContext);
-        Assert.assertNull(deviceContextSpy.onClusterRoleChange(OfpRole.BECOMESLAVE, OfpRole.NOCHANGE).get());
-
-        final StatisticsContext statisticsContext = mock(StatisticsContext.class);
-        deviceContextSpy.setStatisticsContext(statisticsContext);
-
-        deviceContextSpy.onClusterRoleChange(OfpRole.NOCHANGE, OfpRole.BECOMEMASTER);
-        verify(deviceContextSpy).onDeviceTakeClusterLeadership();
-
-        Mockito.when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null));
-        deviceContextSpy.onClusterRoleChange(OfpRole.NOCHANGE, OfpRole.BECOMESLAVE);
-        verify(deviceContextSpy).onDeviceLostClusterLeadership();
-    }
 }
index 8b254137fb25234bca8bf1fa7920275845e00dc3..1a7ddd1847b0247e0d136ab309d5c555e4f83d6a 100644 (file)
@@ -17,6 +17,7 @@ import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
+
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
@@ -50,6 +51,7 @@ import org.opendaylight.openflowplugin.api.OFConstants;
 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
 import org.opendaylight.openflowplugin.api.openflow.connection.OutboundQueueProvider;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator;
 import org.opendaylight.openflowplugin.api.openflow.device.TranslatorLibrary;
@@ -73,6 +75,7 @@ public class DeviceManagerImplTest {
     private static final long TEST_VALUE_GLOBAL_NOTIFICATION_QUOTA = 2000l;
     private static final int barrierCountLimit = 25600;
     private static final int barrierIntervalNanos = 500;
+    public static final NodeId DUMMY_NODE_ID = new NodeId("dummyNodeId");
 
     @Mock
     CheckedFuture<Void, TransactionCommitFailedException> mockedFuture;
@@ -98,15 +101,19 @@ public class DeviceManagerImplTest {
     private LifecycleConductor lifecycleConductor;
     @Mock
     private MessageIntelligenceAgency messageIntelligenceAgency;
+    @Mock
+    private DeviceInfo deviceInfo;
 
     @Before
     public void setUp() throws Exception {
         OpenflowPortsUtil.init();
 
-        when(mockConnectionContext.getNodeId()).thenReturn(new NodeId("dummyNodeId"));
+        when(mockConnectionContext.getNodeId()).thenReturn(DUMMY_NODE_ID);
         when(mockConnectionContext.getFeatures()).thenReturn(mockFeatures);
         when(mockConnectionContext.getConnectionAdapter()).thenReturn(mockedConnectionAdapter);
+        when(mockConnectionContext.getDeviceInfo()).thenReturn(deviceInfo);
         when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(mockConnectionContext);
+        when(deviceInfo.getNodeId()).thenReturn(DUMMY_NODE_ID);
 
         final Capabilities capabilitiesV13 = mock(Capabilities.class);
         final CapabilitiesV10 capabilitiesV10 = mock(CapabilitiesV10.class);
@@ -157,13 +164,12 @@ public class DeviceManagerImplTest {
         final DeviceManagerImpl deviceManager = prepareDeviceManager(withException);
         final DeviceState mockedDeviceState = mock(DeviceState.class);
         when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState);
-        when(mockedDeviceState.getNodeId()).thenReturn(mockedNodeId);
 
         if (withException) {
             doThrow(new IllegalStateException("dummy")).when(mockedDeviceContext).initialSubmitTransaction();
         }
-        deviceManager.addDeviceContextToMap(mockedNodeId, mockedDeviceContext);
-        deviceManager.onDeviceContextLevelUp(mockedDeviceContext.getDeviceState().getNodeId());
+        deviceManager.addDeviceContextToMap(deviceInfo, mockedDeviceContext);
+        deviceManager.onDeviceContextLevelUp(deviceInfo);
         if (withException) {
             verify(mockedDeviceContext).close();
         } else {
@@ -181,12 +187,10 @@ public class DeviceManagerImplTest {
         deviceManager.deviceConnected(mockConnectionContext);
 
         final InOrder order = inOrder(mockConnectionContext);
-        order.verify(mockConnectionContext).getFeatures();
         order.verify(mockConnectionContext).setOutboundQueueProvider(any(OutboundQueueProvider.class));
         order.verify(mockConnectionContext).setOutboundQueueHandleRegistration(
                 Mockito.<OutboundQueueHandlerRegistration<OutboundQueueProvider>>any());
-        order.verify(mockConnectionContext).getNodeId();
-        verify(deviceInitPhaseHandler).onDeviceContextLevelUp(Matchers.<NodeId>any());
+        verify(deviceInitPhaseHandler).onDeviceContextLevelUp(Matchers.<DeviceInfo>any());
     }
 
     @Test
@@ -199,19 +203,17 @@ public class DeviceManagerImplTest {
                 .setPortNo(41L);
         when(mockFeatures.getPhyPort()).thenReturn(Collections.singletonList(phyPort.build()));
         final MessageTranslator<Object, Object> mockedTranslator = mock(MessageTranslator.class);
-        when(mockedTranslator.translate(Matchers.<Object>any(), Matchers.<DeviceState>any(), Matchers.any()))
+        when(mockedTranslator.translate(Matchers.<Object>any(), Matchers.<DeviceInfo>any(), Matchers.any()))
                 .thenReturn(null);
         when(translatorLibrary.lookupTranslator(Matchers.<TranslatorKey>any())).thenReturn(mockedTranslator);
 
         deviceManager.deviceConnected(mockConnectionContext);
 
         final InOrder order = inOrder(mockConnectionContext);
-        order.verify(mockConnectionContext).getFeatures();
         order.verify(mockConnectionContext).setOutboundQueueProvider(any(OutboundQueueProvider.class));
         order.verify(mockConnectionContext).setOutboundQueueHandleRegistration(
                 Mockito.<OutboundQueueHandlerRegistration<OutboundQueueProvider>>any());
-        order.verify(mockConnectionContext).getNodeId();
-        verify(deviceInitPhaseHandler).onDeviceContextLevelUp(Matchers.<NodeId>any());
+        verify(deviceInitPhaseHandler).onDeviceContextLevelUp(Matchers.<DeviceInfo>any());
     }
 
     @Test
@@ -229,8 +231,8 @@ public class DeviceManagerImplTest {
         when(deviceContext.getPrimaryConnectionContext()).thenReturn(connectionContext);
         when(deviceContext.getDeviceState()).thenReturn(deviceState);
 
-        final ConcurrentHashMap<NodeId, DeviceContext> deviceContexts = getContextsCollection(deviceManager);
-        deviceContexts.put(mockedNodeId, deviceContext);
+        final ConcurrentHashMap<DeviceInfo, DeviceContext> deviceContexts = getContextsCollection(deviceManager);
+        deviceContexts.put(deviceInfo, deviceContext);
 
         deviceManager.onDeviceDisconnected(connectionContext);
 
@@ -273,8 +275,8 @@ public class DeviceManagerImplTest {
     public void testClose() throws Exception {
         final DeviceContext deviceContext = mock(DeviceContext.class);
         final DeviceManagerImpl deviceManager = prepareDeviceManager();
-        final ConcurrentHashMap<NodeId, DeviceContext> deviceContexts = getContextsCollection(deviceManager);
-        deviceContexts.put(mockedNodeId, deviceContext);
+        final ConcurrentHashMap<DeviceInfo, DeviceContext> deviceContexts = getContextsCollection(deviceManager);
+        deviceContexts.put(deviceInfo, deviceContext);
         Assert.assertEquals(1, deviceContexts.size());
 
         deviceManager.close();
@@ -283,12 +285,12 @@ public class DeviceManagerImplTest {
         verify(deviceContext, Mockito.never()).close();
     }
 
-    private static ConcurrentHashMap<NodeId, DeviceContext> getContextsCollection(final DeviceManagerImpl deviceManager) throws NoSuchFieldException, IllegalAccessException {
+    private static ConcurrentHashMap<DeviceInfo, DeviceContext> getContextsCollection(final DeviceManagerImpl deviceManager) throws NoSuchFieldException, IllegalAccessException {
         // HACK: contexts collection for testing shall be accessed in some more civilized way
         final Field contextsField = DeviceManagerImpl.class.getDeclaredField("deviceContexts");
         Assert.assertNotNull(contextsField);
         contextsField.setAccessible(true);
-        return (ConcurrentHashMap<NodeId, DeviceContext>) contextsField.get(deviceManager);
+        return (ConcurrentHashMap<DeviceInfo, DeviceContext>) contextsField.get(deviceManager);
     }
 
 }
index 012d744252a87cd24ea40bc9b76bd0dc2cc460a4..5170dd75d64d088b0ace332bd524ef9f36e966c4 100644 (file)
@@ -8,90 +8,31 @@
 
 package org.opendaylight.openflowplugin.impl.device;
 
-import java.util.Arrays;
-import java.util.List;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-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.GetFeaturesOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.features.reply.PhyPort;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.features.reply.PhyPortBuilder;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 
 /**
  * openflowplugin-impl
  * org.opendaylight.openflowplugin.impl.device
  *
  * test of {@link DeviceStateImpl} - lightweight version, using basic ways (TDD)
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- * Created: Mar 29, 2015
  */
 @RunWith(MockitoJUnitRunner.class)
 public class DeviceStateImplTest {
 
-    private NodeId nodeId;
     @Mock
-    private FeaturesReply featuresReply;
-    private DeviceStateImpl deviceState;
+    private DeviceInfo deviceInfo;
 
-    private final short version = 13;
-    private final long portNr = 10L;
-    private final Long portBandwidth = 1024L;
-    private final List<PhyPort> pPort = Arrays.asList(new PhyPortBuilder()
-                    .setPortNo(portNr).setMaxSpeed(portBandwidth).build());
+    private DeviceStateImpl deviceState;
 
     @Before
     public void initialization() {
-        nodeId = new NodeId("test-node-id");
-        Mockito.when(featuresReply.getVersion()).thenReturn(version);
-        Mockito.when(featuresReply.getPhyPort()).thenReturn(pPort);
-        deviceState = new DeviceStateImpl(featuresReply, nodeId);
-    }
-
-    /**
-     * Test method for {@link DeviceStateImpl#DeviceStateImpl(FeaturesReply, NodeId)}.
-     */
-    @Test(expected=NullPointerException.class)
-    public void testDeviceStateImplNullNodeId(){
-        new DeviceStateImpl(featuresReply, null);
-    }
-
-    /**
-     * Test method for {@link DeviceStateImpl#DeviceStateImpl(FeaturesReply, NodeId)}.
-     */
-    @Test(expected=IllegalArgumentException.class)
-    public void testDeviceStateImplNullFeaturesReply(){
-        new DeviceStateImpl(null, nodeId);
-    }
-
-    /**
-     * Test method for {@link DeviceStateImpl#getNodeId()}.
-     */
-    @Test
-    public void testGetNodeId(){
-        final NodeId getNodeId = deviceState.getNodeId();
-        Assert.assertNotNull(getNodeId);
-        Assert.assertEquals(nodeId, getNodeId);
-    }
-
-    /**
-     * Test method for {@link DeviceStateImpl#getFeatures()}.
-     */
-    @Test
-    public void testGetFeatures(){
-        final GetFeaturesOutputBuilder expetedResult = new GetFeaturesOutputBuilder(featuresReply);
-        final GetFeaturesOutput getFeatures = deviceState.getFeatures();
-        Assert.assertNotNull(getFeatures);
-        Assert.assertEquals(expetedResult.getVersion(), getFeatures.getVersion());
-        Assert.assertEquals(expetedResult.getPhyPort(), getFeatures.getPhyPort());
+        deviceState = new DeviceStateImpl(deviceInfo);
     }
 
     @Test
index 296ea4ef6b4d4bb89a7321d65e9276d28645b105..68c07e23539f6a3931ab5ac3f7780cc63ad1100b 100644 (file)
@@ -31,6 +31,7 @@ import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleConductor;
 import org.opendaylight.openflowplugin.impl.util.DeviceStateUtil;
@@ -66,6 +67,8 @@ public class TransactionChainManagerTest {
     @Mock
     DeviceState deviceState;
     @Mock
+    DeviceInfo deviceInfo;
+    @Mock
     LifecycleConductor conductor;
 
     @Mock
@@ -85,9 +88,9 @@ public class TransactionChainManagerTest {
                 .thenReturn(txChain);
         nodeId = new NodeId("h2g2:42");
         nodeKeyIdent = DeviceStateUtil.createNodeInstanceIdentifier(nodeId);
-        Mockito.when(deviceState.getNodeInstanceIdentifier()).thenReturn(nodeKeyIdent);
-        Mockito.when(deviceState.getNodeId()).thenReturn(nodeId);
-        txChainManager = new TransactionChainManager(dataBroker, deviceState, conductor);
+        Mockito.when(deviceInfo.getNodeInstanceIdentifier()).thenReturn(nodeKeyIdent);
+        Mockito.when(deviceInfo.getNodeId()).thenReturn(nodeId);
+        txChainManager = new TransactionChainManager(dataBroker, deviceInfo, conductor);
         Mockito.when(txChain.newWriteOnlyTransaction()).thenReturn(writeTx);
 
         path = InstanceIdentifier.create(Nodes.class).child(Node.class, new NodeKey(nodeId));
index 2df7f6edbe9b48ab7b59b8a563246f32904d13a0..cf60cb5e71ef7c91c7e99af799b73c1f531bd684 100644 (file)
@@ -24,6 +24,7 @@ import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.opendaylight.openflowplugin.api.OFConstants;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
@@ -49,6 +50,8 @@ public class FlowRegistryKeyFactoryTest {
     private DeviceContext deviceContext;
     @Mock
     private DeviceState deviceState;
+    @Mock
+    private DeviceInfo deviceInfo;
 
 
     @Before
@@ -59,7 +62,7 @@ public class FlowRegistryKeyFactoryTest {
         }
         FLOWS_STATISTICS_UPDATE_BUILDER.setFlowAndStatisticsMapList(flowAndStatisticsMapListList);
         Mockito.when(deviceContext.getDeviceState()).thenReturn(deviceState);
-        Mockito.when(deviceState.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
+        Mockito.when(deviceInfo.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
     }
 
     @Test
index a427fbbe0bb3ee90cc72309599f3ad20e74a3b36..8349f477a7053abf2224da79a308f856d9a09dbe 100644 (file)
@@ -21,6 +21,7 @@ import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlready
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidateRegistration;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleConductor;
 import org.opendaylight.openflowplugin.api.openflow.role.RoleContext;
 import org.opendaylight.openflowplugin.api.openflow.role.RoleManager;
@@ -42,6 +43,9 @@ public class RoleContextImplTest {
     @Mock
     private LifecycleConductor conductor;
 
+    @Mock
+    private DeviceInfo deviceInfo;
+
     private final NodeId nodeId = NodeId.getDefaultInstance("openflow:1");
     private final Entity entity = new Entity(RoleManager.ENTITY_TYPE, nodeId.getValue());
     private final Entity txEntity = new Entity(RoleManager.TX_ENTITY_TYPE, nodeId.getValue());
@@ -49,9 +53,10 @@ public class RoleContextImplTest {
 
     @Before
     public void setup() throws CandidateAlreadyRegisteredException {
-        roleContext = new RoleContextImpl(nodeId, entityOwnershipService, entity, txEntity, conductor);
+        roleContext = new RoleContextImpl(deviceInfo, entityOwnershipService, entity, txEntity, conductor);
         Mockito.when(entityOwnershipService.registerCandidate(entity)).thenReturn(entityOwnershipCandidateRegistration);
         Mockito.when(entityOwnershipService.registerCandidate(txEntity)).thenReturn(entityOwnershipCandidateRegistration);
+        Mockito.when(deviceInfo.getNodeId()).thenReturn(nodeId);
     }
 
     //@Test
@@ -108,7 +113,7 @@ public class RoleContextImplTest {
     @Test
     public void testCreateRequestContext() throws Exception {
         roleContext.createRequestContext();
-        Mockito.verify(conductor).reserveXidForDeviceMessage(nodeId);
+        Mockito.verify(conductor).reserveXidForDeviceMessage(deviceInfo);
     }
 
     @Test(expected = NullPointerException.class)
@@ -128,7 +133,7 @@ public class RoleContextImplTest {
 
     @Test
     public void testGetNodeId() throws Exception {
-        Assert.assertTrue(roleContext.getNodeId().equals(nodeId));
+        Assert.assertTrue(roleContext.getDeviceInfo().getNodeId().equals(nodeId));
     }
 
     @Test
index 3febe5466ccd088dd1f7727ba3abffa370f0536e..e4fc2c16e8c8f112dda2c2e2424715a931ea2a3e 100644 (file)
@@ -9,11 +9,13 @@
 package org.opendaylight.openflowplugin.impl.role;
 
 
-import java.math.BigInteger;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
 
 import com.google.common.base.VerifyException;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.Futures;
+import java.math.BigInteger;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -32,9 +34,11 @@ import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipL
 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.TransactionCommitFailedException;
+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;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceManager;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceInitializationPhaseHandler;
@@ -42,16 +46,12 @@ import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceTermin
 import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleConductor;
 import org.opendaylight.openflowplugin.api.openflow.lifecycle.RoleChangeListener;
 import org.opendaylight.openflowplugin.api.openflow.role.RoleContext;
+import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 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.role.service.rev150727.OfpRole;
 
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-
 @RunWith(MockitoJUnitRunner.class)
 public class RoleManagerImplTest {
 
@@ -97,6 +97,18 @@ public class RoleManagerImplTest {
     @Mock
     DeviceState deviceState;
 
+    @Mock
+    DeviceInfo deviceInfo;
+
+    @Mock
+    DeviceInfo deviceInfo2;
+
+    @Mock
+    MessageSpy messageSpy;
+
+    @Mock
+    OutboundQueue outboundQueue;
+
     @Mock
     GetFeaturesOutput featuresOutput;
 
@@ -104,40 +116,50 @@ public class RoleManagerImplTest {
     private RoleManagerImpl roleManagerSpy;
     private RoleContext roleContextSpy;
     private final NodeId nodeId = NodeId.getDefaultInstance("openflow:1");
+    private final NodeId nodeId2 = NodeId.getDefaultInstance("openflow:2");
 
-    private final EntityOwnershipChange masterEntity = new EntityOwnershipChange(RoleManagerImpl.makeEntity(nodeId), false, true, true);
-    private final EntityOwnershipChange masterTxEntity = new EntityOwnershipChange(RoleManagerImpl.makeTxEntity(nodeId), false, true, true);
-    private final EntityOwnershipChange slaveEntity = new EntityOwnershipChange(RoleManagerImpl.makeEntity(nodeId), true, false, true);
-    private final EntityOwnershipChange slaveTxEntityLast = new EntityOwnershipChange(RoleManagerImpl.makeTxEntity(nodeId), true, false, false);
-    private final EntityOwnershipChange masterEntityNotOwner = new EntityOwnershipChange(RoleManagerImpl.makeEntity(nodeId), true, false, true);
+
+    private final EntityOwnershipChange masterEntity = new EntityOwnershipChange(RoleManagerImpl.makeEntity(nodeId), false, true, true, false);
+    private final EntityOwnershipChange masterTxEntity = new EntityOwnershipChange(RoleManagerImpl.makeTxEntity(nodeId), false, true, true, false);
+    private final EntityOwnershipChange slaveEntity = new EntityOwnershipChange(RoleManagerImpl.makeEntity(nodeId), true, false, true, false);
+    private final EntityOwnershipChange slaveTxEntityLast = new EntityOwnershipChange(RoleManagerImpl.makeTxEntity(nodeId), true, false, false, false);
+    private final EntityOwnershipChange masterEntityNotOwner = new EntityOwnershipChange(RoleManagerImpl.makeEntity(nodeId), true, false, true, false);
 
     private InOrder inOrder;
 
     @Before
     public void setUp() throws Exception {
         CheckedFuture<Void, TransactionCommitFailedException> future = Futures.immediateCheckedFuture(null);
-        Mockito.when(deviceState.getFeatures()).thenReturn(featuresOutput);
         Mockito.when(entityOwnershipService.registerListener(Mockito.anyString(), Mockito.any(EntityOwnershipListener.class))).thenReturn(entityOwnershipListenerRegistration);
         Mockito.when(entityOwnershipService.registerCandidate(Mockito.any(Entity.class))).thenReturn(entityOwnershipCandidateRegistration);
         Mockito.when(deviceContext.getPrimaryConnectionContext()).thenReturn(connectionContext);
         Mockito.when(deviceContext.getDeviceState()).thenReturn(deviceState);
+        Mockito.when(deviceContext.getDeviceInfo()).thenReturn(deviceInfo);
+        Mockito.when(deviceContext.getMessageSpy()).thenReturn(messageSpy);
+        Mockito.when(deviceContext.getPrimaryConnectionContext().getOutboundQueueProvider()).thenReturn(outboundQueue);
         Mockito.when(connectionContext.getFeatures()).thenReturn(featuresReply);
         Mockito.when(connectionContext.getNodeId()).thenReturn(nodeId);
         Mockito.when(connectionContext.getConnectionState()).thenReturn(ConnectionContext.CONNECTION_STATE.WORKING);
-        Mockito.when(featuresReply.getDatapathId()).thenReturn(new BigInteger("1"));
-        Mockito.when(featuresReply.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
-        Mockito.doNothing().when(deviceInitializationPhaseHandler).onDeviceContextLevelUp(Mockito.<NodeId>any());
-        Mockito.doNothing().when(deviceTerminationPhaseHandler).onDeviceContextLevelDown(Mockito.<DeviceContext>any());
+        Mockito.when(deviceInfo.getDatapathId()).thenReturn(new BigInteger("1"));
+        Mockito.when(deviceInfo.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
+        Mockito.when(deviceInfo.getNodeId()).thenReturn(nodeId);
+        Mockito.doNothing().when(deviceInitializationPhaseHandler).onDeviceContextLevelUp(Mockito.<DeviceInfo>any());
+        Mockito.doNothing().when(deviceTerminationPhaseHandler).onDeviceContextLevelDown(Mockito.<DeviceInfo>any());
         Mockito.when(dataBroker.newWriteOnlyTransaction()).thenReturn(writeTransaction);
         Mockito.when(writeTransaction.submit()).thenReturn(future);
-        Mockito.when(deviceManager.getDeviceContextFromNodeId(Mockito.<NodeId>any())).thenReturn(deviceContext);
+        Mockito.when(deviceInfo.getNodeId()).thenReturn(nodeId);
+        Mockito.when(deviceInfo2.getNodeId()).thenReturn(nodeId2);
+        Mockito.when(deviceInfo.getDatapathId()).thenReturn(BigInteger.TEN);
         roleManager = new RoleManagerImpl(entityOwnershipService, dataBroker, conductor);
         roleManager.setDeviceInitializationPhaseHandler(deviceInitializationPhaseHandler);
         roleManager.setDeviceTerminationPhaseHandler(deviceTerminationPhaseHandler);
-        Mockito.when(conductor.getDeviceContext(Mockito.<NodeId>any())).thenReturn(deviceContext);
+        Mockito.when(conductor.getDeviceContext(deviceInfo)).thenReturn(deviceContext);
         roleManagerSpy = Mockito.spy(roleManager);
-        roleManagerSpy.onDeviceContextLevelUp(nodeId);
-        roleContextSpy = Mockito.spy(roleManager.getRoleContext(nodeId));
+        roleManagerSpy.onDeviceContextLevelUp(deviceInfo);
+        Mockito.doNothing().when(roleManagerSpy).makeDeviceRoleChange(Mockito.<OfpRole>any(), Mockito.<RoleContext>any(), Mockito.anyBoolean());
+        roleContextSpy = Mockito.spy(roleManager.getRoleContext(deviceInfo));
+        Mockito.when(roleContextSpy.getDeviceInfo()).thenReturn(deviceInfo);
+        Mockito.when(roleContextSpy.getDeviceInfo().getNodeId()).thenReturn(nodeId);
         inOrder = Mockito.inOrder(entityOwnershipListenerRegistration, roleManagerSpy, roleContextSpy);
     }
 
@@ -147,8 +169,8 @@ public class RoleManagerImplTest {
 
     @Test(expected = VerifyException.class)
     public void testOnDeviceContextLevelUp() throws Exception {
-        roleManagerSpy.onDeviceContextLevelUp(nodeId);
-        inOrder.verify(roleManagerSpy).onDeviceContextLevelUp(nodeId);
+        roleManagerSpy.onDeviceContextLevelUp(deviceInfo);
+        inOrder.verify(roleManagerSpy).onDeviceContextLevelUp(deviceInfo);
         inOrder.verifyNoMoreInteractions();
     }
 
@@ -158,7 +180,7 @@ public class RoleManagerImplTest {
         roleManagerSpy.ownershipChanged(masterTxEntity);
         roleManagerSpy.close();
         inOrder.verify(entityOwnershipListenerRegistration, Mockito.calls(2)).close();
-        inOrder.verify(roleManagerSpy).removeDeviceFromOperationalDS(nodeId);
+        inOrder.verify(roleManagerSpy).removeDeviceFromOperationalDS(Mockito.eq(deviceInfo), Mockito.anyInt());
         inOrder.verifyNoMoreInteractions();
     }
 
@@ -167,14 +189,14 @@ public class RoleManagerImplTest {
         roleManagerSpy.ownershipChanged(slaveEntity);
         roleManagerSpy.close();
         inOrder.verify(entityOwnershipListenerRegistration, Mockito.calls(2)).close();
-        inOrder.verify(roleManagerSpy, Mockito.never()).removeDeviceFromOperationalDS(nodeId);
+        inOrder.verify(roleManagerSpy, Mockito.never()).removeDeviceFromOperationalDS(Mockito.eq(deviceInfo), Mockito.anyInt());
         inOrder.verifyNoMoreInteractions();
     }
 
     @Test
     public void testOnDeviceContextLevelDown() throws Exception {
-        roleManagerSpy.onDeviceContextLevelDown(deviceContext);
-        inOrder.verify(roleManagerSpy).onDeviceContextLevelDown(deviceContext);
+        roleManagerSpy.onDeviceContextLevelDown(deviceInfo);
+        inOrder.verify(roleManagerSpy).onDeviceContextLevelDown(deviceInfo);
         inOrder.verifyNoMoreInteractions();
     }
 
@@ -216,7 +238,7 @@ public class RoleManagerImplTest {
         inOrder.verify(roleContextSpy, Mockito.atLeastOnce()).isTxCandidateRegistered();
         inOrder.verify(roleContextSpy, Mockito.calls(1)).unregisterCandidate(Mockito.<Entity>any());
         inOrder.verify(roleContextSpy, Mockito.never()).close();
-        inOrder.verify(roleManagerSpy, Mockito.calls(1)).removeDeviceFromOperationalDS(Mockito.<NodeId>any());
+        inOrder.verify(roleManagerSpy, Mockito.calls(1)).removeDeviceFromOperationalDS(Mockito.any(), Mockito.anyInt());
     }
 
     @Test
@@ -234,8 +256,7 @@ public class RoleManagerImplTest {
         Mockito.when(roleContextSpy.isTxCandidateRegistered()).thenReturn(false);
         roleManagerSpy.changeOwnershipForTxEntity(slaveTxEntityLast, roleContextSpy);
         verify(roleContextSpy).close();
-        verify(roleContextSpy).getNodeId();
-        verify(conductor).closeConnection(nodeId);
+        verify(conductor).closeConnection(deviceInfo);
     }
 
     @Test
@@ -243,50 +264,41 @@ public class RoleManagerImplTest {
         Mockito.when(roleContextSpy.isTxCandidateRegistered()).thenReturn(true);
         roleManagerSpy.changeOwnershipForTxEntity(masterEntityNotOwner, roleContextSpy);
         verify(roleContextSpy).close();
-        verify(conductor).closeConnection(nodeId);
+        verify(conductor).closeConnection(deviceInfo);
     }
 
     @Test
     public void testAddListener() throws Exception {
         roleManager.addRoleChangeListener((new RoleChangeListener() {
             @Override
-            public void roleInitializationDone(final NodeId nodeId, final boolean success) {
-                Assert.assertTrue(nodeId.equals(nodeId));
+            public void roleInitializationDone(final DeviceInfo deviceInfo_, final boolean success) {
+                Assert.assertTrue(deviceInfo.equals(deviceInfo_));
                 Assert.assertTrue(success);
             }
 
             @Override
-            public void roleChangeOnDevice(final NodeId nodeId_, final boolean success, final OfpRole newRole, final boolean initializationPhase) {
-                Assert.assertTrue(nodeId.equals(nodeId_));
+            public void roleChangeOnDevice(final DeviceInfo deviceInfo_, final boolean success, final OfpRole newRole, final boolean initializationPhase) {
+                Assert.assertTrue(RoleManagerImplTest.this.deviceInfo.equals(deviceInfo_));
                 Assert.assertTrue(success);
                 Assert.assertFalse(initializationPhase);
                 Assert.assertTrue(newRole.equals(OfpRole.BECOMEMASTER));
             }
         }));
-        roleManager.notifyListenersRoleInitializationDone(nodeId, true);
-        roleManager.notifyListenersRoleChangeOnDevice(nodeId, true, OfpRole.BECOMEMASTER, false);
-    }
-
-    @Test
-    public void testMakeDeviceRoleChange() throws Exception{
-        roleManagerSpy.makeDeviceRoleChange(OfpRole.BECOMEMASTER, roleContextSpy, true);
-        verify(roleManagerSpy, atLeastOnce()).sendRoleChangeToDevice(Mockito.<OfpRole>any(), Mockito.<RoleContext>any());
-        verify(roleManagerSpy, atLeastOnce()).notifyListenersRoleChangeOnDevice(Mockito.<NodeId>any(), eq(true), Mockito.<OfpRole>any(), eq(true));
+        roleManager.notifyListenersRoleInitializationDone(deviceInfo, true);
+        roleManager.notifyListenersRoleChangeOnDevice(deviceInfo, true, OfpRole.BECOMEMASTER, false);
     }
 
     @Test
     public void testServicesChangeDone() throws Exception {
-        final NodeId nodeId2 = NodeId.getDefaultInstance("openflow:2");
-        roleManagerSpy.setRoleContext(nodeId2, roleContextSpy);
-        roleManagerSpy.servicesChangeDone(nodeId2, true);
+        roleManagerSpy.setRoleContext(deviceInfo2, roleContextSpy);
+        roleManagerSpy.servicesChangeDone(deviceInfo2, true);
         verify(roleContextSpy).unregisterCandidate(Mockito.<Entity>any());
     }
 
     @Test
     public void testServicesChangeDoneContextIsNull() throws Exception {
-        final NodeId nodeId2 = NodeId.getDefaultInstance("openflow:2");
-        roleManagerSpy.setRoleContext(nodeId, roleContextSpy);
-        roleManagerSpy.servicesChangeDone(nodeId2, true);
+        roleManagerSpy.setRoleContext(deviceInfo, roleContextSpy);
+        roleManagerSpy.servicesChangeDone(deviceInfo2, true);
         verify(roleContextSpy, never()).unregisterCandidate(Mockito.<Entity>any());
     }
 }
\ No newline at end of file
index ad31e8000460ff837fc1c8071c27ea7a7a4031a8..1e311581f60bcfcec5a51d5808a02df7c4c4eeb2 100644 (file)
@@ -9,6 +9,7 @@
 package org.opendaylight.openflowplugin.impl.rpc;
 
 import static org.junit.Assert.assertNotNull;
+
 import java.util.concurrent.Future;
 import org.junit.Before;
 import org.junit.Test;
index 18a7942eb808679e8ed786e69b4c04a8c096fba6..bf3a977815ab430758f97b128ed71aedfef73bf5 100644 (file)
@@ -11,6 +11,7 @@ package org.opendaylight.openflowplugin.impl.rpc;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
index f523828cb17d9c76dac987c531dbc1855e352cac..9d982028a88f49c8b6dfae2d0115cdc99cc43537 100644 (file)
@@ -12,6 +12,7 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -21,6 +22,7 @@ import org.mockito.runners.MockitoJUnitRunner;
 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
 import org.opendaylight.openflowplugin.api.openflow.device.XidSequencer;
@@ -58,6 +60,8 @@ public class RpcContextImplTest {
     private NotificationPublishService notificationPublishService;
     @Mock
     private TestRpcService serviceInstance;
+    @Mock
+    private DeviceInfo deviceInfo;
 
     private KeyedInstanceIdentifier<Node, NodeKey> nodeInstanceIdentifier;
 
@@ -67,7 +71,7 @@ public class RpcContextImplTest {
         nodeInstanceIdentifier = InstanceIdentifier.create(Nodes.class).child(Node.class, new NodeKey(nodeId));
 
         when(deviceContext.getDeviceState()).thenReturn(deviceState);
-        when(deviceState.getNodeInstanceIdentifier()).thenReturn(nodeInstanceIdentifier);
+        when(deviceInfo.getNodeInstanceIdentifier()).thenReturn(nodeInstanceIdentifier);
         when(deviceContext.getMessageSpy()).thenReturn(messageSpy);
 
         rpcContext = new RpcContextImpl(rpcProviderRegistry,deviceContext, messageSpy, MAX_REQUESTS,nodeInstanceIdentifier);
index b123dc1e1003ebc9c11bf71889916bf71006db0d..415d443580ff2ec95fafa459a1c29e9437be2890 100644 (file)
@@ -11,6 +11,7 @@ import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+
 import com.google.common.base.VerifyException;
 import java.util.concurrent.ConcurrentMap;
 import org.junit.Before;
@@ -27,6 +28,7 @@ import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderCo
 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;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceInitializationPhaseHandler;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceTerminationPhaseHandler;
@@ -75,7 +77,9 @@ public class RpcManagerImplTest {
     @Mock
     private RpcContext removedContexts;
     @Mock
-    private ConcurrentMap<NodeId, RpcContext> contexts;
+    private ConcurrentMap<DeviceInfo, RpcContext> contexts;
+    @Mock
+    private DeviceInfo deviceInfo;
 
     @Rule
     public ExpectedException expectedException = ExpectedException.none();
@@ -100,58 +104,57 @@ public class RpcManagerImplTest {
         Mockito.when(deviceContext.getPrimaryConnectionContext()).thenReturn(connectionContext);
         Mockito.when(deviceContext.getDeviceState()).thenReturn(deviceState);
         Mockito.when(deviceContext.getItemLifeCycleSourceRegistry()).thenReturn(itemLifeCycleRegistry);
-        Mockito.when(deviceState.getNodeInstanceIdentifier()).thenReturn(nodePath);
-        Mockito.when(deviceState.getFeatures()).thenReturn(featuresOutput);
+        Mockito.when(deviceInfo.getNodeInstanceIdentifier()).thenReturn(nodePath);
         rpcManager.setDeviceTerminationPhaseHandler(deviceTerminationPhaseHandler);
         Mockito.when(connectionContext.getFeatures()).thenReturn(features);
         Mockito.when(deviceContext.getPrimaryConnectionContext()).thenReturn(connectionContext);
         Mockito.when(deviceContext.getDeviceState()).thenReturn(deviceState);
         Mockito.when(deviceContext.getItemLifeCycleSourceRegistry()).thenReturn(itemLifeCycleRegistry);
-        Mockito.when(deviceState.getNodeInstanceIdentifier()).thenReturn(nodePath);
+        Mockito.when(deviceInfo.getNodeInstanceIdentifier()).thenReturn(nodePath);
         Mockito.when(deviceContext.getMessageSpy()).thenReturn(messageSpy);
-        Mockito.when(deviceState.getNodeId()).thenReturn(nodeKey.getId());
+        Mockito.when(deviceInfo.getNodeId()).thenReturn(nodeKey.getId());
         Mockito.when(rpcProviderRegistry.addRoutedRpcImplementation(
                 Matchers.<Class<RpcService>>any(), Matchers.any(RpcService.class)))
                 .thenReturn(routedRpcRegistration);
-        Mockito.when(conductor.getDeviceContext(Mockito.<NodeId>any())).thenReturn(deviceContext);
-        Mockito.when(contexts.remove(nodeId)).thenReturn(removedContexts);
+        Mockito.when(conductor.getDeviceContext(deviceInfo)).thenReturn(deviceContext);
+        Mockito.when(contexts.remove(deviceInfo)).thenReturn(removedContexts);
     }
 
     @Test
     public void onDeviceContextLevelUp() throws Exception {
-        rpcManager.onDeviceContextLevelUp(nodeId);
-        verify(conductor).getDeviceContext(Mockito.<NodeId>any());
+        rpcManager.onDeviceContextLevelUp(deviceInfo);
+        verify(conductor).getDeviceContext(deviceInfo);
     }
 
     @Test
     public void onDeviceContextLevelUpTwice() throws Exception {
-        rpcManager.onDeviceContextLevelUp(nodeId);
+        rpcManager.onDeviceContextLevelUp(deviceInfo);
         expectedException.expect(VerifyException.class);
-        rpcManager.onDeviceContextLevelUp(nodeId);
+        rpcManager.onDeviceContextLevelUp(deviceInfo);
     }
 
     @Test
     public void testOnDeviceContextLevelUpMaster() throws Exception {
-        rpcManager.onDeviceContextLevelUp(nodeId);
-        verify(deviceINitializationPhaseHandler).onDeviceContextLevelUp(nodeId);
+        rpcManager.onDeviceContextLevelUp(deviceInfo);
+        verify(deviceINitializationPhaseHandler).onDeviceContextLevelUp(deviceInfo);
     }
 
     @Test
     public void testOnDeviceContextLevelUpSlave() throws Exception {
-        rpcManager.onDeviceContextLevelUp(nodeId);
-        verify(deviceINitializationPhaseHandler).onDeviceContextLevelUp(nodeId);
+        rpcManager.onDeviceContextLevelUp(deviceInfo);
+        verify(deviceINitializationPhaseHandler).onDeviceContextLevelUp(deviceInfo);
     }
 
     @Test
     public void testOnDeviceContextLevelUpOther() throws Exception {
-        rpcManager.onDeviceContextLevelUp(nodeId);
-        verify(deviceINitializationPhaseHandler).onDeviceContextLevelUp(nodeId);
+        rpcManager.onDeviceContextLevelUp(deviceInfo);
+        verify(deviceINitializationPhaseHandler).onDeviceContextLevelUp(deviceInfo);
     }
 
     @Test
     public void testOnDeviceContextLevelDown() throws Exception {
-        rpcManager.onDeviceContextLevelDown(deviceContext);
-        verify(deviceTerminationPhaseHandler).onDeviceContextLevelDown(deviceContext);
+        rpcManager.onDeviceContextLevelDown(deviceInfo);
+        verify(deviceTerminationPhaseHandler).onDeviceContextLevelDown(deviceInfo);
     }
 
     /**
@@ -159,10 +162,10 @@ public class RpcManagerImplTest {
      */
     @Test
     public void onDeviceContextLevelDown1() {
-        rpcManager.addRecordToContexts(nodeId,removedContexts);
-        rpcManager.onDeviceContextLevelDown(deviceContext);
+        rpcManager.addRecordToContexts(deviceInfo,removedContexts);
+        rpcManager.onDeviceContextLevelDown(deviceInfo);
         verify(removedContexts,times(1)).close();
-        verify(deviceTerminationPhaseHandler,times(1)).onDeviceContextLevelDown(deviceContext);
+        verify(deviceTerminationPhaseHandler,times(1)).onDeviceContextLevelDown(deviceInfo);
     }
 
 
@@ -171,15 +174,15 @@ public class RpcManagerImplTest {
      */
     @Test
     public void onDeviceContextLevelDown2() {
-        rpcManager.onDeviceContextLevelDown(deviceContext);
+        rpcManager.onDeviceContextLevelDown(deviceInfo);
         verify(removedContexts,never()).close();
-        verify(deviceTerminationPhaseHandler,times(1)).onDeviceContextLevelDown(deviceContext);
+        verify(deviceTerminationPhaseHandler,times(1)).onDeviceContextLevelDown(deviceInfo);
 
     }
 
     @Test
     public void close() {
-        rpcManager.addRecordToContexts(nodeId,removedContexts);
+        rpcManager.addRecordToContexts(deviceInfo,removedContexts);
         rpcManager.close();
         verify(removedContexts,atLeastOnce()).close();
     }
index 7b3d80006be936227c5f04bd46dfd577b3a96b4c..ca01864b3624a250a07eca0c712049155af72334 100644 (file)
@@ -2,6 +2,7 @@ package org.opendaylight.openflowplugin.impl.services;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
+
 import com.google.common.util.concurrent.ListenableFuture;
 import java.util.Collection;
 import org.junit.Before;
index 5239335897abfc319efdd9000ddc8f41bf5b1a7a..8916519edd590054bc3119a31156895c452ddeb8 100644 (file)
@@ -51,6 +51,6 @@ public class FlowCapableTransactionServiceImplTest extends ServiceMocking {
 
     private SendBarrierInput buildSendBarrierInput() {
         return new SendBarrierInputBuilder()
-                .setNode(new NodeRef(mockedDeviceState.getNodeInstanceIdentifier())).build();
+                .setNode(new NodeRef(mockedDeviceInfo.getNodeInstanceIdentifier())).build();
     }
 }
\ No newline at end of file
index 756b1ee4371b6cb5a0a85521d5b9823f6100199a..7b3bcd26615e29838ce4bd00e9b56e03f9b68950 100644 (file)
@@ -8,6 +8,7 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
+
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.Futures;
@@ -28,6 +29,7 @@ import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 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;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
 import org.opendaylight.openflowplugin.api.openflow.registry.flow.DeviceFlowRegistry;
@@ -88,6 +90,8 @@ public class MultipartRequestOnTheFlyCallbackTest {
     @Mock
     private DeviceState mockedDeviceState;
     @Mock
+    private DeviceInfo mockedDeviceInfo;
+    @Mock
     private GetFeaturesOutput mocketGetFeaturesOutput;
     @Mock
     private DeviceFlowRegistry mockedFlowRegistry;
@@ -113,15 +117,16 @@ public class MultipartRequestOnTheFlyCallbackTest {
         when(mocketGetFeaturesOutput.getDatapathId()).thenReturn(BigInteger.valueOf(123L));
 
         when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(mockedPrimaryConnection);
-        when(mockedDeviceState.getNodeInstanceIdentifier()).thenReturn(NODE_PATH);
-        when(mockedDeviceState.getFeatures()).thenReturn(mocketGetFeaturesOutput);
+        when(mockedDeviceInfo.getNodeInstanceIdentifier()).thenReturn(NODE_PATH);
         when(mockedDeviceState.deviceSynchronized()).thenReturn(true);
-        when(mockedDeviceState.getNodeId()).thenReturn(mockedNodeId);
+        when(mockedDeviceInfo.getNodeId()).thenReturn(mockedNodeId);
+        when(mockedDeviceInfo.getDatapathId()).thenReturn(BigInteger.TEN);
 
         when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState);
+        when(mockedDeviceContext.getDeviceInfo()).thenReturn(mockedDeviceInfo);
         when(mockedDeviceContext.getDeviceFlowRegistry()).thenReturn(mockedFlowRegistry);
 
-        final InstanceIdentifier<FlowCapableNode> nodePath = mockedDeviceState.getNodeInstanceIdentifier().augmentation(FlowCapableNode.class);
+        final InstanceIdentifier<FlowCapableNode> nodePath = mockedDeviceInfo.getNodeInstanceIdentifier().augmentation(FlowCapableNode.class);
         final FlowCapableNodeBuilder flowNodeBuilder = new FlowCapableNodeBuilder();
         flowNodeBuilder.setTable(Collections.<Table> emptyList());
         final Optional<FlowCapableNode> flowNodeOpt = Optional.of(flowNodeBuilder.build());
@@ -137,7 +142,7 @@ public class MultipartRequestOnTheFlyCallbackTest {
             }
         };
         multipartRequestOnTheFlyCallback = new MultipartRequestOnTheFlyCallback(dummyRequestContext, String.class,
-                mockedDeviceContext.getMessageSpy(),dummyEventIdentifier, mockedDeviceContext.getDeviceState(),
+                mockedDeviceContext.getMessageSpy(),dummyEventIdentifier, mockedDeviceInfo,
                 mockedDeviceContext.getDeviceFlowRegistry(), mockedDeviceContext);
     }
 
@@ -205,7 +210,7 @@ public class MultipartRequestOnTheFlyCallbackTest {
                 .setMultipartReplyBody(multipartReplyFlowCaseBuilder.build())
                 .setXid(21L);
 
-        final InstanceIdentifier<FlowCapableNode> nodePath = mockedDeviceState.getNodeInstanceIdentifier()
+        final InstanceIdentifier<FlowCapableNode> nodePath = mockedDeviceInfo.getNodeInstanceIdentifier()
                 .augmentation(FlowCapableNode.class);
         final FlowCapableNodeBuilder flowNodeBuilder = new FlowCapableNodeBuilder();
         final TableBuilder tableDataBld = new TableBuilder();
index cad3b6968dd0fb9c072b8b0012eddb4e081eea14..7647e5c3367aadadd079c52a0dbd7777d2a1211b 100644 (file)
@@ -79,7 +79,7 @@ public class PacketProcessingServiceImplTest extends ServiceMocking {
     private TransmitPacketInput buildTransmitPacketInput() {
         TransmitPacketInputBuilder transmitPacketInputBld = new TransmitPacketInputBuilder()
                 .setBufferId(OFConstants.OFP_NO_BUFFER)
-                .setNode(new NodeRef(mockedDeviceState.getNodeInstanceIdentifier()))
+                .setNode(new NodeRef(mockedDeviceInfo.getNodeInstanceIdentifier()))
                 .setPayload(ULTIMATE_PAYLOAD.getBytes())
                 .setEgress(new NodeConnectorRef(pathToNodeconnector));
         return transmitPacketInputBld.build();
index 62f00d19ad000a83b90640ffa12b8450dfb92934..af336d62c7ee983f05f4d48dd4c21669865d67db 100644 (file)
@@ -43,7 +43,7 @@ public class SalExperimenterMessageServiceImplTest extends ServiceMocking {
 
     @Override
     protected void setup() {
-        salExperimenterMessageService = new SalExperimenterMessageServiceImpl(mockedRequestContextStack, mockedDeviceContext);
+        salExperimenterMessageService = new SalExperimenterMessageServiceImpl(mockedRequestContextStack, mockedDeviceContext, extensionConverterProvider);
         Mockito.when(mockedDeviceContext.getExtensionConverterProvider()).thenReturn(extensionConverterProvider);
         Mockito.when(extensionConverterProvider.getMessageConverter(Matchers.<TypeVersionKey>any()))
                 .thenReturn(extensionConverter);
@@ -74,7 +74,7 @@ public class SalExperimenterMessageServiceImplTest extends ServiceMocking {
 
     private SendExperimenterInput buildSendExperimenterInput() {
         SendExperimenterInputBuilder sendExperimenterInputBld = new SendExperimenterInputBuilder()
-                .setNode(new NodeRef(mockedDeviceState.getNodeInstanceIdentifier()))
+                .setNode(new NodeRef(mockedDeviceInfo.getNodeInstanceIdentifier()))
                 .setExperimenterMessageOfChoice(new DummyExperimenter());
         return sendExperimenterInputBld.build();
     }
index 3cf72599f8d30a8a62c97fbb72f70289e10788f5..53e422c7c5a84fac01b65d0fea11cdf7b542f502 100644 (file)
@@ -21,6 +21,7 @@ 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;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
@@ -95,6 +96,8 @@ public class SalFlowServiceImplTest extends TestCase {
     @Mock
     private DeviceState mockedDeviceState;
     @Mock
+    private DeviceInfo mockedDeviceInfo;
+    @Mock
     private DeviceFlowRegistry deviceFlowRegistry;
     @Mock
     private GetFeaturesOutput mockedFeaturesOutput;
@@ -119,9 +122,11 @@ public class SalFlowServiceImplTest extends TestCase {
         when(requestContext.getXid()).thenReturn(new Xid(84L));
         when(requestContext.getFuture()).thenReturn(RpcResultBuilder.success().buildFuture());
 
-        when(mockedDeviceState.getNodeInstanceIdentifier()).thenReturn(NODE_II);
-        when(mockedDeviceState.getFeatures()).thenReturn(mockedFeaturesOutput);
+        when(mockedDeviceInfo.getNodeInstanceIdentifier()).thenReturn(NODE_II);
+        when(mockedDeviceInfo.getDatapathId()).thenReturn(DUMMY_DATAPATH_ID);
+        when(mockedDeviceInfo.getVersion()).thenReturn(DUMMY_VERSION);
         when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState);
+        when(mockedDeviceContext.getDeviceInfo()).thenReturn(mockedDeviceInfo);
 
         salFlowService = new SalFlowServiceImpl(mockedRequestContextStack, mockedDeviceContext);
     }
index 61675a940686952d5189923535ac6ce33f7d4e53..0b224bf95191b8e85121def50f5e5df652f3a830 100644 (file)
@@ -4,6 +4,7 @@ import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
+
 import org.junit.Test;
 import org.mockito.Matchers;
 import org.mockito.Mock;
index e30adff06b49d672d06bfc04616fcd9196680f21..e9658b19ec0a17fb9fceb0196cd1920a4bad7c11 100644 (file)
@@ -4,6 +4,7 @@ import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
+
 import org.junit.Test;
 import org.mockito.Matchers;
 import org.mockito.Mock;
index 5f21b80eab864ee71a2a8002a22208c920c11f1a..8b47976735fc92f4be177d2dc5804a630bf2c521 100644 (file)
@@ -3,6 +3,7 @@ package org.opendaylight.openflowplugin.impl.services;
 import static org.mockito.Mockito.verify;
 
 import com.google.common.collect.Lists;
+import java.util.List;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.runners.MockitoJUnitRunner;
@@ -18,7 +19,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.Upda
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.port.update.UpdatedPort;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.port.update.UpdatedPortBuilder;
-import java.util.List;
 
 @RunWith(MockitoJUnitRunner.class)
 public class SalPortServiceImplTest extends ServiceMocking {
index 35c702a5126ee290bd3d5c40c46c890fc29ed9a3..d3041e08abe4f860fd255838b18cd37c610f424e 100644 (file)
@@ -10,6 +10,7 @@ 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 com.google.common.util.concurrent.ListenableFuture;
 import java.math.BigInteger;
 import java.util.concurrent.Future;
@@ -23,6 +24,7 @@ import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
 import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueue;
 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
@@ -76,6 +78,9 @@ public class SalRoleServiceImplTest {
     @Mock
     private DeviceState mockDeviceState;
 
+    @Mock
+    private DeviceInfo mockDeviceInfo;
+
     @Mock
     private GetFeaturesOutput mockFeaturesOutput;
 
@@ -93,10 +98,11 @@ public class SalRoleServiceImplTest {
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
-        Mockito.when(mockDeviceState.getNodeId()).thenReturn(testNodeId);
-        Mockito.when(mockDeviceState.getFeatures()).thenReturn(mockFeaturesOutput);
+        Mockito.when(mockDeviceInfo.getNodeId()).thenReturn(testNodeId);
+        Mockito.when(mockDeviceInfo.getDatapathId()).thenReturn(BigInteger.TEN);
         Mockito.when(mockFeaturesOutput.getVersion()).thenReturn(testVersion);
         Mockito.when(mockDeviceContext.getDeviceState()).thenReturn(mockDeviceState);
+        Mockito.when(mockDeviceContext.getDeviceInfo()).thenReturn(mockDeviceInfo);
         Mockito.when(mockDeviceContext.getPrimaryConnectionContext()).thenReturn(mockConnectionContext);
         Mockito.when(mockConnectionContext.getFeatures()).thenReturn(mockFeaturesReply);
         Mockito.when(mockConnectionContext.getNodeId()).thenReturn(testNodeId);
index d826926f539fa1b4fce479a28c2b779bb7d20d34..63d55df295f394c343e56797889506fd2266d336 100644 (file)
@@ -1,6 +1,7 @@
 package org.opendaylight.openflowplugin.impl.services;
 
 import static org.mockito.Mockito.when;
+
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import java.math.BigInteger;
@@ -14,6 +15,7 @@ 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.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
@@ -64,6 +66,8 @@ public abstract class ServiceMocking {
     @Mock
     protected DeviceState mockedDeviceState;
     @Mock
+    protected DeviceInfo mockedDeviceInfo;
+    @Mock
     protected DeviceInitializationPhaseHandler mockedDevicePhaseHandler;
     @Mock
     protected RequestContext mockedRequestContext;
@@ -88,13 +92,15 @@ public abstract class ServiceMocking {
         when(mockedPrimConnectionContext.getConnectionState()).thenReturn(ConnectionContext.CONNECTION_STATE.WORKING);
         when(mockedPrimConnectionContext.getOutboundQueueProvider()).thenReturn(mockedOutboundQueue);
 
-        when(mockedDeviceState.getNodeInstanceIdentifier()).thenReturn(NODE_II);
-        when(mockedDeviceState.getFeatures()).thenReturn(mockedFeaturesOutput);
+        when(mockedDeviceInfo.getNodeInstanceIdentifier()).thenReturn(NODE_II);
+        when(mockedDeviceInfo.getDatapathId()).thenReturn(DUMMY_DATAPATH_ID);
+        when(mockedDeviceInfo.getVersion()).thenReturn(DUMMY_VERSION);
 
         when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(mockedPrimConnectionContext);
         when(mockedDeviceContext.getMessageSpy()).thenReturn(mockedMessagSpy);
         when(mockedDeviceContext.getDeviceFlowRegistry()).thenReturn(new DeviceFlowRegistryImpl());
         when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState);
+        when(mockedDeviceContext.getDeviceInfo()).thenReturn(mockedDeviceInfo);
         when(mockedDeviceContext.getMultiMsgCollector(Matchers.<RequestContext<List<MultipartReply>>>any())).thenReturn(multiMessageCollector);
 
         setup();
index b5087063d2d7da9b66ee32e2be73d976ccb055bb..7e2c5a9257705a448ec154696d51f9cc9e236d0b 100644 (file)
@@ -4,6 +4,7 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
+
 import com.google.common.collect.Lists;
 import java.math.BigInteger;
 import java.util.Collections;
index bce92039e282e2d7942734dcb955d89693989bd7..f94d43f7e73cdf5c4cddff3b91e2dde3311b83b3 100644 (file)
@@ -14,11 +14,12 @@ package org.opendaylight.openflowplugin.impl.statistics;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import java.math.BigInteger;
 import org.junit.Before;
-import org.mockito.Mockito;
 import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueue;
 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceManager;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleConductor;
@@ -30,7 +31,6 @@ 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.openflow.protocol.rev130731.FeaturesReply;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 
@@ -49,6 +49,7 @@ class StatisticsContextImpMockInitiation {
     StatisticsGatheringService mockedStatisticsGatheringService;
     StatisticsGatheringOnTheFlyService mockedStatisticsOnFlyGatheringService;
     ConnectionContext mockedConnectionContext;
+    DeviceInfo mockedDeviceInfo;
 
     static final KeyedInstanceIdentifier<Node, NodeKey> dummyNodeII = InstanceIdentifier.create(Nodes.class)
             .child(Node.class, new NodeKey(new NodeId("dummyNodeId")));
@@ -62,36 +63,42 @@ class StatisticsContextImpMockInitiation {
         mockedStatisticsOnFlyGatheringService = mock(StatisticsGatheringOnTheFlyService.class);
         mockedConnectionContext = mock(ConnectionContext.class);
         mockedDeviceState = mock(DeviceState.class);
+        mockedDeviceInfo = mock(DeviceInfo.class);
 
         final FeaturesReply mockedFeatures = mock(FeaturesReply.class);
         final MessageSpy mockedMessageSpy = mock(MessageSpy.class);
         final OutboundQueue mockedOutboundQueue = mock(OutboundQueue.class);
         final DeviceManager mockedDeviceManager = mock(DeviceManager.class);
-        final GetFeaturesOutput mockedFeaturesOutput = mock(GetFeaturesOutput.class);
 
         mockConductor = mock(LifecycleConductor.class);
 
+        when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState);
+        when(mockedDeviceContext.getDeviceInfo()).thenReturn(mockedDeviceInfo);
+        when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(mockedConnectionContext);
+        when(mockedDeviceContext.getMessageSpy()).thenReturn(mockedMessageSpy);
+
         when(mockedDeviceState.isTableStatisticsAvailable()).thenReturn(isTable);
         when(mockedDeviceState.isFlowStatisticsAvailable()).thenReturn(isFlow);
         when(mockedDeviceState.isGroupAvailable()).thenReturn(isGroup);
         when(mockedDeviceState.isMetersAvailable()).thenReturn(isMeter);
         when(mockedDeviceState.isPortStatisticsAvailable()).thenReturn(isPort);
         when(mockedDeviceState.isQueueStatisticsAvailable()).thenReturn(isQueue);
-        when(mockedDeviceState.getNodeInstanceIdentifier()).thenReturn(dummyNodeII);
-        when(mockedDeviceState.getFeatures()).thenReturn(mockedFeaturesOutput);
+        when(mockedDeviceInfo.getNodeInstanceIdentifier()).thenReturn(dummyNodeII);
+        when(mockedDeviceInfo.getDatapathId()).thenReturn(BigInteger.TEN);
 
         when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState);
+        when(mockedDeviceContext.getDeviceInfo()).thenReturn(mockedDeviceInfo);
         when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(mockedConnectionContext);
         when(mockedDeviceContext.getMessageSpy()).thenReturn(mockedMessageSpy);
+        when(mockedDeviceInfo.getNodeId()).thenReturn(dummyNodeII.getKey().getId());
 
         when(mockedConnectionContext.getNodeId()).thenReturn(dummyNodeII.getKey().getId());
         when(mockedConnectionContext.getFeatures()).thenReturn(mockedFeatures);
         when(mockedConnectionContext.getConnectionState()).thenReturn(ConnectionContext.CONNECTION_STATE.WORKING);
         when(mockedConnectionContext.getOutboundQueueProvider()).thenReturn(mockedOutboundQueue);
 
-        when(mockedDeviceManager.getDeviceContextFromNodeId(Mockito.<NodeId>any())).thenReturn(mockedDeviceContext);
-        mockConductor.setSafelyDeviceManager(mockedDeviceManager);
-        when(mockConductor.getDeviceContext(Mockito.<NodeId>any())).thenReturn(mockedDeviceContext);
+        mockConductor.setSafelyManager(mockedDeviceManager);
+        when(mockConductor.getDeviceContext(mockedDeviceInfo)).thenReturn(mockedDeviceContext);
 
     }
 }
index 31e74a8b3fcda53964d772d6cd393f1b0b3d7085..c88578b1d83d114ef2cab1dc3048eb468ba4d36e 100644 (file)
@@ -16,6 +16,7 @@ import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.when;
+
 import com.google.common.util.concurrent.ListenableFuture;
 import java.util.Arrays;
 import java.util.Collections;
@@ -64,7 +65,7 @@ public class StatisticsContextImplParamTest extends StatisticsContextImpMockInit
     public void gatherDynamicDataTest() {
 
 
-        final StatisticsContextImpl statisticsContext = new StatisticsContextImpl(mockedDeviceContext.getDeviceState().getNodeId(), false, mockConductor);
+        final StatisticsContextImpl statisticsContext = new StatisticsContextImpl(mockedDeviceInfo, false, mockConductor);
 
         final ListenableFuture<RpcResult<List<MultipartReply>>> rpcResult = immediateFuture(RpcResultBuilder.success(Collections.<MultipartReply>emptyList()).build());
         when(mockedStatisticsGatheringService.getStatisticsOfType(any(EventIdentifier.class), any(MultipartType
index 05cd073993a75c3e41d917ab122b48574183a81c..7d813b0e18d0f9490390601b343eb8c87ca0086d 100644 (file)
@@ -13,7 +13,6 @@ package org.opendaylight.openflowplugin.impl.statistics;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -32,9 +31,7 @@ import org.mockito.runners.MockitoJUnitRunner;
 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
-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.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
@@ -52,12 +49,12 @@ public class StatisticsContextImplTest extends StatisticsContextImpMockInitiatio
     @Before
     public void setUp() throws Exception {
         when(mockedDeviceContext.reserveXidForDeviceMessage()).thenReturn(TEST_XID);
-        when(mockConductor.getDeviceContext(Mockito.<NodeId>any())).thenReturn(mockedDeviceContext);
+        when(mockConductor.getDeviceContext(mockedDeviceInfo)).thenReturn(mockedDeviceContext);
         initStatisticsContext();
     }
 
     private void initStatisticsContext() {
-        statisticsContext = new StatisticsContextImpl(mockedDeviceContext.getDeviceState().getNodeId(), false, mockConductor);
+        statisticsContext = new StatisticsContextImpl(mockedDeviceInfo, false, mockConductor);
         statisticsContext.setStatisticsGatheringService(mockedStatisticsGatheringService);
         statisticsContext.setStatisticsGatheringOnTheFlyService(mockedStatisticsOnFlyGatheringService);
     }
@@ -75,7 +72,7 @@ public class StatisticsContextImplTest extends StatisticsContextImpMockInitiatio
      */
     @Test
     public void testClose() throws Exception {
-        final StatisticsContextImpl statisticsContext = new StatisticsContextImpl(mockedDeviceContext.getDeviceState().getNodeId(), false, mockConductor);
+        final StatisticsContextImpl statisticsContext = new StatisticsContextImpl(mockedDeviceInfo, false, mockConductor);
         final RequestContext<Object> requestContext = statisticsContext.createRequestContext();
         statisticsContext.close();
         try {
@@ -100,14 +97,13 @@ public class StatisticsContextImplTest extends StatisticsContextImpMockInitiatio
     @Test
     public void testGatherDynamicData_all() throws Exception {
         Mockito.reset(mockedDeviceState);
-        when(mockedDeviceState.getFeatures()).thenReturn(mock(GetFeaturesOutput.class));
         when(mockedDeviceState.isTableStatisticsAvailable()).thenReturn(Boolean.TRUE);
         when(mockedDeviceState.isFlowStatisticsAvailable()).thenReturn(Boolean.TRUE);
         when(mockedDeviceState.isGroupAvailable()).thenReturn(Boolean.TRUE);
         when(mockedDeviceState.isMetersAvailable()).thenReturn(Boolean.TRUE);
         when(mockedDeviceState.isPortStatisticsAvailable()).thenReturn(Boolean.TRUE);
         when(mockedDeviceState.isQueueStatisticsAvailable()).thenReturn(Boolean.TRUE);
-        when(mockedDeviceState.getNodeInstanceIdentifier()).thenReturn(dummyNodeII);
+        when(mockedDeviceInfo.getNodeInstanceIdentifier()).thenReturn(dummyNodeII);
         initStatisticsContext();
 
         when(mockedStatisticsGatheringService.getStatisticsOfType(Matchers.any(EventIdentifier.class), Matchers.any(MultipartType.class)))
index b1c389eca913baf3743cfd57f16c42968dfcbf64..64fa767cca3a2022ea6aab3f114f84ff0cc35219 100644 (file)
@@ -13,6 +13,7 @@ package org.opendaylight.openflowplugin.impl.statistics;
 
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
+
 import com.google.common.base.Optional;
 import com.google.common.collect.Lists;
 import com.google.common.util.concurrent.CheckedFuture;
@@ -40,7 +41,9 @@ import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 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;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
+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.FlowRegistryKey;
 import org.opendaylight.openflowplugin.api.openflow.registry.group.DeviceGroupRegistry;
@@ -136,8 +139,8 @@ import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 @RunWith(MockitoJUnitRunner.class)
 public class StatisticsGatheringUtilsTest {
 
-    public static final String DUMMY_NODE_ID_VALUE = "1";
-    public static final NodeId DUMMY_NODE_ID = new NodeId(DUMMY_NODE_ID_VALUE);
+    static final String DUMMY_NODE_ID_VALUE = "1";
+    static final NodeId DUMMY_NODE_ID = new NodeId(DUMMY_NODE_ID_VALUE);
 
     private final KeyedInstanceIdentifier<Node, NodeKey> dummyNodePath = InstanceIdentifier.create(Nodes.class)
             .child(Node.class, new NodeKey(DUMMY_NODE_ID));
@@ -159,6 +162,10 @@ public class StatisticsGatheringUtilsTest {
     private ConnectionContext connectionAdapter;
     @Mock
     private StatisticsGatherer statisticsService;
+    @Mock
+    private DeviceInfo deviceInfo;
+    @Mock
+    private TxFacade txFacade;
 
     public StatisticsGatheringUtilsTest() {
         OpenflowPortsUtil.init();
@@ -167,19 +174,22 @@ public class StatisticsGatheringUtilsTest {
     @Before
     public void setUp() throws Exception {
         when(deviceContext.getDeviceState()).thenReturn(deviceState);
+        when(deviceContext.getDeviceInfo()).thenReturn(deviceInfo);
         when(deviceContext.getDeviceFlowRegistry()).thenReturn(deviceFlowRegistry);
         when(deviceContext.getDeviceGroupRegistry()).thenReturn(deviceGroupRegistry);
         when(deviceContext.getDeviceMeterRegistry()).thenReturn(deviceMeterRegistry);
         when(deviceContext.getReadTransaction()).thenReturn(readTx);
+        when(txFacade.getReadTransaction()).thenReturn(readTx);
         when(deviceContext.getPrimaryConnectionContext()).thenReturn(connectionAdapter);
         when(connectionAdapter.getNodeId()).thenReturn(DUMMY_NODE_ID);
-        when(deviceState.getFeatures()).thenReturn(features);
         when(connectionAdapter.getFeatures()).thenReturn(features);
-
-        when(features.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
         when(features.getDatapathId()).thenReturn(BigInteger.ONE);
+        when(features.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
 
-        when(deviceState.getNodeInstanceIdentifier()).thenReturn(dummyNodePath);
+        when(deviceInfo.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
+        when(deviceInfo.getDatapathId()).thenReturn(BigInteger.ONE);
+        when(deviceInfo.getNodeInstanceIdentifier()).thenReturn(dummyNodePath);
+        when(deviceInfo.getNodeId()).thenReturn(DUMMY_NODE_ID);
     }
 
     @After
@@ -194,7 +204,7 @@ public class StatisticsGatheringUtilsTest {
         final ArgumentCaptor<Flow> flow = ArgumentCaptor.forClass(Flow.class);
 
         StatisticsGatheringUtils.writeFlowStatistics(prepareFlowStatisticsData(),
-                deviceContext.getDeviceState(), deviceContext.getDeviceFlowRegistry(), deviceContext);
+                deviceInfo, deviceContext.getDeviceFlowRegistry(), deviceContext);
 
         Mockito.verify(deviceContext).writeToTransaction(
                 dataStoreType.capture(), flowPath.capture(), flow.capture());
@@ -243,7 +253,7 @@ public class StatisticsGatheringUtilsTest {
                 .child(Group.class, new GroupKey(new org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId(groupIdValue)))
                 .augmentation(NodeGroupStatistics.class)
                 .child(GroupStatistics.class);
-        verify(deviceContext).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL),
+        verify(txFacade).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL),
                 Matchers.eq(groupPath), Matchers.any(GroupStatistics.class));
     }
 
@@ -274,7 +284,7 @@ public class StatisticsGatheringUtilsTest {
         verify(deviceContext, Mockito.never()).addDeleteToTxChain(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.<InstanceIdentifier<?>> any());
         verify(deviceGroupRegistry).removeMarked();
         verify(deviceGroupRegistry).store(storedGroupId);
-        verify(deviceContext).writeToTransaction(
+        verify(txFacade).writeToTransaction(
                 Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.eq(groupPath), Matchers.any(Group.class));
     }
 
@@ -308,7 +318,7 @@ public class StatisticsGatheringUtilsTest {
                 .child(Meter.class, new MeterKey(new org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId(meterIdValue)))
                 .augmentation(NodeMeterStatistics.class)
                 .child(MeterStatistics.class);
-        verify(deviceContext).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL),
+        verify(txFacade).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL),
                 Matchers.eq(meterPath), Matchers.any(MeterStatistics.class));
     }
 
@@ -332,7 +342,7 @@ public class StatisticsGatheringUtilsTest {
                 .child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId("openflow:" + DUMMY_NODE_ID_VALUE + ":11")))
                 .augmentation(FlowCapableNodeConnectorStatisticsData.class)
                 .child(FlowCapableNodeConnectorStatistics.class);
-        verify(deviceContext).writeToTransaction(
+        verify(txFacade).writeToTransaction(
                 Matchers.eq(LogicalDatastoreType.OPERATIONAL),
                 Matchers.eq(portPath),
                 Matchers.any(FlowCapableNodeConnectorStatistics.class));
@@ -362,7 +372,7 @@ public class StatisticsGatheringUtilsTest {
                 .child(Table.class, new TableKey((short) 0))
                 .augmentation(FlowTableStatisticsData.class)
                 .child(FlowTableStatistics.class);
-        verify(deviceContext).writeToTransaction(
+        verify(txFacade).writeToTransaction(
                 Matchers.eq(LogicalDatastoreType.OPERATIONAL),
                 Matchers.eq(tablePath),
                 Matchers.any(FlowTableStatistics.class));
@@ -396,7 +406,7 @@ public class StatisticsGatheringUtilsTest {
                 .child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId("openflow:" + DUMMY_NODE_ID_VALUE + ":11")))
                 .augmentation(FlowCapableNodeConnector.class)
                 .child(Queue.class, new QueueKey(new QueueId(queueIdValue)));
-        verify(deviceContext).writeToTransaction(
+        verify(txFacade).writeToTransaction(
                 Matchers.eq(LogicalDatastoreType.OPERATIONAL),
                 Matchers.eq(queuePath),
                 Matchers.any(Queue.class));
@@ -404,10 +414,20 @@ public class StatisticsGatheringUtilsTest {
 
     @Test
     public void testGatherStatistics_flow() throws Exception {
+        final short tableId = 0;
         final MultipartType type = MultipartType.OFPMPFLOW;
         when(deviceFlowRegistry.storeIfNecessary(Matchers.any(FlowRegistryKey.class), Matchers.anyShort()))
                 .thenReturn(new FlowId("openflow:21"));
 
+        final InstanceIdentifier<FlowCapableNode> nodePath = deviceInfo.getNodeInstanceIdentifier().augmentation(FlowCapableNode.class);
+        final TableBuilder tableDataBld = new TableBuilder();
+        tableDataBld.setId(tableId);
+        final FlowCapableNodeBuilder flowNodeBuilder = new FlowCapableNodeBuilder();
+        flowNodeBuilder.setTable(Collections.singletonList(tableDataBld.build()));
+        final Optional<FlowCapableNode> flowNodeOpt = Optional.of(flowNodeBuilder.build());
+        final CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> flowNodeFuture = Futures.immediateCheckedFuture(flowNodeOpt);
+        when(readTx.read(LogicalDatastoreType.OPERATIONAL, nodePath)).thenReturn(flowNodeFuture);
+
         final org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.MatchBuilder matchBld =
                 new org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.MatchBuilder()
                         .setMatchEntry(Collections.<MatchEntry>emptyList());
@@ -437,7 +457,7 @@ public class StatisticsGatheringUtilsTest {
                 .child(Flow.class, new FlowKey(new FlowId("openflow:21")));
         verify(deviceContext, Mockito.never()).addDeleteToTxChain(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.<InstanceIdentifier<?>>any());
         verify(deviceFlowRegistry).storeIfNecessary(FlowRegistryKeyFactory.create(flowBld.build()), (short) 0);
-        verify(deviceContext).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.eq(flowPath), Matchers.any(Flow.class));
+        verify(txFacade).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.eq(flowPath), Matchers.any(Flow.class));
     }
 
     @Test
@@ -466,16 +486,22 @@ public class StatisticsGatheringUtilsTest {
                 .child(Meter.class, new MeterKey(meterId));
         verify(deviceContext, Mockito.never()).addDeleteToTxChain(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.<InstanceIdentifier<?>>any());
         verify(deviceMeterRegistry).store(meterId);
-        verify(deviceContext).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.eq(meterPath), Matchers.any(Meter.class));
+        verify(txFacade).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.eq(meterPath), Matchers.any(Meter.class));
     }
 
     private void fireAndCheck(final MultipartType type, final List<MultipartReply> statsData) throws InterruptedException, ExecutionException, TimeoutException {
         when(statisticsService.getStatisticsOfType(Matchers.any(EventIdentifier.class), Matchers.eq(type)))
                 .thenReturn(Futures.immediateFuture(RpcResultBuilder.success(statsData).build()));
 
-        final ListenableFuture<Boolean> gatherStatisticsResult = StatisticsGatheringUtils.gatherStatistics(statisticsService, deviceContext, type);
+        final ListenableFuture<Boolean> gatherStatisticsResult = StatisticsGatheringUtils.gatherStatistics(
+                statisticsService,
+                deviceInfo,
+                type,
+                txFacade,
+                deviceContext,
+                false);
         Assert.assertTrue(gatherStatisticsResult.get(1, TimeUnit.SECONDS).booleanValue());
-        verify(deviceContext).submitTransaction();
+        verify(txFacade).submitTransaction();
     }
 
     private static MultipartReplyMessage assembleMPReplyMessage(final MultipartType type, final MultipartReplyBody mpReplyGroupCaseBld) {
@@ -491,19 +517,11 @@ public class StatisticsGatheringUtilsTest {
         return new BucketStatsBuilder().setByteCount(BigInteger.valueOf(byteCount)).setPacketCount(BigInteger.valueOf(packetCount)).build();
     }
 
-    @Test
-    public void testDeleteAllKnownFlowsNotSync() throws Exception {
-        when(deviceState.deviceSynchronized()).thenReturn(false);
-        StatisticsGatheringUtils.deleteAllKnownFlows(deviceContext.getDeviceState(),
-                deviceContext.getDeviceFlowRegistry(), deviceContext);
-        Mockito.verifyNoMoreInteractions(deviceFlowRegistry);
-    }
-
     @Test
     public void testDeleteAllKnownFlows() throws Exception {
         final short tableId = 0;
         when(deviceState.deviceSynchronized()).thenReturn(true);
-        final InstanceIdentifier<FlowCapableNode> nodePath = deviceState.getNodeInstanceIdentifier().augmentation(FlowCapableNode.class);
+        final InstanceIdentifier<FlowCapableNode> nodePath = deviceInfo.getNodeInstanceIdentifier().augmentation(FlowCapableNode.class);
         final TableBuilder tableDataBld = new TableBuilder();
         tableDataBld.setId(tableId);
         final FlowCapableNodeBuilder flowNodeBuilder = new FlowCapableNodeBuilder();
@@ -511,13 +529,13 @@ public class StatisticsGatheringUtilsTest {
         final Optional<FlowCapableNode> flowNodeOpt = Optional.of(flowNodeBuilder.build());
         final CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> flowNodeFuture = Futures.immediateCheckedFuture(flowNodeOpt);
         when(readTx.read(LogicalDatastoreType.OPERATIONAL, nodePath)).thenReturn(flowNodeFuture);
-        final KeyedInstanceIdentifier<Table, TableKey> tablePath = deviceState.getNodeInstanceIdentifier()
+        final KeyedInstanceIdentifier<Table, TableKey> tablePath = deviceInfo.getNodeInstanceIdentifier()
                 .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(tableId));
 
-        StatisticsGatheringUtils.deleteAllKnownFlows(deviceContext.getDeviceState(),
-                deviceContext.getDeviceFlowRegistry(), deviceContext);
+        StatisticsGatheringUtils.deleteAllKnownFlows(deviceInfo,
+                deviceContext.getDeviceFlowRegistry(), txFacade);
 
-        verify(deviceContext).writeToTransaction(
+        verify(txFacade).writeToTransaction(
                 LogicalDatastoreType.OPERATIONAL,
                 tablePath,
                 tableDataBld.setFlow(Collections.<Flow>emptyList()).build());
index b558ae343eea461fe50d7ad33129c8b68762e96b..24e040cd300e75b6208857a0611dac6e24a18510 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.openflowplugin.impl.statistics;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
-import com.google.common.base.Optional;
+
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import io.netty.util.HashedWheelTimer;
@@ -20,6 +20,8 @@ import java.math.BigInteger;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import org.junit.Assert;
 import org.junit.Before;
@@ -40,6 +42,7 @@ 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;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceManager;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
@@ -81,6 +84,7 @@ public class StatisticsManagerImplTest {
 
     private static final BigInteger DUMMY_DATAPATH_ID = new BigInteger("444");
     private static final Short DUMMY_VERSION = OFConstants.OFP_VERSION_1_3;
+    public static final NodeId NODE_ID = new NodeId("ofp-unit-dummy-node-id");
 
     @Mock
     RequestContextStack mockedRequestContextStack;
@@ -99,6 +103,8 @@ public class StatisticsManagerImplTest {
     @Mock
     DeviceState mockedDeviceState;
     @Mock
+    DeviceInfo mockedDeviceInfo;
+    @Mock
     DeviceInitializationPhaseHandler mockedDevicePhaseHandler;
     @Mock
     DeviceTerminationPhaseHandler mockedTerminationPhaseHandler;
@@ -124,6 +130,8 @@ public class StatisticsManagerImplTest {
     private GetFeaturesOutput featuresOutput;
     @Mock
     private DeviceInitializationPhaseHandler deviceInitializationPhaseHandler;
+    @Mock
+    private DeviceInfo deviceInfo;
 
     private RequestContext<List<MultipartReply>> currentRequestContext;
     private StatisticsManagerImpl statisticsManager;
@@ -135,15 +143,10 @@ public class StatisticsManagerImplTest {
                 .create(Nodes.class)
                 .child(Node.class, new NodeKey(new NodeId("openflow:10")));
 
-        when(mockedFeatures.getDatapathId()).thenReturn(DUMMY_DATAPATH_ID);
-        when(mockedFeatures.getVersion()).thenReturn(DUMMY_VERSION);
-        when(mockedFeaturesOutput.getDatapathId()).thenReturn(DUMMY_DATAPATH_ID);
-        when(mockedFeaturesOutput.getVersion()).thenReturn(DUMMY_VERSION);
-
         when(mockedPrimConnectionContext.getFeatures()).thenReturn(mockedFeatures);
         when(mockedPrimConnectionContext.getConnectionAdapter()).thenReturn(mockedConnectionAdapter);
         when(mockedPrimConnectionContext.getConnectionState()).thenReturn(ConnectionContext.CONNECTION_STATE.WORKING);
-        when(mockedPrimConnectionContext.getNodeId()).thenReturn(new NodeId("ut-node:123"));
+        when(mockedPrimConnectionContext.getNodeId()).thenReturn(NODE_ID);
         when(mockedPrimConnectionContext.getOutboundQueueProvider()).thenReturn(outboundQueue);
 
         when(mockedDeviceState.isFlowStatisticsAvailable()).thenReturn(Boolean.TRUE);
@@ -152,11 +155,11 @@ public class StatisticsManagerImplTest {
         when(mockedDeviceState.isPortStatisticsAvailable()).thenReturn(Boolean.TRUE);
         when(mockedDeviceState.isQueueStatisticsAvailable()).thenReturn(Boolean.TRUE);
         when(mockedDeviceState.isTableStatisticsAvailable()).thenReturn(Boolean.TRUE);
-        when(mockedDeviceState.getFeatures()).thenReturn(featuresOutput);
-        when(mockedDeviceState.getNodeInstanceIdentifier()).thenReturn(nodePath);
-
-        when(mockedDeviceState.getNodeId()).thenReturn(new NodeId("ofp-unit-dummy-node-id"));
+        when(mockedDeviceInfo.getNodeInstanceIdentifier()).thenReturn(nodePath);
+        when(mockedDeviceInfo.getDatapathId()).thenReturn(BigInteger.TEN);
+        when(mockedDeviceInfo.getNodeId()).thenReturn(new NodeId("ofp-unit-dummy-node-id"));
 
+        when(mockedDeviceContext.getDeviceInfo()).thenReturn(mockedDeviceInfo);
         when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(mockedPrimConnectionContext);
         when(mockedDeviceContext.getMessageSpy()).thenReturn(mockedMessagSpy);
         when(mockedDeviceContext.getDeviceFlowRegistry()).thenReturn(new DeviceFlowRegistryImpl());
@@ -178,8 +181,7 @@ public class StatisticsManagerImplTest {
 
         statisticsManager = new StatisticsManagerImpl(rpcProviderRegistry, false, conductor);
         statisticsManager.setDeviceInitializationPhaseHandler(deviceInitializationPhaseHandler);
-        when(deviceManager.getDeviceContextFromNodeId(Mockito.<NodeId>any())).thenReturn(mockedDeviceContext);
-        when(conductor.getDeviceContext(Mockito.<NodeId>any())).thenReturn(mockedDeviceContext);
+        when(conductor.getDeviceContext(deviceInfo)).thenReturn(mockedDeviceContext);
     }
 
     @Test
@@ -197,32 +199,32 @@ public class StatisticsManagerImplTest {
                 .commitEntry(Matchers.anyLong(), Matchers.<OfHeader>any(), Matchers.<FutureCallback<OfHeader>>any());
 
         statisticsManager.setDeviceInitializationPhaseHandler(mockedDevicePhaseHandler);
-        statisticsManager.onDeviceContextLevelUp(mockedDeviceContext.getDeviceState().getNodeId());
-        verify(mockedDevicePhaseHandler).onDeviceContextLevelUp(mockedDeviceContext.getDeviceState().getNodeId());
+        statisticsManager.onDeviceContextLevelUp(deviceInfo);
+        verify(mockedDevicePhaseHandler).onDeviceContextLevelUp(deviceInfo);
     }
 
     @Test
     public void testOnDeviceContextClosed() throws Exception {
         final StatisticsContext statisticContext = Mockito.mock(StatisticsContext.class);
-        final Map<NodeId, StatisticsContext> contextsMap = getContextsMap(statisticsManager);
+        final Map<DeviceInfo, StatisticsContext> contextsMap = getContextsMap(statisticsManager);
 
-        contextsMap.put(mockedDeviceContext.getDeviceState().getNodeId(), statisticContext);
+        contextsMap.put(deviceInfo, statisticContext);
         Assert.assertEquals(1, contextsMap.size());
 
         statisticsManager.setDeviceTerminationPhaseHandler(mockedTerminationPhaseHandler);
-        statisticsManager.onDeviceContextLevelDown(mockedDeviceContext);
+        statisticsManager.onDeviceContextLevelDown(deviceInfo);
         verify(statisticContext).close();
-        verify(mockedTerminationPhaseHandler).onDeviceContextLevelDown(mockedDeviceContext);
+        verify(mockedTerminationPhaseHandler).onDeviceContextLevelDown(deviceInfo);
         Assert.assertEquals(0, contextsMap.size());
     }
 
-    private static Map<NodeId, StatisticsContext> getContextsMap(final StatisticsManagerImpl statisticsManager)
+    private static Map<DeviceInfo, StatisticsContext> getContextsMap(final StatisticsManagerImpl statisticsManager)
             throws NoSuchFieldException, IllegalAccessException {
         // HACK: contexts map for testing shall be accessed in some more civilized way
         final Field contextsField = StatisticsManagerImpl.class.getDeclaredField("contexts");
         Assert.assertNotNull(contextsField);
         contextsField.setAccessible(true);
-        return (Map<NodeId, StatisticsContext>) contextsField.get(statisticsManager);
+        return (Map<DeviceInfo, StatisticsContext>) contextsField.get(statisticsManager);
     }
 
     @Test
@@ -242,13 +244,12 @@ public class StatisticsManagerImplTest {
     @Test
     public void testChangeStatisticsWorkMode1() throws Exception {
         final StatisticsContext statisticContext = Mockito.mock(StatisticsContext.class);
-        when(statisticContext.getDeviceContext()).thenReturn(mockedDeviceContext);
         when(statisticContext.getPollTimeout()).thenReturn(
-                Optional.<Timeout>absent());
+                Optional.<Timeout>empty());
         when(itemLifeCycleRegistry.getLifeCycleSources()).thenReturn(
                 Collections.<ItemLifeCycleSource>emptyList());
 
-        getContextsMap(statisticsManager).put(mockedDeviceContext.getDeviceState().getNodeId(), statisticContext);
+        getContextsMap(statisticsManager).put(deviceInfo, statisticContext);
 
         final ChangeStatisticsWorkModeInputBuilder changeStatisticsWorkModeInputBld =
                 new ChangeStatisticsWorkModeInputBuilder()
@@ -262,7 +263,7 @@ public class StatisticsManagerImplTest {
         Mockito.verify(statisticContext).getPollTimeout();
     }
 
-    private static void checkWorkModeChangeOutcome(Future<RpcResult<Void>> workMode) throws InterruptedException, java.util.concurrent.ExecutionException {
+    private static void checkWorkModeChangeOutcome(Future<RpcResult<Void>> workMode) throws InterruptedException, ExecutionException {
         Assert.assertTrue(workMode.isDone());
         Assert.assertTrue(workMode.get().isSuccessful());
     }
@@ -278,13 +279,12 @@ public class StatisticsManagerImplTest {
         final Timeout pollTimeout = Mockito.mock(Timeout.class);
         final ItemLifeCycleSource itemLifecycleSource = Mockito.mock(ItemLifeCycleSource.class);
         final StatisticsContext statisticContext = Mockito.mock(StatisticsContext.class);
-        when(statisticContext.getDeviceContext()).thenReturn(mockedDeviceContext);
         when(statisticContext.getPollTimeout()).thenReturn(
                 Optional.of(pollTimeout));
         when(itemLifeCycleRegistry.getLifeCycleSources()).thenReturn(
                 Collections.singletonList(itemLifecycleSource));
 
-        getContextsMap(statisticsManager).put(mockedDeviceContext.getDeviceState().getNodeId(), statisticContext);
+        getContextsMap(statisticsManager).put(deviceInfo, statisticContext);
 
         final ChangeStatisticsWorkModeInputBuilder changeStatisticsWorkModeInputBld =
                 new ChangeStatisticsWorkModeInputBuilder()
@@ -313,7 +313,6 @@ public class StatisticsManagerImplTest {
                 .setItemLifecycleListener(itemLifeCycleListenerCapt.capture());
 
         final StatisticsContext statisticContext = Mockito.mock(StatisticsContext.class);
-        when(statisticContext.getDeviceContext()).thenReturn(mockedDeviceContext);
         when(statisticContext.getPollTimeout()).thenReturn(
                 Optional.of(pollTimeout));
         when(statisticContext.getItemLifeCycleListener()).thenReturn(
@@ -321,7 +320,7 @@ public class StatisticsManagerImplTest {
         when(itemLifeCycleRegistry.getLifeCycleSources()).thenReturn(
                 Collections.singletonList(itemLifecycleSource));
 
-        getContextsMap(statisticsManager).put(mockedDeviceContext.getDeviceState().getNodeId(), statisticContext);
+        getContextsMap(statisticsManager).put(deviceInfo, statisticContext);
 
         final ChangeStatisticsWorkModeInputBuilder changeStatisticsWorkModeInputBld =
                 new ChangeStatisticsWorkModeInputBuilder()
@@ -356,7 +355,7 @@ public class StatisticsManagerImplTest {
     @Test
     public void testCalculateTimerDelay() throws Exception {
         final TimeCounter timeCounter = Mockito.mock(TimeCounter.class);
-        when(timeCounter.getAverageTimeBetweenMarks()).thenReturn((Long)2000L, (Long)4000L);
+        when(timeCounter.getAverageTimeBetweenMarks()).thenReturn(2000L, (Long)4000L);
 
         statisticsManager.calculateTimerDelay(timeCounter);
         Assert.assertEquals(3000L, StatisticsManagerImpl.getCurrentTimerDelay());
@@ -369,25 +368,23 @@ public class StatisticsManagerImplTest {
         final StatisticsContext statisticsContext = Mockito.mock(StatisticsContext.class);
         final TimeCounter mockTimerCounter = Mockito.mock(TimeCounter.class);
 
-        statisticsManager.pollStatistics(mockedDeviceContext, statisticsContext, mockTimerCounter);
+        statisticsManager.pollStatistics(mockedDeviceContext.getDeviceState(), statisticsContext, mockTimerCounter, mockedDeviceInfo);
         verify(mockedDeviceContext).getDeviceState();
 
         when(mockedDeviceContext.getDeviceState().isValid()).thenReturn(true);
-        statisticsManager.pollStatistics(mockedDeviceContext, statisticsContext, mockTimerCounter);
-        // TODO Make scheduleNextPolling visible for tests?
+        statisticsManager.pollStatistics(mockedDeviceContext.getDeviceState(), statisticsContext, mockTimerCounter, mockedDeviceInfo);
 
         when(mockedDeviceContext.getDeviceState().isStatisticsPollingEnabled()).thenReturn(true);
-        statisticsManager.pollStatistics(mockedDeviceContext, statisticsContext, mockTimerCounter);
-        // TODO Make scheduleNextPolling visible for tests?
+        statisticsManager.pollStatistics(mockedDeviceContext.getDeviceState(), statisticsContext, mockTimerCounter, mockedDeviceInfo);
 
         when(statisticsContext.gatherDynamicData()).thenReturn(Futures.immediateCheckedFuture(Boolean.TRUE));
         when(statisticsContext.isSchedulingEnabled()).thenReturn(Boolean.TRUE);
-        statisticsManager.pollStatistics(mockedDeviceContext, statisticsContext, mockTimerCounter);
+        statisticsManager.pollStatistics(mockedDeviceContext.getDeviceState(), statisticsContext, mockTimerCounter, mockedDeviceInfo);
         Mockito.verify(mockTimerCounter).markStart();
         Mockito.verify(mockTimerCounter).addTimeMark();
 
         when(statisticsContext.gatherDynamicData()).thenReturn(Futures.immediateFailedFuture(new Throwable("error msg")));
-        statisticsManager.pollStatistics(mockedDeviceContext, statisticsContext, mockTimerCounter);
+        statisticsManager.pollStatistics(mockedDeviceContext.getDeviceState(), statisticsContext, mockTimerCounter, mockedDeviceInfo);
         Mockito.verify(mockTimerCounter,times(2)).addTimeMark();
     }
 }
\ No newline at end of file
index 695a2e14a590ef7f770b175164143e35db5cedb6..8b3f29465c41dc04d6003ec9074c96c8a9d54679 100644 (file)
@@ -1,6 +1,7 @@
 package org.opendaylight.openflowplugin.impl.statistics.ofpspecific;
 
 import static org.junit.Assert.assertTrue;
+
 import java.util.List;
 import org.junit.Test;
 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
index a3480ed9ad9775bdc4890d643e19b9a7b4c59bb3..bd25110f4a528f2efaa7e5cf161251c1b6130ab7 100644 (file)
@@ -22,6 +22,7 @@ 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;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
@@ -64,6 +65,8 @@ public abstract class AbstractStatsServiceTest {
     protected TranslatorLibrary translatorLibrary;
     @Mock
     protected DeviceState deviceState;
+    @Mock
+    protected DeviceInfo deviceInfo;
 
 
     public static final NodeId NODE_ID = new NodeId("unit-test-node:123");
@@ -91,9 +94,10 @@ public abstract class AbstractStatsServiceTest {
         Mockito.when(deviceContext.getMultiMsgCollector(Matchers.any(RequestContext.class))).thenReturn(multiMsgCollector);
         Mockito.when(deviceContext.oook()).thenReturn(translatorLibrary);
         Mockito.when(deviceContext.getDeviceState()).thenReturn(deviceState);
-        Mockito.when(deviceState.getNodeId()).thenReturn(NODE_ID);
-        Mockito.when(deviceState.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
-        Mockito.when(deviceState.getFeatures()).thenReturn(getFeaturesOutput);
+        Mockito.when(deviceContext.getDeviceInfo()).thenReturn(deviceInfo);
+        Mockito.when(deviceInfo.getNodeId()).thenReturn(NODE_ID);
+        Mockito.when(deviceInfo.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
+        Mockito.when(deviceInfo.getDatapathId()).thenReturn(BigInteger.TEN);
         Mockito.when(connectionContext.getFeatures()).thenReturn(features);
         Mockito.when(connectionContext.getOutboundQueueProvider()).thenReturn(outboundQueueProvider);
         Mockito.when(features.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
index 236e50577a1d81e77995b223aac88199de7c48bf..8c3d71dbb6debce9ebdcba942fc22549578c7f6b 100644 (file)
@@ -82,7 +82,7 @@ public class OpendaylightFlowStatisticsServiceImpl2Test extends AbstractStatsSer
                          }
         ).when(multiMsgCollector).endCollecting(Matchers.any(EventIdentifier.class));
         Mockito.when(translator.translate(
-                        Matchers.any(MultipartReply.class), Matchers.same(deviceState), Matchers.isNull())
+                        Matchers.any(MultipartReply.class), Matchers.same(deviceInfo), Matchers.isNull())
         ).thenReturn(new AggregatedFlowStatisticsBuilder().build());
 
 
index d6dccf17037816a9bc6fbe6ac31442043455be0a..598ddbcad2d596f49e0df0d6b907daaa8eebd50a 100644 (file)
@@ -24,6 +24,7 @@ import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
 import org.opendaylight.openflowplugin.api.OFConstants;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator;
 import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
@@ -64,6 +65,8 @@ public class AbstractCompatibleStatServiceTest extends AbstractStatsServiceTest
     @Mock
     private DeviceState deviceState;
     @Mock
+    private DeviceInfo deviceInfo;
+    @Mock
     private MessageTranslator<Object, Object> translator;
     @Mock
     private GetFeaturesOutput featuresOutput;
@@ -95,9 +98,9 @@ public class AbstractCompatibleStatServiceTest extends AbstractStatsServiceTest
         Mockito.when(featuresOutput.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
         Mockito.when(rqContextStack.<Object>createRequestContext()).thenReturn(rqContext);
         Mockito.when(deviceContext.getDeviceState()).thenReturn(deviceState);
-        Mockito.when(deviceState.getNodeId()).thenReturn(NODE_ID);
-        Mockito.when(deviceState.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
-        Mockito.when(deviceState.getFeatures()).thenReturn(featuresOutput);
+        Mockito.when(deviceContext.getDeviceInfo()).thenReturn(deviceInfo);
+        Mockito.when(deviceInfo.getNodeId()).thenReturn(NODE_ID);
+        Mockito.when(deviceInfo.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
         Mockito.doAnswer(closeRequestFutureAnswer).when(multiMsgCollector).endCollecting();
         Mockito.doAnswer(closeRequestFutureAnswer).when(multiMsgCollector).endCollecting(Matchers.any(EventIdentifier.class));
 
@@ -140,7 +143,7 @@ public class AbstractCompatibleStatServiceTest extends AbstractStatsServiceTest
                 .setFlowCount(new Counter32(12L))
                 .setPacketCount(new Counter64(BigInteger.valueOf(13L)))
                 .build();
-        Mockito.when(translator.translate(Matchers.any(MultipartReply.class), Matchers.eq(deviceState), Matchers.any()))
+        Mockito.when(translator.translate(Matchers.any(MultipartReply.class), Matchers.eq(deviceInfo), Matchers.any()))
                 .thenReturn(aggregatedStats);
 
 
index 835e489101cbd5b2987bd6448445c44a9194b59e..2e08295b19c60269c2ab3177295dead2c64ad1ec 100644 (file)
@@ -95,7 +95,7 @@ public class OpendaylightFlowStatisticsServiceDelegateImplTest extends AbstractS
                 .setNode(createNodeRef("unitProt:123"))
                 .setTableId(new TableId((short) 1));
 
-        Mockito.when(translator.translate(Matchers.any(MultipartReply.class), Matchers.eq(deviceState), Matchers.any()))
+        Mockito.when(translator.translate(Matchers.any(MultipartReply.class), Matchers.eq(deviceInfo), Matchers.any()))
                 .thenReturn(new AggregatedFlowStatisticsBuilder()
                         .setByteCount(new Counter64(BigInteger.valueOf(50L)))
                         .setPacketCount(new Counter64(BigInteger.valueOf(51L)))
index ab611e216afbb57f0e163a8732e748d2acccd267..eb17d48ae775499080e9c194199cc91b54c3bacd 100644 (file)
@@ -31,7 +31,8 @@ public class StatisticsGatheringOnTheFlyServiceTest extends ServiceMocking {
     protected void setup() {
         statisticsGatheringService = new StatisticsGatheringOnTheFlyService(mockedRequestContextStack, mockedDeviceContext);
         Mockito.doReturn(NODE_ID).when(mockedPrimConnectionContext).getNodeId();
-        Mockito.when(mockedDeviceContext.getDeviceState().getNodeId()).thenReturn(NODE_ID);
+        Mockito.when(mockedDeviceInfo.getNodeId()).thenReturn(NODE_ID);
+        Mockito.when(mockedDeviceContext.getDeviceInfo().getNodeId()).thenReturn(NODE_ID);
     }
 
     @Test
index 7263b980c7841715982f7bbe0b032355e22ec180..024d08762f64275293470e516b35ab30b6dcc555 100644 (file)
@@ -8,6 +8,10 @@
 
 package org.opendaylight.openflowplugin.impl.statistics.services.direct;
 
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.when;
+
+import java.math.BigInteger;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -17,6 +21,7 @@ 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;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
 import org.opendaylight.openflowplugin.api.openflow.device.TranslatorLibrary;
@@ -36,11 +41,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 
-import java.math.BigInteger;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.when;
-
 @RunWith(MockitoJUnitRunner.class)
 public abstract class AbstractDirectStatisticsServiceTest {
     protected static final Long PORT_NO = 1L;
@@ -67,6 +67,8 @@ public abstract class AbstractDirectStatisticsServiceTest {
     @Mock
     protected DeviceState deviceState;
     @Mock
+    protected DeviceInfo deviceInfo;
+    @Mock
     protected GetFeaturesOutput getFeaturesOutput;
 
     protected NodeConnectorId nodeConnectorId;
@@ -95,11 +97,11 @@ public abstract class AbstractDirectStatisticsServiceTest {
         when(deviceContext.getMultiMsgCollector(any())).thenReturn(multiMsgCollector);
         when(deviceContext.oook()).thenReturn(translatorLibrary);
         when(deviceContext.getDeviceState()).thenReturn(deviceState);
-        when(deviceContext.getDeviceState()).thenReturn(deviceState);
-        when(deviceState.getNodeInstanceIdentifier()).thenReturn(nodeInstanceIdentifier);
-        when(deviceState.getNodeId()).thenReturn(new NodeId(NODE_ID));
-        when(deviceState.getVersion()).thenReturn(OF_VERSION);
-        when(deviceState.getFeatures()).thenReturn(getFeaturesOutput);
+        when(deviceContext.getDeviceInfo()).thenReturn(deviceInfo);
+        when(deviceInfo.getNodeInstanceIdentifier()).thenReturn(nodeInstanceIdentifier);
+        when(deviceInfo.getNodeId()).thenReturn(new NodeId(NODE_ID));
+        when(deviceInfo.getVersion()).thenReturn(OF_VERSION);
+        when(deviceInfo.getDatapathId()).thenReturn(DATAPATH_ID);
         when(getFeaturesOutput.getVersion()).thenReturn(OF_VERSION);
         when(getFeaturesOutput.getDatapathId()).thenReturn(DATAPATH_ID);
         when(connectionContext.getFeatures()).thenReturn(features);
index 11b2b63c47927546eb30ba1aa05c47cbcc077dfa..1a12318a0ababc1c7301e446d35fb8d631cbc752 100644 (file)
@@ -8,6 +8,18 @@
 
 package org.opendaylight.openflowplugin.impl.statistics.services.direct;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+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.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsInput;
@@ -24,19 +36,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlowCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.flow._case.MultipartRequestFlow;
 
-import java.math.BigInteger;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
 public class FlowDirectStatisticsServiceTest extends AbstractDirectStatisticsServiceTest {
     static final Short TABLE_NO = 1;
     private FlowDirectStatisticsService service;
index e948929855611bb12b55667d83ebed0f7e843be2..87811f1b92eeed7e1dd621700040dee457873577 100644 (file)
@@ -8,6 +8,17 @@
 
 package org.opendaylight.openflowplugin.impl.statistics.services.direct;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.List;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatisticsInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatisticsOutput;
@@ -19,18 +30,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.group._case.MultipartRequestGroup;
 
-import java.math.BigInteger;
-import java.util.Arrays;
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
 public class GroupDirectStatisticsServiceTest extends AbstractDirectStatisticsServiceTest {
     static final Long GROUP_NO = 1L;
     private GroupDirectStatisticsService service;
index 7c837035be86c98e099c1e1dccea71e8df1c0ef7..b923cff06871a636161f0e638563b75991896774 100644 (file)
@@ -8,6 +8,17 @@
 
 package org.opendaylight.openflowplugin.impl.statistics.services.direct;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.List;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatisticsInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatisticsOutput;
@@ -19,18 +30,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter._case.MultipartRequestMeter;
 
-import java.math.BigInteger;
-import java.util.Arrays;
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
 public class MeterDirectStatisticsServiceTest extends AbstractDirectStatisticsServiceTest {
     static final Long METER_NO = 1L;
     private MeterDirectStatisticsService service;
index 9296347130668a9fc8a8cc92d84f7ed60c42862f..d95595e08205e6c4fb109fbb57ae782ab3275dad 100644 (file)
@@ -8,6 +8,17 @@
 
 package org.opendaylight.openflowplugin.impl.statistics.services.direct;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.List;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsOutput;
@@ -19,18 +30,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.port.stats._case.MultipartRequestPortStats;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
 
-import java.math.BigInteger;
-import java.util.Arrays;
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
 public class NodeConnectorDirectStatisticsServiceTest extends AbstractDirectStatisticsServiceTest {
     private NodeConnectorDirectStatisticsService service;
 
index c3a2c26a178656b7404a6835c28034dc80ab8e5b..33b0746aa9635cb325a976aa2853d2d4bd4ea930 100644 (file)
@@ -8,6 +8,11 @@
 
 package org.opendaylight.openflowplugin.impl.statistics.services.direct;
 
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -27,11 +32,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511
 import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
 @RunWith(MockitoJUnitRunner.class)
 public class OpendaylightDirectStatisticsServiceImplTest {
     @Mock
index 3df2f25f70ba127e4e4b3a3ef308684ca5de3e6b..c8ae34a06bab366bdbb20e0e0735975d3f60012e 100644 (file)
@@ -8,6 +8,17 @@
 
 package org.opendaylight.openflowplugin.impl.statistics.services.direct;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.List;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatisticsInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatisticsOutput;
@@ -21,18 +32,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.queue._case.MultipartRequestQueue;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap;
 
-import java.math.BigInteger;
-import java.util.Arrays;
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
 public class QueueDirectStatisticsServiceTest extends AbstractDirectStatisticsServiceTest {
     static final Long QUEUE_NO = 1L;
     private QueueDirectStatisticsService service;
index bac6d1ebc571885026961161e8d97802f4e9091e..270582ca0bd55bc870444be893804297b8be9487 100644 (file)
@@ -15,7 +15,7 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.aggregate.flow.statistics.from.flow.table._for.given.match.output.AggregatedFlowStatistics;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessageBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCaseBuilder;
@@ -29,7 +29,7 @@ public class AggregatedFlowStatisticsTranslatorTest {
 
     private AggregatedFlowStatisticsTranslator translator;
     @Mock
-    private DeviceState deviceState;
+    private DeviceInfo deviceInfo;
 
     @Before
     public void setUp() throws Exception {
@@ -47,7 +47,7 @@ public class AggregatedFlowStatisticsTranslatorTest {
         MultipartReplyMessageBuilder mpInputBld = new MultipartReplyMessageBuilder()
                 .setMultipartReplyBody(inputBld.build());
 
-        final AggregatedFlowStatistics statistics = translator.translate(mpInputBld.build(), deviceState, null);
+        final AggregatedFlowStatistics statistics = translator.translate(mpInputBld.build(), deviceInfo, null);
 
         Assert.assertEquals(aggregateStatsValueBld.getByteCount(), statistics.getByteCount().getValue());
         Assert.assertEquals(aggregateStatsValueBld.getFlowCount(), statistics.getFlowCount().getValue());
index 823a5b14651c24b875f6315b5d7d5999706b741e..d3e95982193122398c65b6cd178982502ff927a1 100644 (file)
@@ -13,21 +13,21 @@ import static org.mockito.Mockito.when;
 
 import java.math.BigInteger;
 import java.util.Collections;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved;
 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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowWildcardsV10;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.MatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10Builder;
@@ -52,6 +52,9 @@ public class FlowRemovedTranslatorTest {
     @Mock
     private DeviceState deviceState;
 
+    @Mock
+    private DeviceInfo deviceInfo;
+
     @Mock
     private GetFeaturesOutput features;
 
@@ -69,15 +72,14 @@ public class FlowRemovedTranslatorTest {
         translatorV10 = new FlowRemovedV10Translator();
 
         when(deviceContext.getDeviceState()).thenReturn(deviceState);
-        when(deviceState.getNodeInstanceIdentifier()).thenReturn(nodeId);
-        when(deviceState.getFeatures()).thenReturn(features);
+        when(deviceInfo.getNodeInstanceIdentifier()).thenReturn(nodeId);
         when(features.getDatapathId()).thenReturn(BigInteger.TEN);
     }
 
     @Test
     public void testTranslate() throws Exception {
         org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemoved flowRemovedMessage = buildMessage(false);
-        final FlowRemoved flowRemoved = translator.translate(flowRemovedMessage, deviceState, null);
+        final FlowRemoved flowRemoved = translator.translate(flowRemovedMessage, deviceInfo, null);
 
         assertEquals(flowRemovedMessage.getCookie(), flowRemoved.getCookie().getValue());
         assertEquals(flowRemovedMessage.getPriority(), flowRemoved.getPriority());
@@ -87,7 +89,7 @@ public class FlowRemovedTranslatorTest {
     @Test
     public void testTranslateV10() throws Exception {
         org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemoved flowRemovedMessage = buildMessage(true);
-        final FlowRemoved flowRemoved = translatorV10.translate(flowRemovedMessage, deviceState, null);
+        final FlowRemoved flowRemoved = translatorV10.translate(flowRemovedMessage, deviceInfo, null);
 
         assertEquals(flowRemovedMessage.getCookie(), flowRemoved.getCookie().getValue());
         assertEquals(flowRemovedMessage.getPriority(), flowRemoved.getPriority());
@@ -103,7 +105,7 @@ public class FlowRemovedTranslatorTest {
             builder.setMatchV10(new MatchV10Builder().setWildcards(flowWildcards).build());
         } else {
             builder.setMatch(new MatchBuilder().setMatchEntry(Collections.<MatchEntry>emptyList()).build())
-                .setTableId(new TableId(42l));
+                .setTableId(new TableId(42L));
         }
 
         return builder.build();
index f6358fad05462f83e37d6ae8eaf8eebcd4c374cf..62bbe22aa9b2153d0f92e59f806dda05198f23d9 100644 (file)
@@ -4,7 +4,6 @@ import com.google.common.collect.Lists;
 import java.math.BigInteger;
 import java.util.Arrays;
 import java.util.List;
-
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -16,6 +15,7 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 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;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
@@ -63,6 +63,8 @@ public class PacketReceivedTranslatorTest {
     @Mock
     DeviceContext deviceContext;
     @Mock
+    DeviceInfo deviceInfo;
+    @Mock
     List<PhyPort> phyPorts;
     @Mock
     PhyPort phyPort;
@@ -84,8 +86,8 @@ public class PacketReceivedTranslatorTest {
         Mockito.when(connectionContext.getFeatures()).thenReturn(featuresReply);
         Mockito.when(featuresReply.getDatapathId()).thenReturn(BigInteger.TEN);
         Mockito.when(deviceContext.getDeviceState()).thenReturn(deviceState);
-        Mockito.when(deviceState.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
-        Mockito.when(deviceState.getFeatures()).thenReturn(getFeaturesOutput);
+        Mockito.when(deviceInfo.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
+        Mockito.when(deviceInfo.getDatapathId()).thenReturn(BigInteger.TEN);
         Mockito.when(getFeaturesOutput.getDatapathId()).thenReturn(BigInteger.TEN);
         Mockito.when(getFeaturesOutput.getPhyPort()).thenReturn(phyPorts);
         Mockito.when(phyPort.getPortNo()).thenReturn(PORT_NO_DS);
@@ -98,9 +100,9 @@ public class PacketReceivedTranslatorTest {
                 .child(Node.class, new NodeKey(new NodeId("openflow:10")));
         final PacketReceivedTranslator packetReceivedTranslator = new PacketReceivedTranslator();
         final PacketInMessage packetInMessage = createPacketInMessage(DATA.getBytes(), PORT_NO);
-        Mockito.when(deviceState.getNodeInstanceIdentifier()).thenReturn(nodePath);
+        Mockito.when(deviceInfo.getNodeInstanceIdentifier()).thenReturn(nodePath);
 
-        final PacketReceived packetReceived = packetReceivedTranslator.translate(packetInMessage, deviceState, null);
+        final PacketReceived packetReceived = packetReceivedTranslator.translate(packetInMessage, deviceInfo, null);
 
         Assert.assertArrayEquals(packetInMessage.getData(), packetReceived.getPayload());
         Assert.assertEquals("org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.SendToController",
index c4a1f2a285ff76ddac21c96ec5126f12e32a81b7..5500dea5ee8cca73858cc82da691fe1d6c59c57e 100644 (file)
@@ -17,6 +17,7 @@ import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.opendaylight.openflowplugin.api.OFConstants;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
@@ -40,6 +41,8 @@ public class PortUpdateTranslatorTest {
     private DeviceContext deviceContext;
     @Mock
     private DeviceState deviceState;
+    @Mock
+    private DeviceInfo deviceInfo;
 
     private org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortConfig portConfig;
     private StateBuilder portStateBld;
@@ -47,7 +50,7 @@ public class PortUpdateTranslatorTest {
 
     @Before
     public void setUp() throws Exception {
-        Mockito.when(deviceContext.getDeviceState()).thenReturn(deviceState);
+        Mockito.when(deviceContext.getDeviceInfo()).thenReturn(deviceInfo);
         portUpdateTranslator = new PortUpdateTranslator();
 
         portStateBld = new StateBuilder().setLive(true);
@@ -59,13 +62,13 @@ public class PortUpdateTranslatorTest {
 
     @Test
     public void testTranslate_13() throws Exception {
-        Mockito.when(deviceState.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
+        Mockito.when(deviceInfo.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
         final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortFeatures portFeatures =
                 org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortFeatures
                         .getDefaultInstance("hundredGbFd");
 
 
-        final FlowCapableNodeConnector nodeConnector = portUpdateTranslator.translate(portBld.build(), deviceState, null);
+        final FlowCapableNodeConnector nodeConnector = portUpdateTranslator.translate(portBld.build(), deviceInfo, null);
 
         commonCheck(nodeConnector);
 
@@ -88,14 +91,14 @@ public class PortUpdateTranslatorTest {
 
     @Test
     public void testTranslate_10() throws Exception {
-        Mockito.when(deviceState.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_0);
+        Mockito.when(deviceInfo.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_0);
         final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortFeatures portFeatures =
                 new org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortFeatures(
                         null, null, null, false, false, true, null, null,
                         null, false, false, null, null, null, null, null
                 );
 
-        final FlowCapableNodeConnector nodeConnector = portUpdateTranslator.translate(portBld.build(), deviceState, null);
+        final FlowCapableNodeConnector nodeConnector = portUpdateTranslator.translate(portBld.build(), deviceInfo, null);
 
         commonCheck(nodeConnector);
 
index e20beab46b23393a8b9df81efbe0586376b5b0a7..71da6bd8c1388382fe4e228959e041d9e50fbd3a 100644 (file)
@@ -16,18 +16,17 @@ import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import com.google.common.collect.Lists;
+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.ListenableFuture;
 import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
-
-import com.google.common.collect.Lists;
-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.ListenableFuture;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -46,6 +45,7 @@ import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueHandle
 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;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
@@ -130,7 +130,11 @@ public class DeviceInitializationUtilsTest {
     @Mock
     private DeviceContextImpl mockedDeviceContext;
     @Mock
+    private DeviceInfo mockedDeviceInfo;
+    @Mock
     private DeviceInitializationUtils deviceInitializationUtils;
+    @Mock
+    private DeviceInfo deviceInfo;
 
     @Before
     public void setUp() throws Exception {
@@ -140,6 +144,7 @@ public class DeviceInitializationUtilsTest {
         when(mockConnectionContext.getFeatures()).thenReturn(mockFeatures);
         when(mockConnectionContext.getConnectionAdapter()).thenReturn(mockedConnectionAdapter);
         when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(mockConnectionContext);
+        when(mockedDeviceContext.getDeviceInfo()).thenReturn(mockedDeviceInfo);
 
         final Capabilities capabilitiesV13 = mock(Capabilities.class);
         final CapabilitiesV10 capabilitiesV10 = mock(CapabilitiesV10.class);
@@ -156,10 +161,9 @@ public class DeviceInitializationUtilsTest {
 
         GetFeaturesOutput mockedFeatures = mock(GetFeaturesOutput.class);
         when(mockedFeatures.getTables()).thenReturn((short) 2);
-        when(mockedDeviceState.getFeatures()).thenReturn(mockedFeatures);
-        when(mockedDeviceState.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_0);
+        when(mockedDeviceInfo.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_0);
 
-        when(mockedDeviceState.getNodeInstanceIdentifier()).thenReturn(DUMMY_NODE_II);
+        when(mockedDeviceInfo.getNodeInstanceIdentifier()).thenReturn(DUMMY_NODE_II);
         when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState);
         when(mockedDeviceContext.getMultiMsgCollector(Mockito.any(RequestContext.class))).thenReturn(msgCollector);
         when(mockedDeviceContext.oook()).thenReturn(tLibrary);
@@ -179,9 +183,9 @@ public class DeviceInitializationUtilsTest {
 
         final GetFeaturesOutput mockedFeatures = mock(GetFeaturesOutput.class);
         when(mockedFeatures.getTables()).thenReturn((short) 2);
-        when(mockedDeviceState.getFeatures()).thenReturn(mockedFeatures);
+        when(mockConnectionContext.getFeatures()).thenReturn(mockedFeatures);
 
-        when(mockedDeviceState.getNodeInstanceIdentifier()).thenReturn(DUMMY_NODE_II);
+        when(mockedDeviceInfo.getNodeInstanceIdentifier()).thenReturn(DUMMY_NODE_II);
         when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState);
 
         final RpcResult<List<MultipartReply>> mockedRpcResult = mock(RpcResult.class);
@@ -280,7 +284,7 @@ public class DeviceInitializationUtilsTest {
         when(mockedPrimaryConnectionContext.getFeatures()).thenReturn(mockedFeatures);
         when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(mockedPrimaryConnectionContext);
         final DeviceState mockedDeviceState = mock(DeviceState.class);
-        when(mockedDeviceState.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_0);
+        when(mockedDeviceInfo.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_0);
         when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState);
         final MessageTranslator mockedTranslator = mock(MessageTranslator.class);
         when(translatorLibrary.lookupTranslator(any(TranslatorKey.class))).thenReturn(mockedTranslator);
index cf0149cd79ffea230d337755f76834bdb7e5be30..0430590a31bd25400679f43019b075347fb74a59 100644 (file)
@@ -17,15 +17,17 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
+
 import java.math.BigInteger;
 import org.junit.Test;
 import org.mockito.Matchers;
 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext;
+import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
 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.role.service.rev150727.OfpRole;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 
@@ -45,20 +47,21 @@ public class MdSalRegistrationUtilsTest {
         final ConnectionContext mockedConnectionContext = mock(ConnectionContext.class);
 
         final DeviceState mockedDeviceState = mock(DeviceState.class);
+        final DeviceInfo mockedDeviceInfo = mock(DeviceInfo.class);
         when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState);
+        when(mockedDeviceContext.getDeviceInfo()).thenReturn(mockedDeviceInfo);
 
         final FeaturesReply mockedFeatures = mock(FeaturesReply.class);
         when(mockedConnectionContext.getFeatures()).thenReturn(mockedFeatures);
 
-        final GetFeaturesOutput mockedFeaturesOutput = mock(GetFeaturesOutput.class);
-        when(mockedDeviceState.getFeatures()).thenReturn(mockedFeaturesOutput);
-
         final BigInteger mockedDataPathId = mock(BigInteger.class);
         when(mockedFeatures.getDatapathId()).thenReturn(mockedDataPathId);
-        when(mockedFeaturesOutput.getDatapathId()).thenReturn(mockedDataPathId);
+        when(mockedDeviceInfo.getDatapathId()).thenReturn(mockedDataPathId);
 
         when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(mockedConnectionContext);
-        MdSalRegistrationUtils.registerMasterServices(mockedRpcContext, mockedDeviceContext, OfpRole.BECOMEMASTER);
+
+        final ExtensionConverterProvider extensionConverterProvider = mock(ExtensionConverterProvider.class);
+        MdSalRegistrationUtils.registerMasterServices(mockedRpcContext, mockedDeviceContext, OfpRole.BECOMEMASTER, extensionConverterProvider);
         verify(mockedRpcContext, times(NUMBER_OF_RPC_SERVICE_REGISTRATION)).registerRpcServiceImplementation(
                 Matchers.<Class<RpcService>> any(), any(RpcService.class));
     }
index fe0ccc1851728d9232e9288ff08ba57ebf2a5ede..0115b55560799d0c88de9a74b5f6dd42bb3b8ed4 100644 (file)
@@ -261,7 +261,7 @@ public class FlowConvertor {
     }
 
     private static void salToOFFlowCommand(Flow flow, FlowModInputBuilder flowMod) {
-        if (flow instanceof AddFlowInput) {
+        if (flow instanceof AddFlowInput || flow instanceof UpdatedFlow) {
             flowMod.setCommand(FlowModCommand.OFPFCADD);
         } else if (flow instanceof RemoveFlowInput) {
             if (MoreObjects.firstNonNull(flow.isStrict(), Boolean.FALSE)) {
@@ -269,12 +269,6 @@ public class FlowConvertor {
             } else {
                 flowMod.setCommand(FlowModCommand.OFPFCDELETE);
             }
-        } else if (flow instanceof UpdatedFlow) {
-            if (MoreObjects.firstNonNull(flow.isStrict(), Boolean.FALSE)) {
-                flowMod.setCommand(FlowModCommand.OFPFCMODIFYSTRICT);
-            } else {
-                flowMod.setCommand(FlowModCommand.OFPFCMODIFY);
-            }
         }
     }
 
index 1a5f53857a5b3e3fd93dbb334c06621b9dcab36d..67cc3efce7e2abb1867c77a02ca0dd48e38ce6b2 100644 (file)
@@ -99,13 +99,18 @@ public class SessionManagerOFImpl implements ConjunctSessionManager {
             LOG.info("context for invalidation not found");
         } else {
             synchronized (context) {
-                for (Entry<SwitchConnectionDistinguisher, ConnectionConductor> auxEntry : context.getAuxiliaryConductors()) {
-                    invalidateAuxiliary(sessionKey, auxEntry.getKey());
+                if (context.isValid()) {
+                    for (Entry<SwitchConnectionDistinguisher, ConnectionConductor> auxEntry : context.getAuxiliaryConductors()) {
+                        invalidateAuxiliary(sessionKey, auxEntry.getKey());
+                    }
+                    context.getPrimaryConductor().disconnect();
+                    context.setValid(false);
+                    removeSessionContext(context);
+                    // TODO:: notify listeners
+                } else {
+                    LOG.warn("Ignore invalid session context: {}",
+                             Arrays.toString(sessionKey.getId()));
                 }
-                context.getPrimaryConductor().disconnect();
-                context.setValid(false);
-                removeSessionContext(context);
-                // TODO:: notify listeners
             }
         }
     }
@@ -115,13 +120,19 @@ public class SessionManagerOFImpl implements ConjunctSessionManager {
             LOG.info("context for invalidation not found");
         } else {
             synchronized (sessionContext) {
-                for (Entry<SwitchConnectionDistinguisher, ConnectionConductor> auxEntry : sessionContext
-                        .getAuxiliaryConductors()) {
-                    invalidateAuxiliary(sessionContext, auxEntry.getKey(), true);
+                if (sessionContext.isValid()) {
+                    for (Entry<SwitchConnectionDistinguisher, ConnectionConductor> auxEntry : sessionContext
+                             .getAuxiliaryConductors()) {
+                        invalidateAuxiliary(sessionContext, auxEntry.getKey(), true);
+                    }
+                    sessionContext.setValid(false);
+                    removeSessionContext(sessionContext);
+                    // TODO:: notify listeners
+                } else {
+                    LOG.warn("Ignore invalid dead session context: {}",
+                             Arrays.toString(
+                                 sessionContext.getSessionKey().getId()));
                 }
-                sessionContext.setValid(false);
-                removeSessionContext(sessionContext);
-                // TODO:: notify listeners
             }
         }
     }
@@ -130,8 +141,13 @@ public class SessionManagerOFImpl implements ConjunctSessionManager {
         if (LOG.isDebugEnabled()) {
             LOG.debug("removing session: {}", Arrays.toString(sessionContext.getSessionKey().getId()));
         }
-        sessionLot.remove(sessionContext.getSessionKey(), sessionContext);
-        sessionNotifier.onSessionRemoved(sessionContext);
+        if (sessionLot.remove(sessionContext.getSessionKey(), sessionContext)) {
+            sessionNotifier.onSessionRemoved(sessionContext);
+        } else {
+            // This should never happen.
+            LOG.warn("Ignore session context that was already removed: {}",
+                     Arrays.toString(sessionContext.getSessionKey().getId()));
+        }
     }
 
     @Override
index 6779145b00ffc9d45bdcf98c6be37d60b6b50023..210f9f255c06b7ee7d69760d43f6f6a7e31c73cb 100644 (file)
@@ -108,7 +108,7 @@ public class FlowConvertorTest {
                 .toFlowModInputs(flow, EncodeConstants.OF10_VERSION_ID, new BigInteger("42"));\r
 \r
         Assert.assertEquals("Wrong version", 1, flowMod.get(0).getVersion().intValue());\r
-        Assert.assertEquals("Wrong command", FlowModCommand.OFPFCMODIFYSTRICT, flowMod.get(0).getCommand());\r
+        Assert.assertEquals("Wrong command", FlowModCommand.OFPFCADD, flowMod.get(0).getCommand());\r
     }\r
 \r
     /**\r
diff --git a/pom.xml b/pom.xml
index 9547c0502c10ccc36d20c48361f5985d45aa51e0..45f69cab60453e7ab4b3ff75bfec562de4fcbf35 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -41,7 +41,7 @@
       <module>drop-test-karaf</module>
       <module>test-common</module>
       <module>features</module>
-      <module>features-li</module>
+      <module>features-he</module>
       <module>samples/sample-consumer</module>
       <module>samples/learning-switch</module>
       <module>applications</module>