From 617a0726d931230945a8a8d28a6e34be39f56b16 Mon Sep 17 00:00:00 2001 From: deathbeam Date: Mon, 30 Jan 2017 19:16:45 +0100 Subject: [PATCH] Add single layer deserialization support - Update MultiMsgCollector to support multiple reply types - Update DeviceContext to support mulyiple reply types - Update AbstractService and MultipartService* implementations to support multiple reply types - Update GroupDirectStatisticsService - Update FlowDirectStatisticsService - Update MeterDirectStatisticsService - Update PortDirectStatisticsService - Update QueueDirectStatisticsService - Update SalExperimenterMpMessageService - Update SalTableService - Change giant StatisticsGatheringUtils to separate statistics writers and add support for writing both deserialization paths - Refactor structure of services because of a lot of new classes added, it became mess - Create new initialization chain for device that supports both deserialization paths Resolves: bug 7141 Change-Id: I21b9b894d89db220ccf20ebb031fcb9e039b184a Signed-off-by: Tomas Slusny --- .../opendaylight-flow-table-statistics.yang | 3 +- .../yang/opendaylight-port-statistics.yang | 2 - .../yang/opendaylight-queue-statistics.yang | 2 - .../api/openflow/device/DeviceContext.java | 6 +- .../device/handlers/DeviceReplyProcessor.java | 15 +- .../device/handlers/MultiMsgCollector.java | 19 +- .../ofpspecific/StatisticsGatherer.java | 11 +- .../impl/OpenFlowPluginProviderImpl.java | 8 +- .../MultipartReplyTranslatorUtil.java} | 464 +++++++------- .../common/NodeConnectorTranslatorUtil.java | 156 ----- .../common/NodeStaticReplyTranslatorUtil.java | 225 ------- .../datastore/MultipartWriterProvider.java | 41 ++ .../MultipartWriterProviderFactory.java | 63 ++ .../multipart/AbstractMultipartWriter.java | 89 +++ .../multipart/DescMultipartWriter.java | 50 ++ .../multipart/FlowStatsMultipartWriter.java | 75 +++ .../multipart/GroupDescMultipartWriter.java | 57 ++ .../GroupFeaturesMultipartWriter.java | 41 ++ .../multipart/GroupStatsMultipartWriter.java | 46 ++ .../multipart/MeterConfigMultipartWriter.java | 57 ++ .../MeterFeaturesMultipartWriter.java | 39 ++ .../multipart/MeterStatsMultipartWriter.java | 46 ++ .../multipart/PortDescMultipartWriter.java | 72 +++ .../multipart/PortStatsMultipartWriter.java | 66 ++ .../multipart/QueueStatsMultipartWriter.java | 57 ++ .../TableFeaturesMultipartWriter.java | 60 ++ .../multipart/TableStatsMultipartWriter.java | 47 ++ .../impl/device/DeviceContextImpl.java | 76 ++- .../impl/device/DeviceManagerImpl.java | 12 +- .../AbstractDeviceInitializer.java | 65 ++ .../DeviceInitializerProvider.java | 39 ++ .../DeviceInitializerProviderFactory.java | 29 + .../initialization/OF10DeviceInitializer.java | 176 ++++++ .../initialization/OF13DeviceInitializer.java | 276 +++++++++ .../listener/MultiMsgCollectorImpl.java | 47 +- .../deserialization/DeserializerInjector.java | 5 +- .../MultipartReplyGroupDescDeserializer.java | 5 +- ...bstractAggregateFlowMultipartService.java} | 28 +- .../AbstractExperimenterMultipartService.java | 89 +++ .../impl/services/AbstractMessageService.java | 41 -- .../AbstractMultipartCollectorService.java | 58 ++ .../AbstractMultipartOnTheFlyService.java | 24 +- ... => AbstractMultipartRequestCallback.java} | 56 +- ...tractMultipartRequestOnTheFlyCallback.java | 129 ++++ .../services/AbstractMultipartService.java | 26 +- .../services/AbstractRequestCallback.java | 12 +- .../impl/services/AbstractService.java | 39 +- .../services/AbstractSilentErrorService.java | 38 ++ .../AbstractTableMultipartService.java | 103 ++++ .../impl/services/AbstractVoidService.java | 3 +- .../impl/services/EchoService.java | 3 +- .../MultipartRequestOnTheFlyCallback.java | 133 ---- .../impl/services/RoleService.java | 3 +- .../impl/services/SalTableServiceImpl.java | 188 ------ .../impl/services/SimpleRequestCallback.java | 6 +- .../impl/services/VoidRequestCallback.java | 6 +- ...ltiLayerAggregateFlowMultipartService.java | 71 +++ ...ltiLayerExperimenterMultipartService.java} | 72 +-- ...rFlowMultipartRequestOnTheFlyCallback.java | 83 +++ .../MultiLayerFlowService.java} | 16 +- .../MultiLayerGroupService.java} | 12 +- .../MultiLayerMeterService.java} | 14 +- .../MultiLayerMultipartCollectorService.java | 22 + .../MultiLayerMultipartRequestCallback.java | 38 ++ .../MultiLayerTableMultipartService.java | 124 ++++ .../FlowCapableTransactionServiceImpl.java | 4 +- .../{ => sal}/NodeConfigServiceImpl.java | 4 +- .../PacketProcessingServiceImpl.java | 4 +- .../{ => sal}/SalEchoServiceImpl.java | 3 +- .../SalExperimenterMessageServiceImpl.java | 4 +- .../SalExperimenterMpMessageServiceImpl.java | 42 ++ .../{ => sal}/SalFlatBatchServiceImpl.java | 2 +- .../{ => sal}/SalFlowServiceImpl.java | 34 +- .../{ => sal}/SalFlowsBatchServiceImpl.java | 2 +- .../{ => sal}/SalGroupServiceImpl.java | 56 +- .../{ => sal}/SalGroupsBatchServiceImpl.java | 2 +- .../{ => sal}/SalMeterServiceImpl.java | 58 +- .../{ => sal}/SalMetersBatchServiceImpl.java | 2 +- .../{ => sal}/SalPortServiceImpl.java | 11 +- .../{ => sal}/SalRoleServiceImpl.java | 7 +- .../services/sal/SalTableServiceImpl.java | 42 ++ ...gleLayerAggregateFlowMultipartService.java | 67 ++ ...ngleLayerExperimenterMultipartService.java | 80 +++ ...rFlowMultipartRequestOnTheFlyCallback.java | 79 +++ .../SingleLayerFlowService.java} | 16 +- .../SingleLayerGroupService.java} | 27 +- .../SingleLayerMeterService.java} | 30 +- .../SingleLayerMultipartCollectorService.java | 22 + .../SingleLayerMultipartRequestCallback.java | 35 ++ .../SingleLayerPortService.java} | 22 +- .../SingleLayerTableMultipartService.java | 98 +++ .../{ => util}/RequestContextUtil.java | 2 +- .../{ => util}/RequestInputUtils.java | 2 +- .../services/{ => util}/ServiceException.java | 2 +- .../statistics/StatisticsContextImpl.java | 137 +++-- .../statistics/StatisticsGatheringUtils.java | 556 +++++------------ .../statistics/StatisticsManagerImpl.java | 35 +- .../AggregateFlowsInTableService.java | 4 +- .../services/AllFlowsInAllTablesService.java | 4 +- .../services/AllFlowsInTableService.java | 4 +- .../services/AllGroupsStatsService.java | 4 +- .../services/AllMeterConfigStatsService.java | 6 +- .../services/AllMeterStatsService.java | 4 +- .../services/AllPortStatsService.java | 4 +- .../services/AllQueuesAllPortsService.java | 4 +- .../services/AllQueuesOnePortService.java | 4 +- .../services/FlowsInTableService.java | 4 +- .../services/GroupDescriptionService.java | 4 +- .../services/GroupFeaturesService.java | 4 +- .../services/GroupStatsService.java | 4 +- .../services/MeterFeaturesService.java | 4 +- .../services/MeterStatsService.java | 4 +- .../services/OneQueueOnePortService.java | 4 +- ...OpendaylightFlowStatisticsServiceImpl.java | 69 +-- ...aylightFlowTableStatisticsServiceImpl.java | 4 +- .../statistics/services/PortStatsService.java | 4 +- .../AbstractCompatibleStatService.java | 3 +- .../StatisticsGatheringOnTheFlyService.java | 20 +- .../dedicated/StatisticsGatheringService.java | 15 +- .../AbstractDirectStatisticsService.java | 96 +-- .../AbstractFlowDirectStatisticsService.java | 104 ++++ .../AbstractGroupDirectStatisticsService.java | 53 ++ .../AbstractMeterDirectStatisticsService.java | 53 ++ .../AbstractPortDirectStatisticsService.java | 53 ++ .../AbstractQueueDirectStatisticsService.java | 59 ++ .../direct/FlowDirectStatisticsService.java | 173 ------ .../direct/GroupDirectStatisticsService.java | 108 ---- .../direct/MeterDirectStatisticsService.java | 107 ---- .../NodeConnectorDirectStatisticsService.java | 145 ----- ...endaylightDirectStatisticsServiceImpl.java | 58 +- ...ylightDirectStatisticsServiceProvider.java | 9 +- .../direct/QueueDirectStatisticsService.java | 146 ----- .../FlowDirectStatisticsService.java | 73 +++ .../GroupDirectStatisticsService.java | 59 ++ .../MeterDirectStatisticsService.java | 57 ++ ...erDirectStatisticsProviderInitializer.java | 50 ++ .../PortDirectStatisticsService.java | 99 +++ .../QueueDirectStatisticsService.java | 80 +++ .../FlowDirectStatisticsService.java | 54 ++ .../GroupDirectStatisticsService.java | 45 ++ .../MeterDirectStatisticsService.java | 45 ++ .../PortDirectStatisticsService.java | 45 ++ .../QueueDirectStatisticsService.java | 45 ++ ...erDirectStatisticsProviderInitializer.java | 50 ++ .../impl/util/DeviceInitializationUtil.java | 105 ++++ .../impl/util/DeviceInitializationUtils.java | 572 ------------------ .../impl/util/MdSalRegistrationUtils.java | 65 +- .../NodeConnectorTranslatorUtilTest.java | 323 ---------- .../impl/device/DeviceContextImplTest.java | 23 +- .../impl/device/DeviceManagerImplTest.java | 28 +- .../listener/MultiMsgCollectorImplTest.java | 28 +- .../AbstractDeserializerTest.java | 1 + .../MultipartRequestCallbackTest.java | 19 +- .../MultipartRequestOnTheFlyCallbackTest.java | 23 +- ...lExperimenterMpMessageServiceImplTest.java | 9 +- ...FlowCapableTransactionServiceImplTest.java | 10 +- .../{ => sal}/NodeConfigServiceImplTest.java | 8 +- .../PacketProcessingServiceImplTest.java | 9 +- .../{ => sal}/SalEchoServiceImplTest.java | 8 +- ...SalExperimenterMessageServiceImplTest.java | 9 +- .../SalFlatBatchServiceImplTest.java | 8 +- .../{ => sal}/SalFlowServiceImplTest.java | 7 +- .../SalFlowsBatchServiceImplTest.java | 8 +- .../{ => sal}/SalGroupServiceImplTest.java | 5 +- .../SalGroupsBatchServiceImplTest.java | 9 +- .../{ => sal}/SalMeterServiceImplTest.java | 5 +- .../SalMetersBatchServiceImplTest.java | 9 +- .../{ => sal}/SalPortServiceImplTest.java | 6 +- .../{ => sal}/SalRoleServiceImplTest.java | 7 +- .../{ => sal}/SalTableServiceImplTest.java | 8 +- ...java => MultipartReplyTranslatorTest.java} | 108 ++-- .../StatisticsContextImpMockInitiation.java | 5 +- .../StatisticsContextImplParamTest.java | 4 +- .../statistics/StatisticsContextImplTest.java | 11 +- .../StatisticsGatheringUtilsTest.java | 64 +- .../AbstractSingleStatsServiceTest.java | 2 +- .../AbstractCompatibleStatServiceTest.java | 2 +- ...tatisticsGatheringOnTheFlyServiceTest.java | 8 +- .../AbstractDirectStatisticsServiceTest.java | 8 +- ...ylightDirectStatisticsServiceImplTest.java | 34 +- .../FlowDirectStatisticsServiceTest.java | 12 +- .../GroupDirectStatisticsServiceTest.java | 12 +- .../MeterDirectStatisticsServiceTest.java | 12 +- ...eConnectorDirectStatisticsServiceTest.java | 14 +- .../QueueDirectStatisticsServiceTest.java | 12 +- .../util/DeviceInitializationUtilsTest.java | 370 ----------- 186 files changed, 5240 insertions(+), 4268 deletions(-) rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/{statistics/SinglePurposeMultipartReplyTranslator.java => common/MultipartReplyTranslatorUtil.java} (54%) delete mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/common/NodeConnectorTranslatorUtil.java delete mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/common/NodeStaticReplyTranslatorUtil.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/MultipartWriterProvider.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/MultipartWriterProviderFactory.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/AbstractMultipartWriter.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/DescMultipartWriter.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/FlowStatsMultipartWriter.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/GroupDescMultipartWriter.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/GroupFeaturesMultipartWriter.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/GroupStatsMultipartWriter.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/MeterConfigMultipartWriter.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/MeterFeaturesMultipartWriter.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/MeterStatsMultipartWriter.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/PortDescMultipartWriter.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/PortStatsMultipartWriter.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/QueueStatsMultipartWriter.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/TableFeaturesMultipartWriter.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/TableStatsMultipartWriter.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/initialization/AbstractDeviceInitializer.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/initialization/DeviceInitializerProvider.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/initialization/DeviceInitializerProviderFactory.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/initialization/OF10DeviceInitializer.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/initialization/OF13DeviceInitializer.java rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/{statistics/services/MatchingFlowsInTableService.java => services/AbstractAggregateFlowMultipartService.java} (78%) create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractExperimenterMultipartService.java delete mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractMessageService.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractMultipartCollectorService.java rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{MultipartRequestCallback.java => AbstractMultipartRequestCallback.java} (50%) create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractMultipartRequestOnTheFlyCallback.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractSilentErrorService.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractTableMultipartService.java delete mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestOnTheFlyCallback.java delete mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalTableServiceImpl.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerAggregateFlowMultipartService.java rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{SalExperimenterMpMessageServiceImpl.java => multilayer/MultiLayerExperimenterMultipartService.java} (68%) mode change 100755 => 100644 create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerFlowMultipartRequestOnTheFlyCallback.java rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{FlowService.java => multilayer/MultiLayerFlowService.java} (83%) rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{GroupService.java => multilayer/MultiLayerGroupService.java} (75%) rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{MeterService.java => multilayer/MultiLayerMeterService.java} (74%) create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerMultipartCollectorService.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerMultipartRequestCallback.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerTableMultipartService.java rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/FlowCapableTransactionServiceImpl.java (89%) rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/NodeConfigServiceImpl.java (91%) rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/PacketProcessingServiceImpl.java (91%) rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/SalEchoServiceImpl.java (96%) rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/SalExperimenterMessageServiceImpl.java (94%) create mode 100755 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalExperimenterMpMessageServiceImpl.java rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/SalFlatBatchServiceImpl.java (99%) rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/SalFlowServiceImpl.java (91%) rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/SalFlowsBatchServiceImpl.java (99%) rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/SalGroupServiceImpl.java (76%) rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/SalGroupsBatchServiceImpl.java (99%) rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/SalMeterServiceImpl.java (76%) rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/SalMetersBatchServiceImpl.java (99%) rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/SalPortServiceImpl.java (84%) rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/SalRoleServiceImpl.java (96%) create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalTableServiceImpl.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerAggregateFlowMultipartService.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerExperimenterMultipartService.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerFlowMultipartRequestOnTheFlyCallback.java rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{FlowMessageService.java => singlelayer/SingleLayerFlowService.java} (82%) rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{GroupMessageService.java => singlelayer/SingleLayerGroupService.java} (76%) rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{MeterMessageService.java => singlelayer/SingleLayerMeterService.java} (72%) create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerMultipartCollectorService.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerMultipartRequestCallback.java rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{PortMessageService.java => singlelayer/SingleLayerPortService.java} (68%) create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerTableMultipartService.java rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{ => util}/RequestContextUtil.java (96%) rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{ => util}/RequestInputUtils.java (95%) rename openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/{ => util}/ServiceException.java (91%) create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractFlowDirectStatisticsService.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractGroupDirectStatisticsService.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractMeterDirectStatisticsService.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractPortDirectStatisticsService.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractQueueDirectStatisticsService.java delete mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/FlowDirectStatisticsService.java delete mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/GroupDirectStatisticsService.java delete mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/MeterDirectStatisticsService.java delete mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/NodeConnectorDirectStatisticsService.java delete mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/QueueDirectStatisticsService.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/FlowDirectStatisticsService.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/GroupDirectStatisticsService.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/MeterDirectStatisticsService.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/MultiLayerDirectStatisticsProviderInitializer.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/PortDirectStatisticsService.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/QueueDirectStatisticsService.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/singlelayer/FlowDirectStatisticsService.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/singlelayer/GroupDirectStatisticsService.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/singlelayer/MeterDirectStatisticsService.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/singlelayer/PortDirectStatisticsService.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/singlelayer/QueueDirectStatisticsService.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/singlelayer/SingleLayerDirectStatisticsProviderInitializer.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/DeviceInitializationUtil.java delete mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/DeviceInitializationUtils.java delete mode 100644 openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/common/NodeConnectorTranslatorUtilTest.java rename openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/FlowCapableTransactionServiceImplTest.java (83%) rename openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/NodeConfigServiceImplTest.java (87%) rename openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/PacketProcessingServiceImplTest.java (93%) rename openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/SalEchoServiceImplTest.java (90%) rename openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/SalExperimenterMessageServiceImplTest.java (92%) rename openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/SalFlatBatchServiceImplTest.java (99%) rename openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/SalFlowServiceImplTest.java (98%) rename openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/SalFlowsBatchServiceImplTest.java (98%) rename openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/SalGroupServiceImplTest.java (96%) rename openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/SalGroupsBatchServiceImplTest.java (98%) rename openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/SalMeterServiceImplTest.java (96%) rename openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/SalMetersBatchServiceImplTest.java (98%) rename openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/SalPortServiceImplTest.java (93%) rename openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/SalRoleServiceImplTest.java (97%) rename openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/{ => sal}/SalTableServiceImplTest.java (95%) rename openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/{SinglePurposeMultipartReplyTranslatorTest.java => MultipartReplyTranslatorTest.java} (80%) rename openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/{ => multilayer}/FlowDirectStatisticsServiceTest.java (92%) rename openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/{ => multilayer}/GroupDirectStatisticsServiceTest.java (91%) rename openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/{ => multilayer}/MeterDirectStatisticsServiceTest.java (91%) rename openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/{ => multilayer}/NodeConnectorDirectStatisticsServiceTest.java (90%) rename openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/{ => multilayer}/QueueDirectStatisticsServiceTest.java (91%) delete mode 100644 openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/util/DeviceInitializationUtilsTest.java diff --git a/model/model-flow-statistics/src/main/yang/opendaylight-flow-table-statistics.yang b/model/model-flow-statistics/src/main/yang/opendaylight-flow-table-statistics.yang index 025b9a4b31..96e4e8d55a 100644 --- a/model/model-flow-statistics/src/main/yang/opendaylight-flow-table-statistics.yang +++ b/model/model-flow-statistics/src/main/yang/opendaylight-flow-table-statistics.yang @@ -34,8 +34,7 @@ module opendaylight-flow-table-statistics { } grouping flow-table-and-statistics-map { - status deprecated; - description "RPC calls to fetch flow table statistics."; + description "List of flow table and statistic map."; list flow-table-and-statistics-map { key "table-id"; diff --git a/model/model-flow-statistics/src/main/yang/opendaylight-port-statistics.yang b/model/model-flow-statistics/src/main/yang/opendaylight-port-statistics.yang index e23467031a..e63f1bd7af 100644 --- a/model/model-flow-statistics/src/main/yang/opendaylight-port-statistics.yang +++ b/model/model-flow-statistics/src/main/yang/opendaylight-port-statistics.yang @@ -64,8 +64,6 @@ module opendaylight-port-statistics { //Notification for node connector statistics update grouping node-connector-statistics-and-port-number-map { - status deprecated; - description "List of map - node connectors and their statistics"; list node-connector-statistics-and-port-number-map { key "node-connector-id"; diff --git a/model/model-flow-statistics/src/main/yang/opendaylight-queue-statistics.yang b/model/model-flow-statistics/src/main/yang/opendaylight-queue-statistics.yang index 2bd0681619..0768119a88 100644 --- a/model/model-flow-statistics/src/main/yang/opendaylight-queue-statistics.yang +++ b/model/model-flow-statistics/src/main/yang/opendaylight-queue-statistics.yang @@ -36,8 +36,6 @@ module opendaylight-queue-statistics { //RPC calls to fetch queue statistics grouping queue-id-and-statistics-map { - status deprecated; - list queue-id-and-statistics-map { key "queue-id node-connector-id"; leaf queue-id { diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceContext.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceContext.java index b26a7addb8..efd6fe4e7a 100644 --- a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceContext.java +++ b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceContext.java @@ -21,7 +21,7 @@ import org.opendaylight.openflowplugin.api.openflow.device.handlers.MultiMsgColl import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleService; import org.opendaylight.openflowplugin.api.openflow.registry.ItemLifeCycleRegistry; 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.openflow.protocol.rev130731.OfHeader; import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SalRoleService; import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleOutput; import org.opendaylight.yangtools.yang.common.RpcResult; @@ -107,7 +107,7 @@ public interface DeviceContext extends MessageSpy getMessageSpy(); - MultiMsgCollector getMultiMsgCollector(final RequestContext> requestContext); + MultiMsgCollector getMultiMsgCollector(final RequestContext> requestContext); /** * indicates that device context is fully published (e.g.: packetIn messages should be passed) @@ -146,6 +146,6 @@ public interface DeviceContext extends */ ListenableFuture> makeDeviceSlave(); - boolean isUseSingleLayerSerialization(); + boolean canUseSingleLayerSerialization(); } diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/handlers/DeviceReplyProcessor.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/handlers/DeviceReplyProcessor.java index e6f581f706..90f138d0b7 100644 --- a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/handlers/DeviceReplyProcessor.java +++ b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/handlers/DeviceReplyProcessor.java @@ -12,7 +12,6 @@ import java.util.List; import org.opendaylight.openflowplugin.api.openflow.device.Xid; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemoved; -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.PacketInMessage; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage; @@ -32,36 +31,36 @@ public interface DeviceReplyProcessor { /** * Method that set future to context in Map * - * @param xid, - * @param ofHeaderList + * @param xid xid + * @param ofHeaderList openflow header list */ - void processReply(Xid xid, List ofHeaderList); + void processReply(Xid xid, List ofHeaderList); /** * Method process async flow removed from device * - * @param flowRemoved + * @param flowRemoved flow removed */ void processFlowRemovedMessage(FlowRemoved flowRemoved); /** * Method process async port status from device * - * @param portStatus + * @param portStatus port status */ void processPortStatusMessage(PortStatusMessage portStatus); /** * Method process async packet in from device * - * @param packetInMessage + * @param packetInMessage packet in message */ void processPacketInMessage(PacketInMessage packetInMessage); /** * Processing of experimenter symmetric message from device * - * @param notification + * @param notification notification */ void processExperimenterMessage(ExperimenterMessage notification); } diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/handlers/MultiMsgCollector.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/handlers/MultiMsgCollector.java index 6d597eb931..de21d2575e 100644 --- a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/handlers/MultiMsgCollector.java +++ b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/handlers/MultiMsgCollector.java @@ -9,8 +9,9 @@ package org.opendaylight.openflowplugin.api.openflow.device.handlers; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; /** *

@@ -24,24 +25,24 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731 *

* Created: Mar 23, 2015 */ -public interface MultiMsgCollector { +public interface MultiMsgCollector { /** * Method adds a reply multipart message to the collection and if the message has marker * "I'M A LAST" method set whole Collection to Future object and remove from cache. * - * @param reply + * @param reply reply + * @param reqMore request more replies + * @param eventIdentifier event identifier */ - void addMultipartMsg(@Nonnull MultipartReply reply); - - void addMultipartMsg(@Nonnull MultipartReply reply, @Nonnull EventIdentifier eventIdentifier); + void addMultipartMsg(@Nonnull T reply, boolean reqMore, @Nullable EventIdentifier eventIdentifier); /** * Null response could be a valid end multipart collecting event for barrier response scenario. * We are not able to resolve an issue (it is or it isn't barrier scenario) so we have to finish * collecting multipart messages successfully. + * + * @param eventIdentifier event identifier */ - void endCollecting(); - - void endCollecting(EventIdentifier eventIdentifier); + void endCollecting(@Nullable EventIdentifier eventIdentifier); } diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/statistics/ofpspecific/StatisticsGatherer.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/statistics/ofpspecific/StatisticsGatherer.java index b7733ad2de..d9157d2ec3 100644 --- a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/statistics/ofpspecific/StatisticsGatherer.java +++ b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/statistics/ofpspecific/StatisticsGatherer.java @@ -8,15 +8,12 @@ package org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific; +import com.google.common.util.concurrent.ListenableFuture; import java.util.List; -import java.util.concurrent.Future; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; -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.yangtools.yang.common.RpcResult; -/** - * Created by mirehak on 6/2/15. - */ -public interface StatisticsGatherer { - Future>> getStatisticsOfType(EventIdentifier eventIdentifier, MultipartType type); +public interface StatisticsGatherer { + ListenableFuture>> getStatisticsOfType(EventIdentifier eventIdentifier, MultipartType type); } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImpl.java index 2b647610c9..1864a2c38f 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImpl.java @@ -45,6 +45,8 @@ import org.opendaylight.openflowplugin.extension.api.OpenFlowPluginExtensionRegi import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterManager; import org.opendaylight.openflowplugin.impl.connection.ConnectionManagerImpl; import org.opendaylight.openflowplugin.impl.device.DeviceManagerImpl; +import org.opendaylight.openflowplugin.impl.device.initialization.DeviceInitializerProvider; +import org.opendaylight.openflowplugin.impl.device.initialization.DeviceInitializerProviderFactory; import org.opendaylight.openflowplugin.impl.protocol.deserialization.DeserializerInjector; import org.opendaylight.openflowplugin.impl.protocol.serialization.SerializerInjector; import org.opendaylight.openflowplugin.impl.rpc.RpcManagerImpl; @@ -98,6 +100,7 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF private long basicTimerDelay; private long maximumTimerDelay; private boolean useSingleLayerSerialization = false; + private final DeviceInitializerProvider deviceInitializerProvider; private final ThreadPoolExecutor threadPool; private ClusterSingletonServiceProvider singletonServicesProvider; @@ -119,7 +122,9 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF Preconditions.checkNotNull(threadPoolMaxThreads), Preconditions.checkNotNull(threadPoolTimeout), TimeUnit.SECONDS, new SynchronousQueue<>(), "ofppool"); + convertorManager = ConvertorManagerFactory.createDefaultManager(); + deviceInitializerProvider = DeviceInitializerProviderFactory.createDefaultProvider(); } @Override @@ -253,7 +258,8 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF hashedWheelTimer, convertorManager, skipTableFeatures, - useSingleLayerSerialization); + useSingleLayerSerialization, + deviceInitializerProvider); ((ExtensionConverterProviderKeeper) deviceManager).setExtensionConverterProvider(extensionConverterManager); diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/SinglePurposeMultipartReplyTranslator.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/common/MultipartReplyTranslatorUtil.java similarity index 54% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/SinglePurposeMultipartReplyTranslator.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/common/MultipartReplyTranslatorUtil.java index 6116659180..1a07a4340c 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/SinglePurposeMultipartReplyTranslator.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/common/MultipartReplyTranslatorUtil.java @@ -1,37 +1,53 @@ /* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.statistics; + +package org.opendaylight.openflowplugin.impl.common; import java.math.BigInteger; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; +import javax.annotation.Nullable; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo; +import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator; +import org.opendaylight.openflowplugin.api.openflow.device.TranslatorLibrary; +import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey; import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion; import org.opendaylight.openflowplugin.extension.api.path.MatchPath; import org.opendaylight.openflowplugin.impl.util.GroupUtil; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.FlowStatsResponseConvertorData; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData; import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter64; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdateBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.multipart.reply.multipart.reply.body.MultipartReplyDescBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowAggregateStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowAggregateStatsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowStatsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMap; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMapBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.multipart.reply.multipart.reply.body.MultipartReplyFlowTableStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.multipart.reply.multipart.reply.body.MultipartReplyFlowTableStatsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.multipart.reply.multipart.reply.body.MultipartReplyPortDesc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.multipart.reply.multipart.reply.body.MultipartReplyPortDescBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.multipart.reply.multipart.reply.body.multipart.reply.port.desc.PortsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupDescStatsUpdatedBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupFeaturesUpdatedBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupStatisticsUpdatedBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyGroupDescBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyGroupFeaturesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyGroupStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyGroupStatsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.Chaining; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.ChainingChecks; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupAll; @@ -44,10 +60,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.Selec import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.SelectWeight; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterConfigStatsUpdatedBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterFeaturesUpdatedBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterStatisticsUpdatedBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyMeterConfigBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyMeterStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyMeterStatsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBand; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandDrop; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandDscpRemark; @@ -60,10 +76,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.BytesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.PacketsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.multipart.reply.MultipartReplyBody; +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.PortGrouping; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDescCase; @@ -71,10 +89,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfigCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortDescCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableFeaturesCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.aggregate._case.MultipartReplyAggregate; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.desc._case.MultipartReplyDesc; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.MultipartReplyFlow; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.MultipartReplyGroup; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc._case.MultipartReplyGroupDesc; @@ -88,134 +109,174 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStats; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.MultipartReplyTable; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.multipart.reply.table.TableStats; -import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.MultipartReplyTableFeatures; +import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.multipart.reply.multipart.reply.body.MultipartReplyPortStatsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap; import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.QueueStatisticsUpdateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.multipart.reply.multipart.reply.body.MultipartReplyQueueStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.multipart.reply.multipart.reply.body.MultipartReplyQueueStatsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap; import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMapBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.multipart.reply.multipart.reply.body.MultipartReplyTableFeaturesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId; -import org.opendaylight.yangtools.yang.binding.DataObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * Class converts multipart reply messages to the notification objects defined - * by statistics provider (manager ). It is ment to be replaced by translators - * and to be used for translating statistics data only. - * - * @author avishnoi@in.ibm.com + * Class converts multipart reply messages to the objects that can be then written to datastore using + * multipart writers */ -@Deprecated -public class SinglePurposeMultipartReplyTranslator { - - protected static final Logger logger = LoggerFactory - .getLogger(SinglePurposeMultipartReplyTranslator.class); - private final ConvertorExecutor convertorExecutor; +public class MultipartReplyTranslatorUtil { + private static final Logger LOG = LoggerFactory.getLogger(MultipartReplyTranslatorUtil.class); + + public static Optional translate(final OfHeader message, + final DeviceInfo deviceInfo, + @Nullable final ConvertorExecutor convertorExecutor, + @Nullable final TranslatorLibrary translatorLibrary) { + if (message instanceof MultipartReply) { + final Optional convertor = Optional.ofNullable(convertorExecutor); + final Optional translator = Optional.ofNullable(translatorLibrary); + final MultipartReply msg = MultipartReply.class.cast(message); + final OpenflowVersion ofVersion = OpenflowVersion.get(deviceInfo.getVersion()); + final VersionDatapathIdConvertorData data = new VersionDatapathIdConvertorData(deviceInfo.getVersion()); + data.setDatapathId(deviceInfo.getDatapathId()); + + switch (msg.getType()) { + case OFPMPFLOW: + return convertor.flatMap(c -> Optional.of(translateFlow(msg, data, c))); + case OFPMPAGGREGATE: + return Optional.of(translateAggregate(msg)); + case OFPMPPORTSTATS: + return Optional.of(translatePortStats(msg, ofVersion, deviceInfo.getDatapathId())); + case OFPMPGROUP: + return convertor.flatMap(c -> Optional.of(translateGroup(msg, data, c))); + case OFPMPGROUPDESC: + return convertor.flatMap(c -> Optional.of(translateGroupDesc(msg, data, c))); + case OFPMPGROUPFEATURES: + return Optional.of(translateGroupFeatures(msg)); + case OFPMPMETER: + return convertor.flatMap(c -> Optional.of(translateMeter(msg, data, c))); + case OFPMPMETERCONFIG: + return convertor.flatMap(c -> Optional.of(translateMeterConfig(msg, data, c))); + case OFPMPMETERFEATURES: + return Optional.of(translateMeterFeatures(msg)); + case OFPMPTABLE: + return Optional.of(translateTable(msg)); + case OFPMPQUEUE: + return Optional.of(translateQueue(msg, ofVersion, deviceInfo.getDatapathId())); + case OFPMPDESC: + return Optional.of(translateDesc(msg)); + case OFPMPTABLEFEATURES: + return convertor.flatMap(c -> Optional.of(translateTableFeatures(msg, deviceInfo.getVersion(), c))); + case OFPMPPORTDESC: + return translator.flatMap(t -> Optional.of(translatePortDesc(msg, deviceInfo, t))); + } + } else if (message instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112 + .MultipartReply) { + return Optional.of(org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112 + .MultipartReply.class.cast(message).getMultipartReplyBody()); + } - public SinglePurposeMultipartReplyTranslator(ConvertorExecutor convertorExecutor) { - this.convertorExecutor = convertorExecutor; + LOG.debug("Failed to translate {} for node {}.", message.getImplementedInterface(), deviceInfo.getLOGValue()); + return Optional.empty(); } - public List translate(final BigInteger datapathId, final short version, final OfHeader msg) { - - List listDataObject = new ArrayList<>(); - - if (msg instanceof MultipartReplyMessage) { - MultipartReplyMessage mpReply = (MultipartReplyMessage) msg; - OpenflowVersion ofVersion = OpenflowVersion.get(version); - NodeId node = nodeIdFromDatapathId(datapathId); - VersionDatapathIdConvertorData data = new VersionDatapathIdConvertorData(version); - data.setDatapathId(datapathId); - - translateFlow(listDataObject, mpReply, node, data); - translateAggregate(listDataObject, mpReply, node); - translatePortStats(listDataObject, mpReply, node, ofVersion, datapathId); - translateGroup(listDataObject, mpReply, node, data); - translateGroupDesc(listDataObject, mpReply, node, data); - translateGroupFeatures(listDataObject, mpReply, node); - translateMeter(listDataObject, mpReply, node, data); - translateMeterConfig(listDataObject, mpReply, node, data); - translateMeterFeatures(listDataObject, mpReply, node); - translateTable(listDataObject, mpReply, node); - translateQueue(listDataObject, mpReply, node, ofVersion, datapathId); - } + private static MultipartReplyPortDesc translatePortDesc(final MultipartReply msg, + final DeviceInfo deviceInfo, + final TranslatorLibrary translatorLibrary) { + return new MultipartReplyPortDescBuilder() + .setPorts(((MultipartReplyPortDescCase) msg.getMultipartReplyBody()) + .getMultipartReplyPortDesc() + .getPorts() + .stream() + .map(port -> { + final TranslatorKey translatorKey = new TranslatorKey( + deviceInfo.getVersion(), + PortGrouping.class.getName()); + + final MessageTranslator translator = translatorLibrary + .lookupTranslator(translatorKey); + + return new PortsBuilder(translator + .translate(port, deviceInfo, null)) + .build(); + }) + .collect(Collectors.toList())) + .build(); + } - return listDataObject; + private static org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.multipart.reply.multipart.reply.body + .MultipartReplyTableFeatures translateTableFeatures(final MultipartReply msg, + final short version, + final ConvertorExecutor convertorExecutor) { + MultipartReplyTableFeaturesCase caseBody = (MultipartReplyTableFeaturesCase) msg.getMultipartReplyBody(); + final MultipartReplyTableFeatures multipartReplyTableFeatures = caseBody.getMultipartReplyTableFeatures(); + final Optional> tableFeaturesList = convertorExecutor + .convert(multipartReplyTableFeatures, new VersionConvertorData(version)); + + return new MultipartReplyTableFeaturesBuilder() + .setTableFeatures(tableFeaturesList.orElse(Collections.emptyList())) + .build(); } - private void translateFlow(final List listDataObject, - final MultipartReplyMessage mpReply, - final NodeId node, VersionDatapathIdConvertorData data) { - if (!MultipartType.OFPMPFLOW.equals(mpReply.getType())) { - return; - } + private static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.multipart.reply.multipart.reply.body + .MultipartReplyDesc translateDesc(final MultipartReply msg) { + final MultipartReplyDesc desc = ((MultipartReplyDescCase) msg.getMultipartReplyBody()).getMultipartReplyDesc(); + + return new MultipartReplyDescBuilder() + .setDescription(desc.getDpDesc()) + .setHardware(desc.getHwDesc()) + .setManufacturer(desc.getMfrDesc()) + .setSoftware(desc.getSwDesc()) + .setSerialNumber(desc.getSerialNum()) + .build(); + } + private static MultipartReplyFlowStats translateFlow(final MultipartReply msg, + final VersionDatapathIdConvertorData data, + final ConvertorExecutor convertorExecutor) { FlowStatsResponseConvertorData flowData = new FlowStatsResponseConvertorData(data.getVersion()); flowData.setDatapathId(data.getDatapathId()); flowData.setMatchPath(MatchPath.FLOWSSTATISTICSUPDATE_FLOWANDSTATISTICSMAPLIST_MATCH); - FlowsStatisticsUpdateBuilder message = new FlowsStatisticsUpdateBuilder(); - message.setId(node); - message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE()); - message.setTransactionId(generateTransactionId(mpReply.getXid())); - MultipartReplyFlowCase caseBody = (MultipartReplyFlowCase) mpReply.getMultipartReplyBody(); + MultipartReplyFlowStatsBuilder message = new MultipartReplyFlowStatsBuilder(); + MultipartReplyFlowCase caseBody = (MultipartReplyFlowCase) msg.getMultipartReplyBody(); MultipartReplyFlow replyBody = caseBody.getMultipartReplyFlow(); final Optional> flowAndStatisticsMapLists = - convertorExecutor.convert(replyBody.getFlowStats(), flowData); + convertorExecutor.convert(replyBody.getFlowStats(), flowData); message.setFlowAndStatisticsMapList(flowAndStatisticsMapLists.orElse(Collections.emptyList())); - - listDataObject.add(message.build()); + return message.build(); } - private void translateAggregate(final List listDataObject, - final MultipartReplyMessage mpReply, - final NodeId node) { - if (!MultipartType.OFPMPAGGREGATE.equals(mpReply.getType())) { - return; - } - - AggregateFlowStatisticsUpdateBuilder message = new AggregateFlowStatisticsUpdateBuilder(); - message.setId(node); - message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE()); - message.setTransactionId(generateTransactionId(mpReply.getXid())); - - MultipartReplyAggregateCase caseBody = (MultipartReplyAggregateCase) mpReply.getMultipartReplyBody(); + private static MultipartReplyFlowAggregateStats translateAggregate(final MultipartReply msg) { + MultipartReplyFlowAggregateStatsBuilder message = new MultipartReplyFlowAggregateStatsBuilder(); + MultipartReplyAggregateCase caseBody = (MultipartReplyAggregateCase) msg.getMultipartReplyBody(); MultipartReplyAggregate replyBody = caseBody.getMultipartReplyAggregate(); message.setByteCount(new Counter64(replyBody.getByteCount())); message.setPacketCount(new Counter64(replyBody.getPacketCount())); message.setFlowCount(new Counter32(replyBody.getFlowCount())); - - listDataObject.add(message.build()); + return message.build(); } - private void translatePortStats(final List listDataObject, - final MultipartReplyMessage mpReply, - final NodeId node, - final OpenflowVersion ofVersion, - final BigInteger datapathId) { - if (!MultipartType.OFPMPPORTSTATS.equals(mpReply.getType())) { - return; - } - - NodeConnectorStatisticsUpdateBuilder message = new NodeConnectorStatisticsUpdateBuilder(); - message.setId(node); - message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE()); - message.setTransactionId(generateTransactionId(mpReply.getXid())); - - MultipartReplyPortStatsCase caseBody = (MultipartReplyPortStatsCase) mpReply.getMultipartReplyBody(); + private static org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.multipart.reply.multipart.reply.body + .MultipartReplyPortStats translatePortStats(final MultipartReply msg, + final OpenflowVersion ofVersion, + final BigInteger datapathId) { + MultipartReplyPortStatsBuilder message = new MultipartReplyPortStatsBuilder(); + MultipartReplyPortStatsCase caseBody = (MultipartReplyPortStatsCase) msg.getMultipartReplyBody(); MultipartReplyPortStats replyBody = caseBody.getMultipartReplyPortStats(); List statsMap = - new ArrayList<>(); + new ArrayList<>(); for (PortStats portStats : replyBody.getPortStats()) { NodeConnectorStatisticsAndPortNumberMapBuilder statsBuilder = - new NodeConnectorStatisticsAndPortNumberMapBuilder(); + new NodeConnectorStatisticsAndPortNumberMapBuilder(); statsBuilder.setNodeConnectorId( - InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId, - portStats.getPortNo(), ofVersion)); + InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId, + portStats.getPortNo(), ofVersion)); BytesBuilder bytesBuilder = new BytesBuilder(); bytesBuilder.setReceived(portStats.getRxBytes()); @@ -250,69 +311,46 @@ public class SinglePurposeMultipartReplyTranslator { message.setNodeConnectorStatisticsAndPortNumberMap(statsMap); - listDataObject.add(message.build()); + return message.build(); } - private void translateGroup(final List listDataObject, - final MultipartReplyMessage mpReply, - final NodeId node, - final VersionDatapathIdConvertorData data) { - if (!MultipartType.OFPMPGROUP.equals(mpReply.getType())) { - return; - } - - GroupStatisticsUpdatedBuilder message = new GroupStatisticsUpdatedBuilder(); - message.setId(node); - message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE()); - message.setTransactionId(generateTransactionId(mpReply.getXid())); - MultipartReplyGroupCase caseBody = (MultipartReplyGroupCase) mpReply.getMultipartReplyBody(); + private static MultipartReplyGroupStats translateGroup(final MultipartReply msg, + final VersionDatapathIdConvertorData data, + final ConvertorExecutor convertorExecutor) { + MultipartReplyGroupStatsBuilder message = new MultipartReplyGroupStatsBuilder(); + MultipartReplyGroupCase caseBody = (MultipartReplyGroupCase) msg.getMultipartReplyBody(); MultipartReplyGroup replyBody = caseBody.getMultipartReplyGroup(); final Optional> groupStatsList = convertorExecutor.convert( - replyBody.getGroupStats(), data); + replyBody.getGroupStats(), data); message.setGroupStats(groupStatsList.orElse(Collections.emptyList())); - listDataObject.add(message.build()); + return message.build(); } - private void translateGroupDesc(final List listDataObject, - final MultipartReplyMessage mpReply, - final NodeId node, - final VersionDatapathIdConvertorData data) { - if (!MultipartType.OFPMPGROUPDESC.equals(mpReply.getType())) { - return; - } - - GroupDescStatsUpdatedBuilder message = new GroupDescStatsUpdatedBuilder(); - message.setId(node); - message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE()); - message.setTransactionId(generateTransactionId(mpReply.getXid())); - MultipartReplyGroupDescCase caseBody = (MultipartReplyGroupDescCase) mpReply.getMultipartReplyBody(); + private static org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart.reply.body + .MultipartReplyGroupDesc translateGroupDesc(final MultipartReply msg, + final VersionDatapathIdConvertorData data, + final ConvertorExecutor convertorExecutor) { + MultipartReplyGroupDescBuilder message = new MultipartReplyGroupDescBuilder(); + MultipartReplyGroupDescCase caseBody = (MultipartReplyGroupDescCase) msg.getMultipartReplyBody(); MultipartReplyGroupDesc replyBody = caseBody.getMultipartReplyGroupDesc(); final Optional> groupDescStatsList = convertorExecutor.convert( - replyBody.getGroupDesc(), data); + replyBody.getGroupDesc(), data); message.setGroupDescStats(groupDescStatsList.orElse(Collections.emptyList())); - listDataObject.add(message.build()); + return message.build(); } - private void translateGroupFeatures(final List listDataObject, - final MultipartReplyMessage mpReply, - final NodeId node) { - if (!MultipartType.OFPMPGROUPFEATURES.equals(mpReply.getType())) { - return; - } - - GroupFeaturesUpdatedBuilder message = new GroupFeaturesUpdatedBuilder(); - message.setId(node); - message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE()); - message.setTransactionId(generateTransactionId(mpReply.getXid())); - MultipartReplyGroupFeaturesCase caseBody = (MultipartReplyGroupFeaturesCase) mpReply.getMultipartReplyBody(); + private static org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart.reply.body + .MultipartReplyGroupFeatures translateGroupFeatures(final MultipartReply msg) { + MultipartReplyGroupFeaturesBuilder message = new MultipartReplyGroupFeaturesBuilder(); + MultipartReplyGroupFeaturesCase caseBody = (MultipartReplyGroupFeaturesCase) msg.getMultipartReplyBody(); MultipartReplyGroupFeatures replyBody = caseBody.getMultipartReplyGroupFeatures(); List> supportedGroups = - new ArrayList<>(); + new ArrayList<>(); if (replyBody.getTypes().isOFPGTALL()) { supportedGroups.add(GroupAll.class); @@ -330,7 +368,7 @@ public class SinglePurposeMultipartReplyTranslator { message.setMaxGroups(replyBody.getMaxGroups()); List> supportedCapabilities = - new ArrayList<>(); + new ArrayList<>(); if (replyBody.getCapabilities().isOFPGFCCHAINING()) { supportedCapabilities.add(Chaining.class); @@ -348,75 +386,48 @@ public class SinglePurposeMultipartReplyTranslator { message.setGroupCapabilitiesSupported(supportedCapabilities); message.setActions(GroupUtil.extractGroupActionsSupportBitmap(replyBody.getActionsBitmap())); - listDataObject.add(message.build()); + return message.build(); } - private void translateMeter(final List listDataObject, - final MultipartReplyMessage mpReply, - final NodeId node, - final VersionDatapathIdConvertorData data) { - if (!MultipartType.OFPMPMETER.equals(mpReply.getType())) { - return; - } - - MeterStatisticsUpdatedBuilder message = new MeterStatisticsUpdatedBuilder(); - message.setId(node); - message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE()); - message.setTransactionId(generateTransactionId(mpReply.getXid())); - - MultipartReplyMeterCase caseBody = (MultipartReplyMeterCase) mpReply.getMultipartReplyBody(); + private static MultipartReplyMeterStats translateMeter(final MultipartReply msg, + final VersionDatapathIdConvertorData data, + final ConvertorExecutor convertorExecutor) { + MultipartReplyMeterStatsBuilder message = new MultipartReplyMeterStatsBuilder(); + MultipartReplyMeterCase caseBody = (MultipartReplyMeterCase) msg.getMultipartReplyBody(); MultipartReplyMeter replyBody = caseBody.getMultipartReplyMeter(); final Optional> meterStatsList = - convertorExecutor.convert(replyBody.getMeterStats(), data); + convertorExecutor.convert(replyBody.getMeterStats(), data); message.setMeterStats(meterStatsList.orElse(Collections.emptyList())); - listDataObject.add(message.build()); + return message.build(); } - private void translateMeterConfig(final List listDataObject, - final MultipartReplyMessage mpReply, - final NodeId node, - final VersionDatapathIdConvertorData data) { - if (!MultipartType.OFPMPMETERCONFIG.equals(mpReply.getType())) { - return; - } - - MeterConfigStatsUpdatedBuilder message = new MeterConfigStatsUpdatedBuilder(); - message.setId(node); - message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE()); - message.setTransactionId(generateTransactionId(mpReply.getXid())); - - MultipartReplyMeterConfigCase caseBody = (MultipartReplyMeterConfigCase) mpReply.getMultipartReplyBody(); + private static org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart.reply.body + .MultipartReplyMeterConfig translateMeterConfig(final MultipartReply msg, + final VersionDatapathIdConvertorData data, + final ConvertorExecutor convertorExecutor) { + MultipartReplyMeterConfigBuilder message = new MultipartReplyMeterConfigBuilder(); + MultipartReplyMeterConfigCase caseBody = (MultipartReplyMeterConfigCase) msg.getMultipartReplyBody(); MultipartReplyMeterConfig replyBody = caseBody.getMultipartReplyMeterConfig(); final Optional> meterConfigStatsList = convertorExecutor.convert(replyBody.getMeterConfig(), data); message.setMeterConfigStats(meterConfigStatsList.orElse(Collections.emptyList())); - listDataObject.add(message.build()); + return message.build(); } - private void translateMeterFeatures(final List listDataObject, - final MultipartReplyMessage mpReply, - final NodeId node) { - if (!MultipartType.OFPMPMETERFEATURES.equals(mpReply.getType())) { - return; - } - - //Convert OF message and send it to SAL listener - MeterFeaturesUpdatedBuilder message = new MeterFeaturesUpdatedBuilder(); - message.setId(node); - message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE()); - message.setTransactionId(generateTransactionId(mpReply.getXid())); - - MultipartReplyMeterFeaturesCase caseBody = (MultipartReplyMeterFeaturesCase) mpReply.getMultipartReplyBody(); + private static org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart.reply.body + .MultipartReplyMeterFeatures translateMeterFeatures(final MultipartReply msg) { + MultipartReplyMeterFeaturesBuilder message = new MultipartReplyMeterFeaturesBuilder(); + MultipartReplyMeterFeaturesCase caseBody = (MultipartReplyMeterFeaturesCase) msg.getMultipartReplyBody(); MultipartReplyMeterFeatures replyBody = caseBody.getMultipartReplyMeterFeatures(); message.setMaxBands(replyBody.getMaxBands()); message.setMaxColor(replyBody.getMaxColor()); message.setMaxMeter(new Counter32(replyBody.getMaxMeter())); List> supportedCapabilities = - new ArrayList<>(); + new ArrayList<>(); if (replyBody.getCapabilities().isOFPMFBURST()) { supportedCapabilities.add(MeterBurst.class); } @@ -435,7 +446,7 @@ public class SinglePurposeMultipartReplyTranslator { message.setMeterCapabilitiesSupported(supportedCapabilities); List> supportedMeterBand = - new ArrayList<>(); + new ArrayList<>(); if (replyBody.getBandTypes().isOFPMBTDROP()) { supportedMeterBand.add(MeterBandDrop.class); } @@ -443,22 +454,12 @@ public class SinglePurposeMultipartReplyTranslator { supportedMeterBand.add(MeterBandDscpRemark.class); } message.setMeterBandSupported(supportedMeterBand); - listDataObject.add(message.build()); + return message.build(); } - private void translateTable(final List listDataObject, - final MultipartReplyMessage mpReply, - final NodeId node) { - if (!MultipartType.OFPMPTABLE.equals(mpReply.getType())) { - return; - } - - FlowTableStatisticsUpdateBuilder message = new FlowTableStatisticsUpdateBuilder(); - message.setId(node); - message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE()); - message.setTransactionId(generateTransactionId(mpReply.getXid())); - - MultipartReplyTableCase caseBody = (MultipartReplyTableCase) mpReply.getMultipartReplyBody(); + private static MultipartReplyFlowTableStats translateTable(final MultipartReply msg) { + MultipartReplyFlowTableStatsBuilder message = new MultipartReplyFlowTableStatsBuilder(); + MultipartReplyTableCase caseBody = (MultipartReplyTableCase) msg.getMultipartReplyBody(); MultipartReplyTable replyBody = caseBody.getMultipartReplyTable(); List swTablesStats = replyBody.getTableStats(); @@ -474,36 +475,26 @@ public class SinglePurposeMultipartReplyTranslator { } message.setFlowTableAndStatisticsMap(salFlowStats); - listDataObject.add(message.build()); + return message.build(); } - private void translateQueue(final List listDataObject, - final MultipartReplyMessage mpReply, - final NodeId node, - final OpenflowVersion ofVersion, - final BigInteger datapathId) { - if (!MultipartType.OFPMPQUEUE.equals(mpReply.getType())) { - return; - } - - QueueStatisticsUpdateBuilder message = new QueueStatisticsUpdateBuilder(); - message.setId(node); - message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE()); - message.setTransactionId(generateTransactionId(mpReply.getXid())); - - MultipartReplyQueueCase caseBody = (MultipartReplyQueueCase) mpReply.getMultipartReplyBody(); + private static MultipartReplyQueueStats translateQueue(final MultipartReply msg, + final OpenflowVersion ofVersion, + final BigInteger datapathId) { + MultipartReplyQueueStatsBuilder message = new MultipartReplyQueueStatsBuilder(); + MultipartReplyQueueCase caseBody = (MultipartReplyQueueCase) msg.getMultipartReplyBody(); MultipartReplyQueue replyBody = caseBody.getMultipartReplyQueue(); List statsMap = - new ArrayList(); + new ArrayList<>(); for (QueueStats queueStats : replyBody.getQueueStats()) { QueueIdAndStatisticsMapBuilder statsBuilder = - new QueueIdAndStatisticsMapBuilder(); + new QueueIdAndStatisticsMapBuilder(); statsBuilder.setNodeConnectorId( - InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId, - queueStats.getPortNo(), ofVersion)); + InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId, + queueStats.getPortNo(), ofVersion)); statsBuilder.setTransmissionErrors(new Counter64(queueStats.getTxErrors())); statsBuilder.setTransmittedBytes(new Counter64(queueStats.getTxBytes())); statsBuilder.setTransmittedPackets(new Counter64(queueStats.getTxPackets())); @@ -515,22 +506,13 @@ public class SinglePurposeMultipartReplyTranslator { statsBuilder.setQueueId(new QueueId(queueStats.getQueueId())); statsBuilder.setNodeConnectorId(InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId, - queueStats.getPortNo(), ofVersion)); + queueStats.getPortNo(), ofVersion)); statsMap.add(statsBuilder.build()); } message.setQueueIdAndStatisticsMap(statsMap); - listDataObject.add(message.build()); + return message.build(); } - private static NodeId nodeIdFromDatapathId(final BigInteger datapathId) { - String current = datapathId.toString(); - return new NodeId("openflow:" + current); - } - - private static TransactionId generateTransactionId(final Long xid) { - BigInteger bigIntXid = BigInteger.valueOf(xid); - return new TransactionId(bigIntXid); - } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/common/NodeConnectorTranslatorUtil.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/common/NodeConnectorTranslatorUtil.java deleted file mode 100644 index 9afc37e125..0000000000 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/common/NodeConnectorTranslatorUtil.java +++ /dev/null @@ -1,156 +0,0 @@ -/** - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.openflowplugin.impl.common; - -import com.google.common.base.Preconditions; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; -import org.opendaylight.openflowplugin.api.OFConstants; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortConfig; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortFeatures; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortNumberUni; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.flow.capable.port.State; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.flow.capable.port.StateBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfigV10; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeaturesV10; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortState; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortStateV10; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FeaturesReply; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.features.reply.PhyPort; - -/** - * openflowplugin-impl - * org.opendaylight.openflowplugin.impl.common - * - * Translator helper for Translating OF java models to MD-SAL inventory models. - * Translator focus for {@link NodeConnector} object and relevant OF augmentation - * {@link FlowCapableNodeConnector}. - * - * @author Vaclav Demcak - * - * Created: Mar 31, 2015 - */ -public final class NodeConnectorTranslatorUtil { - - private NodeConnectorTranslatorUtil () { - throw new UnsupportedOperationException("Utility class"); - } - - /** - * Method translates {@link PhyPort} object directly to {@link NodeConnector} which is augmented - * by {@link FlowCapableNodeConnector} and contains all relevant content translated by actual OF version. - * - * @param featuresReply - * @return - */ - public static List translateNodeConnectorFromFeaturesReply(@CheckForNull final FeaturesReply featuresReply) { - Preconditions.checkArgument(featuresReply != null); - Preconditions.checkArgument(featuresReply.getPhyPort() != null); - final Short version = featuresReply.getVersion(); - final BigInteger dataPathId = featuresReply.getDatapathId(); - final List resultList = new ArrayList<>(featuresReply.getPhyPort().size()); - for (final PhyPort port : featuresReply.getPhyPort()) { - final NodeConnectorBuilder ncBuilder = new NodeConnectorBuilder(); - ncBuilder.setId(makeNodeConnectorId(dataPathId, port.getName(), port.getPortNo())); - ncBuilder.addAugmentation(FlowCapableNodeConnector.class, translateFlowCapableNodeFromPhyPort(port, version)); - resultList.add(ncBuilder.build()); - } - return resultList; - } - - /** - * Method translates {@link PhyPort} object directly to {@link FlowCapableNodeConnector} which is augmented - * by {@link NodeConnector} and contains all relevant content translated by actual OF version. - * - * @param port - * @param version - * @return - */ - public static FlowCapableNodeConnector translateFlowCapableNodeFromPhyPort(@CheckForNull final PhyPort port, final short version) { - Preconditions.checkArgument(port != null); - final FlowCapableNodeConnectorBuilder fcncBuilder = new FlowCapableNodeConnectorBuilder(); - fcncBuilder.setHardwareAddress(port.getHwAddr()); - fcncBuilder.setCurrentSpeed(port.getCurrSpeed()); - fcncBuilder.setMaximumSpeed(port.getMaxSpeed()); - fcncBuilder.setName(port.getName()); - fcncBuilder.setPortNumber(new PortNumberUni(port.getPortNo())); - if (OFConstants.OFP_VERSION_1_3 == version) { - fcncBuilder.setAdvertisedFeatures(translatePortFeatures(port.getAdvertisedFeatures())); - fcncBuilder.setConfiguration(translatePortConfig(port.getConfig())); - fcncBuilder.setCurrentFeature(translatePortFeatures(port.getCurrentFeatures())); - fcncBuilder.setPeerFeatures(translatePortFeatures(port.getPeerFeatures())); - fcncBuilder.setSupported(translatePortFeatures(port.getSupportedFeatures())); - fcncBuilder.setState(translatePortState(port.getState())); - } else if (OFConstants.OFP_VERSION_1_0 == version) { - fcncBuilder.setAdvertisedFeatures(translatePortFeatures(port.getAdvertisedFeaturesV10())); - fcncBuilder.setConfiguration(translatePortConfig(port.getConfigV10())); - fcncBuilder.setCurrentFeature(translatePortFeatures(port.getCurrentFeaturesV10())); - fcncBuilder.setPeerFeatures(translatePortFeatures(port.getPeerFeaturesV10())); - fcncBuilder.setSupported(translatePortFeatures(port.getSupportedFeaturesV10())); - fcncBuilder.setState(translatePortState(port.getStateV10())); - } else { - throw new IllegalArgumentException("Unknown OF version " + version); - } - return fcncBuilder.build(); - } - - private static PortConfig translatePortConfig(@CheckForNull final org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfig pc) { - Preconditions.checkArgument(pc != null); - return new PortConfig(pc.isNoFwd(), pc.isNoPacketIn(), pc.isNoRecv(), pc.isPortDown()); - } - - private static PortConfig translatePortConfig(@CheckForNull final PortConfigV10 pc) { - Preconditions.checkArgument(pc != null); - return new PortConfig(pc.isNoFwd(), pc.isNoPacketIn(), pc.isNoRecv(), pc.isPortDown()); - } - - private static PortFeatures translatePortFeatures(@CheckForNull final org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeatures pf) { - Preconditions.checkArgument(pf != null); - return new PortFeatures(pf.isAutoneg(), pf.isCopper(), pf.isFiber(), pf.is_40gbFd(), pf.is_100gbFd(), pf.is_100mbFd(), pf.is_100mbHd(), - pf.is_1gbFd(), pf.is_1gbHd(), pf.is_1tbFd(), pf.isOther(), pf.isPause(), pf.isPauseAsym(), pf.is_10gbFd(), pf.is_10mbFd(), pf.is_10mbHd()); - } - - private static PortFeatures translatePortFeatures(@CheckForNull final PortFeaturesV10 pf) { - Preconditions.checkArgument(pf != null); - return new PortFeatures(pf.isAutoneg(), pf.isCopper(), pf.isFiber(), Boolean.FALSE, Boolean.FALSE, pf.is_100mbFd(), pf.is_100mbHd(), - pf.is_1gbFd(), pf.is_1gbHd(), Boolean.FALSE, Boolean.FALSE, pf.isPause(), pf.isPauseAsym(), pf.is_10gbFd(), pf.is_10mbFd(), pf.is_10mbHd()); - } - - private static State translatePortState(@CheckForNull final PortState state) { - Preconditions.checkArgument(state != null); - return new StateBuilder().setBlocked(state.isBlocked()).setLinkDown(state.isLinkDown()).setLive(state.isLive()).build(); - } - - private static State translatePortState(@CheckForNull final PortStateV10 state) { - Preconditions.checkArgument(state != null); - return new StateBuilder().setBlocked(state.isBlocked()).setLinkDown(state.isLinkDown()).setLive(state.isLive()).build(); - } - - /** - * Method makes NodeConnectorId with prefix "openflow:" from dataPathId and logical name or port number - * - * @param dataPathId - * @param logicalName - * @param portNo - * @return - */ - public static NodeConnectorId makeNodeConnectorId(@CheckForNull final BigInteger dataPathId, - @Nullable final String logicalName, final long portNo) { - Preconditions.checkArgument(dataPathId != null); - return new NodeConnectorId(OFConstants.OF_URI_PREFIX + dataPathId + ":" + (logicalName == null ? portNo : logicalName)); - } -} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/common/NodeStaticReplyTranslatorUtil.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/common/NodeStaticReplyTranslatorUtil.java deleted file mode 100644 index 78018d83a6..0000000000 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/common/NodeStaticReplyTranslatorUtil.java +++ /dev/null @@ -1,225 +0,0 @@ -/** - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.openflowplugin.impl.common; - -import com.google.common.base.Preconditions; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import javax.annotation.CheckForNull; -import org.opendaylight.openflowplugin.api.OFConstants; -import org.opendaylight.openflowplugin.impl.util.GroupUtil; -import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; -import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData; -import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeatures; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeaturesBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.features.GroupFeaturesBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.Chaining; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.ChainingChecks; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupAll; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupCapability; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupFf; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupIndirect; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupSelect; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.SelectLiveness; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.SelectWeight; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeatures; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeaturesBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.MeterFeaturesBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBand; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandDrop; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandDscpRemark; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBurst; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterCapability; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterKbps; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterPktps; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterStats; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.desc._case.MultipartReplyDesc; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.features._case.MultipartReplyGroupFeatures; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.features._case.MultipartReplyMeterFeatures; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.MultipartReplyTableFeatures; -import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures; - -/** - *

- * openflowplugin-impl - * org.opendaylight.openflowplugin.impl.common - * - * @author Vaclav Demcak - *

- * Created: Mar 31, 2015 - */ -public class NodeStaticReplyTranslatorUtil { - - private NodeStaticReplyTranslatorUtil() { - throw new UnsupportedOperationException("Utility class"); - } - - /** - * Method transforms OFjava multipart reply model {@link MultipartReplyDesc} object - * to inventory data model {@link FlowCapableNode} object. - * - * @param reply - * @return - */ - public static FlowCapableNodeBuilder nodeDescTranslator(@CheckForNull final MultipartReplyDesc reply, final IpAddress ipAddress) { - Preconditions.checkArgument(reply != null); - final FlowCapableNodeBuilder flowCapAugBuilder = new FlowCapableNodeBuilder(); - flowCapAugBuilder.setDescription(reply.getDpDesc()); - flowCapAugBuilder.setHardware(reply.getHwDesc()); - flowCapAugBuilder.setManufacturer(reply.getMfrDesc()); - flowCapAugBuilder.setSoftware(reply.getSwDesc()); - flowCapAugBuilder.setSerialNumber(reply.getSerialNum()); - flowCapAugBuilder.setTable(Collections.emptyList()); - flowCapAugBuilder.setMeter(Collections.emptyList()); - flowCapAugBuilder.setGroup(Collections.emptyList()); - if (ipAddress != null) { - flowCapAugBuilder.setIpAddress(ipAddress); - } - return flowCapAugBuilder; - } - - /** - * Method transforms OFjava multipart reply model {@link MultipartReplyMeterFeatures} object - * to inventory data model {@link NodeMeterFeatures} object. - * - * @param reply - * @return - */ - public static NodeMeterFeatures nodeMeterFeatureTranslator(@CheckForNull final MultipartReplyMeterFeatures reply) { - Preconditions.checkArgument(reply != null); - final MeterFeaturesBuilder meterFeature = new MeterFeaturesBuilder(); - meterFeature.setMaxBands(reply.getMaxBands()); - meterFeature.setMaxColor(reply.getMaxColor()); - meterFeature.setMaxMeter(new Counter32(reply.getMaxMeter())); - final List> meterBandTypes = new ArrayList<>(); - if (reply.getBandTypes().isOFPMBTDROP()) { - meterBandTypes.add(MeterBandDrop.class); - } - if (reply.getBandTypes().isOFPMBTDSCPREMARK()) { - meterBandTypes.add(MeterBandDscpRemark.class); - } - meterFeature.setMeterBandSupported(Collections.unmodifiableList(meterBandTypes)); - - final List> mCapability = new ArrayList<>(); - if (reply.getCapabilities().isOFPMFBURST()) { - mCapability.add(MeterBurst.class); - } - if (reply.getCapabilities().isOFPMFKBPS()) { - mCapability.add(MeterKbps.class); - - } - if (reply.getCapabilities().isOFPMFPKTPS()) { - mCapability.add(MeterPktps.class); - - } - if (reply.getCapabilities().isOFPMFSTATS()) { - mCapability.add(MeterStats.class); - - } - meterFeature.setMeterCapabilitiesSupported(Collections.unmodifiableList(mCapability)); - return new NodeMeterFeaturesBuilder().setMeterFeatures(meterFeature.build()).build(); - } - - /** - * Method transforms OFjava reply model {@link MultipartReplyGroupFeatures} object - * to inventory data model {@link NodeGroupFeatures} object. - * - * @param reply - * @return - */ - public static NodeGroupFeatures nodeGroupFeatureTranslator(@CheckForNull final MultipartReplyGroupFeatures reply) { - Preconditions.checkArgument(reply != null); - final GroupFeaturesBuilder groupFeature = new GroupFeaturesBuilder(); - groupFeature.setMaxGroups(reply.getMaxGroups()); - - final List> supportedGroups = new ArrayList<>(); - addSupportedGroups(reply, supportedGroups); - groupFeature.setGroupTypesSupported(supportedGroups); - - final List> gCapability = new ArrayList<>(); - addGroupCapabilities(reply, gCapability); - groupFeature.setGroupCapabilitiesSupported(gCapability); - - groupFeature.setActions(GroupUtil.extractGroupActionsSupportBitmap(reply.getActionsBitmap())); - return new NodeGroupFeaturesBuilder().setGroupFeatures(groupFeature.build()).build(); - } - - private static void addGroupCapabilities(final MultipartReplyGroupFeatures reply, final List> gCapability) { - if (reply.getCapabilities().isOFPGFCCHAINING()) { - gCapability.add(Chaining.class); - } - if (reply.getCapabilities().isOFPGFCCHAININGCHECKS()) { - gCapability.add(ChainingChecks.class); - } - if (reply.getCapabilities().isOFPGFCSELECTLIVENESS()) { - gCapability.add(SelectLiveness.class); - } - if (reply.getCapabilities().isOFPGFCSELECTWEIGHT()) { - gCapability.add(SelectWeight.class); - } - } - - private static void addSupportedGroups(final MultipartReplyGroupFeatures reply, final List> supportedGroups) { - if (reply.getTypes().isOFPGTALL()) { - supportedGroups.add(GroupAll.class); - } - if (reply.getTypes().isOFPGTSELECT()) { - supportedGroups.add(GroupSelect.class); - } - if (reply.getTypes().isOFPGTINDIRECT()) { - supportedGroups.add(GroupIndirect.class); - } - if (reply.getTypes().isOFPGTFF()) { - supportedGroups.add(GroupFf.class); - } - } - - /** - * Method transform {@link MultipartReplyTableFeatures} to list of {@link TableFeatures}. Every - * table can have List of TableFeatures so add it directly to - * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder} - * - * @param reply reply - * @param version Openflow version - * @param convertorExecutor convertor executor - * @return list of table features - */ - public static List nodeTableFeatureTranslator(@CheckForNull final MultipartReplyTableFeatures reply, final short version, @CheckForNull final ConvertorExecutor convertorExecutor) { - Preconditions.checkArgument(reply != null); - Preconditions.checkArgument(convertorExecutor != null); - final Optional> tableFeaturesList = convertorExecutor.convert(reply, new VersionConvertorData(version)); - return tableFeaturesList.orElse(Collections.emptyList()); - } - - /** - * Method build a ID Node Connector from version and port number. - * - * @param datapathId - * @param portNo - * @param version - * @return - */ - public static NodeConnectorId nodeConnectorId(@CheckForNull final String datapathId, final long portNo, final short version) { - Preconditions.checkArgument(datapathId != null); - final String logicalName = OpenflowPortsUtil.getPortLogicalName(version, portNo); - return new NodeConnectorId(OFConstants.OF_URI_PREFIX + datapathId + ":" + (logicalName == null ? portNo : logicalName)); - } -} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/MultipartWriterProvider.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/MultipartWriterProvider.java new file mode 100644 index 0000000000..0f50c24fc5 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/MultipartWriterProvider.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.datastore; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import org.opendaylight.openflowplugin.impl.datastore.multipart.AbstractMultipartWriter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; + +public class MultipartWriterProvider { + + private final Map writers = new HashMap<>(); + + /** + * Register statistics writer. + * + * @param type the writer type + * @param writer the writer instance + */ + public void register(final MultipartType type, final AbstractMultipartWriter writer) { + writers.put(type, writer); + } + + /** + * Lookup statistics writer. + * + * @param type the writer type + * @return the writer instance + */ + public Optional lookup(final MultipartType type) { + return Optional.ofNullable(writers.get(type)); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/MultipartWriterProviderFactory.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/MultipartWriterProviderFactory.java new file mode 100644 index 0000000000..bc0d817d28 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/MultipartWriterProviderFactory.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.datastore; + +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.impl.datastore.multipart.DescMultipartWriter; +import org.opendaylight.openflowplugin.impl.datastore.multipart.FlowStatsMultipartWriter; +import org.opendaylight.openflowplugin.impl.datastore.multipart.GroupDescMultipartWriter; +import org.opendaylight.openflowplugin.impl.datastore.multipart.GroupFeaturesMultipartWriter; +import org.opendaylight.openflowplugin.impl.datastore.multipart.GroupStatsMultipartWriter; +import org.opendaylight.openflowplugin.impl.datastore.multipart.MeterConfigMultipartWriter; +import org.opendaylight.openflowplugin.impl.datastore.multipart.MeterFeaturesMultipartWriter; +import org.opendaylight.openflowplugin.impl.datastore.multipart.MeterStatsMultipartWriter; +import org.opendaylight.openflowplugin.impl.datastore.multipart.PortDescMultipartWriter; +import org.opendaylight.openflowplugin.impl.datastore.multipart.PortStatsMultipartWriter; +import org.opendaylight.openflowplugin.impl.datastore.multipart.QueueStatsMultipartWriter; +import org.opendaylight.openflowplugin.impl.datastore.multipart.TableFeaturesMultipartWriter; +import org.opendaylight.openflowplugin.impl.datastore.multipart.TableStatsMultipartWriter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Multipart writer provider factory + */ +public class MultipartWriterProviderFactory { + + /** + * Create default #{@link MultipartWriterProvider} + * @param deviceContext device context + * @return the statistics writer provider + */ + public static MultipartWriterProvider createDefaultProvider(final DeviceContext deviceContext) { + final InstanceIdentifier instanceIdentifier = deviceContext.getDeviceInfo().getNodeInstanceIdentifier(); + final MultipartWriterProvider provider = new MultipartWriterProvider(); + + // Periodic/direct statistics writers + provider.register(MultipartType.OFPMPTABLE, new TableStatsMultipartWriter(deviceContext, instanceIdentifier)); + provider.register(MultipartType.OFPMPGROUP, new GroupStatsMultipartWriter(deviceContext, instanceIdentifier)); + provider.register(MultipartType.OFPMPMETER, new MeterStatsMultipartWriter(deviceContext, instanceIdentifier)); + provider.register(MultipartType.OFPMPPORTSTATS, new PortStatsMultipartWriter(deviceContext, instanceIdentifier, deviceContext.getPrimaryConnectionContext().getFeatures())); + provider.register(MultipartType.OFPMPQUEUE, new QueueStatsMultipartWriter(deviceContext, instanceIdentifier)); + provider.register(MultipartType.OFPMPFLOW, new FlowStatsMultipartWriter(deviceContext, instanceIdentifier, deviceContext, deviceContext.getDeviceInfo().getVersion())); + provider.register(MultipartType.OFPMPGROUPDESC, new GroupDescMultipartWriter(deviceContext, instanceIdentifier, deviceContext)); + provider.register(MultipartType.OFPMPMETERCONFIG, new MeterConfigMultipartWriter(deviceContext, instanceIdentifier, deviceContext)); + + // Device initialization writers + provider.register(MultipartType.OFPMPDESC, new DescMultipartWriter(deviceContext, instanceIdentifier, deviceContext.getPrimaryConnectionContext())); + provider.register(MultipartType.OFPMPGROUPFEATURES, new GroupFeaturesMultipartWriter(deviceContext, instanceIdentifier)); + provider.register(MultipartType.OFPMPMETERFEATURES, new MeterFeaturesMultipartWriter(deviceContext, instanceIdentifier)); + provider.register(MultipartType.OFPMPTABLEFEATURES, new TableFeaturesMultipartWriter(deviceContext, instanceIdentifier)); + provider.register(MultipartType.OFPMPPORTDESC, new PortDescMultipartWriter(deviceContext, instanceIdentifier, deviceContext.getPrimaryConnectionContext().getFeatures())); + + return provider; + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/AbstractMultipartWriter.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/AbstractMultipartWriter.java new file mode 100644 index 0000000000..28a2d2c390 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/AbstractMultipartWriter.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.datastore.multipart; + +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.openflowplugin.api.openflow.device.TxFacade; +import org.opendaylight.openflowplugin.impl.services.AbstractMultipartService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yangtools.yang.binding.DataContainer; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class AbstractMultipartWriter { + + private static final Logger LOG = LoggerFactory.getLogger(AbstractMultipartService.class); + + private final TxFacade txFacade; + private final InstanceIdentifier instanceIdentifier; + + AbstractMultipartWriter(final TxFacade txFacade, final InstanceIdentifier instanceIdentifier) { + this.txFacade = txFacade; + this.instanceIdentifier = instanceIdentifier; + } + + /** + * Creates put operation using provided data in underlying transaction chain. + * @param path path + * @param data data + * @param data type + */ + protected void writeToTransaction(final InstanceIdentifier path, + final O data, + final boolean withParents) { + if (withParents) { + txFacade.writeToTransactionWithParentsSlow(LogicalDatastoreType.OPERATIONAL, path, data); + } else { + txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, path, data); + } + } + + /** + * Get instance identifier + * @return instance identifier + */ + protected InstanceIdentifier getInstanceIdentifier() { + return instanceIdentifier; + } + + /** + * Write dataContainer + * @param dataContainer dataContainer + * @param withParents write missing parents if needed (slower) + * @return true if we have correct dataContainer type + */ + public boolean write(final DataContainer dataContainer, final boolean withParents) { + if (getType().isInstance(dataContainer)) { + LOG.debug("Writing multipart data of type {} for node {}", getType(), getInstanceIdentifier()); + storeStatistics(getType().cast(dataContainer), withParents); + return true; + } + + LOG.debug("Failed to write multipart data of type {} for node {}", getType(), getInstanceIdentifier()); + return false; + } + + /** + * Get type of writer + * @return type of writer + */ + protected abstract Class getType(); + + /** + * Write statistics + * @param statistics statistics + * @param withParents write missing parents if needed (slower) + */ + protected abstract void storeStatistics(final T statistics, + final boolean withParents); + + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/DescMultipartWriter.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/DescMultipartWriter.java new file mode 100644 index 0000000000..b9f3177083 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/DescMultipartWriter.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.datastore.multipart; + +import java.util.Collections; +import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext; +import org.opendaylight.openflowplugin.api.openflow.device.TxFacade; +import org.opendaylight.openflowplugin.impl.util.DeviceInitializationUtil; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.Desc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class DescMultipartWriter extends AbstractMultipartWriter { + + private final ConnectionContext connectionContext; + + public DescMultipartWriter(final TxFacade txFacade, + final InstanceIdentifier instanceIdentifier, + final ConnectionContext connectionContext) { + super(txFacade, instanceIdentifier); + this.connectionContext = connectionContext; + } + + @Override + protected Class getType() { + return Desc.class; + } + + @Override + public void storeStatistics(final Desc statistics, final boolean withParents) { + writeToTransaction(getInstanceIdentifier() + .augmentation(FlowCapableNode.class), + new FlowCapableNodeBuilder(statistics) + .setTable(Collections.emptyList()) + .setMeter(Collections.emptyList()) + .setGroup(Collections.emptyList()) + .setIpAddress(DeviceInitializationUtil.getIpAddress(connectionContext, getInstanceIdentifier())) + .setSwitchFeatures(DeviceInitializationUtil.getSwitchFeatures(connectionContext)) + .build(), + withParents); + } +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/FlowStatsMultipartWriter.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/FlowStatsMultipartWriter.java new file mode 100644 index 0000000000..6974386935 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/FlowStatsMultipartWriter.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.datastore.multipart; + +import org.opendaylight.openflowplugin.api.openflow.device.DeviceRegistry; +import org.opendaylight.openflowplugin.api.openflow.device.TxFacade; +import org.opendaylight.openflowplugin.impl.registry.flow.FlowRegistryKeyFactory; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey; +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.FlowBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowAndStatisticsMapList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsDataBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.statistics.FlowStatisticsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class FlowStatsMultipartWriter extends AbstractMultipartWriter { + + private final DeviceRegistry registry; + private final short version; + + public FlowStatsMultipartWriter(final TxFacade txFacade, + final InstanceIdentifier instanceIdentifier, + final DeviceRegistry registry, + final short version) { + super(txFacade, instanceIdentifier); + this.registry = registry; + this.version = version; + } + + @Override + protected Class getType() { + return FlowAndStatisticsMapList.class; + } + + @Override + public void storeStatistics(final FlowAndStatisticsMapList statistics, final boolean withParents) { + statistics.getFlowAndStatisticsMapList() + .forEach(stat -> { + final FlowBuilder flow = new FlowBuilder(stat) + .addAugmentation( + FlowStatisticsData.class, + new FlowStatisticsDataBuilder() + .setFlowStatistics(new FlowStatisticsBuilder(stat).build()) + .build()); + + final FlowKey key = new FlowKey(registry + .getDeviceFlowRegistry() + .storeIfNecessary(FlowRegistryKeyFactory + .create(version, flow.build()))); + + writeToTransaction( + getInstanceIdentifier() + .augmentation(FlowCapableNode.class) + .child(Table.class, new TableKey(stat.getTableId())) + .child(Flow.class, key), + flow + .setId(key.getId()) + .setKey(key) + .build(), + withParents); + }); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/GroupDescMultipartWriter.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/GroupDescMultipartWriter.java new file mode 100644 index 0000000000..b02e24649d --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/GroupDescMultipartWriter.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.datastore.multipart; + +import org.opendaylight.openflowplugin.api.openflow.device.DeviceRegistry; +import org.opendaylight.openflowplugin.api.openflow.device.TxFacade; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatisticsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupDescStatsReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class GroupDescMultipartWriter extends AbstractMultipartWriter { + + private final DeviceRegistry registry; + + public GroupDescMultipartWriter(final TxFacade txFacade, + final InstanceIdentifier instanceIdentifier, + final DeviceRegistry registry) { + super(txFacade, instanceIdentifier); + this.registry = registry; + } + + @Override + protected Class getType() { + return GroupDescStatsReply.class; + } + + @Override + public void storeStatistics(final GroupDescStatsReply statistics, final boolean withParents) { + statistics.getGroupDescStats() + .forEach(stat -> { + writeToTransaction( + getInstanceIdentifier() + .augmentation(FlowCapableNode.class) + .child(Group.class, new GroupKey(stat.getGroupId())), + new GroupBuilder(stat) + .setKey(new GroupKey(stat.getGroupId())) + .addAugmentation(NodeGroupStatistics.class, new NodeGroupStatisticsBuilder().build()) + .build(), + withParents); + + registry.getDeviceGroupRegistry().store(stat.getGroupId()); + }); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/GroupFeaturesMultipartWriter.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/GroupFeaturesMultipartWriter.java new file mode 100644 index 0000000000..f83afee336 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/GroupFeaturesMultipartWriter.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.datastore.multipart; + +import org.opendaylight.openflowplugin.api.openflow.device.TxFacade; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeatures; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeaturesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.features.GroupFeaturesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupFeatures; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class GroupFeaturesMultipartWriter extends AbstractMultipartWriter { + + public GroupFeaturesMultipartWriter(final TxFacade txFacade, final InstanceIdentifier instanceIdentifier) { + super(txFacade, instanceIdentifier); + } + + @Override + protected Class getType() { + return GroupFeatures.class; + } + + @Override + public void storeStatistics(final GroupFeatures statistics, final boolean withParents) { + writeToTransaction(getInstanceIdentifier() + .augmentation(NodeGroupFeatures.class), + new NodeGroupFeaturesBuilder() + .setGroupFeatures(new GroupFeaturesBuilder(statistics) + .build()) + .build(), + withParents); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/GroupStatsMultipartWriter.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/GroupStatsMultipartWriter.java new file mode 100644 index 0000000000..702ad5661b --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/GroupStatsMultipartWriter.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.datastore.multipart; + +import org.opendaylight.openflowplugin.api.openflow.device.TxFacade; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.statistics.GroupStatistics; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.statistics.GroupStatisticsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupStatisticsReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class GroupStatsMultipartWriter extends AbstractMultipartWriter { + + public GroupStatsMultipartWriter(final TxFacade txFacade, final InstanceIdentifier instanceIdentifier) { + super(txFacade, instanceIdentifier); + } + + @Override + protected Class getType() { + return GroupStatisticsReply.class; + } + + @Override + public void storeStatistics(final GroupStatisticsReply statistics, final boolean withParents) { + statistics.getGroupStats() + .forEach(stat -> writeToTransaction( + getInstanceIdentifier() + .augmentation(FlowCapableNode.class) + .child(Group.class, new GroupKey(stat.getGroupId())) + .augmentation(NodeGroupStatistics.class) + .child(GroupStatistics.class), + new GroupStatisticsBuilder(stat).build(), + withParents)); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/MeterConfigMultipartWriter.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/MeterConfigMultipartWriter.java new file mode 100644 index 0000000000..42a8c2ec72 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/MeterConfigMultipartWriter.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.datastore.multipart; + +import org.opendaylight.openflowplugin.api.openflow.device.DeviceRegistry; +import org.opendaylight.openflowplugin.api.openflow.device.TxFacade; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatistics; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatisticsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterConfigStatsReply; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class MeterConfigMultipartWriter extends AbstractMultipartWriter { + + private final DeviceRegistry registry; + + public MeterConfigMultipartWriter(final TxFacade txFacade, + final InstanceIdentifier instanceIdentifier, + final DeviceRegistry registry) { + super(txFacade, instanceIdentifier); + this.registry = registry; + } + + @Override + protected Class getType() { + return MeterConfigStatsReply.class; + } + + @Override + public void storeStatistics(final MeterConfigStatsReply statistics, final boolean withParents) { + statistics.getMeterConfigStats() + .forEach(stat -> { + writeToTransaction( + getInstanceIdentifier() + .augmentation(FlowCapableNode.class) + .child(Meter.class, new MeterKey(stat.getMeterId())), + new MeterBuilder(stat) + .setKey(new MeterKey(stat.getMeterId())) + .addAugmentation(NodeMeterStatistics.class, new NodeMeterStatisticsBuilder().build()) + .build(), + withParents); + + registry.getDeviceMeterRegistry().store(stat.getMeterId()); + }); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/MeterFeaturesMultipartWriter.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/MeterFeaturesMultipartWriter.java new file mode 100644 index 0000000000..ffaedc8b95 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/MeterFeaturesMultipartWriter.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.datastore.multipart; + +import org.opendaylight.openflowplugin.api.openflow.device.TxFacade; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeatures; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeaturesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.MeterFeatures; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class MeterFeaturesMultipartWriter extends AbstractMultipartWriter { + + public MeterFeaturesMultipartWriter(final TxFacade txFacade, final InstanceIdentifier instanceIdentifier) { + super(txFacade, instanceIdentifier); + } + + @Override + protected Class getType() { + return MeterFeatures.class; + } + + @Override + public void storeStatistics(final MeterFeatures statistics, final boolean withParents) { + writeToTransaction(getInstanceIdentifier() + .augmentation(NodeMeterFeatures.class), + new NodeMeterFeaturesBuilder() + .setMeterFeatures(statistics) + .build(), + withParents); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/MeterStatsMultipartWriter.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/MeterStatsMultipartWriter.java new file mode 100644 index 0000000000..5abd7850fc --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/MeterStatsMultipartWriter.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.datastore.multipart; + +import org.opendaylight.openflowplugin.api.openflow.device.TxFacade; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatistics; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterStatistics; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterStatisticsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterStatisticsReply; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class MeterStatsMultipartWriter extends AbstractMultipartWriter { + + public MeterStatsMultipartWriter(final TxFacade txFacade, final InstanceIdentifier instanceIdentifier) { + super(txFacade, instanceIdentifier); + } + + @Override + protected Class getType() { + return MeterStatisticsReply.class; + } + + @Override + public void storeStatistics(final MeterStatisticsReply statistics, final boolean withParents) { + statistics.getMeterStats() + .forEach(stat -> writeToTransaction( + getInstanceIdentifier() + .augmentation(FlowCapableNode.class) + .child(Meter.class, new MeterKey(stat.getMeterId())) + .augmentation(NodeMeterStatistics.class) + .child(MeterStatistics.class), + new MeterStatisticsBuilder(stat).build(), + withParents)); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/PortDescMultipartWriter.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/PortDescMultipartWriter.java new file mode 100644 index 0000000000..36dac14e79 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/PortDescMultipartWriter.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.datastore.multipart; + +import org.opendaylight.openflowplugin.api.openflow.device.TxFacade; +import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion; +import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil; +import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.multipart.reply.multipart.reply.body.MultipartReplyPortDesc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FeaturesReply; +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.yangtools.yang.binding.InstanceIdentifier; + +public class PortDescMultipartWriter extends AbstractMultipartWriter { + + private final FeaturesReply features; + + public PortDescMultipartWriter(final TxFacade txFacade, + final InstanceIdentifier instanceIdentifier, + final FeaturesReply features) { + super(txFacade, instanceIdentifier); + this.features = features; + } + + @Override + protected Class getType() { + return MultipartReplyPortDesc.class; + } + + @Override + public void storeStatistics(final MultipartReplyPortDesc statistics, final boolean withParents) { + statistics.getPorts() + .forEach(stat -> { + final NodeConnectorId id = InventoryDataServiceUtil + .nodeConnectorIdfromDatapathPortNo( + features.getDatapathId(), + OpenflowPortsUtil.getProtocolPortNumber( + OpenflowVersion.get(features.getVersion()), + stat.getPortNumber()), + OpenflowVersion.get(features.getVersion())); + + writeToTransaction( + getInstanceIdentifier() + .child(NodeConnector.class, new NodeConnectorKey(id)), + new NodeConnectorBuilder() + .setId(id) + .addAugmentation( + FlowCapableNodeConnector.class, + new FlowCapableNodeConnectorBuilder(stat).build()) + .addAugmentation( + FlowCapableNodeConnectorStatisticsData.class, + new FlowCapableNodeConnectorStatisticsDataBuilder().build()) + .build(), + withParents); + }); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/PortStatsMultipartWriter.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/PortStatsMultipartWriter.java new file mode 100644 index 0000000000..8faf97fb98 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/PortStatsMultipartWriter.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.datastore.multipart; + +import org.opendaylight.openflowplugin.api.openflow.device.TxFacade; +import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion; +import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FeaturesReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData; +import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsAndPortNumberMap; +import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.flow.capable.node.connector.statistics.FlowCapableNodeConnectorStatistics; +import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.flow.capable.node.connector.statistics.FlowCapableNodeConnectorStatisticsBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class PortStatsMultipartWriter extends AbstractMultipartWriter { + + private final FeaturesReply features; + + public PortStatsMultipartWriter(final TxFacade txFacade, + final InstanceIdentifier instanceIdentifier, + final FeaturesReply features) { + super(txFacade, instanceIdentifier); + this.features = features; + } + + @Override + protected Class getType() { + return NodeConnectorStatisticsAndPortNumberMap.class; + } + + @Override + public void storeStatistics(final NodeConnectorStatisticsAndPortNumberMap statistics, final boolean withParents) { + statistics.getNodeConnectorStatisticsAndPortNumberMap() + .forEach(stat -> { + final OpenflowVersion openflowVersion = OpenflowVersion.get(features.getVersion()); + final Long port = InventoryDataServiceUtil + .portNumberfromNodeConnectorId(openflowVersion, stat.getNodeConnectorId()); + + final NodeConnectorId id = InventoryDataServiceUtil + .nodeConnectorIdfromDatapathPortNo( + features.getDatapathId(), + port, + OpenflowVersion.get(features.getVersion())); + + writeToTransaction( + getInstanceIdentifier() + .child(NodeConnector.class, new NodeConnectorKey(id)) + .augmentation(FlowCapableNodeConnectorStatisticsData.class) + .child(FlowCapableNodeConnectorStatistics.class), + new FlowCapableNodeConnectorStatisticsBuilder(stat) + .build(), + withParents); + }); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/QueueStatsMultipartWriter.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/QueueStatsMultipartWriter.java new file mode 100644 index 0000000000..6fe50d03cb --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/QueueStatsMultipartWriter.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.datastore.multipart; + +import org.opendaylight.openflowplugin.api.openflow.device.TxFacade; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsData; +import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsDataBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.QueueIdAndStatisticsMap; +import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.flow.capable.node.connector.queue.statistics.FlowCapableNodeConnectorQueueStatisticsBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class QueueStatsMultipartWriter extends AbstractMultipartWriter { + + public QueueStatsMultipartWriter(final TxFacade txFacade, final InstanceIdentifier instanceIdentifier) { + super(txFacade, instanceIdentifier); + } + + @Override + protected Class getType() { + return QueueIdAndStatisticsMap.class; + } + + @Override + public void storeStatistics(final QueueIdAndStatisticsMap statistics, final boolean withParents) { + statistics.getQueueIdAndStatisticsMap() + .forEach(stat -> writeToTransaction( + getInstanceIdentifier() + .child(NodeConnector.class, new NodeConnectorKey(stat.getNodeConnectorId())) + .augmentation(FlowCapableNodeConnector.class) + .child(Queue.class, new QueueKey(stat.getQueueId())), + new QueueBuilder() + .setKey(new QueueKey(stat.getQueueId())) + .setQueueId(stat.getQueueId()) + .addAugmentation( + FlowCapableNodeConnectorQueueStatisticsData.class, + new FlowCapableNodeConnectorQueueStatisticsDataBuilder() + .setFlowCapableNodeConnectorQueueStatistics( + new FlowCapableNodeConnectorQueueStatisticsBuilder(stat).build()) + .build()) + .build(), + withParents)); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/TableFeaturesMultipartWriter.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/TableFeaturesMultipartWriter.java new file mode 100644 index 0000000000..f839ac352e --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/TableFeaturesMultipartWriter.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.datastore.multipart; + +import org.opendaylight.openflowplugin.api.openflow.device.TxFacade; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsDataBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableFeatures; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeaturesKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class TableFeaturesMultipartWriter extends AbstractMultipartWriter { + + public TableFeaturesMultipartWriter(final TxFacade txFacade, + final InstanceIdentifier instanceIdentifier) { + super(txFacade, instanceIdentifier); + } + + @Override + protected Class getType() { + return TableFeatures.class; + } + + @Override + public void storeStatistics(final TableFeatures statistics, final boolean withParents) { + statistics.getTableFeatures() + .forEach(stat -> { + writeToTransaction(getInstanceIdentifier() + .augmentation(FlowCapableNode.class) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features + .TableFeatures.class, + new TableFeaturesKey(stat.getTableId())), + stat, + withParents); + + // Write parent for table statistics + writeToTransaction(getInstanceIdentifier() + .augmentation(FlowCapableNode.class) + .child(Table.class, new TableKey(stat.getTableId())), + new TableBuilder() + .setId(stat.getTableId()) + .addAugmentation(FlowTableStatisticsData.class, new FlowTableStatisticsDataBuilder() + .build()) + .build(), + withParents); + }); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/TableStatsMultipartWriter.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/TableStatsMultipartWriter.java new file mode 100644 index 0000000000..95758ab906 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/datastore/multipart/TableStatsMultipartWriter.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.datastore.multipart; + +import org.opendaylight.openflowplugin.api.openflow.device.TxFacade; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableAndStatisticsMap; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatistics; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatisticsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class TableStatsMultipartWriter extends AbstractMultipartWriter { + + public TableStatsMultipartWriter(final TxFacade txFacade, final InstanceIdentifier instanceIdentifier) { + super(txFacade, instanceIdentifier); + } + + @Override + protected Class getType() { + return FlowTableAndStatisticsMap.class; + } + + @Override + public void storeStatistics(final FlowTableAndStatisticsMap statistics, + final boolean withParents) { + statistics.getFlowTableAndStatisticsMap() + .forEach(stat -> writeToTransaction( + getInstanceIdentifier() + .augmentation(FlowCapableNode.class) + .child(Table.class, new TableKey(stat.getTableId().getValue())) + .augmentation(FlowTableStatisticsData.class) + .child(FlowTableStatistics.class), + new FlowTableStatisticsBuilder(stat).build(), + withParents)); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImpl.java index cb01c5cabe..43db4f34eb 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImpl.java @@ -23,6 +23,7 @@ import java.math.BigInteger; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @@ -35,6 +36,7 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier; import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter; import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey; +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; @@ -50,6 +52,7 @@ import org.opendaylight.openflowplugin.api.openflow.device.handlers.MultiMsgColl import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleService; import org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher; import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey; +import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion; import org.opendaylight.openflowplugin.api.openflow.registry.ItemLifeCycleRegistry; import org.opendaylight.openflowplugin.api.openflow.registry.flow.DeviceFlowRegistry; import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowDescriptor; @@ -65,16 +68,19 @@ import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionCon import org.opendaylight.openflowplugin.extension.api.exception.ConversionException; import org.opendaylight.openflowplugin.extension.api.path.MessagePath; import org.opendaylight.openflowplugin.impl.common.ItemLifeCycleSourceImpl; -import org.opendaylight.openflowplugin.impl.common.NodeStaticReplyTranslatorUtil; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProviderFactory; +import org.opendaylight.openflowplugin.impl.device.initialization.AbstractDeviceInitializer; +import org.opendaylight.openflowplugin.impl.device.initialization.DeviceInitializerProvider; import org.opendaylight.openflowplugin.impl.device.listener.MultiMsgCollectorImpl; 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.rpc.AbstractRequestContext; -import org.opendaylight.openflowplugin.impl.util.DeviceInitializationUtils; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; import org.opendaylight.openflowplugin.openflow.md.core.session.SwitchConnectionCookieOFImpl; +import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil; 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; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector; @@ -91,7 +97,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev13 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.FlowRemoved; -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; @@ -159,23 +164,27 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi private volatile CONTEXT_STATE state; private ClusterInitializationPhaseHandler clusterInitializationPhaseHandler; private final DeviceManager myManager; + private final DeviceInitializerProvider deviceInitializerProvider; private final boolean useSingleLayerSerialization; DeviceContextImpl( - @Nonnull final ConnectionContext primaryConnectionContext, - @Nonnull final DataBroker dataBroker, - @Nonnull final MessageSpy messageSpy, - @Nonnull final TranslatorLibrary translatorLibrary, - @Nonnull final DeviceManager manager, - final ConvertorExecutor convertorExecutor, - final boolean skipTableFeatures, - final HashedWheelTimer hashedWheelTimer, - final DeviceManager myManager, - final boolean useSingleLayerSerialization) { + @Nonnull final ConnectionContext primaryConnectionContext, + @Nonnull final DataBroker dataBroker, + @Nonnull final MessageSpy messageSpy, + @Nonnull final TranslatorLibrary translatorLibrary, + @Nonnull final DeviceManager manager, + final ConvertorExecutor convertorExecutor, + final boolean skipTableFeatures, + final HashedWheelTimer hashedWheelTimer, + final DeviceManager myManager, + final boolean useSingleLayerSerialization, + final DeviceInitializerProvider deviceInitializerProvider) { + this.primaryConnectionContext = primaryConnectionContext; this.deviceInfo = primaryConnectionContext.getDeviceInfo(); this.hashedWheelTimer = hashedWheelTimer; this.myManager = myManager; + this.deviceInitializerProvider = deviceInitializerProvider; this.deviceState = new DeviceStateImpl(); this.dataBroker = dataBroker; this.auxiliaryConnectionContexts = new HashMap<>(); @@ -295,18 +304,20 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi @Override public void processReply(final OfHeader ofHeader) { - if (ofHeader instanceof Error) { - messageSpy.spyMessage(ofHeader.getImplementedInterface(), MessageSpy.STATISTIC_GROUP.FROM_SWITCH_PUBLISHED_FAILURE); - } else { - messageSpy.spyMessage(ofHeader.getImplementedInterface(), MessageSpy.STATISTIC_GROUP.FROM_SWITCH_PUBLISHED_SUCCESS); - } + messageSpy.spyMessage( + ofHeader.getImplementedInterface(), + (ofHeader instanceof Error) + ? MessageSpy.STATISTIC_GROUP.FROM_SWITCH_PUBLISHED_FAILURE + : MessageSpy.STATISTIC_GROUP.FROM_SWITCH_PUBLISHED_SUCCESS); } @Override - public void processReply(final Xid xid, final List ofHeaderList) { - for (final MultipartReply multipartReply : ofHeaderList) { - messageSpy.spyMessage(multipartReply.getImplementedInterface(), MessageSpy.STATISTIC_GROUP.FROM_SWITCH_PUBLISHED_FAILURE); - } + public void processReply(final Xid xid, final List ofHeaderList) { + ofHeaderList.forEach(header -> messageSpy.spyMessage( + header.getImplementedInterface(), + (header instanceof Error) + ? MessageSpy.STATISTIC_GROUP.FROM_SWITCH_PUBLISHED_FAILURE + : MessageSpy.STATISTIC_GROUP.FROM_SWITCH_PUBLISHED_SUCCESS)); } @Override @@ -370,7 +381,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi private KeyedInstanceIdentifier provideIIToNodeConnector(final long portNo, final short version) { final InstanceIdentifier iiToNodes = getDeviceInfo().getNodeInstanceIdentifier(); final BigInteger dataPathId = getDeviceInfo().getDatapathId(); - final NodeConnectorId nodeConnectorId = NodeStaticReplyTranslatorUtil.nodeConnectorId(dataPathId.toString(), portNo, version); + final NodeConnectorId nodeConnectorId = InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(dataPathId, portNo, OpenflowVersion.get(version)); return iiToNodes.child(NodeConnector.class, new NodeConnectorKey(nodeConnectorId)); } @@ -485,8 +496,8 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi } @Override - public MultiMsgCollector getMultiMsgCollector(final RequestContext> requestContext) { - return new MultiMsgCollectorImpl(this, requestContext); + public MultiMsgCollector getMultiMsgCollector(final RequestContext> requestContext) { + return new MultiMsgCollectorImpl<>(this, requestContext); } @Override @@ -648,8 +659,8 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi } @Override - public boolean isUseSingleLayerSerialization() { - return useSingleLayerSerialization; + public boolean canUseSingleLayerSerialization() { + return useSingleLayerSerialization && getDeviceInfo().getVersion() >= OFConstants.OFP_VERSION_1_3; } @Override @@ -682,14 +693,21 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi this.transactionChainManager.activateTransactionManager(); try { - DeviceInitializationUtils.initializeNodeInformation(this, switchFeaturesMandatory, this.convertorExecutor); + final Optional initializer = deviceInitializerProvider + .lookup(deviceInfo.getVersion()); + + if (initializer.isPresent()) { + final MultipartWriterProvider writerProvider = MultipartWriterProviderFactory.createDefaultProvider(this); + initializer.get().initialize(this, switchFeaturesMandatory, writerProvider, convertorExecutor); + } else { + throw new ExecutionException(new ConnectionException("Unsupported version " + deviceInfo.getVersion())); + } } catch (ExecutionException | InterruptedException e) { LOG.warn("Device {} cannot be initialized: ", deviceInfo.getLOGValue(), e); return false; } Futures.addCallback(sendRoleChangeToDevice(OfpRole.BECOMEMASTER), new RpcResultFutureCallback()); - return this.clusterInitializationPhaseHandler.onContextInstantiateService(getPrimaryConnectionContext()); } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java index 9144f61d5e..df49b14437 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java @@ -51,9 +51,10 @@ import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.Messa 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.initialization.DeviceInitializerProvider; import org.opendaylight.openflowplugin.impl.device.listener.OpenflowProtocolListenerFullImpl; import org.opendaylight.openflowplugin.impl.lifecycle.LifecycleServiceImpl; -import org.opendaylight.openflowplugin.impl.services.SalRoleServiceImpl; +import org.opendaylight.openflowplugin.impl.services.sal.SalRoleServiceImpl; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder; @@ -78,6 +79,7 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi private static final int SPY_RATE = 10; private final DataBroker dataBroker; + private final DeviceInitializerProvider deviceInitializerProvider; private final ConvertorExecutor convertorExecutor; private TranslatorLibrary translatorLibrary; private DeviceInitializationPhaseHandler deviceInitPhaseHandler; @@ -109,9 +111,11 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi final HashedWheelTimer hashedWheelTimer, final ConvertorExecutor convertorExecutor, final boolean skipTableFeatures, - final boolean useSingleLayerSerialization) { + final boolean useSingleLayerSerialization, + final DeviceInitializerProvider deviceInitializerProvider) { this.dataBroker = dataBroker; + this.deviceInitializerProvider = deviceInitializerProvider; /* merge empty nodes to oper DS to predict any problems with missing parent for Node */ final WriteTransaction tx = dataBroker.newWriteOnlyTransaction(); @@ -198,7 +202,6 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi connectionContext.setOutboundQueueHandleRegistration(outboundQueueHandlerRegistration); final LifecycleService lifecycleService = new LifecycleServiceImpl(); - final DeviceContext deviceContext = new DeviceContextImpl( connectionContext, dataBroker, @@ -209,7 +212,8 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi skipTableFeatures, hashedWheelTimer, this, - useSingleLayerSerialization); + useSingleLayerSerialization, + deviceInitializerProvider); deviceContext.setSalRoleService(new SalRoleServiceImpl(deviceContext, deviceContext)); deviceContexts.put(deviceInfo, deviceContext); diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/initialization/AbstractDeviceInitializer.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/initialization/AbstractDeviceInitializer.java new file mode 100644 index 0000000000..25a84ef0ac --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/initialization/AbstractDeviceInitializer.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.device.initialization; + +import com.google.common.base.Preconditions; +import java.util.Collections; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.openflowplugin.api.ConnectionException; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class AbstractDeviceInitializer { + + private static final Logger LOG = LoggerFactory.getLogger(AbstractDeviceInitializer.class); + + /** + * Perform initial information gathering and store them to operational datastore + * @param deviceContext device context + * @param multipartWriterProvider multipart writer provider + */ + public void initialize(@Nonnull final DeviceContext deviceContext, + final boolean switchFeaturesMandatory, + @Nullable final MultipartWriterProvider multipartWriterProvider, + @Nullable final ConvertorExecutor convertorExecutor) throws ExecutionException,InterruptedException { + Preconditions.checkNotNull(deviceContext); + + // Write node to datastore + LOG.debug("Initializing node information for node {}", deviceContext.getDeviceInfo().getLOGValue()); + try { + deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, deviceContext + .getDeviceInfo() + .getNodeInstanceIdentifier(), + new NodeBuilder() + .setId(deviceContext.getDeviceInfo().getNodeId()) + .setNodeConnector(Collections.emptyList()) + .build()); + } catch (final Exception e) { + LOG.warn("Failed to write node {} to DS ", deviceContext.getDeviceInfo().getNodeId(), e); + throw new ExecutionException(new ConnectionException("Failed to write node " + deviceContext.getDeviceInfo().getNodeId() + " to DS ", e)); + } + + // Synchronously get information about device + initializeNodeInformation(deviceContext, switchFeaturesMandatory, multipartWriterProvider, convertorExecutor) + .get(); + } + + protected abstract Future initializeNodeInformation(@Nonnull final DeviceContext deviceContext, + final boolean switchFeaturesMandatory, + @Nullable final MultipartWriterProvider multipartWriterProvider, + @Nullable final ConvertorExecutor convertorExecutor); +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/initialization/DeviceInitializerProvider.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/initialization/DeviceInitializerProvider.java new file mode 100644 index 0000000000..9ed66e9d11 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/initialization/DeviceInitializerProvider.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.device.initialization; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +public class DeviceInitializerProvider { + + private final Map initializers = new HashMap<>(); + + /** + * Register device initializer. + * + * @param version the initializer version + * @param initializer the initializer instance + */ + public void register(final Short version, final AbstractDeviceInitializer initializer) { + initializers.put(version, initializer); + } + + /** + * Lookup device initializer. + * + * @param version the initializer version + * @return the initializer instance + */ + public Optional lookup(final Short version) { + return Optional.ofNullable(initializers.get(version)); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/initialization/DeviceInitializerProviderFactory.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/initialization/DeviceInitializerProviderFactory.java new file mode 100644 index 0000000000..a49515f171 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/initialization/DeviceInitializerProviderFactory.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.device.initialization; + +import org.opendaylight.openflowplugin.api.OFConstants; + +/** + * Multipart writer provider factory + */ +public class DeviceInitializerProviderFactory { + + /** + * Create default #{@link org.opendaylight.openflowplugin.impl.device.initialization.DeviceInitializerProvider} + * @return the device initialization provider + */ + public static DeviceInitializerProvider createDefaultProvider() { + final DeviceInitializerProvider provider = new DeviceInitializerProvider(); + provider.register(OFConstants.OFP_VERSION_1_0, new OF10DeviceInitializer()); + provider.register(OFConstants.OFP_VERSION_1_3, new OF13DeviceInitializer()); + return provider; + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/initialization/OF10DeviceInitializer.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/initialization/OF10DeviceInitializer.java new file mode 100644 index 0000000000..a9f7386e79 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/initialization/OF10DeviceInitializer.java @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.device.initialization; + +import com.google.common.base.Function; +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.List; +import java.util.concurrent.Future; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +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.TxFacade; +import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey; +import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerMultipartCollectorService; +import org.opendaylight.openflowplugin.impl.services.singlelayer.SingleLayerMultipartCollectorService; +import org.opendaylight.openflowplugin.impl.util.DeviceInitializationUtil; +import org.opendaylight.openflowplugin.impl.util.DeviceStateUtil; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.CapabilitiesV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortGrouping; +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.yangtools.yang.common.RpcResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class OF10DeviceInitializer extends AbstractDeviceInitializer { + + private static final Logger LOG = LoggerFactory.getLogger(OF10DeviceInitializer.class); + + @Override + protected Future initializeNodeInformation(@Nonnull final DeviceContext deviceContext, + final boolean switchFeaturesMandatory, + @Nullable final MultipartWriterProvider multipartWriterProvider, + @Nullable final ConvertorExecutor convertorExecutor) { + final ConnectionContext connectionContext = Preconditions.checkNotNull(deviceContext.getPrimaryConnectionContext()); + final DeviceState deviceState = Preconditions.checkNotNull(deviceContext.getDeviceState()); + final DeviceInfo deviceInfo = Preconditions.checkNotNull(deviceContext.getDeviceInfo()); + final CapabilitiesV10 capabilitiesV10 = connectionContext.getFeatures().getCapabilitiesV10(); + + // Set capabilities for this device based on capabilities of connection context + LOG.debug("Setting capabilities for device {}", deviceInfo.getLOGValue()); + DeviceStateUtil.setDeviceStateBasedOnV10Capabilities(deviceState, capabilitiesV10); + final ListenableFuture future = requestMultipart(MultipartType.OFPMPDESC, deviceContext); + + Futures.addCallback(future, new FutureCallback() { + @Override + public void onSuccess(@Nullable final Boolean result) { + if (Boolean.TRUE.equals(result)) { + LOG.debug("Creating empty flow capable node: {}", deviceInfo.getLOGValue()); + makeEmptyFlowCapableNode(deviceContext, deviceInfo); + + LOG.debug("Creating empty tables for {}", deviceInfo.getLOGValue()); + DeviceInitializationUtil.makeEmptyTables( + deviceContext, + deviceInfo, + deviceContext.getPrimaryConnectionContext().getFeatures().getTables()); + } + } + + @Override + public void onFailure(@Nonnull final Throwable t) { + LOG.warn("Error occurred in preparation node {} for protocol 1.0", deviceInfo.getLOGValue()); + LOG.trace("Error for node {} : ", deviceInfo.getLOGValue(), t); + } + }); + + return Futures.transform(future, new Function() { + @Nullable + @Override + public Void apply(@Nullable final Boolean input) { + writePhyPortInformation(deviceContext); + return null; + } + }); + } + + private static void writePhyPortInformation(final DeviceContext deviceContext) { + final DeviceInfo deviceInfo = deviceContext.getDeviceInfo(); + final ConnectionContext connectionContext = deviceContext.getPrimaryConnectionContext(); + final MessageTranslator translator = deviceContext + .oook() + .lookupTranslator(new TranslatorKey(deviceInfo.getVersion(), PortGrouping.class.getName())); + + connectionContext.getFeatures().getPhyPort().forEach(port -> { + final NodeConnectorId nodeConnectorId = InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo( + deviceInfo.getDatapathId(), + port.getPortNo(), + OpenflowVersion.get(deviceInfo.getVersion())); + + try { + deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, + deviceInfo + .getNodeInstanceIdentifier() + .child(NodeConnector.class, new NodeConnectorKey(nodeConnectorId)), + new NodeConnectorBuilder() + .setId(nodeConnectorId) + .addAugmentation( + FlowCapableNodeConnector.class, + translator.translate(port, deviceInfo, null)) + .addAugmentation( + FlowCapableNodeConnectorStatisticsData.class, + new FlowCapableNodeConnectorStatisticsDataBuilder().build()) + .build()); + } catch (final Exception e) { + LOG.debug("Failed to write node {} to DS ", deviceInfo.getLOGValue(), e); + } + }); + } + + private static void makeEmptyFlowCapableNode(final TxFacade txFacade, final DeviceInfo deviceInfo) { + try { + txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, + deviceInfo + .getNodeInstanceIdentifier() + .augmentation(FlowCapableNode.class), + new FlowCapableNodeBuilder().build()); + } catch (final Exception e) { + LOG.debug("Failed to write empty node {} to DS ", deviceInfo.getLOGValue(), e); + } + } + + private static ListenableFuture requestMultipart(final MultipartType multipartType, + final DeviceContext deviceContext) { + if (deviceContext.canUseSingleLayerSerialization()) { + final SingleLayerMultipartCollectorService service = + new SingleLayerMultipartCollectorService(deviceContext, deviceContext); + + return Futures.transform(service.handleServiceCall(multipartType), new Function>, Boolean>() { + @Nullable + @Override + public Boolean apply(final RpcResult> input) { + return input.isSuccessful(); + } + }); + } + + final MultiLayerMultipartCollectorService service = + new MultiLayerMultipartCollectorService(deviceContext, deviceContext); + + return Futures.transform(service.handleServiceCall(multipartType), new Function>, Boolean>() { + @Nullable + @Override + public Boolean apply(final RpcResult> input) { + return input.isSuccessful(); + } + }); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/initialization/OF13DeviceInitializer.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/initialization/OF13DeviceInitializer.java new file mode 100644 index 0000000000..abb1b70aa8 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/initialization/OF13DeviceInitializer.java @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.device.initialization; + +import com.google.common.base.Function; +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.AsyncFunction; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.Future; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +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.impl.common.MultipartReplyTranslatorUtil; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerMultipartCollectorService; +import org.opendaylight.openflowplugin.impl.services.singlelayer.SingleLayerMultipartCollectorService; +import org.opendaylight.openflowplugin.impl.util.DeviceInitializationUtil; +import org.opendaylight.openflowplugin.impl.util.DeviceStateUtil; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterFeatures; +import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply; +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.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class OF13DeviceInitializer extends AbstractDeviceInitializer { + + private static final Logger LOG = LoggerFactory.getLogger(OF13DeviceInitializer.class); + + @Override + protected Future initializeNodeInformation(@Nonnull final DeviceContext deviceContext, + final boolean switchFeaturesMandatory, + @Nullable final MultipartWriterProvider multipartWriterProvider, + @Nullable final ConvertorExecutor convertorExecutor) { + final ConnectionContext connectionContext = Preconditions.checkNotNull(deviceContext.getPrimaryConnectionContext()); + final DeviceState deviceState = Preconditions.checkNotNull(deviceContext.getDeviceState()); + final DeviceInfo deviceInfo = Preconditions.checkNotNull(deviceContext.getDeviceInfo()); + final Capabilities capabilities = connectionContext.getFeatures().getCapabilities(); + LOG.debug("Setting capabilities for device {}", deviceInfo.getLOGValue()); + DeviceStateUtil.setDeviceStateBasedOnV13Capabilities(deviceState, capabilities); + + // First process description reply, write data to DS and write consequent data if successful + return Futures.transform( + requestMultipart(MultipartType.OFPMPDESC, deviceContext), + (AsyncFunction>, Void>) input -> { + translateAndWriteResult( + MultipartType.OFPMPDESC, + input.getResult(), + deviceContext, + multipartWriterProvider, + convertorExecutor); + + final List>>> futures = new ArrayList<>(); + futures.add(requestAndProcessMultipart(MultipartType.OFPMPMETERFEATURES, deviceContext, multipartWriterProvider, convertorExecutor)); + futures.add(requestAndProcessMultipart(MultipartType.OFPMPGROUPFEATURES, deviceContext, multipartWriterProvider, convertorExecutor)); + futures.add(requestAndProcessMultipart(MultipartType.OFPMPTABLEFEATURES, deviceContext, multipartWriterProvider, convertorExecutor)); + futures.add(requestAndProcessMultipart(MultipartType.OFPMPPORTDESC, deviceContext, multipartWriterProvider, convertorExecutor)); + + return Futures.transform( + (switchFeaturesMandatory ? Futures.allAsList(futures) : Futures.successfulAsList(futures)), + new Function>>, Void>() { + @Nullable + @Override + public Void apply(@Nullable final List>> input) { + LOG.info("Static node {} successfully finished collecting", deviceContext.getDeviceInfo().getLOGValue()); + return null; + } + }); + }); + + } + + /** + * Request multipart of specified type and then run some processing on it + * @param type multipart type + * @param deviceContext device context + * @param multipartWriterProvider multipart writer provider + * @param convertorExecutor convertor executor + * @return list of multipart messages unified to parent interface + */ + private static ListenableFuture>> requestAndProcessMultipart(final MultipartType type, + final DeviceContext deviceContext, + final MultipartWriterProvider multipartWriterProvider, + @Nullable final ConvertorExecutor convertorExecutor) { + final ListenableFuture>> rpcResultListenableFuture = + MultipartType.OFPMPTABLEFEATURES.equals(type) && deviceContext.isSkipTableFeatures() + ? RpcResultBuilder.>success().buildFuture() + : requestMultipart(type, deviceContext); + + createCallback(type, rpcResultListenableFuture, deviceContext, multipartWriterProvider, convertorExecutor); + return rpcResultListenableFuture; + } + + /** + * Inject callback ti future for specified multipart type. This callback will translate and write + * result of multipart messages + * @param type multipart type + * @param future multipart collection future + * @param deviceContext device context + * @param multipartWriterProvider multipart writer provider + * @param convertorExecutor convertor executor + */ + private static void createCallback(final MultipartType type, + final ListenableFuture>> future, + final DeviceContext deviceContext, + @Nullable final MultipartWriterProvider multipartWriterProvider, + @Nullable final ConvertorExecutor convertorExecutor) { + Futures.addCallback(future, new FutureCallback>>() { + @Override + public void onSuccess(final RpcResult> result) { + if (Objects.nonNull(result.getResult())) { + LOG.info("Static node {} info: {} collected", deviceContext.getDeviceInfo().getLOGValue(), type); + translateAndWriteResult( + type, + result.getResult(), + deviceContext, + multipartWriterProvider, + convertorExecutor); + } else { + result.getErrors().forEach(rpcError -> { + LOG.warn("Failed to retrieve static node {} info: {}", type, rpcError.getMessage()); + + if (LOG.isTraceEnabled() && Objects.nonNull(rpcError.getCause())) { + LOG.trace("Detailed error:", rpcError.getCause()); + } + }); + + // If table features are disabled or returned nothing, at least make empty tables + if (MultipartType.OFPMPTABLEFEATURES.equals(type)) { + DeviceInitializationUtil.makeEmptyTables( + deviceContext, + deviceContext.getDeviceInfo(), + deviceContext.getPrimaryConnectionContext().getFeatures().getTables()); + } + } + } + + @Override + public void onFailure(@Nonnull final Throwable t) { + LOG.warn("Request of type {} for static info of node {} failed.", type, deviceContext.getDeviceInfo().getLOGValue()); + } + }); + } + + /** + * Translate and write multipart messages from OpenflowJava + * @param type multipart type + * @param result multipart messages + * @param deviceContext device context + * @param multipartWriterProvider multipart writer provider + * @param convertorExecutor convertor executor + */ + private static void translateAndWriteResult(final MultipartType type, + final List result, + final DeviceContext deviceContext, + @Nullable final MultipartWriterProvider multipartWriterProvider, + @Nullable final ConvertorExecutor convertorExecutor) { + if (Objects.nonNull(result)) { + try { + result.forEach(reply -> { + // First, translate collected data to proper openflowplugin representation + MultipartReplyTranslatorUtil + .translate( + reply, + deviceContext.getDeviceInfo(), + convertorExecutor, + deviceContext.oook()) + .ifPresent(translatedReply -> { + // If we collected meter features, check if we have support for meters + // and pass this information to device context + if (MultipartType.OFPMPMETERFEATURES.equals(type) && + translatedReply instanceof MeterFeatures) { + final MeterFeatures meterFeatures = (MeterFeatures) translatedReply; + + if (meterFeatures.getMaxMeter().getValue() > 0) { + deviceContext.getDeviceState().setMeterAvailable(true); + } + } + + // Now. try to write translated collected features + Optional.ofNullable(multipartWriterProvider) + .flatMap(provider -> provider.lookup(type)) + .ifPresent(writer -> writer.write(translatedReply, false)); + }); + }); + } catch (final Exception e) { + LOG.warn("Failed to write node {} to DS ", deviceContext.getDeviceInfo().getLOGValue(), e); + } + } else { + LOG.warn("Failed to write node {} to DS because we failed to gather device info.", + deviceContext.getDeviceInfo().getLOGValue()); + } + } + + /** + * Send request to device and unify different possible reply types from OpenflowJava to common parent interface + * @param multipartType multipart type + * @param deviceContext device context + * @return unified replies + */ + private static ListenableFuture>> requestMultipart(final MultipartType multipartType, + final DeviceContext deviceContext) { + if (deviceContext.canUseSingleLayerSerialization()) { + final SingleLayerMultipartCollectorService service = + new SingleLayerMultipartCollectorService(deviceContext, deviceContext); + + return Futures.transform(service.handleServiceCall(multipartType), new Function>, RpcResult>>() { + @Nullable + @Override + public RpcResult> apply(final RpcResult> input) { + if (Objects.isNull(input.getResult()) && input.isSuccessful()) { + final List temp = null; + return RpcResultBuilder.success(temp).build(); + } + + return input.isSuccessful() + ? RpcResultBuilder.success(input + .getResult() + .stream() + .map(reply -> (OfHeader) reply) + .collect(Collectors.toList())) + .build() + : RpcResultBuilder.>failed() + .withRpcErrors(input.getErrors()) + .build(); + } + }); + } + + final MultiLayerMultipartCollectorService service = + new MultiLayerMultipartCollectorService(deviceContext, deviceContext); + + return Futures.transform(service.handleServiceCall(multipartType), new Function>, RpcResult>>() { + @Nullable + @Override + public RpcResult> apply(final RpcResult> input) { + if (Objects.isNull(input.getResult()) && input.isSuccessful()) { + final List temp = null; + return RpcResultBuilder.success(temp).build(); + } + + return input.isSuccessful() + ? RpcResultBuilder.success(input + .getResult() + .stream() + .map(reply -> (OfHeader) reply) + .collect(Collectors.toList())) + .build() + : RpcResultBuilder.>failed() + .withRpcErrors(input.getErrors()) + .build(); + } + }); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/listener/MultiMsgCollectorImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/listener/MultiMsgCollectorImpl.java index b373427f59..532a81fbf8 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/listener/MultiMsgCollectorImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/listener/MultiMsgCollectorImpl.java @@ -11,14 +11,15 @@ package org.opendaylight.openflowplugin.impl.device.listener; import com.google.common.base.Preconditions; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import org.opendaylight.openflowplugin.api.openflow.device.RequestContext; import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceReplyProcessor; import org.opendaylight.openflowplugin.api.openflow.device.handlers.MultiMsgCollector; import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier; import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.EventsTimeCounter; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; -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.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; import org.slf4j.Logger; @@ -34,54 +35,38 @@ import org.slf4j.LoggerFactory; *

* Created: Mar 23, 2015 */ -public class MultiMsgCollectorImpl implements MultiMsgCollector { - +public class MultiMsgCollectorImpl implements MultiMsgCollector { private static final Logger LOG = LoggerFactory.getLogger(MultiMsgCollectorImpl.class); - - private final List replyCollection = new ArrayList<>(); - private final RequestContext> requestContext; + private final List replyCollection = new ArrayList<>(); + private final RequestContext> requestContext; private final DeviceReplyProcessor deviceReplyProcessor; - private MultipartType msgType; - public MultiMsgCollectorImpl(final DeviceReplyProcessor deviceReplyProcessor, final RequestContext> requestContext) { + public MultiMsgCollectorImpl(final DeviceReplyProcessor deviceReplyProcessor, final RequestContext> requestContext) { this.deviceReplyProcessor = Preconditions.checkNotNull(deviceReplyProcessor); this.requestContext = Preconditions.checkNotNull(requestContext); } @Override - public void addMultipartMsg(final MultipartReply reply) { - addMultipartMsg(reply, null); - } - - @Override - public void addMultipartMsg(@Nonnull final MultipartReply reply, @Nonnull final EventIdentifier eventIdentifier) { + public void addMultipartMsg(@Nonnull final T reply, final boolean reqMore, @Nullable final EventIdentifier eventIdentifier) { Preconditions.checkNotNull(reply); + Preconditions.checkNotNull(requestContext.getXid()); Preconditions.checkArgument(requestContext.getXid().getValue().equals(reply.getXid())); LOG.trace("Try to add Multipart reply msg with XID {}", reply.getXid()); - - if (msgType == null) { - msgType = reply.getType(); - } - - if (!msgType.equals(reply.getType())) { - LOG.warn("MultiMsgCollector get incorrect multipart msg with type {} but expected type is {}", reply.getType(), msgType); - } - replyCollection.add(reply); - if (!reply.getFlags().isOFPMPFREQMORE()) { + + if (!reqMore) { endCollecting(eventIdentifier); } } - public void endCollecting() { - endCollecting(null); - } + @Override + public void endCollecting(@Nullable final EventIdentifier eventIdentifier) { + final RpcResult> rpcResult = RpcResultBuilder.success(replyCollection).build(); - public void endCollecting(final EventIdentifier eventIdentifier) { - final RpcResult> rpcResult = RpcResultBuilder.success(replyCollection).build(); - if (null != eventIdentifier) { + if (Objects.nonNull(eventIdentifier)) { EventsTimeCounter.markEnd(eventIdentifier); } + requestContext.setResult(rpcResult); requestContext.close(); deviceReplyProcessor.processReply(requestContext.getXid(), replyCollection); diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/protocol/deserialization/DeserializerInjector.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/protocol/deserialization/DeserializerInjector.java index 58ff118840..e88138385f 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/protocol/deserialization/DeserializerInjector.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/protocol/deserialization/DeserializerInjector.java @@ -24,7 +24,10 @@ public class DeserializerInjector { MatchDeserializerInjector.injectDeserializers(provider); ActionDeserializerInjector.injectDeserializers(provider); InstructionDeserializerInjector.injectDeserializers(provider); - MessageDeserializerInjector.injectDeserializers(provider); MultipartDeserializerInjector.injectDeserializers(provider); + + // Message deserializers are not used, so disable them here + // Uncomment to enable + // MessageDeserializerInjector.injectDeserializers(provider); } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/protocol/deserialization/multipart/MultipartReplyGroupDescDeserializer.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/protocol/deserialization/multipart/MultipartReplyGroupDescDeserializer.java index abd9df9c86..14795a8c96 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/protocol/deserialization/multipart/MultipartReplyGroupDescDeserializer.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/protocol/deserialization/multipart/MultipartReplyGroupDescDeserializer.java @@ -53,6 +53,7 @@ public class MultipartReplyGroupDescDeserializer implements OFDeserializer subItems = new ArrayList<>(); int actualLength = GROUP_DESC_HEADER_LENGTH; @@ -68,8 +69,6 @@ public class MultipartReplyGroupDescDeserializer implements OFDeserializer actions = new ArrayList<>(); @@ -90,11 +89,11 @@ public class MultipartReplyGroupDescDeserializer implements OFDeserializer { +public abstract class AbstractAggregateFlowMultipartService + extends AbstractMultipartService { private final ConvertorExecutor convertorExecutor; - public MatchingFlowsInTableService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final ConvertorExecutor convertorExecutor) { + public AbstractAggregateFlowMultipartService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final ConvertorExecutor convertorExecutor) { super(requestContextStack, deviceContext); this.convertorExecutor = convertorExecutor; } @@ -38,7 +41,7 @@ final class MatchingFlowsInTableService extends AbstractMultipartService> handleAndReply( + final GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input); + } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractExperimenterMultipartService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractExperimenterMultipartService.java new file mode 100644 index 0000000000..a2fc1429b0 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractExperimenterMultipartService.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.services; + +import java.util.Objects; +import java.util.concurrent.Future; +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.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.openflowplugin.impl.services.util.RequestInputUtils; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; +import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestExperimenterCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.experimenter._case.MultipartRequestExperimenterBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.experimenter.types.rev151020.experimenter.core.message.ExperimenterMessageOfChoice; +import org.opendaylight.yangtools.yang.common.RpcResult; + +public abstract class AbstractExperimenterMultipartService extends AbstractMultipartService { + + private final ExtensionConverterProvider extensionConverterProvider; + + protected AbstractExperimenterMultipartService(RequestContextStack requestContextStack, DeviceContext deviceContext, + ExtensionConverterProvider extensionConverterProvider) { + super(requestContextStack, deviceContext); + this.extensionConverterProvider = extensionConverterProvider; + } + + @Override + @SuppressWarnings("unchecked") + protected OfHeader buildRequest(Xid xid, SendExperimenterMpRequestInput input) throws ServiceException { + final TypeVersionKey key = new TypeVersionKey<>( + input.getExperimenterMessageOfChoice().getImplementedInterface(), + getVersion()); + + final ConvertorMessageToOFJava messageConverter = + getExtensionConverterProvider().getMessageConverter(key); + + if (Objects.isNull(messageConverter)) { + throw new ServiceException(new ConverterNotFoundException(key.toString())); + } + + try { + return RequestInputUtils + .createMultipartHeader(MultipartType.OFPMPEXPERIMENTER, xid.getValue(), getVersion()) + .setMultipartRequestBody(new MultipartRequestExperimenterCaseBuilder() + .setMultipartRequestExperimenter(new MultipartRequestExperimenterBuilder() + .setExperimenter(messageConverter.getExperimenterId()) + .setExpType(messageConverter.getType()) + .setExperimenterDataOfChoice(messageConverter + .convert(input.getExperimenterMessageOfChoice())) + .build()) + .build()) + .build(); + } catch (final ConversionException e) { + throw new ServiceException(e); + } + } + + /** + * Get extension converter provider + * @return extension converter provider + */ + protected ExtensionConverterProvider getExtensionConverterProvider() { + return extensionConverterProvider; + } + + /** + * Process experimenter input and result experimenter output + * @param input experimenter input + * @return experimenter output + */ + public abstract Future> handleAndReply(SendExperimenterMpRequestInput input); + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractMessageService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractMessageService.java deleted file mode 100644 index 96e8c40648..0000000000 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractMessageService.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.openflowplugin.impl.services; - -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; -import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.common.RpcResult; -import org.opendaylight.yangtools.yang.common.RpcResultBuilder; - -abstract class AbstractMessageService, O extends DataObject> - extends AbstractSimpleService { - private final boolean useSingleLayerSerialization; - - protected AbstractMessageService(RequestContextStack requestContextStack, DeviceContext deviceContext, Class clazz) { - super(requestContextStack, deviceContext, clazz); - useSingleLayerSerialization = deviceContext.isUseSingleLayerSerialization(); - } - - @Override - public ListenableFuture> handleServiceCall(R input) { - return Futures.withFallback(super.handleServiceCall(input), t -> RpcResultBuilder.failed().buildFuture()); - } - - /** - * Check if this service is supported in current OpenFlowPlugin configuration - * @return true if supported and single layer serialization is turned on - */ - public boolean isSupported() { - return useSingleLayerSerialization; - } -} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractMultipartCollectorService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractMultipartCollectorService.java new file mode 100644 index 0000000000..c643bf8aaf --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractMultipartCollectorService.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.openflowplugin.impl.services; + +import com.google.common.util.concurrent.FutureCallback; +import java.util.List; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.api.openflow.device.Xid; +import org.opendaylight.openflowplugin.impl.common.MultipartRequestInputFactory; +import org.opendaylight.openflowplugin.impl.util.DeviceInitializationUtil; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; + +public abstract class AbstractMultipartCollectorService extends AbstractMultipartService { + + protected AbstractMultipartCollectorService(final RequestContextStack requestContextStack, final DeviceContext deviceContext) { + super(requestContextStack, deviceContext); + } + + @Override + protected FutureCallback createCallback(RequestContext> context, Class requestType) { + final FutureCallback callback = super.createCallback(context, requestType); + + return new FutureCallback() { + @Override + public void onSuccess(@Nullable final OfHeader result) { + callback.onSuccess(result); + } + + @Override + public void onFailure(@Nonnull final Throwable t) { + // If we failed getting table features, at least create empty tables + if (MultipartType.OFPMPTABLEFEATURES.getClass().equals(requestType)) { + DeviceInitializationUtil.makeEmptyTables( + getTxFacade(), + getDeviceInfo(), + getDeviceContext().getPrimaryConnectionContext().getFeatures().getTables()); + } + + callback.onFailure(t); + } + }; + } + + @Override + protected OfHeader buildRequest(final Xid xid, final MultipartType input) { + return MultipartRequestInputFactory.makeMultipartRequestInput(xid.getValue(), getVersion(), input); + } +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractMultipartOnTheFlyService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractMultipartOnTheFlyService.java index 06ccafd774..9873807cb6 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractMultipartOnTheFlyService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractMultipartOnTheFlyService.java @@ -13,25 +13,31 @@ import java.util.List; import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; import org.opendaylight.openflowplugin.api.openflow.device.RequestContext; import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerFlowMultipartRequestOnTheFlyCallback; +import org.opendaylight.openflowplugin.impl.services.singlelayer.SingleLayerFlowMultipartRequestOnTheFlyCallback; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; -public abstract class AbstractMultipartOnTheFlyService extends AbstractService> { +public abstract class AbstractMultipartOnTheFlyService extends AbstractMultipartService { + private final ConvertorExecutor convertorExecutor; + private final MultipartWriterProvider statisticsWriterProvider; - protected AbstractMultipartOnTheFlyService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final ConvertorExecutor convertorExecutor) { + protected AbstractMultipartOnTheFlyService(final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ConvertorExecutor convertorExecutor, + final MultipartWriterProvider statisticsWriterProvider) { super(requestContextStack, deviceContext); this.convertorExecutor = convertorExecutor; + this.statisticsWriterProvider = statisticsWriterProvider; } @Override - protected final FutureCallback createCallback(final RequestContext> context, final Class requestType) { - return new MultipartRequestOnTheFlyCallback(context, requestType, - getMessageSpy(), getEventIdentifier(), getDeviceInfo(), - getDeviceContext().getDeviceFlowRegistry(), getTxFacade(), - convertorExecutor); + protected final FutureCallback createCallback(final RequestContext> context, final Class requestType) { + return canUseSingleLayerSerialization() + ? new SingleLayerFlowMultipartRequestOnTheFlyCallback<>(context, requestType, getDeviceContext(), getEventIdentifier(), statisticsWriterProvider) + : new MultiLayerFlowMultipartRequestOnTheFlyCallback<>(context, requestType, getDeviceContext(), getEventIdentifier(), statisticsWriterProvider, convertorExecutor); } - } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestCallback.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractMultipartRequestCallback.java similarity index 50% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestCallback.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractMultipartRequestCallback.java index 27369a3616..d138b2ec79 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestCallback.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractMultipartRequestCallback.java @@ -8,51 +8,65 @@ package org.opendaylight.openflowplugin.impl.services; import java.util.List; +import java.util.Objects; import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; import org.opendaylight.openflowplugin.api.openflow.device.RequestContext; import org.opendaylight.openflowplugin.api.openflow.device.handlers.MultiMsgCollector; import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier; -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.yangtools.yang.common.RpcError; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -final class MultipartRequestCallback extends AbstractRequestCallback> { - private static final Logger LOG = LoggerFactory.getLogger(MultipartRequestCallback.class); - private final MultiMsgCollector collector; +public abstract class AbstractMultipartRequestCallback extends AbstractRequestCallback> { + private static final Logger LOG = LoggerFactory.getLogger(AbstractMultipartRequestCallback.class); + private final MultiMsgCollector collector; - public MultipartRequestCallback(final RequestContext> context, final Class requestType, final DeviceContext deviceContext) { - super(context, requestType, deviceContext.getMessageSpy()); - collector = deviceContext.getMultiMsgCollector(context); - } - - public MultipartRequestCallback(final RequestContext> context, - final Class requestType, - final DeviceContext deviceContext, - final EventIdentifier eventIdentifier) { + public AbstractMultipartRequestCallback( + final RequestContext> context, + final Class requestType, + final DeviceContext deviceContext, + final EventIdentifier eventIdentifier) { super(context, requestType, deviceContext.getMessageSpy(), eventIdentifier); collector = deviceContext.getMultiMsgCollector(context); } @Override + @SuppressWarnings("unchecked") public void onSuccess(final OfHeader result) { - if (result == null) { - LOG.info("Ofheader was null."); + if (Objects.isNull(result)) { + LOG.info("Response received was null."); collector.endCollecting(getEventIdentifier()); return; } - if (!(result instanceof MultipartReply)) { + if (!isMultipart(result)) { LOG.info("Unexpected response type received {}.", result.getClass()); - final RpcResultBuilder> rpcResultBuilder = - RpcResultBuilder.>failed().withError(RpcError.ErrorType.APPLICATION, - String.format("Unexpected response type received %s.", result.getClass())); - setResult(rpcResultBuilder.build()); + + setResult(RpcResultBuilder + .>failed() + .withError(RpcError.ErrorType.APPLICATION, + String.format("Unexpected response type received %s.", result.getClass())) + .build()); } else { - collector.addMultipartMsg((MultipartReply) result, getEventIdentifier()); + final T resultCast = (T) result; + collector.addMultipartMsg(resultCast, isReqMore(resultCast), getEventIdentifier()); } } + /** + * Check if result is multipart + * @param result result + * @return true if result is multipart + */ + protected abstract boolean isMultipart(final OfHeader result); + + /** + * Check if result requests more multiparts + * @param result result + * @return true if result requests more multiparts + */ + protected abstract boolean isReqMore(final T result); + } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractMultipartRequestOnTheFlyCallback.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractMultipartRequestOnTheFlyCallback.java new file mode 100644 index 0000000000..36ece3d94a --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractMultipartRequestOnTheFlyCallback.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.openflowplugin.impl.services; + +import com.google.common.base.Function; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +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.statistics.ofpspecific.EventIdentifier; +import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.EventsTimeCounter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.multipart.reply.MultipartReplyBody; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; +import org.opendaylight.yangtools.yang.common.RpcError; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class AbstractMultipartRequestOnTheFlyCallback extends AbstractMultipartRequestCallback { + private static final Logger LOG = LoggerFactory.getLogger(AbstractMultipartRequestOnTheFlyCallback.class); + private final DeviceInfo deviceInfo; + private boolean finished = false; + private final EventIdentifier doneEventIdentifier; + private final TxFacade txFacade; + private final MultipartWriterProvider statisticsWriterProvider; + + public AbstractMultipartRequestOnTheFlyCallback(final RequestContext> context, Class requestType, + final DeviceContext deviceContext, + final EventIdentifier eventIdentifier, + final MultipartWriterProvider statisticsWriterProvider) { + super(context, requestType, deviceContext, eventIdentifier); + deviceInfo = deviceContext.getDeviceInfo(); + doneEventIdentifier = new EventIdentifier(getMultipartType().name(), deviceContext.getDeviceInfo().getNodeId().toString()); + txFacade = deviceContext; + this.statisticsWriterProvider = statisticsWriterProvider; + } + + @Override + @SuppressWarnings("unchecked") + public void onSuccess(final OfHeader result) { + if (Objects.isNull(result)) { + LOG.info("OfHeader was null."); + if (!finished) { + endCollecting(); + return; + } + } else if (finished) { + LOG.debug("Unexpected multipart response received: xid={}, {}", result.getXid(), result.getImplementedInterface()); + return; + } + + if (!isMultipart(result)) { + LOG.info("Unexpected response type received {}.", result.getClass()); + setResult(RpcResultBuilder.>failed().withError(RpcError.ErrorType.APPLICATION, + String.format("Unexpected response type received %s.", result.getClass())).build()); + endCollecting(); + } else { + final T resultCast = (T) result; + + Futures.transform(processStatistics(resultCast), (Function, Void>) input -> { + input.ifPresent(reply -> { + try { + statisticsWriterProvider + .lookup(getMultipartType()) + .ifPresent(writer -> writer.write(reply, false)); + } catch (final Exception ex) { + LOG.warn("Stats processing of type {} for node {} failed during write-to-tx step", + getMultipartType(), deviceInfo.getLOGValue(), ex); + } + }); + + if (!isReqMore(resultCast)) { + endCollecting(); + } + + return null; + }); + } + } + + /** + * Get tx facade + * @return tx facade + */ + protected TxFacade getTxFacade() { + return txFacade; + } + + /** + * Ends collecting of multipart data + */ + private void endCollecting() { + EventsTimeCounter.markEnd(doneEventIdentifier); + EventsTimeCounter.markEnd(getEventIdentifier()); + spyMessage(MessageSpy.STATISTIC_GROUP.FROM_SWITCH_TRANSLATE_OUT_SUCCESS); + txFacade.submitTransaction(); + setResult(RpcResultBuilder.success(Collections.emptyList()).build()); + finished = true; + } + + /** + * Process statistics. + * + * @param result result + */ + protected abstract ListenableFuture> processStatistics(final T result); + + /** + * Get multipart type + * @return multipart type + */ + protected abstract MultipartType getMultipartType(); + + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractMultipartService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractMultipartService.java index f2949cef16..d16f3b7ccf 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractMultipartService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractMultipartService.java @@ -8,22 +8,40 @@ package org.opendaylight.openflowplugin.impl.services; import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.ListenableFuture; import java.util.List; +import java.util.function.Function; +import javax.annotation.Nonnull; import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; import org.opendaylight.openflowplugin.api.openflow.device.RequestContext; import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; +import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerMultipartRequestCallback; +import org.opendaylight.openflowplugin.impl.services.singlelayer.SingleLayerMultipartRequestCallback; +import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; +import org.opendaylight.yangtools.yang.common.RpcResult; + +public abstract class AbstractMultipartService extends AbstractService> { + + private static final Function ALTERNATE_IS_COMPLETE = message -> + !(message instanceof MultipartReply) || !((MultipartReply) message).isRequestMore(); -public abstract class AbstractMultipartService extends AbstractService> { protected AbstractMultipartService(final RequestContextStack requestContextStack, final DeviceContext deviceContext) { super(requestContextStack, deviceContext); } @Override - protected final FutureCallback createCallback(final RequestContext> context, final Class requestType) { - return new MultipartRequestCallback(context, requestType, getDeviceContext(), getEventIdentifier()); + protected FutureCallback createCallback(RequestContext> context, Class requestType) { + return canUseSingleLayerSerialization() + ? new SingleLayerMultipartRequestCallback<>(context, requestType, getDeviceContext(), getEventIdentifier()) + : new MultiLayerMultipartRequestCallback<>(context, requestType, getDeviceContext(), getEventIdentifier()); } + @Override + public final ListenableFuture>> handleServiceCall(@Nonnull final I input) { + return canUseSingleLayerSerialization() + ? super.handleServiceCall(input, ALTERNATE_IS_COMPLETE) + : super.handleServiceCall(input); + } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractRequestCallback.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractRequestCallback.java index ca6ddd759d..8992a7b5e1 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractRequestCallback.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractRequestCallback.java @@ -16,6 +16,7 @@ import org.opendaylight.openflowplugin.api.openflow.device.RequestContext; import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier; import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy; import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy.STATISTIC_GROUP; +import org.opendaylight.openflowplugin.impl.services.util.RequestContextUtil; import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.EventsTimeCounter; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.Error; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; @@ -23,19 +24,12 @@ import org.opendaylight.yangtools.yang.common.RpcError; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; -abstract class AbstractRequestCallback implements FutureCallback { +public abstract class AbstractRequestCallback implements FutureCallback { private final RequestContext context; private final Class requestType; private final MessageSpy spy; private EventIdentifier eventIdentifier; - - protected AbstractRequestCallback(final RequestContext context, final Class requestType, final MessageSpy spy) { - this.context = Preconditions.checkNotNull(context); - this.requestType = Preconditions.checkNotNull(requestType); - this.spy = Preconditions.checkNotNull(spy); - } - protected AbstractRequestCallback(final RequestContext context, final Class requestType, final MessageSpy spy, @@ -60,7 +54,7 @@ abstract class AbstractRequestCallback implements FutureCallback { } @Override - public final void onFailure(final Throwable t) { + public final void onFailure(@Nonnull final Throwable t) { final RpcResultBuilder builder; if (null != eventIdentifier) { EventsTimeCounter.markEnd(eventIdentifier); diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractService.java index 94804be16c..3c267c9b42 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractService.java @@ -16,6 +16,7 @@ import java.math.BigInteger; import java.util.Objects; import java.util.function.Function; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueue; import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo; @@ -26,6 +27,8 @@ 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.openflowplugin.impl.services.util.RequestContextUtil; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; 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; @@ -34,7 +37,7 @@ import org.opendaylight.yangtools.yang.common.RpcResultBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -abstract class AbstractService { +public abstract class AbstractService { private static final Logger LOG = LoggerFactory.getLogger(AbstractService.class); private final short version; @@ -54,6 +57,10 @@ abstract class AbstractService { this.messageSpy = deviceContext.getMessageSpy(); } + public boolean canUseSingleLayerSerialization() { + return deviceContext.canUseSingleLayerSerialization(); + } + public EventIdentifier getEventIdentifier() { return eventIdentifier; } @@ -79,7 +86,7 @@ abstract class AbstractService { return deviceContext; } - protected DeviceRegistry getDeviceRegistry() { + public DeviceRegistry getDeviceRegistry() { return deviceContext; } @@ -104,26 +111,28 @@ abstract class AbstractService { } public ListenableFuture> handleServiceCall(@Nonnull final I input, - @Nonnull final Function isComplete) { + @Nullable final Function isComplete) { Preconditions.checkNotNull(input); - final Class requestType; - if (input instanceof DataContainer) { - requestType = ((DataContainer) input).getImplementedInterface(); - } else { - requestType = input.getClass(); - } + final Class requestType = input instanceof DataContainer + ? DataContainer.class.cast(input).getImplementedInterface() + : input.getClass(); + getMessageSpy().spyMessage(requestType, MessageSpy.STATISTIC_GROUP.TO_SWITCH_ENTERED); LOG.trace("Handling general service call"); final RequestContext requestContext = requestContextStack.createRequestContext(); - if (requestContext == null) { + + if (Objects.isNull(requestContext)) { LOG.trace("Request context refused."); getMessageSpy().spyMessage(AbstractService.class, MessageSpy.STATISTIC_GROUP.TO_SWITCH_DISREGARDED); - return failedFuture(); + return Futures.immediateFuture(RpcResultBuilder + .failed() + .withError(RpcError.ErrorType.APPLICATION, "", "Request quota exceeded") + .build()); } - if (requestContext.getXid() == null) { + if (Objects.isNull(requestContext.getXid())) { getMessageSpy().spyMessage(requestContext.getClass(), MessageSpy.STATISTIC_GROUP.TO_SWITCH_RESERVATION_REJECTED); return RequestContextUtil.closeRequestContextWithRpcError(requestContext, "Outbound queue wasn't able to reserve XID."); } @@ -150,10 +159,4 @@ abstract class AbstractService { return requestContext.getFuture(); } - - protected static ListenableFuture> failedFuture() { - final RpcResult rpcResult = RpcResultBuilder.failed() - .withError(RpcError.ErrorType.APPLICATION, "", "Request quota exceeded").build(); - return Futures.immediateFuture(rpcResult); - } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractSilentErrorService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractSilentErrorService.java new file mode 100644 index 0000000000..6ef58b7cab --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractSilentErrorService.java @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.services; + +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import java.util.function.Function; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; + +public abstract class AbstractSilentErrorService + extends AbstractSimpleService { + + protected AbstractSilentErrorService(RequestContextStack requestContextStack, DeviceContext deviceContext, Class clazz) { + super(requestContextStack, deviceContext, clazz); + } + + @Override + public ListenableFuture> handleServiceCall(@Nonnull I input, + @Nullable final Function isComplete) { + return Futures.withFallback( + super.handleServiceCall(input, isComplete), + t -> RpcResultBuilder.failed().buildFuture()); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractTableMultipartService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractTableMultipartService.java new file mode 100644 index 0000000000..b712cbe6b5 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractTableMultipartService.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.services; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.Future; +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.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.MultipartRequestTableFeaturesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeatures; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.TableUpdatedBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutput; +import org.opendaylight.yangtools.yang.common.RpcResult; + +public abstract class AbstractTableMultipartService extends AbstractMultipartService { + + private final ConvertorExecutor convertorExecutor; + private final MultipartWriterProvider multipartWriterProvider; + private final VersionConvertorData data; + + protected AbstractTableMultipartService(final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ConvertorExecutor convertorExecutor, + final MultipartWriterProvider multipartWriterProvider) { + super(requestContextStack, deviceContext); + this.convertorExecutor = convertorExecutor; + this.multipartWriterProvider = multipartWriterProvider; + data = new VersionConvertorData(getVersion()); + } + + @Override + protected OfHeader buildRequest(final Xid xid, final UpdateTableInput input) throws ServiceException { + final Optional> tableFeatures = getConvertorExecutor().convert(input.getUpdatedTable(), data); + + return RequestInputUtils.createMultipartHeader(MultipartType.OFPMPTABLEFEATURES, xid.getValue(), getVersion()) + .setMultipartRequestBody(new MultipartRequestTableFeaturesCaseBuilder() + .setMultipartRequestTableFeatures(new MultipartRequestTableFeaturesBuilder() + .setTableFeatures(tableFeatures + .orElseGet(Collections::emptyList)) + .build()) + .build()) + .build(); + } + + /** + * Get convertor executor + * @return convertor executor + */ + protected ConvertorExecutor getConvertorExecutor() { + return convertorExecutor; + } + + /** + * Get data + * @return data + */ + protected VersionConvertorData getData() { + return data; + } + + /** + * Stores table features to operational datastore + */ + protected void storeStatistics(List result) { + multipartWriterProvider + .lookup(MultipartType.OFPMPTABLEFEATURES) + .ifPresent(writer -> { + writer.write( + new TableUpdatedBuilder() + .setTableFeatures(result) + .build(), + false); + + getTxFacade().submitTransaction(); + }); + } + + /** + * Process experimenter input and result experimenter output + * @param input experimenter input + * @return experimenter output + */ + public abstract Future> handleAndReply(UpdateTableInput input); + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractVoidService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractVoidService.java index 15ca0d1b9d..a24fcda674 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractVoidService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractVoidService.java @@ -12,9 +12,8 @@ import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; import org.opendaylight.openflowplugin.api.openflow.device.RequestContext; import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; -import org.opendaylight.yangtools.yang.binding.DataObject; -public abstract class AbstractVoidService extends AbstractService { +public abstract class AbstractVoidService extends AbstractService { protected AbstractVoidService(final RequestContextStack requestContextStack, final DeviceContext deviceContext) { super(requestContextStack, deviceContext); } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/EchoService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/EchoService.java index 0bf4a5bba7..b0334fb0f6 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/EchoService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/EchoService.java @@ -10,6 +10,7 @@ package org.opendaylight.openflowplugin.impl.services; 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.impl.services.util.ServiceException; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; @@ -26,4 +27,4 @@ public class EchoService extends AbstractSimpleService> { - private static final Logger LOG = LoggerFactory.getLogger(MultipartRequestOnTheFlyCallback.class); - private final SinglePurposeMultipartReplyTranslator multipartReplyTranslator; - private final DeviceInfo deviceInfo; - private final DeviceFlowRegistry registry; - private boolean virgin = true; - private boolean finished = false; - private final EventIdentifier doneEventIdentifier; - private final TxFacade txFacade; - - - public MultipartRequestOnTheFlyCallback(final RequestContext> context, - final Class requestType, - final MessageSpy messageSpy, - final EventIdentifier eventIdentifier, - final DeviceInfo deviceInfo, - final DeviceFlowRegistry registry, - final TxFacade txFacade, - final ConvertorExecutor convertorExecutor) { - super(context, requestType, messageSpy, eventIdentifier); - - this.deviceInfo = deviceInfo; - this.registry = registry; - this.txFacade = txFacade; - - multipartReplyTranslator = new SinglePurposeMultipartReplyTranslator(convertorExecutor); - - //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(), deviceInfo.getNodeId().toString()); - } - - public EventIdentifier getDoneEventIdentifier() { - return doneEventIdentifier; - } - - @Override - public void onSuccess(final OfHeader result) { - if (result == null) { - LOG.info("Ofheader was null."); - if (!finished) { - endCollecting(); - return; - } - } else if (finished) { - LOG.debug("Unexpected multipart response received: xid={}, {}", result.getXid(), result.getImplementedInterface()); - return; - } - - if (!(result instanceof MultipartReply)) { - LOG.info("Unexpected response type received {}.", result.getClass()); - final RpcResultBuilder> rpcResultBuilder = - RpcResultBuilder.>failed().withError(RpcError.ErrorType.APPLICATION, - String.format("Unexpected response type received %s.", result.getClass())); - setResult(rpcResultBuilder.build()); - endCollecting(); - } else { - final MultipartReply multipartReply = (MultipartReply) result; - - final MultipartReply singleReply = multipartReply; - final List multipartDataList = multipartReplyTranslator.translate( - deviceInfo.getDatapathId(), deviceInfo.getVersion(), singleReply); - final Iterable allMultipartData = multipartDataList; - - //TODO: following part is focused on flow stats only - need more general approach if used for more than flow stats - ListenableFuture future; - if (virgin) { - future = StatisticsGatheringUtils.deleteAllKnownFlows(deviceInfo, registry, txFacade); - virgin = false; - } else { - future = Futures.immediateFuture(null); - } - - Futures.transform(future, new Function() { - - @Override - public Void apply(final Void input) { - StatisticsGatheringUtils.writeFlowStatistics((Iterable) allMultipartData, - deviceInfo, registry, txFacade); - - if (!multipartReply.getFlags().isOFPMPFREQMORE()) { - endCollecting(); - } - return input; - } - }); - } - } - - private void endCollecting() { - EventsTimeCounter.markEnd(getDoneEventIdentifier()); - EventsTimeCounter.markEnd(getEventIdentifier()); - final RpcResult> rpcResult = RpcResultBuilder.success(Collections.emptyList()).build(); - spyMessage(MessageSpy.STATISTIC_GROUP.FROM_SWITCH_TRANSLATE_OUT_SUCCESS); - txFacade.submitTransaction(); - setResult(rpcResult); - finished = true; - } -} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/RoleService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/RoleService.java index c2653bf208..446f8372a8 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/RoleService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/RoleService.java @@ -19,6 +19,7 @@ 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.impl.role.RoleChangeException; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ControllerRole; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; @@ -41,7 +42,7 @@ public class RoleService extends AbstractSimpleService clazz) { + public RoleService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final Class clazz) { super(requestContextStack, deviceContext, clazz); this.deviceContext = deviceContext; } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalTableServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalTableServiceImpl.java deleted file mode 100644 index ef757c9c4f..0000000000 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalTableServiceImpl.java +++ /dev/null @@ -1,188 +0,0 @@ -/** - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.openflowplugin.impl.services; - -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.SettableFuture; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.Future; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; -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.openflow.md.core.sal.convertor.ConvertorExecutor; -import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId; -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.MultipartRequestFlags; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.MultipartReplyBody; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableFeaturesCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.MultipartReplyTableFeatures; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCaseBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.MultipartRequestTableFeaturesBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeatures; -import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.SalTableService; -import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeaturesKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; -import org.opendaylight.yangtools.yang.common.RpcError.ErrorType; -import org.opendaylight.yangtools.yang.common.RpcResult; -import org.opendaylight.yangtools.yang.common.RpcResultBuilder; -import org.slf4j.Logger; - -public final class SalTableServiceImpl extends AbstractMultipartService implements SalTableService { - private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(SalTableServiceImpl.class); - private final TxFacade txFacade; - private final ConvertorExecutor convertorExecutor; - private final VersionConvertorData data; - - public SalTableServiceImpl(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final ConvertorExecutor convertorExecutor) { - super(requestContextStack, deviceContext); - this.txFacade = deviceContext; - this.convertorExecutor = convertorExecutor; - data = new VersionConvertorData(getVersion()); - } - - @Override - public Future> updateTable(final UpdateTableInput input) { - final ListenableFuture>> multipartFuture = handleServiceCall(input); - final SettableFuture> finalFuture = SettableFuture.create(); - - class CallBackImpl implements FutureCallback>> { - @Override - public void onSuccess(final RpcResult> result) { - - if (result.isSuccessful()) { - final List multipartReplies = result.getResult(); - if (multipartReplies.isEmpty()) { - LOG.debug("Multipart reply to table features request shouldn't be empty list."); - finalFuture.set(RpcResultBuilder.failed() - .withError(ErrorType.RPC, "Multipart reply list is empty.").build()); - } else { - final Long xid = multipartReplies.get(0).getXid(); - LOG.debug( - "OnSuccess, rpc result successful, multipart response for rpc update-table with xid {} obtained.", - xid); - final UpdateTableOutputBuilder updateTableOutputBuilder = new UpdateTableOutputBuilder(); - updateTableOutputBuilder.setTransactionId(new TransactionId(BigInteger.valueOf(xid))); - finalFuture.set(RpcResultBuilder.success(updateTableOutputBuilder.build()).build()); - try { - writeResponseToOperationalDatastore(multipartReplies); - } catch (Exception e) { - LOG.warn("Not able to write to operational datastore: {}", e.getMessage()); - } - } - } else { - LOG.debug("OnSuccess, rpc result unsuccessful, multipart response for rpc update-table was unsuccessful."); - finalFuture.set(RpcResultBuilder.failed().withRpcErrors(result.getErrors()) - .build()); - } - } - - @Override - public void onFailure(final Throwable t) { - LOG.error("Failure multipart response for table features request. Exception: {}", t); - finalFuture.set(RpcResultBuilder.failed() - .withError(ErrorType.RPC, "Future error", t).build()); - } - } - - Futures.addCallback(multipartFuture, new CallBackImpl()); - - return finalFuture; - } - - /** - * @param multipartReplies - */ - private void writeResponseToOperationalDatastore(final List multipartReplies) throws Exception { - - final List salTableFeatures = convertToSalTableFeatures(multipartReplies); - - final InstanceIdentifier flowCapableNodeII = InstanceIdentifier.create(Nodes.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 tableFeaturesII = flowCapableNodeII - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures.class, - new TableFeaturesKey(tableId)); - txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, tableFeaturesII, - tableFeatureData); - } - - txFacade.submitTransaction(); - } - - protected List convertToSalTableFeatures( - final List multipartReplies) { - final List salTableFeaturesAll = new ArrayList<>(); - for (final MultipartReply multipartReply : multipartReplies) { - if (multipartReply.getType().equals(MultipartType.OFPMPTABLEFEATURES)) { - final MultipartReplyBody multipartReplyBody = multipartReply.getMultipartReplyBody(); - if (multipartReplyBody instanceof MultipartReplyTableFeaturesCase) { - final MultipartReplyTableFeaturesCase tableFeaturesCase = ((MultipartReplyTableFeaturesCase) multipartReplyBody); - final MultipartReplyTableFeatures salTableFeatures = tableFeaturesCase - .getMultipartReplyTableFeatures(); - - final Optional> salTableFeaturesPartial = - convertorExecutor.convert(salTableFeatures, data); - - if (salTableFeaturesPartial.isPresent()) { - salTableFeaturesAll.addAll(salTableFeaturesPartial.get()); - } - - LOG.debug("TableFeature {} for xid {}.", salTableFeatures, multipartReply.getXid()); - } - } - } - return salTableFeaturesAll; - } - - private MultipartRequestInputBuilder createMultipartHeader(final MultipartType multipart, final Long xid) { - final MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder(); - mprInput.setType(multipart); - mprInput.setVersion(getVersion()); - mprInput.setXid(xid); - mprInput.setFlags(new MultipartRequestFlags(false)); - return mprInput; - } - - @Override - protected OfHeader buildRequest(final Xid xid, final UpdateTableInput input) throws ServiceException { - final MultipartRequestTableFeaturesCaseBuilder caseBuilder = new MultipartRequestTableFeaturesCaseBuilder(); - final MultipartRequestTableFeaturesBuilder requestBuilder = new MultipartRequestTableFeaturesBuilder(); - - final Optional> ofTableFeatureList = convertorExecutor.convert(input.getUpdatedTable(), data); - requestBuilder.setTableFeatures(ofTableFeatureList.orElse(Collections.emptyList())); - caseBuilder.setMultipartRequestTableFeatures(requestBuilder.build()); - - // Set request body to main multipart request - final MultipartRequestInputBuilder mprInput = createMultipartHeader(MultipartType.OFPMPTABLEFEATURES, - xid.getValue()); - mprInput.setMultipartRequestBody(caseBuilder.build()); - - return mprInput.build(); - } -} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SimpleRequestCallback.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SimpleRequestCallback.java index 034d2fa3bf..3f94add007 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SimpleRequestCallback.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SimpleRequestCallback.java @@ -17,16 +17,16 @@ import org.opendaylight.yangtools.yang.common.RpcResultBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -final class SimpleRequestCallback extends AbstractRequestCallback { +public final class SimpleRequestCallback extends AbstractRequestCallback { private static final Logger LOG = LoggerFactory.getLogger(SimpleRequestCallback.class); private final Class clazz; private SimpleRequestCallback(final RequestContext context, final Class requestType, final MessageSpy spy, final Class clazz) { - super(context, requestType, spy); + super(context, requestType, spy, null); this.clazz = Preconditions.checkNotNull(clazz); } - static FutureCallback create(final RequestContext context, final Class requestType, final MessageSpy spy, final Class clazz) { + public static FutureCallback create(final RequestContext context, final Class requestType, final MessageSpy spy, final Class clazz) { return new SimpleRequestCallback<>(context, requestType, spy, clazz); } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/VoidRequestCallback.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/VoidRequestCallback.java index 5860a183f8..97109ad401 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/VoidRequestCallback.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/VoidRequestCallback.java @@ -14,11 +14,11 @@ 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; -final class VoidRequestCallback extends AbstractRequestCallback { +public final class VoidRequestCallback extends AbstractRequestCallback { private static final RpcResult SUCCESS = RpcResultBuilder.success().build(); - VoidRequestCallback(final RequestContext context, final Class requestType, final MessageSpy spy) { - super(context, requestType, spy); + public VoidRequestCallback(final RequestContext context, final Class requestType, final MessageSpy spy) { + super(context, requestType, spy, null); } @Override diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerAggregateFlowMultipartService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerAggregateFlowMultipartService.java new file mode 100644 index 0000000000..ee10af7138 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerAggregateFlowMultipartService.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.services.multilayer; + +import com.google.common.base.Function; +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.Futures; +import java.util.List; +import java.util.concurrent.Future; +import java.util.stream.Collectors; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.api.openflow.device.TranslatorLibrary; +import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey; +import org.opendaylight.openflowplugin.impl.services.AbstractAggregateFlowMultipartService; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder; +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.MultipartReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCase; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; + +public class MultiLayerAggregateFlowMultipartService extends AbstractAggregateFlowMultipartService { + + private final TranslatorLibrary translatorLibrary; + + public MultiLayerAggregateFlowMultipartService(final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ConvertorExecutor convertorExecutor, + final TranslatorLibrary translatorLibrary) { + super(requestContextStack, deviceContext, convertorExecutor); + this.translatorLibrary = translatorLibrary; + } + + @Override + public Future> handleAndReply(final GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input) { + return Futures.transform(handleServiceCall(input), + (Function>, RpcResult>) result -> { + if (Preconditions.checkNotNull(result).isSuccessful()) { + final MessageTranslator messageTranslator = translatorLibrary + .lookupTranslator(new TranslatorKey(getVersion(), MultipartReplyAggregateCase.class.getName())); + + return RpcResultBuilder + .success(new GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder() + .setAggregatedFlowStatistics(result + .getResult() + .stream() + .map(multipartReply -> messageTranslator + .translate(multipartReply, getDeviceInfo(), null)) + .collect(Collectors.toList()))) + .build(); + } + + return RpcResultBuilder + .failed() + .withRpcErrors(result.getErrors()) + .build(); + }); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalExperimenterMpMessageServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerExperimenterMultipartService.java old mode 100755 new mode 100644 similarity index 68% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalExperimenterMpMessageServiceImpl.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerExperimenterMultipartService.java index fa6797299c..5f717af622 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalExperimenterMpMessageServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerExperimenterMultipartService.java @@ -1,67 +1,55 @@ /* - * Copyright (c) 2016 Pantheon Technologies s.r.o. and others. All rights reserved. + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.multilayer; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.SettableFuture; import java.util.ArrayList; import java.util.List; -import java.util.Objects; import java.util.concurrent.Future; - import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey; 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.ConvertorMessageFromOFJava; -import org.opendaylight.openflowplugin.extension.api.ConvertorMessageToOFJava; -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.openflowplugin.extension.api.path.MessagePath; -import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SalExperimenterMpMessageService; +import org.opendaylight.openflowplugin.impl.services.AbstractExperimenterMultipartService; import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.send.experimenter.mp.request.output.ExperimenterCoreMessageItem; import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.send.experimenter.mp.request.output.ExperimenterCoreMessageItemBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; 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.experimenter.core.ExperimenterDataOfChoice; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyExperimenterCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.experimenter._case.MultipartReplyExperimenter; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestExperimenterCaseBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.experimenter._case.MultipartRequestExperimenterBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.experimenter.types.rev151020.experimenter.core.message.ExperimenterMessageOfChoice; import org.opendaylight.yangtools.yang.common.RpcError.ErrorType; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; import org.slf4j.Logger; -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.SettableFuture; +public class MultiLayerExperimenterMultipartService extends AbstractExperimenterMultipartService { -public class SalExperimenterMpMessageServiceImpl extends AbstractMultipartService implements SalExperimenterMpMessageService { - private final ExtensionConverterProvider extensionConverterProvider; - private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(SalExperimenterMpMessageServiceImpl.class); + private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(MultiLayerExperimenterMultipartService.class); - public SalExperimenterMpMessageServiceImpl(final RequestContextStack requestContextStack, - final DeviceContext deviceContext, - final ExtensionConverterProvider extensionConverterProvider) { - super(requestContextStack, deviceContext); - this.extensionConverterProvider = extensionConverterProvider; + public MultiLayerExperimenterMultipartService(RequestContextStack requestContextStack, DeviceContext deviceContext, + ExtensionConverterProvider extensionConverterProvider) { + super(requestContextStack, deviceContext, extensionConverterProvider); } @Override - public Future> sendExperimenterMpRequest(SendExperimenterMpRequestInput input) { + @SuppressWarnings("unchecked") + public Future> handleAndReply(SendExperimenterMpRequestInput input) { final ListenableFuture>> multipartFuture = handleServiceCall(input); final SettableFuture> finalFuture = SettableFuture.create(); @@ -87,7 +75,7 @@ public class SalExperimenterMpMessageServiceImpl extends AbstractMultipartServic getVersion(), (Class) vendorData.getImplementedInterface()); final ConvertorMessageFromOFJava messageConverter = - extensionConverterProvider.getMessageConverter(key); + getExtensionConverterProvider().getMessageConverter(key); if (messageConverter == null) { LOG.warn("Custom converter for {}[OF:{}] not found", vendorData.getImplementedInterface(), @@ -127,34 +115,4 @@ public class SalExperimenterMpMessageServiceImpl extends AbstractMultipartServic return finalFuture; } - @Override - @SuppressWarnings("unchecked") - protected OfHeader buildRequest(Xid xid, SendExperimenterMpRequestInput input) throws ServiceException { - final TypeVersionKey key = new TypeVersionKey( - input.getExperimenterMessageOfChoice().getImplementedInterface(), - getVersion()); - - final ConvertorMessageToOFJava messageConverter = - extensionConverterProvider.getMessageConverter(key); - - if (Objects.isNull(messageConverter)) { - throw new ServiceException(new ConverterNotFoundException(key.toString())); - } - - try { - return RequestInputUtils - .createMultipartHeader(MultipartType.OFPMPEXPERIMENTER, xid.getValue(), getVersion()) - .setMultipartRequestBody(new MultipartRequestExperimenterCaseBuilder() - .setMultipartRequestExperimenter(new MultipartRequestExperimenterBuilder() - .setExperimenter(messageConverter.getExperimenterId()) - .setExpType(messageConverter.getType()) - .setExperimenterDataOfChoice(messageConverter - .convert(input.getExperimenterMessageOfChoice())) - .build()) - .build()) - .build(); - } catch (final ConversionException e) { - throw new ServiceException(e); - } - } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerFlowMultipartRequestOnTheFlyCallback.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerFlowMultipartRequestOnTheFlyCallback.java new file mode 100644 index 0000000000..982bb62128 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerFlowMultipartRequestOnTheFlyCallback.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.services.multilayer; + +import com.google.common.base.Function; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import java.util.List; +import java.util.Optional; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContext; +import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier; +import org.opendaylight.openflowplugin.impl.common.MultipartReplyTranslatorUtil; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.services.AbstractMultipartRequestOnTheFlyCallback; +import org.opendaylight.openflowplugin.impl.statistics.StatisticsGatheringUtils; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.multipart.reply.MultipartReplyBody; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; + +public class MultiLayerFlowMultipartRequestOnTheFlyCallback extends AbstractMultipartRequestOnTheFlyCallback { + + private final ConvertorExecutor convertorExecutor; + private final DeviceInfo deviceInfo; + private boolean virgin = true; + + public MultiLayerFlowMultipartRequestOnTheFlyCallback(final RequestContext> context, + final Class requestType, + final DeviceContext deviceContext, + final EventIdentifier eventIdentifier, + final MultipartWriterProvider statisticsWriterProvider, + final ConvertorExecutor convertorExecutor) { + super(context, requestType, deviceContext, eventIdentifier, statisticsWriterProvider); + this.convertorExecutor = convertorExecutor; + deviceInfo = deviceContext.getDeviceInfo(); + } + + @Override + protected boolean isMultipart(OfHeader result) { + return result instanceof MultipartReply + && MultipartReply.class.cast(result).getType().equals(getMultipartType()); + } + + @Override + protected boolean isReqMore(T result) { + return MultipartReply.class.cast(result).getFlags().isOFPMPFREQMORE(); + } + + @Override + protected MultipartType getMultipartType() { + return MultipartType.OFPMPFLOW; + } + + @Override + protected ListenableFuture> processStatistics(T result) { + final ListenableFuture> future = Futures.transform( + StatisticsGatheringUtils.deleteAllKnownFlows( + getTxFacade(), + deviceInfo + .getNodeInstanceIdentifier() + .augmentation(FlowCapableNode.class), + !virgin), + (Function>) input -> MultipartReplyTranslatorUtil + .translate(result, deviceInfo, convertorExecutor, null)); + + if (virgin) { + virgin = false; + } + + return future; + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/FlowService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerFlowService.java similarity index 83% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/FlowService.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerFlowService.java index e865d90330..c26638fae9 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/FlowService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerFlowService.java @@ -1,11 +1,11 @@ -/** - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.multilayer; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; @@ -19,6 +19,8 @@ import org.opendaylight.openflowplugin.api.OFConstants; 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.impl.services.AbstractSimpleService; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow; @@ -29,12 +31,12 @@ import org.opendaylight.yangtools.yang.common.RpcError; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; -final class FlowService extends AbstractSimpleService { +public final class MultiLayerFlowService extends AbstractSimpleService { private final ConvertorExecutor convertorExecutor; private final VersionDatapathIdConvertorData data; - protected FlowService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final Class clazz, final ConvertorExecutor convertorExecutor) { + public MultiLayerFlowService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final Class clazz, final ConvertorExecutor convertorExecutor) { super(requestContextStack, deviceContext, clazz); this.convertorExecutor = convertorExecutor; data = new VersionDatapathIdConvertorData(getVersion()); @@ -47,12 +49,12 @@ final class FlowService extends AbstractSimpleService toFlowModInputs(final Flow input) { + public List toFlowModInputs(final Flow input) { final Optional> flowModInputBuilders = convertorExecutor.convert(input, data); return flowModInputBuilders.orElse(Collections.emptyList()); } - ListenableFuture> processFlowModInputBuilders(final List ofFlowModInputs) { + public ListenableFuture> processFlowModInputBuilders(final List ofFlowModInputs) { final List>> partialFutures = new ArrayList<>(ofFlowModInputs.size()); for (final FlowModInputBuilder flowModInputBuilder : ofFlowModInputs) { diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/GroupService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerGroupService.java similarity index 75% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/GroupService.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerGroupService.java index aa1ebe15cc..c2a3355e88 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/GroupService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerGroupService.java @@ -1,16 +1,18 @@ -/** - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.multilayer; import java.util.Optional; 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.impl.services.AbstractSimpleService; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.GroupConvertor; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData; @@ -19,11 +21,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; import org.opendaylight.yangtools.yang.binding.DataObject; -final class GroupService extends AbstractSimpleService { +public final class MultiLayerGroupService extends AbstractSimpleService { private final ConvertorExecutor convertorExecutor; private final VersionDatapathIdConvertorData data; - GroupService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final Class clazz, final ConvertorExecutor convertorExecutor) { + public MultiLayerGroupService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final Class clazz, final ConvertorExecutor convertorExecutor) { super(requestContextStack, deviceContext, clazz); this.convertorExecutor = convertorExecutor; data = new VersionDatapathIdConvertorData(getVersion()); diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/MeterService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerMeterService.java similarity index 74% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/MeterService.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerMeterService.java index 7b6fc8e69b..9ef9d0b9b1 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/MeterService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerMeterService.java @@ -1,16 +1,18 @@ -/** - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.multilayer; import java.util.Optional; 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.impl.services.AbstractSimpleService; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.MeterConvertor; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData; @@ -19,12 +21,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; import org.opendaylight.yangtools.yang.binding.DataObject; -final class MeterService extends AbstractSimpleService { +public final class MultiLayerMeterService extends AbstractSimpleService { private final ConvertorExecutor convertorExecutor; private final VersionConvertorData data; - MeterService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final Class clazz, final ConvertorExecutor convertorExecutor) { + public MultiLayerMeterService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final Class clazz, final ConvertorExecutor convertorExecutor) { super(requestContextStack, deviceContext, clazz); this.convertorExecutor = convertorExecutor; data = new VersionConvertorData(getVersion()); @@ -39,4 +41,4 @@ final class MeterService extends Abstract meterModInputBuilder.setXid(xid.getValue()); return meterModInputBuilder.build(); } -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerMultipartCollectorService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerMultipartCollectorService.java new file mode 100644 index 0000000000..f41e7f9fbf --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerMultipartCollectorService.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.services.multilayer; + +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.impl.services.AbstractMultipartCollectorService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; + +public class MultiLayerMultipartCollectorService extends AbstractMultipartCollectorService { + + public MultiLayerMultipartCollectorService(final RequestContextStack requestContextStack, final DeviceContext deviceContext) { + super(requestContextStack, deviceContext); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerMultipartRequestCallback.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerMultipartRequestCallback.java new file mode 100644 index 0000000000..d8bf0b12d9 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerMultipartRequestCallback.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.services.multilayer; + +import java.util.List; +import java.util.Objects; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContext; +import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier; +import org.opendaylight.openflowplugin.impl.services.AbstractMultipartRequestCallback; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; + +public class MultiLayerMultipartRequestCallback extends AbstractMultipartRequestCallback { + + public MultiLayerMultipartRequestCallback(RequestContext> context, Class requestType, DeviceContext deviceContext, EventIdentifier eventIdentifier) { + super(context, requestType, deviceContext, eventIdentifier); + } + + @Override + protected boolean isMultipart(OfHeader result) { + return result instanceof MultipartReply; + } + + @Override + protected boolean isReqMore(T result) { + final MultipartRequestFlags flags = MultipartReply.class.cast(result).getFlags(); + return Objects.nonNull(flags) && flags.isOFPMPFREQMORE(); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerTableMultipartService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerTableMultipartService.java new file mode 100644 index 0000000000..1310431d8a --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/multilayer/MultiLayerTableMultipartService.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.services.multilayer; + +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.SettableFuture; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.Future; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.services.AbstractTableMultipartService; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.MultipartReplyBody; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableFeaturesCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.MultipartReplyTableFeatures; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures; +import org.opendaylight.yangtools.yang.common.RpcError.ErrorType; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MultiLayerTableMultipartService extends AbstractTableMultipartService { + + private static final Logger LOG = LoggerFactory.getLogger(MultiLayerTableMultipartService.class); + + public MultiLayerTableMultipartService(RequestContextStack requestContextStack, + DeviceContext deviceContext, + ConvertorExecutor convertorExecutor, + MultipartWriterProvider multipartWriterProvider) { + super(requestContextStack, deviceContext, convertorExecutor, multipartWriterProvider); + } + + @Override + public Future> handleAndReply(UpdateTableInput input) { + final ListenableFuture>> multipartFuture = handleServiceCall(input); + final SettableFuture> finalFuture = SettableFuture.create(); + + class CallBackImpl implements FutureCallback>> { + @Override + public void onSuccess(final RpcResult> result) { + + if (result.isSuccessful()) { + final List multipartReplies = result.getResult(); + if (multipartReplies.isEmpty()) { + LOG.debug("Multipart reply to table features request shouldn't be empty list."); + finalFuture.set(RpcResultBuilder.failed() + .withError(ErrorType.RPC, "Multipart reply list is empty.").build()); + } else { + final Long xid = multipartReplies.get(0).getXid(); + LOG.debug( + "OnSuccess, rpc result successful, multipart response for rpc update-table with xid {} obtained.", + xid); + final UpdateTableOutputBuilder updateTableOutputBuilder = new UpdateTableOutputBuilder(); + updateTableOutputBuilder.setTransactionId(new TransactionId(BigInteger.valueOf(xid))); + finalFuture.set(RpcResultBuilder.success(updateTableOutputBuilder.build()).build()); + try { + storeStatistics(convertToSalTableFeatures(multipartReplies)); + } catch (Exception e) { + LOG.warn("Not able to write to operational datastore: {}", e.getMessage()); + } + } + } else { + LOG.debug("OnSuccess, rpc result unsuccessful, multipart response for rpc update-table was unsuccessful."); + finalFuture.set(RpcResultBuilder.failed().withRpcErrors(result.getErrors()) + .build()); + } + } + + @Override + public void onFailure(final Throwable t) { + LOG.error("Failure multipart response for table features request. Exception: {}", t); + finalFuture.set(RpcResultBuilder.failed() + .withError(ErrorType.RPC, "Future error", t).build()); + } + } + + Futures.addCallback(multipartFuture, new CallBackImpl()); + + return finalFuture; + } + + protected List convertToSalTableFeatures( + final List multipartReplies) { + final List salTableFeaturesAll = new ArrayList<>(); + for (final MultipartReply multipartReply : multipartReplies) { + if (multipartReply.getType().equals(MultipartType.OFPMPTABLEFEATURES)) { + final MultipartReplyBody multipartReplyBody = multipartReply.getMultipartReplyBody(); + if (multipartReplyBody instanceof MultipartReplyTableFeaturesCase) { + final MultipartReplyTableFeaturesCase tableFeaturesCase = ((MultipartReplyTableFeaturesCase) multipartReplyBody); + final MultipartReplyTableFeatures salTableFeatures = tableFeaturesCase + .getMultipartReplyTableFeatures(); + + final Optional> salTableFeaturesPartial = + getConvertorExecutor().convert(salTableFeatures, getData()); + + salTableFeaturesPartial.ifPresent(salTableFeaturesAll::addAll); + + LOG.debug("TableFeature {} for xid {}.", salTableFeatures, multipartReply.getXid()); + } + } + } + + return salTableFeaturesAll; + } +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/FlowCapableTransactionServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/FlowCapableTransactionServiceImpl.java similarity index 89% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/FlowCapableTransactionServiceImpl.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/FlowCapableTransactionServiceImpl.java index f319947cf3..38c05cdc41 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/FlowCapableTransactionServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/FlowCapableTransactionServiceImpl.java @@ -5,12 +5,14 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import java.util.concurrent.Future; 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.impl.services.AbstractVoidService; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.FlowCapableTransactionService; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.SendBarrierInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInputBuilder; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/NodeConfigServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/NodeConfigServiceImpl.java similarity index 91% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/NodeConfigServiceImpl.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/NodeConfigServiceImpl.java index 5a45f44336..8e063fcbc7 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/NodeConfigServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/NodeConfigServiceImpl.java @@ -5,12 +5,14 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import java.util.concurrent.Future; 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.impl.services.AbstractSimpleService; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.yang.gen.v1.urn.opendaylight.module.config.rev141015.NodeConfigService; import org.opendaylight.yang.gen.v1.urn.opendaylight.module.config.rev141015.SetConfigInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.module.config.rev141015.SetConfigOutput; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/PacketProcessingServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/PacketProcessingServiceImpl.java similarity index 91% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/PacketProcessingServiceImpl.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/PacketProcessingServiceImpl.java index e32dbb5337..7419940413 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/PacketProcessingServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/PacketProcessingServiceImpl.java @@ -5,13 +5,15 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import java.util.Optional; import java.util.concurrent.Future; 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.impl.services.AbstractVoidService; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.PacketOutConvertor; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.PacketOutConvertorData; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalEchoServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalEchoServiceImpl.java similarity index 96% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalEchoServiceImpl.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalEchoServiceImpl.java index 750a63a772..b719ec417d 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalEchoServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalEchoServiceImpl.java @@ -5,7 +5,7 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import com.google.common.base.Function; import com.google.common.base.Preconditions; @@ -15,6 +15,7 @@ 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.impl.services.EchoService; import org.opendaylight.yang.gen.v1.urn.opendaylight.echo.service.rev150305.SalEchoService; import org.opendaylight.yang.gen.v1.urn.opendaylight.echo.service.rev150305.SendEchoInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.echo.service.rev150305.SendEchoOutput; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalExperimenterMessageServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalExperimenterMessageServiceImpl.java similarity index 94% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalExperimenterMessageServiceImpl.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalExperimenterMessageServiceImpl.java index b1969eb08d..ac3ff50335 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalExperimenterMessageServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalExperimenterMessageServiceImpl.java @@ -5,7 +5,7 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import java.util.concurrent.Future; import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; @@ -16,6 +16,8 @@ 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.openflowplugin.impl.services.AbstractVoidService; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.message.service.rev151020.SalExperimenterMessageService; import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.message.service.rev151020.SendExperimenterInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInputBuilder; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalExperimenterMpMessageServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalExperimenterMpMessageServiceImpl.java new file mode 100755 index 0000000000..a0761fdb5b --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalExperimenterMpMessageServiceImpl.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.services.sal; + +import java.util.concurrent.Future; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider; +import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerExperimenterMultipartService; +import org.opendaylight.openflowplugin.impl.services.singlelayer.SingleLayerExperimenterMultipartService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SalExperimenterMpMessageService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestOutput; +import org.opendaylight.yangtools.yang.common.RpcResult; + +public class SalExperimenterMpMessageServiceImpl implements SalExperimenterMpMessageService { + private final MultiLayerExperimenterMultipartService multiLayerService; + private final SingleLayerExperimenterMultipartService singleLayerService; + + public SalExperimenterMpMessageServiceImpl(final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ExtensionConverterProvider extensionConverterProvider) { + this.singleLayerService = new SingleLayerExperimenterMultipartService(requestContextStack, deviceContext, + extensionConverterProvider); + this.multiLayerService = new MultiLayerExperimenterMultipartService(requestContextStack, deviceContext, + extensionConverterProvider); + } + + @Override + public Future> sendExperimenterMpRequest(SendExperimenterMpRequestInput input) { + return singleLayerService.canUseSingleLayerSerialization() + ? singleLayerService.handleAndReply(input) + : multiLayerService.handleAndReply(input); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalFlatBatchServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalFlatBatchServiceImpl.java similarity index 99% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalFlatBatchServiceImpl.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalFlatBatchServiceImpl.java index 9945854e30..3eca9a73ac 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalFlatBatchServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalFlatBatchServiceImpl.java @@ -6,7 +6,7 @@ * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalFlowServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalFlowServiceImpl.java similarity index 91% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalFlowServiceImpl.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalFlowServiceImpl.java index 50cd420b36..a164063bad 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalFlowServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalFlowServiceImpl.java @@ -5,7 +5,7 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import com.google.common.annotations.VisibleForTesting; import com.google.common.util.concurrent.FutureCallback; @@ -27,6 +27,8 @@ import org.opendaylight.openflowplugin.api.openflow.rpc.ItemLifeCycleSource; import org.opendaylight.openflowplugin.api.openflow.rpc.listener.ItemLifecycleListener; import org.opendaylight.openflowplugin.impl.registry.flow.FlowDescriptorFactory; import org.opendaylight.openflowplugin.impl.registry.flow.FlowRegistryKeyFactory; +import org.opendaylight.openflowplugin.impl.services.singlelayer.SingleLayerFlowService; +import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerFlowService; import org.opendaylight.openflowplugin.impl.util.ErrorUtil; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; import org.opendaylight.openflowplugin.openflow.md.util.FlowCreatorUtil; @@ -59,23 +61,23 @@ import org.slf4j.LoggerFactory; public class SalFlowServiceImpl implements SalFlowService, ItemLifeCycleSource { private static final Logger LOG = LoggerFactory.getLogger(SalFlowServiceImpl.class); - private final FlowService flowUpdate; - private final FlowService flowAdd; - private final FlowService flowRemove; - private final FlowMessageService flowAddMessage; - private final FlowMessageService flowUpdateMessage; - private final FlowMessageService flowRemoveMessage; + private final MultiLayerFlowService flowUpdate; + private final MultiLayerFlowService flowAdd; + private final MultiLayerFlowService flowRemove; + private final SingleLayerFlowService flowAddMessage; + private final SingleLayerFlowService flowUpdateMessage; + private final SingleLayerFlowService flowRemoveMessage; private final DeviceContext deviceContext; private ItemLifecycleListener itemLifecycleListener; public SalFlowServiceImpl(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final ConvertorExecutor convertorExecutor) { this.deviceContext = deviceContext; - flowRemove = new FlowService<>(requestContextStack, deviceContext, RemoveFlowOutput.class, convertorExecutor); - flowAdd = new FlowService<>(requestContextStack, deviceContext, AddFlowOutput.class, convertorExecutor); - flowUpdate = new FlowService<>(requestContextStack, deviceContext, UpdateFlowOutput.class, convertorExecutor); - flowAddMessage = new FlowMessageService<>(requestContextStack, deviceContext, AddFlowOutput.class); - flowUpdateMessage = new FlowMessageService<>(requestContextStack, deviceContext, UpdateFlowOutput.class); - flowRemoveMessage= new FlowMessageService<>(requestContextStack, deviceContext, RemoveFlowOutput.class); + flowRemove = new MultiLayerFlowService<>(requestContextStack, deviceContext, RemoveFlowOutput.class, convertorExecutor); + flowAdd = new MultiLayerFlowService<>(requestContextStack, deviceContext, AddFlowOutput.class, convertorExecutor); + flowUpdate = new MultiLayerFlowService<>(requestContextStack, deviceContext, UpdateFlowOutput.class, convertorExecutor); + flowAddMessage = new SingleLayerFlowService<>(requestContextStack, deviceContext, AddFlowOutput.class); + flowUpdateMessage = new SingleLayerFlowService<>(requestContextStack, deviceContext, UpdateFlowOutput.class); + flowRemoveMessage= new SingleLayerFlowService<>(requestContextStack, deviceContext, RemoveFlowOutput.class); } @Override @@ -88,7 +90,7 @@ public class SalFlowServiceImpl implements SalFlowService, ItemLifeCycleSource { final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(deviceContext.getDeviceInfo().getVersion(), input); final ListenableFuture> future; - if (flowAddMessage.isSupported()) { + if (flowAddMessage.canUseSingleLayerSerialization()) { future = flowAddMessage.handleServiceCall(input); Futures.addCallback(future, new AddFlowCallback(input, flowRegistryKey)); } else { @@ -103,7 +105,7 @@ public class SalFlowServiceImpl implements SalFlowService, ItemLifeCycleSource { public Future> removeFlow(final RemoveFlowInput input) { final ListenableFuture> future; - if (flowRemoveMessage.isSupported()) { + if (flowRemoveMessage.canUseSingleLayerSerialization()) { future = flowRemoveMessage.handleServiceCall(input); Futures.addCallback(future, new RemoveFlowCallback(input)); @@ -124,7 +126,7 @@ public class SalFlowServiceImpl implements SalFlowService, ItemLifeCycleSource { final List ofFlowModInputs; ListenableFuture> future; - if (flowUpdateMessage.isSupported()) { + if (flowUpdateMessage.canUseSingleLayerSerialization()) { if (!FlowCreatorUtil.canModifyFlow(original, updated, flowUpdateMessage.getVersion())) { final SettableFuture> objectSettableFuture = SettableFuture.create(); diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalFlowsBatchServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalFlowsBatchServiceImpl.java similarity index 99% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalFlowsBatchServiceImpl.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalFlowsBatchServiceImpl.java index 00f9fbc771..73ca65df3b 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalFlowsBatchServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalFlowsBatchServiceImpl.java @@ -5,7 +5,7 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import com.google.common.base.Preconditions; import com.google.common.util.concurrent.Futures; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalGroupServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalGroupServiceImpl.java similarity index 76% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalGroupServiceImpl.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalGroupServiceImpl.java index 946c701b39..ece2a7a665 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalGroupServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalGroupServiceImpl.java @@ -5,7 +5,7 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; @@ -16,6 +16,8 @@ import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; import org.opendaylight.openflowplugin.api.openflow.rpc.ItemLifeCycleSource; import org.opendaylight.openflowplugin.api.openflow.rpc.listener.ItemLifecycleListener; +import org.opendaylight.openflowplugin.impl.services.singlelayer.SingleLayerGroupService; +import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerGroupService; import org.opendaylight.openflowplugin.impl.util.ErrorUtil; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; @@ -39,25 +41,25 @@ import org.slf4j.LoggerFactory; public class SalGroupServiceImpl implements SalGroupService, ItemLifeCycleSource { private static final Logger LOG = LoggerFactory.getLogger(SalGroupServiceImpl.class); - private final GroupService addGroup; - private final GroupService updateGroup; - private final GroupService removeGroup; - private final GroupMessageService addGroupMessage; - private final GroupMessageService updateGroupMessage; - private final GroupMessageService removeGroupMessage; + private final MultiLayerGroupService addGroup; + private final MultiLayerGroupService updateGroup; + private final MultiLayerGroupService removeGroup; + private final SingleLayerGroupService addGroupMessage; + private final SingleLayerGroupService updateGroupMessage; + private final SingleLayerGroupService removeGroupMessage; private final DeviceContext deviceContext; private ItemLifecycleListener itemLifecycleListener; public SalGroupServiceImpl(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final ConvertorExecutor convertorExecutor) { this.deviceContext = deviceContext; - addGroup = new GroupService<>(requestContextStack, deviceContext, AddGroupOutput.class, convertorExecutor); - updateGroup = new GroupService<>(requestContextStack, deviceContext, UpdateGroupOutput.class, convertorExecutor); - removeGroup = new GroupService<>(requestContextStack, deviceContext, RemoveGroupOutput.class, convertorExecutor); + addGroup = new MultiLayerGroupService<>(requestContextStack, deviceContext, AddGroupOutput.class, convertorExecutor); + updateGroup = new MultiLayerGroupService<>(requestContextStack, deviceContext, UpdateGroupOutput.class, convertorExecutor); + removeGroup = new MultiLayerGroupService<>(requestContextStack, deviceContext, RemoveGroupOutput.class, convertorExecutor); - addGroupMessage = new GroupMessageService<>(requestContextStack, deviceContext, AddGroupOutput.class); - updateGroupMessage = new GroupMessageService<>(requestContextStack, deviceContext, UpdateGroupOutput.class); - removeGroupMessage = new GroupMessageService<>(requestContextStack, deviceContext, RemoveGroupOutput.class); + addGroupMessage = new SingleLayerGroupService<>(requestContextStack, deviceContext, AddGroupOutput.class); + updateGroupMessage = new SingleLayerGroupService<>(requestContextStack, deviceContext, UpdateGroupOutput.class); + removeGroupMessage = new SingleLayerGroupService<>(requestContextStack, deviceContext, RemoveGroupOutput.class); } @Override @@ -67,7 +69,7 @@ public class SalGroupServiceImpl implements SalGroupService, ItemLifeCycleSource @Override public Future> addGroup(final AddGroupInput input) { - final ListenableFuture> resultFuture = addGroupMessage.isSupported() + final ListenableFuture> resultFuture = addGroupMessage.canUseSingleLayerSerialization() ? addGroupMessage.handleServiceCall(input) : addGroup.handleServiceCall(input); @@ -83,7 +85,7 @@ public class SalGroupServiceImpl implements SalGroupService, ItemLifeCycleSource } else { if (LOG.isDebugEnabled()) { LOG.debug("Group add with id={} failed, errors={}", input.getGroupId().getValue(), - ErrorUtil.errorsToString(result.getErrors())); + ErrorUtil.errorsToString(result.getErrors())); } } } @@ -99,25 +101,24 @@ public class SalGroupServiceImpl implements SalGroupService, ItemLifeCycleSource @Override public Future> updateGroup(final UpdateGroupInput input) { - final ListenableFuture> resultFuture = updateGroupMessage.isSupported() + final ListenableFuture> resultFuture = updateGroupMessage.canUseSingleLayerSerialization() ? updateGroupMessage.handleServiceCall(input.getUpdatedGroup()) : updateGroup.handleServiceCall(input.getUpdatedGroup()); Futures.addCallback(resultFuture, new FutureCallback>() { @Override - public void onSuccess(@Nullable RpcResult result) { + public void onSuccess(RpcResult result) { if (result.isSuccessful()) { if (LOG.isDebugEnabled()) { LOG.debug("Group update with original id={} finished without error", - input.getOriginalGroup().getGroupId().getValue()); + input.getOriginalGroup().getGroupId().getValue()); } removeIfNecessaryFromDS(input.getOriginalGroup().getGroupId()); addIfNecessaryToDS(input.getUpdatedGroup().getGroupId(), input.getUpdatedGroup()); } else { - if (LOG.isDebugEnabled()) { - LOG.debug("Group update with original id={} failed, errors={}", - input.getOriginalGroup().getGroupId(), ErrorUtil.errorsToString(result.getErrors())); - } + LOG.warn("Group update with original id={} failed, errors={}", + input.getOriginalGroup().getGroupId(), ErrorUtil.errorsToString(result.getErrors())); + LOG.debug("Group input={}", input.getUpdatedGroup()); } } @@ -132,13 +133,13 @@ public class SalGroupServiceImpl implements SalGroupService, ItemLifeCycleSource @Override public Future> removeGroup(final RemoveGroupInput input) { - final ListenableFuture> resultFuture = removeGroupMessage.isSupported() + final ListenableFuture> resultFuture = removeGroupMessage.canUseSingleLayerSerialization() ? removeGroupMessage.handleServiceCall(input) : removeGroup.handleServiceCall(input); Futures.addCallback(resultFuture, new FutureCallback>() { @Override - public void onSuccess(@Nullable RpcResult result) { + public void onSuccess(RpcResult result) { if (result.isSuccessful()) { if (LOG.isDebugEnabled()) { LOG.debug("Group remove with id={} finished without error", input.getGroupId().getValue()); @@ -146,10 +147,9 @@ public class SalGroupServiceImpl implements SalGroupService, ItemLifeCycleSource removeGroup.getDeviceRegistry().getDeviceGroupRegistry().markToBeremoved(input.getGroupId()); removeIfNecessaryFromDS(input.getGroupId()); } else { - if (LOG.isDebugEnabled()) { - LOG.debug("Group remove with id={} failed, errors={}", input.getGroupId().getValue(), - ErrorUtil.errorsToString(result.getErrors())); - } + LOG.warn("Group remove with id={} failed, errors={}", input.getGroupId().getValue(), + ErrorUtil.errorsToString(result.getErrors())); + LOG.debug("Group input={}", input); } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalGroupsBatchServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalGroupsBatchServiceImpl.java similarity index 99% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalGroupsBatchServiceImpl.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalGroupsBatchServiceImpl.java index 92840a2a2c..ebe4dac627 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalGroupsBatchServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalGroupsBatchServiceImpl.java @@ -6,7 +6,7 @@ * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import com.google.common.base.Function; import com.google.common.base.Preconditions; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalMeterServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalMeterServiceImpl.java similarity index 76% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalMeterServiceImpl.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalMeterServiceImpl.java index 1e3715d454..450746c510 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalMeterServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalMeterServiceImpl.java @@ -5,7 +5,7 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; @@ -16,6 +16,8 @@ import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; import org.opendaylight.openflowplugin.api.openflow.rpc.ItemLifeCycleSource; import org.opendaylight.openflowplugin.api.openflow.rpc.listener.ItemLifecycleListener; +import org.opendaylight.openflowplugin.impl.services.singlelayer.SingleLayerMeterService; +import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerMeterService; import org.opendaylight.openflowplugin.impl.util.ErrorUtil; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; @@ -39,25 +41,25 @@ import org.slf4j.LoggerFactory; public class SalMeterServiceImpl implements SalMeterService, ItemLifeCycleSource { private static final Logger LOG = LoggerFactory.getLogger(SalMeterServiceImpl.class); - private final MeterService addMeter; - private final MeterService updateMeter; - private final MeterService removeMeter; - private final MeterMessageService addMeterMessage; - private final MeterMessageService updateMeterMessage; - private final MeterMessageService removeMeterMessage; + private final MultiLayerMeterService addMeter; + private final MultiLayerMeterService updateMeter; + private final MultiLayerMeterService removeMeter; + private final SingleLayerMeterService addMeterMessage; + private final SingleLayerMeterService updateMeterMessage; + private final SingleLayerMeterService removeMeterMessage; private ItemLifecycleListener itemLifecycleListener; private final DeviceContext deviceContext; public SalMeterServiceImpl(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final ConvertorExecutor convertorExecutor) { this.deviceContext = deviceContext; - addMeter = new MeterService<>(requestContextStack, deviceContext, AddMeterOutput.class, convertorExecutor); - updateMeter = new MeterService<>(requestContextStack, deviceContext, UpdateMeterOutput.class, convertorExecutor); - removeMeter = new MeterService<>(requestContextStack, deviceContext, RemoveMeterOutput.class, convertorExecutor); + addMeter = new MultiLayerMeterService<>(requestContextStack, deviceContext, AddMeterOutput.class, convertorExecutor); + updateMeter = new MultiLayerMeterService<>(requestContextStack, deviceContext, UpdateMeterOutput.class, convertorExecutor); + removeMeter = new MultiLayerMeterService<>(requestContextStack, deviceContext, RemoveMeterOutput.class, convertorExecutor); - addMeterMessage = new MeterMessageService<>(requestContextStack, deviceContext, AddMeterOutput.class); - updateMeterMessage = new MeterMessageService<>(requestContextStack, deviceContext, UpdateMeterOutput.class); - removeMeterMessage = new MeterMessageService<>(requestContextStack, deviceContext, RemoveMeterOutput.class); + addMeterMessage = new SingleLayerMeterService<>(requestContextStack, deviceContext, AddMeterOutput.class); + updateMeterMessage = new SingleLayerMeterService<>(requestContextStack, deviceContext, UpdateMeterOutput.class); + removeMeterMessage = new SingleLayerMeterService<>(requestContextStack, deviceContext, RemoveMeterOutput.class); } @Override @@ -67,15 +69,15 @@ public class SalMeterServiceImpl implements SalMeterService, ItemLifeCycleSource @Override public Future> addMeter(final AddMeterInput input) { - final ListenableFuture> resultFuture = addMeterMessage.isSupported() + final ListenableFuture> resultFuture = addMeterMessage.canUseSingleLayerSerialization() ? addMeterMessage.handleServiceCall(input) : addMeter.handleServiceCall(input); Futures.addCallback(resultFuture, new FutureCallback>() { @Override - public void onSuccess(@Nullable RpcResult result) { + public void onSuccess(RpcResult result) { if (result.isSuccessful()) { - if (LOG.isDebugEnabled()) { + if (LOG.isDebugEnabled()) { LOG.debug("Meter add with id={} finished without error", input.getMeterId()); } deviceContext.getDeviceMeterRegistry().store(input.getMeterId()); @@ -83,7 +85,7 @@ public class SalMeterServiceImpl implements SalMeterService, ItemLifeCycleSource } else { if (LOG.isDebugEnabled()) { LOG.debug("Meter add with id={} failed, errors={}", input.getMeterId(), - ErrorUtil.errorsToString(result.getErrors())); + ErrorUtil.errorsToString(result.getErrors())); } } } @@ -98,14 +100,14 @@ public class SalMeterServiceImpl implements SalMeterService, ItemLifeCycleSource @Override public Future> updateMeter(final UpdateMeterInput input) { - final ListenableFuture> resultFuture = updateMeterMessage.isSupported() + final ListenableFuture> resultFuture = updateMeterMessage.canUseSingleLayerSerialization() ? updateMeterMessage.handleServiceCall(input.getUpdatedMeter()) : updateMeter.handleServiceCall(input.getUpdatedMeter()); Futures.addCallback(resultFuture, new FutureCallback>() { @Override - public void onSuccess(@Nullable RpcResult result) { + public void onSuccess(RpcResult result) { if (result.isSuccessful()) { if (LOG.isDebugEnabled()) { LOG.debug("Meter update with id={} finished without error", input.getOriginalMeter().getMeterId()); @@ -115,10 +117,9 @@ public class SalMeterServiceImpl implements SalMeterService, ItemLifeCycleSource addIfNecessaryToDS(input.getUpdatedMeter().getMeterId(),input.getUpdatedMeter()); } } else { - if (LOG.isDebugEnabled()) { - LOG.debug("Meter update with id={} failed, errors={}", input.getOriginalMeter().getMeterId(), + LOG.warn("Meter update with id={} failed, errors={}", input.getOriginalMeter().getMeterId(), ErrorUtil.errorsToString(result.getErrors())); - } + LOG.debug("Meter input={}", input.getUpdatedMeter()); } } @@ -133,24 +134,23 @@ public class SalMeterServiceImpl implements SalMeterService, ItemLifeCycleSource @Override public Future> removeMeter(final RemoveMeterInput input) { - removeMeter.getDeviceRegistry().getDeviceMeterRegistry().markToBeremoved(input.getMeterId()); - final ListenableFuture> resultFuture = removeMeterMessage.isSupported() + final ListenableFuture> resultFuture = removeMeterMessage.canUseSingleLayerSerialization() ? removeMeterMessage.handleServiceCall(input) : removeMeter.handleServiceCall(input); Futures.addCallback(resultFuture, new FutureCallback>() { @Override - public void onSuccess(@Nullable RpcResult result) { + public void onSuccess(RpcResult result) { if (result.isSuccessful()) { if (LOG.isDebugEnabled()) { LOG.debug("Meter remove with id={} finished without error", input.getMeterId()); } + removeMeter.getDeviceRegistry().getDeviceMeterRegistry().markToBeremoved(input.getMeterId()); removeIfNecessaryFromDS(input.getMeterId()); } else { - if (LOG.isDebugEnabled()) { - LOG.debug("Meter remove with id={} failed, errors={}", input.getMeterId(), - ErrorUtil.errorsToString(result.getErrors())); - } + LOG.warn("Meter remove with id={} failed, errors={}", input.getMeterId(), + ErrorUtil.errorsToString(result.getErrors())); + LOG.debug("Meter input={}", input); } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalMetersBatchServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalMetersBatchServiceImpl.java similarity index 99% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalMetersBatchServiceImpl.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalMetersBatchServiceImpl.java index 6f61bc5968..9a9a00b2c1 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalMetersBatchServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalMetersBatchServiceImpl.java @@ -6,7 +6,7 @@ * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import com.google.common.base.Function; import com.google.common.base.Preconditions; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalPortServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalPortServiceImpl.java similarity index 84% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalPortServiceImpl.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalPortServiceImpl.java index 8caae19810..317a7cb101 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalPortServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalPortServiceImpl.java @@ -5,13 +5,16 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import java.util.Optional; import java.util.concurrent.Future; 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.impl.services.AbstractSimpleService; +import org.opendaylight.openflowplugin.impl.services.singlelayer.SingleLayerPortService; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.PortConvertor; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData; @@ -27,18 +30,18 @@ import org.opendaylight.yangtools.yang.common.RpcResult; public final class SalPortServiceImpl extends AbstractSimpleService implements SalPortService { private final ConvertorExecutor convertorExecutor; private final VersionConvertorData data; - private final PortMessageService portMessage; + private final SingleLayerPortService portMessage; public SalPortServiceImpl(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final ConvertorExecutor convertorExecutor) { super(requestContextStack, deviceContext, UpdatePortOutput.class); this.convertorExecutor = convertorExecutor; data = new VersionConvertorData(getVersion()); - portMessage = new PortMessageService<>(requestContextStack, deviceContext, UpdatePortOutput.class); + portMessage = new SingleLayerPortService<>(requestContextStack, deviceContext, UpdatePortOutput.class); } @Override public Future> updatePort(final UpdatePortInput input) { - return portMessage.isSupported() + return portMessage.canUseSingleLayerSerialization() ? portMessage.handleServiceCall(getPortFromInput(input)) : handleServiceCall(input); } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalRoleServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalRoleServiceImpl.java similarity index 96% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalRoleServiceImpl.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalRoleServiceImpl.java index 9906515af6..20f063f5c2 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalRoleServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalRoleServiceImpl.java @@ -5,7 +5,7 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import com.google.common.base.Preconditions; import com.google.common.util.concurrent.AsyncFunction; @@ -23,6 +23,9 @@ 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.impl.role.RoleChangeException; +import org.opendaylight.openflowplugin.impl.services.AbstractSimpleService; +import org.opendaylight.openflowplugin.impl.services.RoleService; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.OfpRole; @@ -80,7 +83,7 @@ public final class SalRoleServiceImpl extends AbstractSimpleService success().buildFuture(); } - final SettableFuture> resultFuture = SettableFuture.> create(); + final SettableFuture> resultFuture = SettableFuture.create(); repeaterForChangeRole(resultFuture, input, 0); /* Add Callback for release Guard */ Futures.addCallback(resultFuture, new FutureCallback>() { diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalTableServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalTableServiceImpl.java new file mode 100644 index 0000000000..bfa4069235 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/sal/SalTableServiceImpl.java @@ -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.impl.services.sal; + +import java.util.concurrent.Future; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerTableMultipartService; +import org.opendaylight.openflowplugin.impl.services.singlelayer.SingleLayerTableMultipartService; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.SalTableService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutput; +import org.opendaylight.yangtools.yang.common.RpcResult; + +public final class SalTableServiceImpl implements SalTableService { + + private final SingleLayerTableMultipartService singleLayerService; + private final MultiLayerTableMultipartService multiLayerService; + + public SalTableServiceImpl(final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ConvertorExecutor convertorExecutor, + final MultipartWriterProvider multipartWriterProvider) { + singleLayerService = new SingleLayerTableMultipartService(requestContextStack, deviceContext, convertorExecutor, multipartWriterProvider); + multiLayerService = new MultiLayerTableMultipartService(requestContextStack, deviceContext, convertorExecutor, multipartWriterProvider); + } + + @Override + public Future> updateTable(final UpdateTableInput input) { + return singleLayerService.canUseSingleLayerSerialization() + ? singleLayerService.handleAndReply(input) + : multiLayerService.handleAndReply(input); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerAggregateFlowMultipartService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerAggregateFlowMultipartService.java new file mode 100644 index 0000000000..7a732fbf35 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerAggregateFlowMultipartService.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.services.singlelayer; + +import com.google.common.base.Function; +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.Futures; +import java.util.List; +import java.util.concurrent.Future; +import java.util.stream.Collectors; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.impl.services.AbstractAggregateFlowMultipartService; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.aggregate.flow.statistics.from.flow.table._for.given.match.output.AggregatedFlowStatisticsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowAggregateStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; + +public class SingleLayerAggregateFlowMultipartService + extends AbstractAggregateFlowMultipartService { + + public SingleLayerAggregateFlowMultipartService(final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ConvertorExecutor convertorExecutor) { + super(requestContextStack, deviceContext, convertorExecutor); + } + + @Override + public Future> handleAndReply( + final GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input) { + return Futures.transform(handleServiceCall(input), + (Function>, RpcResult>) result -> { + if (Preconditions.checkNotNull(result).isSuccessful()) { + return RpcResultBuilder + .success(new GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder() + .setAggregatedFlowStatistics(result + .getResult() + .stream() + .map(MultipartReply::getMultipartReplyBody) + .filter(MultipartReplyFlowAggregateStats.class::isInstance) + .map(multipartReplyBody -> + new AggregatedFlowStatisticsBuilder(MultipartReplyFlowAggregateStats.class + .cast(multipartReplyBody)) + .build()) + .collect(Collectors.toList()))) + .build(); + } + + return RpcResultBuilder + .failed() + .withRpcErrors(result.getErrors()) + .build(); + }); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerExperimenterMultipartService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerExperimenterMultipartService.java new file mode 100644 index 0000000000..4aec8d08f5 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerExperimenterMultipartService.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.services.singlelayer; + +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.SettableFuture; +import java.util.List; +import java.util.concurrent.Future; +import java.util.stream.Collectors; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider; +import org.opendaylight.openflowplugin.impl.services.AbstractExperimenterMultipartService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.send.experimenter.mp.request.output.ExperimenterCoreMessageItemBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.experimenter.types.rev151020.multipart.reply.multipart.reply.body.MultipartReplyExperimenter; +import org.opendaylight.yangtools.yang.common.RpcError.ErrorType; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.slf4j.Logger; + +public class SingleLayerExperimenterMultipartService extends AbstractExperimenterMultipartService { + + private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(SingleLayerExperimenterMultipartService.class); + + public SingleLayerExperimenterMultipartService(RequestContextStack requestContextStack, DeviceContext deviceContext, + ExtensionConverterProvider extensionConverterProvider) { + super(requestContextStack, deviceContext, extensionConverterProvider); + } + + @Override + public Future> handleAndReply(SendExperimenterMpRequestInput input) { + final SettableFuture> future = SettableFuture.create(); + + Futures.addCallback(handleServiceCall(input), new FutureCallback>>() { + @Override + public void onSuccess(final RpcResult> result) { + if (result.isSuccessful()) { + future.set(RpcResultBuilder + .success(new SendExperimenterMpRequestOutputBuilder() + .setExperimenterCoreMessageItem(result + .getResult() + .stream() + .map(MultipartReply::getMultipartReplyBody) + .filter(MultipartReplyExperimenter.class::isInstance) + .map(experimenter -> new ExperimenterCoreMessageItemBuilder() + .setExperimenterMessageOfChoice(MultipartReplyExperimenter.class + .cast(experimenter) + .getExperimenterMessageOfChoice()) + .build()) + .collect(Collectors.toList())) + .build()) + .build()); + } else { + LOG.warn("OnSuccess, rpc result unsuccessful, multipart response for rpc sendExperimenterMpRequest was unsuccessful."); + future.set(RpcResultBuilder.failed().withRpcErrors(result.getErrors()).build()); + } + } + + @Override + public void onFailure(final Throwable t) { + LOG.warn("Failure multipart response for Experimenter-Mp request. Exception: {}", t); + future.set(RpcResultBuilder.failed().withError(ErrorType.RPC, "Future error", t).build()); + } + }); + + return future; + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerFlowMultipartRequestOnTheFlyCallback.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerFlowMultipartRequestOnTheFlyCallback.java new file mode 100644 index 0000000000..b810a369df --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerFlowMultipartRequestOnTheFlyCallback.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.services.singlelayer; + +import com.google.common.base.Function; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import java.util.List; +import java.util.Optional; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContext; +import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier; +import org.opendaylight.openflowplugin.impl.common.MultipartReplyTranslatorUtil; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.services.AbstractMultipartRequestOnTheFlyCallback; +import org.opendaylight.openflowplugin.impl.statistics.StatisticsGatheringUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.multipart.reply.MultipartReplyBody; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; + +public class SingleLayerFlowMultipartRequestOnTheFlyCallback extends AbstractMultipartRequestOnTheFlyCallback { + + private final DeviceInfo deviceInfo; + private boolean virgin = true; + + public SingleLayerFlowMultipartRequestOnTheFlyCallback(final RequestContext> context, Class requestType, + final DeviceContext deviceContext, + final EventIdentifier eventIdentifier, + final MultipartWriterProvider statisticsWriterProvider) { + super(context, requestType, deviceContext, eventIdentifier, statisticsWriterProvider); + deviceInfo = deviceContext.getDeviceInfo(); + } + + @Override + protected boolean isMultipart(OfHeader result) { + return result instanceof MultipartReply + && MultipartReply.class.cast(result).getMultipartReplyBody() instanceof MultipartReplyFlowStats; + } + + @Override + protected boolean isReqMore(T result) { + return MultipartReply.class.cast(result).isRequestMore(); + } + + @Override + protected MultipartType getMultipartType() { + return MultipartType.OFPMPFLOW; + } + + @Override + protected ListenableFuture> processStatistics(T result) { + final ListenableFuture> future = Futures.transform( + StatisticsGatheringUtils.deleteAllKnownFlows( + getTxFacade(), + deviceInfo + .getNodeInstanceIdentifier() + .augmentation(FlowCapableNode.class), + !virgin), + (Function>) input -> MultipartReplyTranslatorUtil + .translate(result, deviceInfo, null, null)); + + if (virgin) { + virgin = false; + } + + return future; + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/FlowMessageService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerFlowService.java similarity index 82% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/FlowMessageService.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerFlowService.java index 6282abb91a..6c924cd5ed 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/FlowMessageService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerFlowService.java @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the @@ -6,12 +6,13 @@ * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.singlelayer; -import org.opendaylight.openflowplugin.api.OFConstants; 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.impl.services.AbstractSilentErrorService; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlow; @@ -23,8 +24,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731 import org.opendaylight.yangtools.yang.binding.DataContainer; import org.opendaylight.yangtools.yang.binding.DataObject; -final class FlowMessageService extends AbstractMessageService { - protected FlowMessageService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final Class clazz) { +public final class SingleLayerFlowService extends AbstractSilentErrorService { + public SingleLayerFlowService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final Class clazz) { super(requestContextStack, deviceContext, clazz); } @@ -49,9 +50,4 @@ final class FlowMessageService extends AbstractMessageServ .build(); } - @Override - public boolean isSupported() { - return super.isSupported() && getVersion() >= OFConstants.OFP_VERSION_1_3; - } - } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/GroupMessageService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerGroupService.java similarity index 76% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/GroupMessageService.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerGroupService.java index 7f48028b3e..0779c409d8 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/GroupMessageService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerGroupService.java @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the @@ -6,12 +6,13 @@ * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.singlelayer; -import org.opendaylight.openflowplugin.api.OFConstants; 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.impl.services.AbstractSimpleService; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroup; @@ -23,12 +24,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731 import org.opendaylight.yangtools.yang.binding.DataContainer; import org.opendaylight.yangtools.yang.binding.DataObject; -final class GroupMessageService extends AbstractMessageService { +public final class SingleLayerGroupService extends AbstractSimpleService { - protected GroupMessageService( - final RequestContextStack requestContextStack, - final DeviceContext deviceContext, - final Class clazz) { + public SingleLayerGroupService( + final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final Class clazz) { super(requestContextStack, deviceContext, clazz); } @@ -37,9 +38,10 @@ final class GroupMessageService extends AbstractMessageSer final GroupMessageBuilder groupMessageBuilder = new GroupMessageBuilder(input); final Class clazz = input.getImplementedInterface(); - if (clazz.equals(AddGroupInput.class) - || clazz.equals(UpdatedGroup.class)) { + if (clazz.equals(AddGroupInput.class)) { groupMessageBuilder.setCommand(GroupModCommand.OFPGCADD); + } else if (clazz.equals(UpdatedGroup.class)) { + groupMessageBuilder.setCommand(GroupModCommand.OFPGCMODIFY); } else if (clazz.equals(RemoveGroupInput.class) || clazz.equals(OriginalGroup.class)) { groupMessageBuilder.setCommand(GroupModCommand.OFPGCDELETE); @@ -51,9 +53,4 @@ final class GroupMessageService extends AbstractMessageSer .build(); } - @Override - public boolean isSupported() { - return super.isSupported() && getVersion() >= OFConstants.OFP_VERSION_1_3; - } - } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/MeterMessageService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerMeterService.java similarity index 72% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/MeterMessageService.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerMeterService.java index 5a9b869150..1b80d932c4 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/MeterMessageService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerMeterService.java @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the @@ -6,12 +6,13 @@ * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.singlelayer; -import org.opendaylight.openflowplugin.api.OFConstants; 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.impl.services.AbstractSilentErrorService; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.OriginalMeter; @@ -23,37 +24,32 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731 import org.opendaylight.yangtools.yang.binding.DataContainer; import org.opendaylight.yangtools.yang.binding.DataObject; -final class MeterMessageService extends AbstractMessageService { +public final class SingleLayerMeterService extends AbstractSilentErrorService { - protected MeterMessageService( - final RequestContextStack requestContextStack, - final DeviceContext deviceContext, - final Class clazz) { + public SingleLayerMeterService( + final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final Class clazz) { super(requestContextStack, deviceContext, clazz); } @Override protected OfHeader buildRequest(final Xid xid, final Meter input) throws ServiceException { - final MeterMessageBuilder groupMessageBuilder = new MeterMessageBuilder(input); + final MeterMessageBuilder meterMessageBuilder = new MeterMessageBuilder(input); final Class clazz = input.getImplementedInterface(); if (clazz.equals(AddMeterInput.class) || clazz.equals(UpdatedMeter.class)) { - groupMessageBuilder.setCommand(MeterModCommand.OFPMCADD); + meterMessageBuilder.setCommand(MeterModCommand.OFPMCADD); } else if (clazz.equals(RemoveMeterInput.class) || clazz.equals(OriginalMeter.class)) { - groupMessageBuilder.setCommand(MeterModCommand.OFPMCDELETE); + meterMessageBuilder.setCommand(MeterModCommand.OFPMCDELETE); } - return groupMessageBuilder + return meterMessageBuilder .setVersion(getVersion()) .setXid(xid.getValue()) .build(); } - @Override - public boolean isSupported() { - return super.isSupported() && getVersion() >= OFConstants.OFP_VERSION_1_3; - } - } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerMultipartCollectorService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerMultipartCollectorService.java new file mode 100644 index 0000000000..2d1b7837f8 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerMultipartCollectorService.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.services.singlelayer; + +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.impl.services.AbstractMultipartCollectorService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply; + +public class SingleLayerMultipartCollectorService extends AbstractMultipartCollectorService { + + public SingleLayerMultipartCollectorService(final RequestContextStack requestContextStack, final DeviceContext deviceContext) { + super(requestContextStack, deviceContext); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerMultipartRequestCallback.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerMultipartRequestCallback.java new file mode 100644 index 0000000000..407637ddd0 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerMultipartRequestCallback.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.services.singlelayer; + +import java.util.List; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContext; +import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier; +import org.opendaylight.openflowplugin.impl.services.AbstractMultipartRequestCallback; +import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; + +public class SingleLayerMultipartRequestCallback extends AbstractMultipartRequestCallback { + + public SingleLayerMultipartRequestCallback(RequestContext> context, Class requestType, DeviceContext deviceContext, EventIdentifier eventIdentifier) { + super(context, requestType, deviceContext, eventIdentifier); + } + + @Override + protected boolean isMultipart(OfHeader result) { + return result instanceof MultipartReply; + } + + @Override + protected boolean isReqMore(T result) { + return MultipartReply.class.cast(result).isRequestMore(); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/PortMessageService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerPortService.java similarity index 68% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/PortMessageService.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerPortService.java index 4d17f6d120..814e5a0304 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/PortMessageService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerPortService.java @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the @@ -6,23 +6,24 @@ * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.singlelayer; -import org.opendaylight.openflowplugin.api.OFConstants; 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.impl.services.AbstractSimpleService; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.CommonPort; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortMessageBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; import org.opendaylight.yangtools.yang.binding.DataObject; -final class PortMessageService extends AbstractMessageService { +public final class SingleLayerPortService extends AbstractSimpleService { - protected PortMessageService( - final RequestContextStack requestContextStack, - final DeviceContext deviceContext, - final Class clazz) { + public SingleLayerPortService( + final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final Class clazz) { super(requestContextStack, deviceContext, clazz); } @@ -34,9 +35,4 @@ final class PortMessageService extends AbstractMessageServ .build(); } - @Override - public boolean isSupported() { - return super.isSupported() && getVersion() >= OFConstants.OFP_VERSION_1_3; - } - } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerTableMultipartService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerTableMultipartService.java new file mode 100644 index 0000000000..a1a93a3755 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/singlelayer/SingleLayerTableMultipartService.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.services.singlelayer; + +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.SettableFuture; +import java.math.BigInteger; +import java.util.List; +import java.util.concurrent.Future; +import java.util.stream.Collectors; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.services.AbstractTableMultipartService; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.multipart.reply.multipart.reply.body.MultipartReplyTableFeatures; +import org.opendaylight.yangtools.yang.common.RpcError.ErrorType; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SingleLayerTableMultipartService extends AbstractTableMultipartService { + + private static final Logger LOG = LoggerFactory.getLogger(SingleLayerTableMultipartService.class); + + public SingleLayerTableMultipartService(RequestContextStack requestContextStack, + DeviceContext deviceContext, + ConvertorExecutor convertorExecutor, + MultipartWriterProvider multipartWriterProvider) { + super(requestContextStack, deviceContext, convertorExecutor, multipartWriterProvider); + } + + @Override + public Future> handleAndReply(UpdateTableInput input) { + final SettableFuture> finalFuture = SettableFuture.create(); + + Futures.addCallback(handleServiceCall(input), new FutureCallback>>() { + @Override + public void onSuccess(final RpcResult> result) { + if (result.isSuccessful()) { + final List multipartReplies = result.getResult(); + if (multipartReplies.isEmpty()) { + LOG.debug("Multipart reply to table features request shouldn't be empty list."); + finalFuture.set(RpcResultBuilder.failed() + .withError(ErrorType.RPC, "Multipart reply list is empty.").build()); + } else { + finalFuture.set(RpcResultBuilder + .success(new UpdateTableOutputBuilder() + .setTransactionId(new TransactionId(BigInteger.valueOf(multipartReplies.get(0).getXid()))) + .build()) + .build()); + + try { + storeStatistics(multipartReplies + .stream() + .map(MultipartReply::getMultipartReplyBody) + .filter(MultipartReplyTableFeatures.class::isInstance) + .flatMap(multipartReplyBody -> MultipartReplyTableFeatures.class + .cast(multipartReplyBody) + .getTableFeatures() + .stream()) + .collect(Collectors.toList())); + } catch (Exception e) { + LOG.warn("Not able to write to operational datastore: {}", e.getMessage()); + } + } + } else { + LOG.debug("OnSuccess, rpc result unsuccessful, multipart response for rpc update-table was unsuccessful."); + finalFuture.set(RpcResultBuilder.failed().withRpcErrors(result.getErrors()) + .build()); + } + } + + @Override + public void onFailure(Throwable t) { + LOG.error("Failure multipart response for table features request. Exception: {}", t); + finalFuture.set(RpcResultBuilder.failed() + .withError(ErrorType.RPC, "Future error", t).build()); + } + }); + + return finalFuture; + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/RequestContextUtil.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/util/RequestContextUtil.java similarity index 96% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/RequestContextUtil.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/util/RequestContextUtil.java index 25c6ec555f..a14f565638 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/RequestContextUtil.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/util/RequestContextUtil.java @@ -5,7 +5,7 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.util; import com.google.common.util.concurrent.ListenableFuture; import org.opendaylight.openflowplugin.api.openflow.device.RequestContext; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/RequestInputUtils.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/util/RequestInputUtils.java similarity index 95% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/RequestInputUtils.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/util/RequestInputUtils.java index b8aa9949fe..421cecd750 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/RequestInputUtils.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/util/RequestInputUtils.java @@ -6,7 +6,7 @@ * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.util; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/ServiceException.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/util/ServiceException.java similarity index 91% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/ServiceException.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/util/ServiceException.java index 7804e0bf6d..56c8c12df9 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/ServiceException.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/util/ServiceException.java @@ -6,7 +6,7 @@ * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.util; /** * Exception thrown by {@link org.opendaylight.openflowplugin.impl.services.AbstractService#buildRequest(org.opendaylight.openflowplugin.api.openflow.device.Xid, Object)} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpl.java index 4b5b7be9ca..4c9996a621 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpl.java @@ -43,15 +43,17 @@ import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsContext import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsManager; import org.opendaylight.openflowplugin.impl.rpc.AbstractRequestContext; import org.opendaylight.openflowplugin.impl.rpc.listener.ItemLifecycleListenerImpl; -import org.opendaylight.openflowplugin.impl.services.RequestContextUtil; +import org.opendaylight.openflowplugin.impl.services.util.RequestContextUtil; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; import org.opendaylight.openflowplugin.impl.statistics.services.dedicated.StatisticsGatheringOnTheFlyService; import org.opendaylight.openflowplugin.impl.statistics.services.dedicated.StatisticsGatheringService; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -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."; @@ -62,13 +64,14 @@ class StatisticsContextImpl implements StatisticsContext { private final DeviceState devState; private final ListenableFuture emptyFuture; private final boolean isStatisticsPollingOn; - private final SinglePurposeMultipartReplyTranslator multipartReplyTranslator; private final Object collectionStatTypeLock = new Object(); + private final ConvertorExecutor convertorExecutor; + private final MultipartWriterProvider statisticsWriterProvider; @GuardedBy("collectionStatTypeLock") private List collectingStatType; - private StatisticsGatheringService statisticsGatheringService; - private StatisticsGatheringOnTheFlyService statisticsGatheringOnTheFlyService; + private StatisticsGatheringService statisticsGatheringService; + private StatisticsGatheringOnTheFlyService statisticsGatheringOnTheFlyService; private Timeout pollTimeout; private final DeviceInfo deviceInfo; private final StatisticsManager myManager; @@ -85,21 +88,24 @@ class StatisticsContextImpl implements StatisticsContext { final boolean isStatisticsPollingOn, @Nonnull final LifecycleService lifecycleService, @Nonnull final ConvertorExecutor convertorExecutor, - @Nonnull final StatisticsManager myManager) { + @Nonnull final StatisticsManager myManager, + @Nonnull final MultipartWriterProvider statisticsWriterProvider) { this.lifecycleService = lifecycleService; this.deviceContext = lifecycleService.getDeviceContext(); this.devState = Preconditions.checkNotNull(deviceContext.getDeviceState()); this.isStatisticsPollingOn = isStatisticsPollingOn; - multipartReplyTranslator = new SinglePurposeMultipartReplyTranslator(convertorExecutor); + this.convertorExecutor = convertorExecutor; emptyFuture = Futures.immediateFuture(false); - statisticsGatheringService = new StatisticsGatheringService(this, deviceContext); - statisticsGatheringOnTheFlyService = new StatisticsGatheringOnTheFlyService(this, deviceContext, convertorExecutor); + statisticsGatheringService = new StatisticsGatheringService<>(this, deviceContext); + statisticsGatheringOnTheFlyService = new StatisticsGatheringOnTheFlyService<>(this, + deviceContext, convertorExecutor, statisticsWriterProvider); itemLifeCycleListener = new ItemLifecycleListenerImpl(deviceContext); statListForCollectingInitialization(); this.state = CONTEXT_STATE.INITIALIZATION; this.deviceInfo = deviceInfo; this.myManager = myManager; this.lastDataGathering = null; + this.statisticsWriterProvider = statisticsWriterProvider; } @Override @@ -275,7 +281,7 @@ class StatisticsContextImpl implements StatisticsContext { private void statChainFuture(final Iterator iterator, final SettableFuture 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.", - getDeviceInfo().getNodeId()); + getDeviceInfo().getNodeId()); LOG.debug(errMsg); resultFuture.setException(new ConnectionException(errMsg)); return; @@ -306,7 +312,7 @@ class StatisticsContextImpl implements StatisticsContext { * Method checks a device state. It returns null for be able continue. Otherwise it returns immediateFuture * which has to be returned from caller too * - * @return + * @return future */ @VisibleForTesting ListenableFuture deviceConnectionCheck() { @@ -315,7 +321,7 @@ class StatisticsContextImpl implements StatisticsContext { switch (deviceContext.getPrimaryConnectionContext().getConnectionState()) { case RIP: final String errMsg = String.format("Device connection doesn't exist anymore. Primary connection status : %s", - deviceContext.getPrimaryConnectionContext().getConnectionState()); + deviceContext.getPrimaryConnectionContext().getConnectionState()); resultingFuture = Futures.immediateFailedFuture(new Throwable(errMsg)); break; default: @@ -330,92 +336,107 @@ class StatisticsContextImpl implements StatisticsContext { //TODO: Refactor twice sending deviceContext into gatheringStatistics private ListenableFuture collectFlowStatistics(final MultipartType multipartType, final boolean initial) { return devState.isFlowStatisticsAvailable() ? StatisticsGatheringUtils.gatherStatistics( - statisticsGatheringOnTheFlyService, - getDeviceInfo(), - /*MultipartType.OFPMPFLOW*/ multipartType, - deviceContext, - deviceContext, - initial, multipartReplyTranslator) : emptyFuture; + statisticsGatheringOnTheFlyService, + getDeviceInfo(), + /*MultipartType.OFPMPFLOW*/ multipartType, + deviceContext, + deviceContext, + initial, + convertorExecutor, + statisticsWriterProvider) : emptyFuture; } private ListenableFuture collectTableStatistics(final MultipartType multipartType) { return devState.isTableStatisticsAvailable() ? StatisticsGatheringUtils.gatherStatistics( - statisticsGatheringService, - getDeviceInfo(), + statisticsGatheringService, + getDeviceInfo(), /*MultipartType.OFPMPTABLE*/ multipartType, - deviceContext, - deviceContext, - false, multipartReplyTranslator) : emptyFuture; + deviceContext, + deviceContext, + false, + convertorExecutor, + statisticsWriterProvider) : emptyFuture; } private ListenableFuture collectPortStatistics(final MultipartType multipartType) { return devState.isPortStatisticsAvailable() ? StatisticsGatheringUtils.gatherStatistics( - statisticsGatheringService, - getDeviceInfo(), + statisticsGatheringService, + getDeviceInfo(), /*MultipartType.OFPMPPORTSTATS*/ multipartType, - deviceContext, - deviceContext, - false, multipartReplyTranslator) : emptyFuture; + deviceContext, + deviceContext, + false, + convertorExecutor, + statisticsWriterProvider) : emptyFuture; } private ListenableFuture collectQueueStatistics(final MultipartType multipartType) { return !devState.isQueueStatisticsAvailable() ? emptyFuture : StatisticsGatheringUtils.gatherStatistics( - statisticsGatheringService, - getDeviceInfo(), + statisticsGatheringService, + getDeviceInfo(), /*MultipartType.OFPMPQUEUE*/ multipartType, - deviceContext, - deviceContext, - false, multipartReplyTranslator); + deviceContext, + deviceContext, + false, + convertorExecutor, + statisticsWriterProvider); } private ListenableFuture collectGroupDescStatistics(final MultipartType multipartType) { return devState.isGroupAvailable() ? StatisticsGatheringUtils.gatherStatistics( - statisticsGatheringService, - getDeviceInfo(), + statisticsGatheringService, + getDeviceInfo(), /*MultipartType.OFPMPGROUPDESC*/ multipartType, - deviceContext, - deviceContext, - false, multipartReplyTranslator) : emptyFuture; + deviceContext, + deviceContext, + false, + convertorExecutor, + statisticsWriterProvider) : emptyFuture; } private ListenableFuture collectGroupStatistics(final MultipartType multipartType) { return devState.isGroupAvailable() ? StatisticsGatheringUtils.gatherStatistics( - statisticsGatheringService, - getDeviceInfo(), + statisticsGatheringService, + getDeviceInfo(), /*MultipartType.OFPMPGROUP*/ multipartType, - deviceContext, - deviceContext, - false, multipartReplyTranslator) : emptyFuture; + deviceContext, + deviceContext, + false, + convertorExecutor, + statisticsWriterProvider) : emptyFuture; } private ListenableFuture collectMeterConfigStatistics(final MultipartType multipartType) { return devState.isMetersAvailable() ? StatisticsGatheringUtils.gatherStatistics( - statisticsGatheringService, - getDeviceInfo(), + statisticsGatheringService, + getDeviceInfo(), /*MultipartType.OFPMPMETERCONFIG*/ multipartType, - deviceContext, - deviceContext, - false, multipartReplyTranslator) : emptyFuture; + deviceContext, + deviceContext, + false, + convertorExecutor, + statisticsWriterProvider) : emptyFuture; } private ListenableFuture collectMeterStatistics(final MultipartType multipartType) { return devState.isMetersAvailable() ? StatisticsGatheringUtils.gatherStatistics( - statisticsGatheringService, - getDeviceInfo(), + statisticsGatheringService, + getDeviceInfo(), /*MultipartType.OFPMPMETER*/ multipartType, - deviceContext, - deviceContext, - false, multipartReplyTranslator) : emptyFuture; + deviceContext, + deviceContext, + false, + convertorExecutor, + statisticsWriterProvider) : emptyFuture; } @VisibleForTesting - void setStatisticsGatheringService(final StatisticsGatheringService statisticsGatheringService) { + void setStatisticsGatheringService(final StatisticsGatheringService statisticsGatheringService) { this.statisticsGatheringService = statisticsGatheringService; } @VisibleForTesting - void setStatisticsGatheringOnTheFlyService(final StatisticsGatheringOnTheFlyService - statisticsGatheringOnTheFlyService) { + void setStatisticsGatheringOnTheFlyService(final StatisticsGatheringOnTheFlyService statisticsGatheringOnTheFlyService) { this.statisticsGatheringOnTheFlyService = statisticsGatheringOnTheFlyService; } @@ -500,7 +521,7 @@ class StatisticsContextImpl implements StatisticsContext { } @Override - public void onFailure(Throwable throwable) { + public void onFailure(@Nonnull Throwable throwable) { LOG.warn("Initial gathering statistics unsuccessful for node {}", deviceInfo.getLOGValue()); lifecycleService.closeConnection(); } @@ -517,4 +538,4 @@ class StatisticsContextImpl implements StatisticsContext { public void setInitialSubmitHandler(final ClusterInitializationPhaseHandler initialSubmitHandler) { this.initialSubmitHandler = initialSubmitHandler; } -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsGatheringUtils.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsGatheringUtils.java index e0dd990709..2704e06c17 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsGatheringUtils.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsGatheringUtils.java @@ -10,117 +10,60 @@ package org.opendaylight.openflowplugin.impl.statistics; import com.google.common.base.Function; import com.google.common.base.Optional; -import com.google.common.collect.Iterables; import com.google.common.util.concurrent.AsyncFunction; -import com.google.common.util.concurrent.CheckedFuture; -import com.google.common.util.concurrent.FutureFallback; import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.JdkFutureAdapters; import com.google.common.util.concurrent.ListenableFuture; import java.text.SimpleDateFormat; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Objects; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; import org.opendaylight.controller.md.sal.common.api.data.TransactionChainClosedException; import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo; import org.opendaylight.openflowplugin.api.openflow.device.DeviceRegistry; import org.opendaylight.openflowplugin.api.openflow.device.TxFacade; -import org.opendaylight.openflowplugin.api.openflow.registry.flow.DeviceFlowRegistry; -import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowDescriptor; -import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey; import org.opendaylight.openflowplugin.api.openflow.registry.group.DeviceGroupRegistry; import org.opendaylight.openflowplugin.api.openflow.registry.meter.DeviceMeterRegistry; 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; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.EventsTimeCounter; +import org.opendaylight.openflowplugin.impl.common.MultipartReplyTranslatorUtil; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableStatisticsGatheringStatus; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableStatisticsGatheringStatusBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.snapshot.gathering.status.grouping.SnapshotGatheringStatusEnd; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.snapshot.gathering.status.grouping.SnapshotGatheringStatusEndBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.snapshot.gathering.status.grouping.SnapshotGatheringStatusStartBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey; -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.FlowBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsDataBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.statistics.FlowStatisticsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdate; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMap; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatistics; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatisticsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupDescStatsUpdated; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupStatisticsUpdated; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatisticsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.statistics.GroupStatistics; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.statistics.GroupStatisticsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterConfigStatsUpdated; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterStatisticsUpdated; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatistics; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatisticsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterStatistics; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterStatisticsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; -import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData; -import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdate; -import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.flow.capable.node.connector.statistics.FlowCapableNodeConnectorStatistics; -import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.flow.capable.node.connector.statistics.FlowCapableNodeConnectorStatisticsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap; -import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsData; -import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsDataBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.QueueStatisticsUpdate; -import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.flow.capable.node.connector.queue.statistics.FlowCapableNodeConnectorQueueStatistics; -import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.flow.capable.node.connector.queue.statistics.FlowCapableNodeConnectorQueueStatisticsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap; -import org.opendaylight.yangtools.yang.binding.DataObject; +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.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * Utils for gatherig statistics + * Utils for gathering statistics */ public final class StatisticsGatheringUtils { - private static String DATE_AND_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"; - + private static final 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 String QUEUE2_REQCTX = "QUEUE2REQCTX-"; @@ -128,363 +71,196 @@ public final class StatisticsGatheringUtils { throw new IllegalStateException("This class should not be instantiated."); } - //TODO: Flow-,Group- and Meter- registry should be not in device context, consider move it in separate class - static ListenableFuture gatherStatistics(final StatisticsGatherer statisticsGatheringService, - final DeviceInfo deviceInfo, - final MultipartType type, - final TxFacade txFacade, - final DeviceRegistry registry, - final Boolean initial, - final SinglePurposeMultipartReplyTranslator multipartReplyTranslator) { - EventIdentifier wholeProcessEventIdentifier = null; + static ListenableFuture gatherStatistics(final StatisticsGatherer statisticsGatheringService, + final DeviceInfo deviceInfo, + final MultipartType type, + final TxFacade txFacade, + final DeviceRegistry registry, + final Boolean initial, + final ConvertorExecutor convertorExecutor, + final MultipartWriterProvider statisticsWriterProvider) { + + final EventIdentifier eventIdentifier; if (MultipartType.OFPMPFLOW.equals(type)) { - wholeProcessEventIdentifier = new EventIdentifier(type.toString(), deviceInfo.getNodeId().getValue()); - EventsTimeCounter.markStart(wholeProcessEventIdentifier); + eventIdentifier = new EventIdentifier(type.toString(), deviceInfo.getNodeId().getValue()); + EventsTimeCounter.markStart(eventIdentifier); + } else { + eventIdentifier = null; } - final EventIdentifier ofpQueuToRequestContextEventIdentifier = new EventIdentifier(QUEUE2_REQCTX + type.toString(), deviceInfo.getNodeId().toString()); - final ListenableFuture>> statisticsDataInFuture = - JdkFutureAdapters.listenInPoolThread(statisticsGatheringService.getStatisticsOfType( - ofpQueuToRequestContextEventIdentifier, type)); - return transformAndStoreStatisticsData(statisticsDataInFuture, deviceInfo, wholeProcessEventIdentifier, type, txFacade, registry, initial, multipartReplyTranslator); - } - private static ListenableFuture transformAndStoreStatisticsData(final ListenableFuture>> statisticsDataInFuture, - final DeviceInfo deviceInfo, - final EventIdentifier eventIdentifier, - final MultipartType type, - final TxFacade txFacade, - final DeviceRegistry registry, - final boolean initial, - final SinglePurposeMultipartReplyTranslator multipartReplyTranslator) { - return Futures.transform(statisticsDataInFuture, new AsyncFunction>, Boolean>() { - @Nullable - @Override - public ListenableFuture apply(final RpcResult> rpcResult) { - boolean isMultipartProcessed = Boolean.TRUE; - if (rpcResult.isSuccessful()) { - 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 - if (null != rpcResult.getResult()) { - Iterable allMultipartData = Collections.emptyList(); - DataObject multipartData = null; - - - try { - for (final MultipartReply singleReply : rpcResult.getResult()) { - final List multipartDataList = multipartReplyTranslator.translate( - deviceInfo.getDatapathId(), - deviceInfo.getVersion(), singleReply); - multipartData = multipartDataList.get(0); - allMultipartData = Iterables.concat(allMultipartData, multipartDataList); + return Futures.transform( + statisticsGatheringService.getStatisticsOfType( + new EventIdentifier(QUEUE2_REQCTX + type.toString(), deviceInfo.getNodeId().toString()), + type), + new AsyncFunction>, Boolean>() { + @Nullable + @Override + public ListenableFuture apply(@Nonnull final RpcResult> rpcResult) { + boolean isMultipartProcessed = Boolean.TRUE; + + if (rpcResult.isSuccessful()) { + 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 + if (Objects.nonNull(rpcResult.getResult()) && !rpcResult.getResult().isEmpty()) { + final List allMultipartData; + + try { + allMultipartData = rpcResult + .getResult() + .stream() + .map(reply -> MultipartReplyTranslatorUtil + .translate(reply, deviceInfo, convertorExecutor, null)) + .filter(java.util.Optional::isPresent) + .map(java.util.Optional::get) + .collect(Collectors.toList()); + } catch (final Exception e) { + LOG.warn("Stats processing of type {} for node {} failed during transformation step", + type, deviceInfo.getLOGValue(), e); + return Futures.immediateFailedFuture(e); } - } catch (final Exception e) { - LOG.warn("stats processing of type {} for node {} failed during transfomation step", - type, deviceInfo.getNodeId(), e); - return Futures.immediateFailedFuture(e); - } - - try { - if (multipartData instanceof GroupStatisticsUpdated) { - processGroupStatistics((Iterable) allMultipartData, deviceInfo, txFacade); - } else if (multipartData instanceof MeterStatisticsUpdated) { - processMetersStatistics((Iterable) allMultipartData, deviceInfo, txFacade); - } else if (multipartData instanceof NodeConnectorStatisticsUpdate) { - processNodeConnectorStatistics((Iterable) allMultipartData, deviceInfo, txFacade); - } else if (multipartData instanceof FlowTableStatisticsUpdate) { - processFlowTableStatistics((Iterable) allMultipartData, deviceInfo, txFacade); - } else if (multipartData instanceof QueueStatisticsUpdate) { - processQueueStatistics((Iterable) 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) allMultipartData, deviceInfo, txFacade, registry.getDeviceFlowRegistry(), initial, eventIdentifier); - - } else if (multipartData instanceof GroupDescStatsUpdated) { - processGroupDescStats((Iterable) allMultipartData, deviceInfo, txFacade, registry.getDeviceGroupRegistry()); - } else if (multipartData instanceof MeterConfigStatsUpdated) { - processMeterConfigStatsUpdated((Iterable) 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", + try { + return processStatistics(type, allMultipartData, txFacade, registry, deviceInfo, + statisticsWriterProvider, + eventIdentifier, initial); + } catch (final Exception e) { + LOG.warn("Stats processing of type {} for node {} failed during processing step", type, deviceInfo.getNodeId(), e); - return Futures.immediateFailedFuture(e); + return Futures.immediateFailedFuture(e); + } + } else { + LOG.debug("Stats reply was empty for node {} of type {}", deviceInfo.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 {}", deviceInfo.getNodeId(), type); + LOG.warn("Stats reply FAILED for node {} of type {}: {}", deviceInfo.getNodeId(), type, + rpcResult.getErrors()); + isMultipartProcessed = Boolean.FALSE; } - } else { - LOG.debug("Stats reply FAILED for node {} of type {}: {}", deviceInfo.getNodeId(), type, rpcResult.getErrors()); - isMultipartProcessed = Boolean.FALSE; + return Futures.immediateFuture(isMultipartProcessed); } - return Futures.immediateFuture(isMultipartProcessed); - } - }); + }); } - private static void processMeterConfigStatsUpdated(final Iterable data, - final DeviceInfo deviceInfo, - final TxFacade txFacade, - final DeviceMeterRegistry meterRegistry) throws Exception { - final InstanceIdentifier fNodeIdent = assembleFlowCapableNodeInstanceIdentifier(deviceInfo); - deleteAllKnownMeters(meterRegistry, fNodeIdent, txFacade); - for (final MeterConfigStatsUpdated meterConfigStatsUpdated : data) { - for (final MeterConfigStats meterConfigStats : meterConfigStatsUpdated.getMeterConfigStats()) { - final MeterId meterId = meterConfigStats.getMeterId(); - final InstanceIdentifier meterInstanceIdentifier = fNodeIdent.child(Meter.class, new MeterKey(meterId)); - - final MeterBuilder meterBuilder = new MeterBuilder(meterConfigStats); - meterBuilder.setKey(new MeterKey(meterId)); - meterBuilder.addAugmentation(NodeMeterStatistics.class, new NodeMeterStatisticsBuilder().build()); - meterRegistry.store(meterId); - txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, meterInstanceIdentifier, meterBuilder.build()); - } + private static ListenableFuture processStatistics(final MultipartType type, + final List statistics, + final TxFacade txFacade, + final DeviceRegistry deviceRegistry, + final DeviceInfo deviceInfo, + final MultipartWriterProvider statisticsWriterProvider, + final EventIdentifier eventIdentifier, + final boolean initial) { + + ListenableFuture future = Futures.immediateFuture(null); + + final InstanceIdentifier instanceIdentifier = deviceInfo + .getNodeInstanceIdentifier() + .augmentation(FlowCapableNode.class); + + switch (type) { + case OFPMPFLOW: + future = deleteAllKnownFlows(txFacade, instanceIdentifier, initial); + break; + case OFPMPMETERCONFIG: + deleteAllKnownMeters(txFacade, instanceIdentifier, deviceRegistry.getDeviceMeterRegistry()); + break; + case OFPMPGROUPDESC: + deleteAllKnownGroups(txFacade, instanceIdentifier, deviceRegistry.getDeviceGroupRegistry()); + break; } - txFacade.submitTransaction(); - } - private static ListenableFuture processFlowStatistics(final Iterable data, - final DeviceInfo deviceInfo, - final TxFacade txFacade, - final DeviceFlowRegistry flowRegistry, - final boolean initial, - final EventIdentifier eventIdentifier) { - final ListenableFuture deleteFuture = initial ? Futures.immediateFuture(null) : deleteAllKnownFlows(deviceInfo, - flowRegistry, txFacade); - return Futures.transform(deleteFuture, new Function() { - - @Override - public Boolean apply(final Void input) { - writeFlowStatistics(data, deviceInfo, flowRegistry, txFacade); + return Futures.transform(future, (Function) input -> { + if (writeStatistics(type, statistics, deviceInfo, statisticsWriterProvider)) { txFacade.submitTransaction(); - EventsTimeCounter.markEnd(eventIdentifier); + + if (MultipartType.OFPMPFLOW.equals(type)) { + EventsTimeCounter.markEnd(eventIdentifier); + } + + LOG.debug("Stats reply added to transaction for node {} of type {}", deviceInfo.getNodeId(), type); return Boolean.TRUE; } + + LOG.warn("Stats processing of type {} for node {} failed during write-to-tx step", type, deviceInfo.getLOGValue()); + return Boolean.FALSE; }); } - public static void writeFlowStatistics(final Iterable data, - final DeviceInfo deviceInfo, - final DeviceFlowRegistry registry, - final TxFacade txFacade) { - final InstanceIdentifier fNodeIdent = assembleFlowCapableNodeInstanceIdentifier(deviceInfo); + private static boolean writeStatistics(final MultipartType type, + final List statistics, + final DeviceInfo deviceInfo, + final MultipartWriterProvider statisticsWriterProvider) { + final AtomicBoolean result = new AtomicBoolean(false); + try { - for (final FlowsStatisticsUpdate flowsStatistics : data) { - for (final FlowAndStatisticsMapList flowStat : flowsStatistics.getFlowAndStatisticsMapList()) { - final FlowBuilder flowBuilder = new FlowBuilder(flowStat); - flowBuilder.addAugmentation(FlowStatisticsData.class, refineFlowStatisticsAugmentation(flowStat).build()); - - final short tableId = flowStat.getTableId(); - final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flowBuilder.build()); - final FlowId flowId = registry.storeIfNecessary(flowRegistryKey); - - final FlowKey flowKey = new FlowKey(flowId); - flowBuilder.setKey(flowKey); - final TableKey tableKey = new TableKey(tableId); - final InstanceIdentifier flowIdent = fNodeIdent.child(Table.class, tableKey).child(Flow.class, flowKey); - txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, flowIdent, flowBuilder.build()); + statistics.forEach(stat -> statisticsWriterProvider.lookup(type).ifPresent(p -> { + final boolean write = p.write(stat, false); + + if (!result.get()) { + result.set(write); } - } - } catch (Exception e) { - LOG.warn("Not able to write to transaction: {}", e.getMessage()); + })); + } catch (final Exception ex) { + LOG.warn("Stats processing of type {} for node {} failed during write-to-tx step", type, deviceInfo.getLOGValue(), ex); } - } - /** - * Method extracts flow statistics out of flowAndStatistics model - * - * @param flowAndStats - */ - private static FlowStatisticsDataBuilder refineFlowStatisticsAugmentation(final FlowAndStatisticsMapList flowAndStats) { - final FlowStatisticsBuilder flowStatisticsBuilder = new FlowStatisticsBuilder(flowAndStats); - final FlowStatisticsDataBuilder flowStatisticsDataBld = new FlowStatisticsDataBuilder(); - flowStatisticsDataBld.setFlowStatistics(flowStatisticsBuilder.build()); - return flowStatisticsDataBld; + return result.get(); } - public static ListenableFuture deleteAllKnownFlows(final DeviceInfo deviceInfo, - final DeviceFlowRegistry registry, - final TxFacade txFacade) { - final InstanceIdentifier flowCapableNodePath = assembleFlowCapableNodeInstanceIdentifier(deviceInfo); - final ReadOnlyTransaction readTx = txFacade.getReadTransaction(); - final CheckedFuture, ReadFailedException> flowCapableNodeFuture = readTx.read( - LogicalDatastoreType.OPERATIONAL, flowCapableNodePath); - - /* we wish to close readTx for fallBack */ - Futures.withFallback(flowCapableNodeFuture, new FutureFallback>() { + public static ListenableFuture deleteAllKnownFlows(final TxFacade txFacade, + final InstanceIdentifier instanceIdentifier, + final boolean initial) { + if (initial) { + return Futures.immediateFuture(null); + } - @Override - public ListenableFuture> create(final Throwable t) throws Exception { + final ReadOnlyTransaction readTx = txFacade.getReadTransaction(); + return Futures.transform(Futures + .withFallback(readTx.read(LogicalDatastoreType.OPERATIONAL, instanceIdentifier), t -> { + // we wish to close readTx for fallBack 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, Void>() { - - @Override - public ListenableFuture apply(final Optional flowCapNodeOpt) throws Exception { - if (flowCapNodeOpt.isPresent()) { + }), (Function, Void>) + flowCapNodeOpt -> { + // we have to read actual tables with all information before we set empty Flow list, merge is expensive and + // not applicable for lists + if (flowCapNodeOpt != null && flowCapNodeOpt.isPresent()) { for (final Table tableData : flowCapNodeOpt.get().getTable()) { - final Table table = new TableBuilder(tableData).setFlow(Collections.emptyList()).build(); - final InstanceIdentifier
iiToTable = flowCapableNodePath.child(Table.class, tableData.getKey()); + final Table table = new TableBuilder(tableData).setFlow(Collections.emptyList()).build(); + final InstanceIdentifier
iiToTable = instanceIdentifier.child(Table.class, tableData.getKey()); txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, iiToTable, table); } } - readTx.close(); - return Futures.immediateFuture(null); - } - }); - } - - private static void processQueueStatistics(final Iterable 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 nodeIdent = deviceInfo.getNodeInstanceIdentifier(); - for (final QueueStatisticsUpdate queueStatisticsUpdate : data) { - for (final QueueIdAndStatisticsMap queueStat : queueStatisticsUpdate.getQueueIdAndStatisticsMap()) { - if (queueStat.getQueueId() != null) { - final FlowCapableNodeConnectorQueueStatistics statChild = - new FlowCapableNodeConnectorQueueStatisticsBuilder(queueStat).build(); - final FlowCapableNodeConnectorQueueStatisticsDataBuilder statBuild = - new FlowCapableNodeConnectorQueueStatisticsDataBuilder(); - statBuild.setFlowCapableNodeConnectorQueueStatistics(statChild); - final QueueKey qKey = new QueueKey(queueStat.getQueueId()); - final InstanceIdentifier queueIdent = nodeIdent - .child(NodeConnector.class, new NodeConnectorKey(queueStat.getNodeConnectorId())) - .augmentation(FlowCapableNodeConnector.class) - .child(Queue.class, qKey); - final QueueBuilder queueBuilder = new QueueBuilder() - .setKey(qKey) - .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()); - txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, queueIdent, queueBuilder.build()); - } - } - } - txFacade.submitTransaction(); - } - - private static void processFlowTableStatistics(final Iterable data, final DeviceInfo deviceInfo, final TxFacade txFacade) throws Exception { - final InstanceIdentifier fNodeIdent = assembleFlowCapableNodeInstanceIdentifier(deviceInfo); - for (final FlowTableStatisticsUpdate flowTableStatisticsUpdate : data) { - - for (final FlowTableAndStatisticsMap tableStat : flowTableStatisticsUpdate.getFlowTableAndStatisticsMap()) { - final InstanceIdentifier tStatIdent = fNodeIdent.child(Table.class, new TableKey(tableStat.getTableId().getValue())) - .augmentation(FlowTableStatisticsData.class).child(FlowTableStatistics.class); - final FlowTableStatistics stats = new FlowTableStatisticsBuilder(tableStat).build(); - txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, tStatIdent, stats); - } - } - txFacade.submitTransaction(); - } - - private static void processNodeConnectorStatistics(final Iterable data, final DeviceInfo deviceInfo, final TxFacade txFacade) throws Exception { - final InstanceIdentifier nodeIdent = deviceInfo.getNodeInstanceIdentifier(); - for (final NodeConnectorStatisticsUpdate nodeConnectorStatisticsUpdate : data) { - for (final NodeConnectorStatisticsAndPortNumberMap nConnectPort : nodeConnectorStatisticsUpdate.getNodeConnectorStatisticsAndPortNumberMap()) { - final FlowCapableNodeConnectorStatistics stats = new FlowCapableNodeConnectorStatisticsBuilder(nConnectPort).build(); - final NodeConnectorKey key = new NodeConnectorKey(nConnectPort.getNodeConnectorId()); - final InstanceIdentifier nodeConnectorIdent = nodeIdent.child(NodeConnector.class, key); - final InstanceIdentifier nodeConnStatIdent = nodeConnectorIdent - .augmentation(FlowCapableNodeConnectorStatisticsData.class); - final InstanceIdentifier flowCapNodeConnStatIdent = - nodeConnStatIdent.child(FlowCapableNodeConnectorStatistics.class); - txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, flowCapNodeConnStatIdent, stats); - } - } - txFacade.submitTransaction(); + readTx.close(); + return null; + }); } - private static void processMetersStatistics(final Iterable data, - final DeviceInfo deviceInfo, - final TxFacade txFacade) throws Exception { - final InstanceIdentifier fNodeIdent = assembleFlowCapableNodeInstanceIdentifier(deviceInfo); - for (final MeterStatisticsUpdated meterStatisticsUpdated : data) { - for (final MeterStats mStat : meterStatisticsUpdated.getMeterStats()) { - final MeterStatistics stats = new MeterStatisticsBuilder(mStat).build(); - final MeterId meterId = mStat.getMeterId(); - final InstanceIdentifier meterIdent = fNodeIdent.child(Meter.class, new MeterKey(meterId)); - final InstanceIdentifier nodeMeterStatIdent = meterIdent - .augmentation(NodeMeterStatistics.class); - final InstanceIdentifier msIdent = nodeMeterStatIdent.child(MeterStatistics.class); - txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, msIdent, stats); - } - } - txFacade.submitTransaction(); - } + private static void deleteAllKnownMeters(final TxFacade txFacade, + final InstanceIdentifier instanceIdentifier, + final DeviceMeterRegistry meterRegistry) { + meterRegistry.getAllMeterIds().forEach(meterId -> txFacade + .addDeleteToTxChain( + LogicalDatastoreType.OPERATIONAL, + instanceIdentifier.child(Meter.class, new MeterKey(meterId)))); - private static void deleteAllKnownMeters(final DeviceMeterRegistry meterRegistry, final InstanceIdentifier fNodeIdent, final TxFacade txFacade) throws Exception { - for (final MeterId meterId : meterRegistry.getAllMeterIds()) { - final InstanceIdentifier meterIdent = fNodeIdent.child(Meter.class, new MeterKey(meterId)); - txFacade.addDeleteToTxChain(LogicalDatastoreType.OPERATIONAL, meterIdent); - } meterRegistry.removeMarked(); } - private static void processGroupDescStats(final Iterable data, final DeviceInfo deviceInfo, final TxFacade txFacade, final DeviceGroupRegistry groupRegistry) throws Exception { - final InstanceIdentifier fNodeIdent = assembleFlowCapableNodeInstanceIdentifier(deviceInfo); - deleteAllKnownGroups(txFacade, fNodeIdent, groupRegistry); - - for (final GroupDescStatsUpdated groupDescStatsUpdated : data) { - for (final GroupDescStats groupDescStats : groupDescStatsUpdated.getGroupDescStats()) { - final GroupId groupId = groupDescStats.getGroupId(); - - final GroupBuilder groupBuilder = new GroupBuilder(groupDescStats); - groupBuilder.setKey(new GroupKey(groupId)); - groupBuilder.addAugmentation(NodeGroupStatistics.class, new NodeGroupStatisticsBuilder().build()); + private static void deleteAllKnownGroups(final TxFacade txFacade, + final InstanceIdentifier instanceIdentifier, + final DeviceGroupRegistry groupRegistry) { + groupRegistry.getAllGroupIds().forEach(groupId -> txFacade + .addDeleteToTxChain( + LogicalDatastoreType.OPERATIONAL, + instanceIdentifier.child(Group.class, new GroupKey(groupId)))); - final InstanceIdentifier groupIdent = fNodeIdent.child(Group.class, new GroupKey(groupId)); - - groupRegistry.store(groupId); - txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, groupIdent, groupBuilder.build()); - } - } - txFacade.submitTransaction(); - } - - private static void deleteAllKnownGroups(final TxFacade txFacade, final InstanceIdentifier fNodeIdent, final DeviceGroupRegistry groupRegistry) throws Exception { - for (final GroupId groupId : groupRegistry.getAllGroupIds()) { - final InstanceIdentifier groupIdent = fNodeIdent.child(Group.class, new GroupKey(groupId)); - txFacade.addDeleteToTxChain(LogicalDatastoreType.OPERATIONAL, groupIdent); - } groupRegistry.removeMarked(); } - private static void processGroupStatistics(final Iterable data, final DeviceInfo deviceInfo, final TxFacade txFacade) throws Exception { - final InstanceIdentifier fNodeIdent = assembleFlowCapableNodeInstanceIdentifier(deviceInfo); - for (final GroupStatisticsUpdated groupStatistics : data) { - for (final GroupStats groupStats : groupStatistics.getGroupStats()) { - - final InstanceIdentifier groupIdent = fNodeIdent.child(Group.class, new GroupKey(groupStats.getGroupId())); - final InstanceIdentifier nGroupStatIdent = groupIdent - .augmentation(NodeGroupStatistics.class); - - final InstanceIdentifier gsIdent = nGroupStatIdent.child(GroupStatistics.class); - final GroupStatistics stats = new GroupStatisticsBuilder(groupStats).build(); - txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, gsIdent, stats); - } - } - txFacade.submitTransaction(); - } - - private static InstanceIdentifier assembleFlowCapableNodeInstanceIdentifier(final DeviceInfo deviceInfo) { - return deviceInfo.getNodeInstanceIdentifier().augmentation(FlowCapableNode.class); - } - /** * Writes snapshot gathering start timestamp + cleans end mark * @@ -492,15 +268,15 @@ public final class StatisticsGatheringUtils { */ static void markDeviceStateSnapshotStart(final DeviceContext deviceContext) { final InstanceIdentifier statusPath = deviceContext.getDeviceInfo() - .getNodeInstanceIdentifier().augmentation(FlowCapableStatisticsGatheringStatus.class); + .getNodeInstanceIdentifier().augmentation(FlowCapableStatisticsGatheringStatus.class); final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_AND_TIME_FORMAT); final FlowCapableStatisticsGatheringStatus gatheringStatus = new FlowCapableStatisticsGatheringStatusBuilder() - .setSnapshotGatheringStatusStart(new SnapshotGatheringStatusStartBuilder() - .setBegin(new DateAndTime(simpleDateFormat.format(new Date()))) - .build()) - .setSnapshotGatheringStatusEnd(null) // TODO: reconsider if really need to clean end mark here - .build(); + .setSnapshotGatheringStatusStart(new SnapshotGatheringStatusStartBuilder() + .setBegin(new DateAndTime(simpleDateFormat.format(new Date()))) + .build()) + .setSnapshotGatheringStatusEnd(null) // TODO: reconsider if really need to clean end mark here + .build(); try { deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, statusPath, gatheringStatus); } catch (final TransactionChainClosedException e) { @@ -519,14 +295,14 @@ public final class StatisticsGatheringUtils { */ static void markDeviceStateSnapshotEnd(final DeviceContext deviceContext, final boolean succeeded) { final InstanceIdentifier statusEndPath = deviceContext.getDeviceInfo() - .getNodeInstanceIdentifier().augmentation(FlowCapableStatisticsGatheringStatus.class) - .child(SnapshotGatheringStatusEnd.class); + .getNodeInstanceIdentifier().augmentation(FlowCapableStatisticsGatheringStatus.class) + .child(SnapshotGatheringStatusEnd.class); final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_AND_TIME_FORMAT); final SnapshotGatheringStatusEnd gatheringStatus = new SnapshotGatheringStatusEndBuilder() - .setEnd(new DateAndTime(simpleDateFormat.format(new Date()))) - .setSucceeded(succeeded) - .build(); + .setEnd(new DateAndTime(simpleDateFormat.format(new Date()))) + .setSucceeded(succeeded) + .build(); try { deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, statusEndPath, gatheringStatus); } catch (TransactionChainClosedException e) { diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImpl.java index 7127bb5eda..3a67890bae 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImpl.java @@ -15,6 +15,9 @@ import com.google.common.collect.Iterators; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; +import io.netty.util.HashedWheelTimer; +import io.netty.util.Timeout; +import io.netty.util.TimerTask; import java.util.Iterator; import java.util.Map; import java.util.Optional; @@ -38,7 +41,10 @@ import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleService; 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.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProviderFactory; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply; 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; @@ -49,9 +55,6 @@ import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import io.netty.util.HashedWheelTimer; -import io.netty.util.Timeout; -import io.netty.util.TimerTask; public class StatisticsManagerImpl implements StatisticsManager, StatisticsManagerControlService { @@ -59,7 +62,6 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag private static final long DEFAULT_STATS_TIMEOUT_SEC = 50L; private final ConvertorExecutor converterExecutor; - private DeviceInitializationPhaseHandler deviceInitPhaseHandler; private DeviceTerminationPhaseHandler deviceTerminationPhaseHandler; @@ -103,13 +105,26 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag public void onDeviceContextLevelUp(final DeviceInfo deviceInfo, final LifecycleService lifecycleService) throws Exception { + final MultipartWriterProvider statisticsWriterProvider = MultipartWriterProviderFactory + .createDefaultProvider(lifecycleService.getDeviceContext()); + final StatisticsContext statisticsContext = - new StatisticsContextImpl( - deviceInfo, - isStatisticsPollingOn, - lifecycleService, - converterExecutor, - this); + lifecycleService.getDeviceContext().canUseSingleLayerSerialization() ? + new StatisticsContextImpl( + deviceInfo, + isStatisticsPollingOn, + lifecycleService, + converterExecutor, + this, + statisticsWriterProvider) : + new StatisticsContextImpl( + deviceInfo, + isStatisticsPollingOn, + lifecycleService, + converterExecutor, + this, + statisticsWriterProvider); Verify.verify( contexts.putIfAbsent(deviceInfo, statisticsContext) == null, diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AggregateFlowsInTableService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AggregateFlowsInTableService.java index 5d8fa400d7..73554ee59b 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AggregateFlowsInTableService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AggregateFlowsInTableService.java @@ -17,8 +17,8 @@ import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; import org.opendaylight.openflowplugin.api.openflow.device.TranslatorLibrary; import org.opendaylight.openflowplugin.api.openflow.device.Xid; import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey; -import org.opendaylight.openflowplugin.impl.services.RequestInputUtils; -import org.opendaylight.openflowplugin.impl.services.ServiceException; +import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService; import org.opendaylight.openflowplugin.openflow.md.util.FlowCreatorUtil; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdate; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllFlowsInAllTablesService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllFlowsInAllTablesService.java index c466f1dde3..315c0799f9 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllFlowsInAllTablesService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllFlowsInAllTablesService.java @@ -13,8 +13,8 @@ import org.opendaylight.openflowplugin.api.OFConstants; 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.impl.services.RequestInputUtils; -import org.opendaylight.openflowplugin.impl.services.ServiceException; +import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.FlowStatisticsToNotificationTransformer; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllFlowsInTableService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllFlowsInTableService.java index ca24e48007..19aa517cdd 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllFlowsInTableService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllFlowsInTableService.java @@ -13,8 +13,8 @@ import org.opendaylight.openflowplugin.api.OFConstants; 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.impl.services.RequestInputUtils; -import org.opendaylight.openflowplugin.impl.services.ServiceException; +import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.FlowStatisticsToNotificationTransformer; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllGroupsStatsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllGroupsStatsService.java index 55e3368ddf..547085fb08 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllGroupsStatsService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllGroupsStatsService.java @@ -13,8 +13,8 @@ import org.opendaylight.openflowjava.protocol.api.util.BinContent; 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.impl.services.RequestInputUtils; -import org.opendaylight.openflowplugin.impl.services.ServiceException; +import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.GroupStatisticsToNotificationTransformer; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllMeterConfigStatsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllMeterConfigStatsService.java index bb72f11925..278df7c692 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllMeterConfigStatsService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllMeterConfigStatsService.java @@ -15,8 +15,8 @@ import org.opendaylight.openflowjava.protocol.api.util.BinContent; 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.impl.services.RequestInputUtils; -import org.opendaylight.openflowplugin.impl.services.ServiceException; +import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData; @@ -98,4 +98,4 @@ final class AllMeterConfigStatsService return message.build(); } -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllMeterStatsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllMeterStatsService.java index ef80529f9c..cb99ea6f92 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllMeterStatsService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllMeterStatsService.java @@ -13,8 +13,8 @@ import org.opendaylight.openflowjava.protocol.api.util.BinContent; 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.impl.services.RequestInputUtils; -import org.opendaylight.openflowplugin.impl.services.ServiceException; +import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.MeterStatisticsToNotificationTransformer; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllPortStatsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllPortStatsService.java index 393dc43b95..b43925b9c3 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllPortStatsService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllPortStatsService.java @@ -13,8 +13,8 @@ import org.opendaylight.openflowplugin.api.OFConstants; 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.impl.services.RequestInputUtils; -import org.opendaylight.openflowplugin.impl.services.ServiceException; +import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.NodeConnectorStatisticsToNotificationTransformer; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllQueuesAllPortsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllQueuesAllPortsService.java index 054a99ac36..60686c97c9 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllQueuesAllPortsService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllQueuesAllPortsService.java @@ -13,8 +13,8 @@ import org.opendaylight.openflowplugin.api.OFConstants; 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.impl.services.RequestInputUtils; -import org.opendaylight.openflowplugin.impl.services.ServiceException; +import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.QueueStatisticsToNotificationTransformer; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllQueuesOnePortService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllQueuesOnePortService.java index 0372c699f8..e73411ce28 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllQueuesOnePortService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/AllQueuesOnePortService.java @@ -14,8 +14,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.api.openflow.md.util.OpenflowVersion; -import org.opendaylight.openflowplugin.impl.services.RequestInputUtils; -import org.opendaylight.openflowplugin.impl.services.ServiceException; +import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.QueueStatisticsToNotificationTransformer; import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/FlowsInTableService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/FlowsInTableService.java index 58f5c45df8..a875c0d6e3 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/FlowsInTableService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/FlowsInTableService.java @@ -13,8 +13,8 @@ import org.opendaylight.openflowplugin.api.OFConstants; 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.impl.services.RequestInputUtils; -import org.opendaylight.openflowplugin.impl.services.ServiceException; +import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.FlowStatisticsToNotificationTransformer; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/GroupDescriptionService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/GroupDescriptionService.java index 2e6ca05a69..c1c79e44bf 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/GroupDescriptionService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/GroupDescriptionService.java @@ -14,8 +14,8 @@ import java.util.concurrent.atomic.AtomicLong; 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.impl.services.RequestInputUtils; -import org.opendaylight.openflowplugin.impl.services.ServiceException; +import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/GroupFeaturesService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/GroupFeaturesService.java index 80dfc7bb8b..fbd98649e1 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/GroupFeaturesService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/GroupFeaturesService.java @@ -15,8 +15,8 @@ import java.util.concurrent.atomic.AtomicLong; 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.impl.services.RequestInputUtils; -import org.opendaylight.openflowplugin.impl.services.ServiceException; +import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService; import org.opendaylight.openflowplugin.impl.util.GroupUtil; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/GroupStatsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/GroupStatsService.java index ce95e5f75e..1ffb55533a 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/GroupStatsService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/GroupStatsService.java @@ -12,8 +12,8 @@ import java.util.concurrent.atomic.AtomicLong; 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.impl.services.RequestInputUtils; -import org.opendaylight.openflowplugin.impl.services.ServiceException; +import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.GroupStatisticsToNotificationTransformer; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/MeterFeaturesService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/MeterFeaturesService.java index cd97a7364b..f41e1a72f3 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/MeterFeaturesService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/MeterFeaturesService.java @@ -15,8 +15,8 @@ import java.util.concurrent.atomic.AtomicLong; 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.impl.services.RequestInputUtils; -import org.opendaylight.openflowplugin.impl.services.ServiceException; +import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/MeterStatsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/MeterStatsService.java index 2a0b96969f..5a0d8ef2c8 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/MeterStatsService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/MeterStatsService.java @@ -12,8 +12,8 @@ import java.util.concurrent.atomic.AtomicLong; 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.impl.services.RequestInputUtils; -import org.opendaylight.openflowplugin.impl.services.ServiceException; +import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.MeterStatisticsToNotificationTransformer; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/OneQueueOnePortService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/OneQueueOnePortService.java index 12ebb39efc..139f9b5d20 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/OneQueueOnePortService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/OneQueueOnePortService.java @@ -13,8 +13,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.api.openflow.md.util.OpenflowVersion; -import org.opendaylight.openflowplugin.impl.services.RequestInputUtils; -import org.opendaylight.openflowplugin.impl.services.ServiceException; +import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.QueueStatisticsToNotificationTransformer; import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/OpendaylightFlowStatisticsServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/OpendaylightFlowStatisticsServiceImpl.java index 4d9a2b3ce1..79d621d9ed 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/OpendaylightFlowStatisticsServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/OpendaylightFlowStatisticsServiceImpl.java @@ -7,24 +7,18 @@ */ package org.opendaylight.openflowplugin.impl.statistics.services; -import com.google.common.base.Function; -import com.google.common.util.concurrent.Futures; -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; -import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey; import org.opendaylight.openflowplugin.api.openflow.statistics.compatibility.Delegator; +import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerAggregateFlowMultipartService; +import org.opendaylight.openflowplugin.impl.services.singlelayer.SingleLayerAggregateFlowMultipartService; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInput; @@ -32,54 +26,15 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.G import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService; -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.MultipartReply; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCase; import org.opendaylight.yangtools.yang.common.RpcResult; -import org.opendaylight.yangtools.yang.common.RpcResultBuilder; /** * @author joe */ public class OpendaylightFlowStatisticsServiceImpl implements OpendaylightFlowStatisticsService, Delegator { - private final Function>, RpcResult> matchingConvertor = - new Function>, RpcResult>() { - @Override - public RpcResult apply(final RpcResult> input) { - final DeviceInfo deviceInfo = matchingFlowsInTable.getDeviceInfo(); - final RpcResult rpcResult; - if (input.isSuccessful()) { - MultipartReply reply = input.getResult().get(0); - final TranslatorKey translatorKey = new TranslatorKey(reply.getVersion(), MultipartReplyAggregateCase.class.getName()); - final MessageTranslator messageTranslator = translatorLibrary.lookupTranslator(translatorKey); - List aggregStats = new ArrayList(); - - for (MultipartReply multipartReply : input.getResult()) { - aggregStats.add(messageTranslator.translate(multipartReply, deviceInfo, null)); - } - - GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder getAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder = - new GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder(); - getAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder.setAggregatedFlowStatistics(aggregStats); - - rpcResult = RpcResultBuilder - .success() - .withResult(getAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder.build()) - .build(); - - } else { - rpcResult = RpcResultBuilder - .failed() - .withRpcErrors(input.getErrors()) - .build(); - } - return rpcResult; - } - }; - - private final MatchingFlowsInTableService matchingFlowsInTable; - private final TranslatorLibrary translatorLibrary; + private final SingleLayerAggregateFlowMultipartService singleLayerService; + private final MultiLayerAggregateFlowMultipartService multiLayerService; private OpendaylightFlowStatisticsService delegate; public static OpendaylightFlowStatisticsServiceImpl createWithOook(final RequestContextStack requestContextStack, @@ -87,10 +42,14 @@ public class OpendaylightFlowStatisticsServiceImpl implements OpendaylightFlowSt return new OpendaylightFlowStatisticsServiceImpl(requestContextStack, deviceContext, deviceContext.oook(), convertorExecutor); } - public OpendaylightFlowStatisticsServiceImpl(final RequestContextStack requestContextStack, final DeviceContext deviceContext, - final TranslatorLibrary translatorLibrary, final ConvertorExecutor convertorExecutor) { - matchingFlowsInTable = new MatchingFlowsInTableService(requestContextStack, deviceContext, convertorExecutor); - this.translatorLibrary = translatorLibrary; + public OpendaylightFlowStatisticsServiceImpl(final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final TranslatorLibrary translatorLibrary, + final ConvertorExecutor convertorExecutor) { + singleLayerService = new SingleLayerAggregateFlowMultipartService(requestContextStack, deviceContext, + convertorExecutor); + multiLayerService = new MultiLayerAggregateFlowMultipartService(requestContextStack, deviceContext, + convertorExecutor, translatorLibrary); } @Override @@ -115,7 +74,9 @@ public class OpendaylightFlowStatisticsServiceImpl implements OpendaylightFlowSt @Override public Future> getAggregateFlowStatisticsFromFlowTableForGivenMatch( final GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input) { - return Futures.transform(matchingFlowsInTable.handleServiceCall(input), matchingConvertor); + return singleLayerService.canUseSingleLayerSerialization() + ? singleLayerService.handleAndReply(input) + : multiLayerService.handleAndReply(input); } /** diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/OpendaylightFlowTableStatisticsServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/OpendaylightFlowTableStatisticsServiceImpl.java index efc8e6fcb2..0f8ea8ae83 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/OpendaylightFlowTableStatisticsServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/OpendaylightFlowTableStatisticsServiceImpl.java @@ -15,8 +15,8 @@ import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService 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.impl.services.RequestInputUtils; -import org.opendaylight.openflowplugin.impl.services.ServiceException; +import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter64; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/PortStatsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/PortStatsService.java index 8355c96e0d..f4686c831b 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/PortStatsService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/PortStatsService.java @@ -13,8 +13,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.api.openflow.md.util.OpenflowVersion; -import org.opendaylight.openflowplugin.impl.services.RequestInputUtils; -import org.opendaylight.openflowplugin.impl.services.ServiceException; +import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.NodeConnectorStatisticsToNotificationTransformer; import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil; diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/AbstractCompatibleStatService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/AbstractCompatibleStatService.java index 1a5c5a1d5f..e0340bac59 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/AbstractCompatibleStatService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/AbstractCompatibleStatService.java @@ -23,6 +23,7 @@ import org.opendaylight.openflowplugin.api.openflow.statistics.compatibility.Bac import org.opendaylight.openflowplugin.impl.services.AbstractMultipartService; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; +import org.opendaylight.yangtools.yang.binding.DataContainer; import org.opendaylight.yangtools.yang.binding.Notification; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; @@ -32,7 +33,7 @@ import org.slf4j.LoggerFactory; /** * pulled up common functionality of notification emitting stats services (backward compatibility relic) */ -public abstract class AbstractCompatibleStatService extends AbstractMultipartService implements BackwardCompatibleAtomicService { +public abstract class AbstractCompatibleStatService extends AbstractMultipartService implements BackwardCompatibleAtomicService { private static final Logger LOG = LoggerFactory.getLogger(AbstractCompatibleStatService.class); diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/dedicated/StatisticsGatheringOnTheFlyService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/dedicated/StatisticsGatheringOnTheFlyService.java index a88e405b7c..4d944231e8 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/dedicated/StatisticsGatheringOnTheFlyService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/dedicated/StatisticsGatheringOnTheFlyService.java @@ -8,8 +8,8 @@ package org.opendaylight.openflowplugin.impl.statistics.services.dedicated; +import com.google.common.util.concurrent.ListenableFuture; import java.util.List; -import java.util.concurrent.Future; import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; import org.opendaylight.openflowplugin.api.openflow.device.Xid; @@ -17,11 +17,11 @@ import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.Event import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.StatisticsGatherer; import org.opendaylight.openflowplugin.impl.common.MultipartRequestInputFactory; import org.opendaylight.openflowplugin.impl.services.AbstractMultipartOnTheFlyService; -import org.opendaylight.openflowplugin.impl.services.ServiceException; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.EventsTimeCounter; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; -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.yangtools.yang.common.RpcResult; import org.slf4j.Logger; @@ -30,16 +30,21 @@ import org.slf4j.LoggerFactory; /** * collects statistics and processes them on the fly */ -public class StatisticsGatheringOnTheFlyService extends AbstractMultipartOnTheFlyService implements StatisticsGatherer { +public class StatisticsGatheringOnTheFlyService + extends AbstractMultipartOnTheFlyService + implements StatisticsGatherer { private static final Logger LOG = LoggerFactory.getLogger(StatisticsGatheringOnTheFlyService.class); - public StatisticsGatheringOnTheFlyService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final ConvertorExecutor convertorExecutor) { - super(requestContextStack, deviceContext, convertorExecutor); + public StatisticsGatheringOnTheFlyService(final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ConvertorExecutor convertorExecutor, + final MultipartWriterProvider statisticsWriterProvider) { + super(requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider); } @Override - public Future>> getStatisticsOfType(final EventIdentifier eventIdentifier, final MultipartType type) { + public ListenableFuture>> getStatisticsOfType(final EventIdentifier eventIdentifier, final MultipartType type) { LOG.debug("Getting statistics (onTheFly) for node {} of type {}", getDeviceInfo().getNodeId(), type); EventsTimeCounter.markStart(eventIdentifier); setEventIdentifier(eventIdentifier); @@ -50,4 +55,5 @@ public class StatisticsGatheringOnTheFlyService extends AbstractMultipartOnTheFl protected OfHeader buildRequest(final Xid xid, final MultipartType input) throws ServiceException { return MultipartRequestInputFactory.makeMultipartRequestInput(xid.getValue(), getVersion(), input); } + } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/dedicated/StatisticsGatheringService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/dedicated/StatisticsGatheringService.java index fc0f8d3f3f..3f8e355f1e 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/dedicated/StatisticsGatheringService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/dedicated/StatisticsGatheringService.java @@ -8,8 +8,8 @@ package org.opendaylight.openflowplugin.impl.statistics.services.dedicated; +import com.google.common.util.concurrent.ListenableFuture; import java.util.List; -import java.util.concurrent.Future; import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; import org.opendaylight.openflowplugin.api.openflow.device.Xid; @@ -17,19 +17,17 @@ import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.Event import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.StatisticsGatherer; import org.opendaylight.openflowplugin.impl.common.MultipartRequestInputFactory; import org.opendaylight.openflowplugin.impl.services.AbstractMultipartService; -import org.opendaylight.openflowplugin.impl.services.ServiceException; +import org.opendaylight.openflowplugin.impl.services.util.ServiceException; import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.EventsTimeCounter; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; -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.yangtools.yang.common.RpcResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -/** - * Created by Martin Bobak <mbobak@cisco.com> on 4.4.2015. - */ -public class StatisticsGatheringService extends AbstractMultipartService implements StatisticsGatherer { +public class StatisticsGatheringService + extends AbstractMultipartService + implements StatisticsGatherer { private static final Logger LOG = LoggerFactory.getLogger(StatisticsGatheringService.class); @@ -38,7 +36,7 @@ public class StatisticsGatheringService extends AbstractMultipartService>> getStatisticsOfType(final EventIdentifier eventIdentifier, final MultipartType type) { + public ListenableFuture>> getStatisticsOfType(final EventIdentifier eventIdentifier, final MultipartType type) { LOG.debug("Getting statistics for node {} of type {}", getDeviceInfo().getNodeId(), type); EventsTimeCounter.markStart(eventIdentifier); setEventIdentifier(eventIdentifier); @@ -49,4 +47,5 @@ public class StatisticsGatheringService extends AbstractMultipartService the input type parameter * @param the output type parameter */ -public abstract class AbstractDirectStatisticsService extends AbstractMultipartService { +abstract class AbstractDirectStatisticsService + extends AbstractMultipartService { - private final Function>, RpcResult> resultTransformFunction = - new Function>, RpcResult>() { + private final Function>, RpcResult> resultTransformFunction = + new Function>, RpcResult>() { @Nullable @Override - public RpcResult apply(@Nullable RpcResult> input) { - Preconditions.checkNotNull(input); - final O reply = buildReply(input.getResult(), input.isSuccessful()); - return RpcResultBuilder.success(reply).build(); + public RpcResult apply(@Nullable RpcResult> input) { + return Preconditions.checkNotNull(input).isSuccessful() + ? RpcResultBuilder.success(buildReply(input.getResult(), input.isSuccessful())).build() + : RpcResultBuilder.failed().build(); } }; - private final AsyncFunction, RpcResult> resultStoreFunction = - new AsyncFunction, RpcResult>() { + private final Function, RpcResult> resultStoreFunction = + new Function, RpcResult>() { @Nullable @Override - public ListenableFuture> apply(@Nullable RpcResult input) throws Exception { + public RpcResult apply(@Nullable RpcResult input) { Preconditions.checkNotNull(input); if (input.isSuccessful()) { - storeStatistics(input.getResult()); - getTxFacade().submitTransaction(); // TODO: If submitTransaction will ever return future, chain it + multipartWriterProvider + .lookup(multipartType) + .ifPresent(writer -> { + writer.write(input.getResult(), true); + getTxFacade().submitTransaction(); + }); } - return Futures.immediateFuture(input); + return input; } }; private final MultipartType multipartType; - private final ConvertorExecutor convertorExecutor; private final OpenflowVersion ofVersion = OpenflowVersion.get(getVersion()); + private final ConvertorExecutor convertorExecutor; + private final MultipartWriterProvider multipartWriterProvider; + /** * Instantiates a new Abstract direct statistics service. - * - * @param multipartType the multipart type - * @param requestContextStack the request context stack - * @param deviceContext the device context - * @param convertorExecutor + * @param multipartType the multipart type + * @param requestContextStack the request context stack + * @param deviceContext the device context + * @param convertorExecutor convertor executor + * @param multipartWriterProvider statistics writer provider */ - protected AbstractDirectStatisticsService(MultipartType multipartType, RequestContextStack requestContextStack, - DeviceContext deviceContext, ConvertorExecutor convertorExecutor) { + AbstractDirectStatisticsService(final MultipartType multipartType, + final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ConvertorExecutor convertorExecutor, + final MultipartWriterProvider multipartWriterProvider) { super(requestContextStack, deviceContext); this.multipartType = multipartType; this.convertorExecutor = convertorExecutor; - } - - protected ConvertorExecutor getConvertorExecutor() { - return convertorExecutor; + this.multipartWriterProvider = multipartWriterProvider; } /** @@ -96,12 +103,12 @@ public abstract class AbstractDirectStatisticsService> handleAndReply(final I input) { - final ListenableFuture>> rpcReply = handleServiceCall(input); - ListenableFuture> rpcResult = Futures.transform(rpcReply, resultTransformFunction); + Future> handleAndReply(final I input) { + final ListenableFuture>> rpcReply = handleServiceCall(input); + ListenableFuture> rpcResult = Futures.transform(rpcReply, resultTransformFunction::apply); if (Boolean.TRUE.equals(input.isStoreStats())) { - rpcResult = Futures.transform(rpcResult, resultStoreFunction); + rpcResult = Futures.transform(rpcResult, resultStoreFunction::apply); } return rpcResult; @@ -114,6 +121,14 @@ public abstract class AbstractDirectStatisticsService input, boolean success); + protected abstract O buildReply(List input, boolean success); - /** - * Store statistics. - * TODO: Remove dependency on deviceContext from derived methods - * TODO: Return future, so we will be able to chain it - * - * @param output the output - * @throws Exception the exception - */ - protected abstract void storeStatistics(O output) throws Exception; } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractFlowDirectStatisticsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractFlowDirectStatisticsService.java new file mode 100644 index 0000000000..6c7b4a1e55 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractFlowDirectStatisticsService.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.statistics.services.direct; + +import org.opendaylight.openflowplugin.api.OFConstants; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey; +import org.opendaylight.openflowplugin.impl.registry.flow.FlowRegistryKeyFactory; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchReactor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsDataBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.statistics.FlowStatisticsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlowCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.flow._case.MultipartRequestFlowBuilder; + +/** + * The Flow direct statistics service. + */ +public abstract class AbstractFlowDirectStatisticsService + extends AbstractDirectStatisticsService { + + protected AbstractFlowDirectStatisticsService(final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ConvertorExecutor convertorExecutor, + final MultipartWriterProvider statisticsWriterProvider) { + super(MultipartType.OFPMPFLOW, requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider); + } + + @Override + public MultipartRequestBody buildRequestBody(GetFlowStatisticsInput input) { + final MultipartRequestFlowBuilder mprFlowRequestBuilder = new MultipartRequestFlowBuilder(); + + if (input.getTableId() != null) { + mprFlowRequestBuilder.setTableId(input.getTableId()); + } else { + mprFlowRequestBuilder.setTableId(OFConstants.OFPTT_ALL); + } + + if (input.getOutPort() != null) { + mprFlowRequestBuilder.setOutPort(input.getOutPort().longValue()); + } else { + mprFlowRequestBuilder.setOutPort(OFConstants.OFPP_ANY); + } + + if (input.getOutGroup() != null) { + mprFlowRequestBuilder.setOutGroup(input.getOutGroup()); + } else { + mprFlowRequestBuilder.setOutGroup(OFConstants.OFPG_ANY); + } + + if (input.getCookie() != null) { + mprFlowRequestBuilder.setCookie(input.getCookie().getValue()); + } else { + mprFlowRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE); + } + + if (input.getCookieMask() != null) { + mprFlowRequestBuilder.setCookieMask(input.getCookieMask().getValue()); + } else { + mprFlowRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK); + } + + MatchReactor.getInstance().convert(input.getMatch(), getVersion(), mprFlowRequestBuilder, getConvertorExecutor()); + + return new MultipartRequestFlowCaseBuilder() + .setMultipartRequestFlow(mprFlowRequestBuilder.build()) + .build(); + } + + /** + * Get flow ID from #{@link org.opendaylight.openflowplugin.api.openflow.registry.flow.DeviceFlowRegistry} or + * create alien ID + * @param flowStatistics flow statistics + * @return generated flow ID + */ + protected FlowId generateFlowId(FlowAndStatisticsMapList flowStatistics) { + final FlowStatisticsDataBuilder flowStatisticsDataBld = new FlowStatisticsDataBuilder() + .setFlowStatistics(new FlowStatisticsBuilder(flowStatistics).build()); + + final FlowBuilder flowBuilder = new FlowBuilder(flowStatistics) + .addAugmentation(FlowStatisticsData.class, flowStatisticsDataBld.build()); + + final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(getVersion(), flowBuilder.build()); + return getDeviceRegistry().getDeviceFlowRegistry().storeIfNecessary(flowRegistryKey); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractGroupDirectStatisticsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractGroupDirectStatisticsService.java new file mode 100644 index 0000000000..32b2819d6d --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractGroupDirectStatisticsService.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.statistics.services.direct; + +import org.opendaylight.openflowplugin.api.OFConstants; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatisticsInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatisticsOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.group._case.MultipartRequestGroupBuilder; + +/** + * The Group direct statistics service. + */ +public abstract class AbstractGroupDirectStatisticsService + extends AbstractDirectStatisticsService { + + protected AbstractGroupDirectStatisticsService(final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ConvertorExecutor convertorExecutor, + final MultipartWriterProvider statisticsWriterProvider) { + super(MultipartType.OFPMPGROUP, requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider); + } + + @Override + public MultipartRequestBody buildRequestBody(GetGroupStatisticsInput input) { + final MultipartRequestGroupBuilder mprGroupBuild = new MultipartRequestGroupBuilder(); + + if (input.getGroupId() != null) { + mprGroupBuild.setGroupId(new GroupId(input.getGroupId().getValue())); + } else { + mprGroupBuild.setGroupId(new GroupId(OFConstants.OFPG_ALL)); + } + + return new MultipartRequestGroupCaseBuilder() + .setMultipartRequestGroup(mprGroupBuild.build()) + .build(); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractMeterDirectStatisticsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractMeterDirectStatisticsService.java new file mode 100644 index 0000000000..d0477521cb --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractMeterDirectStatisticsService.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.statistics.services.direct; + +import org.opendaylight.openflowplugin.api.OFConstants; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatisticsInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatisticsOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter._case.MultipartRequestMeterBuilder; + +/** + * The Meter direct statistics service. + */ +public abstract class AbstractMeterDirectStatisticsService extends + AbstractDirectStatisticsService { + + public AbstractMeterDirectStatisticsService(final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ConvertorExecutor convertorExecutor, + final MultipartWriterProvider statisticsWriterProvider) { + super(MultipartType.OFPMPMETER, requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider); + } + + @Override + public MultipartRequestBody buildRequestBody(GetMeterStatisticsInput input) { + final MultipartRequestMeterBuilder mprMeterBuild = new MultipartRequestMeterBuilder(); + + if (input.getMeterId() != null) { + mprMeterBuild.setMeterId(new MeterId(input.getMeterId().getValue())); + } else { + mprMeterBuild.setMeterId(new MeterId(OFConstants.OFPM_ALL)); + } + + return new MultipartRequestMeterCaseBuilder() + .setMultipartRequestMeter(mprMeterBuild.build()) + .build(); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractPortDirectStatisticsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractPortDirectStatisticsService.java new file mode 100644 index 0000000000..9b556895c8 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractPortDirectStatisticsService.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.statistics.services.direct; + +import org.opendaylight.openflowplugin.api.OFConstants; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortStatsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.port.stats._case.MultipartRequestPortStatsBuilder; + +/** + * The Node connector direct statistics service. + */ +public abstract class AbstractPortDirectStatisticsService + extends AbstractDirectStatisticsService { + + public AbstractPortDirectStatisticsService(final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ConvertorExecutor convertorExecutor, + final MultipartWriterProvider statisticsWriterProvider) { + super(MultipartType.OFPMPPORTSTATS, requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider); + } + + @Override + public MultipartRequestBody buildRequestBody(GetNodeConnectorStatisticsInput input) { + final MultipartRequestPortStatsBuilder mprPortStatsBuilder = new MultipartRequestPortStatsBuilder(); + + if (input.getNodeConnectorId() != null) { + mprPortStatsBuilder.setPortNo(InventoryDataServiceUtil.portNumberfromNodeConnectorId(getOfVersion(), input.getNodeConnectorId())); + } else { + mprPortStatsBuilder.setPortNo(OFConstants.OFPP_ANY); + } + + return new MultipartRequestPortStatsCaseBuilder() + .setMultipartRequestPortStats(mprPortStatsBuilder.build()) + .build(); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractQueueDirectStatisticsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractQueueDirectStatisticsService.java new file mode 100644 index 0000000000..79cd9a41c6 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractQueueDirectStatisticsService.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.statistics.services.direct; + +import org.opendaylight.openflowplugin.api.OFConstants; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatisticsInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatisticsOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueueCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.queue._case.MultipartRequestQueueBuilder; + +/** + * The Queue direct statistics service. + */ +public abstract class AbstractQueueDirectStatisticsService + extends AbstractDirectStatisticsService { + + public AbstractQueueDirectStatisticsService(final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ConvertorExecutor convertorExecutor, + final MultipartWriterProvider statisticsWriterProvider) { + super(MultipartType.OFPMPQUEUE, requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider); + } + + @Override + public MultipartRequestBody buildRequestBody(GetQueueStatisticsInput input) { + final MultipartRequestQueueBuilder mprQueueBuilder = new MultipartRequestQueueBuilder(); + + if (input.getQueueId() != null) { + mprQueueBuilder.setQueueId(input.getQueueId().getValue()); + } else { + mprQueueBuilder.setQueueId(OFConstants.OFPQ_ALL); + } + + if (input.getNodeConnectorId() != null) { + mprQueueBuilder.setPortNo(InventoryDataServiceUtil.portNumberfromNodeConnectorId(getOfVersion(), input.getNodeConnectorId())); + } else { + mprQueueBuilder.setPortNo(OFConstants.OFPP_ANY); + } + + return new MultipartRequestQueueCaseBuilder() + .setMultipartRequestQueue(mprQueueBuilder.build()) + .build(); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/FlowDirectStatisticsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/FlowDirectStatisticsService.java deleted file mode 100644 index a106ad93e5..0000000000 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/FlowDirectStatisticsService.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.openflowplugin.impl.statistics.services.direct; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.openflowplugin.api.OFConstants; -import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; -import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; -import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey; -import org.opendaylight.openflowplugin.extension.api.path.MatchPath; -import org.opendaylight.openflowplugin.impl.registry.flow.FlowRegistryKeyFactory; -import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; -import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.FlowStatsResponseConvertorData; -import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData; -import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchReactor; -import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsOutputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey; -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.FlowBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsDataBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.statistics.FlowStatisticsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.MultipartReplyFlow; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlowCaseBuilder; -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; - -/** - * The Flow direct statistics service. - */ -public class FlowDirectStatisticsService extends AbstractDirectStatisticsService { - private final FlowStatsResponseConvertorData data; - - /** - * Instantiates a new Flow direct statistics service. - * @param requestContextStack the request context stack - * @param deviceContext the device context - * @param convertorExecutor - */ - public FlowDirectStatisticsService(RequestContextStack requestContextStack, DeviceContext deviceContext, ConvertorExecutor convertorExecutor) { - super(MultipartType.OFPMPFLOW, requestContextStack, deviceContext, convertorExecutor); - data = new FlowStatsResponseConvertorData(getVersion()); - data.setDatapathId(getDatapathId()); - data.setMatchPath(MatchPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_MATCH); - } - - @Override - protected MultipartRequestBody buildRequestBody(GetFlowStatisticsInput input) { - final MultipartRequestFlowBuilder mprFlowRequestBuilder = new MultipartRequestFlowBuilder(); - - if (input.getTableId() != null) { - mprFlowRequestBuilder.setTableId(input.getTableId()); - } else { - mprFlowRequestBuilder.setTableId(OFConstants.OFPTT_ALL); - } - - if (input.getOutPort() != null) { - mprFlowRequestBuilder.setOutPort(input.getOutPort().longValue()); - } else { - mprFlowRequestBuilder.setOutPort(OFConstants.OFPP_ANY); - } - - if (input.getOutGroup() != null) { - mprFlowRequestBuilder.setOutGroup(input.getOutGroup()); - } else { - mprFlowRequestBuilder.setOutGroup(OFConstants.OFPG_ANY); - } - - if (input.getCookie() != null) { - mprFlowRequestBuilder.setCookie(input.getCookie().getValue()); - } else { - mprFlowRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE); - } - - if (input.getCookieMask() != null) { - mprFlowRequestBuilder.setCookieMask(input.getCookieMask().getValue()); - } else { - mprFlowRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK); - } - - MatchReactor.getInstance().convert(input.getMatch(), getVersion(), mprFlowRequestBuilder, getConvertorExecutor()); - - return new MultipartRequestFlowCaseBuilder() - .setMultipartRequestFlow(mprFlowRequestBuilder.build()) - .build(); - } - - @Override - protected GetFlowStatisticsOutput buildReply(List input, boolean success) { - final List statsList = new ArrayList<>(); - - if (success) { - for (final MultipartReply mpReply : input) { - final MultipartReplyFlowCase caseBody = (MultipartReplyFlowCase) mpReply.getMultipartReplyBody(); - final MultipartReplyFlow replyBody = caseBody.getMultipartReplyFlow(); - final Optional> statsListPart = getConvertorExecutor().convert( - replyBody.getFlowStats(), data); - - if (statsListPart.isPresent()) { - for (final FlowAndStatisticsMapList part : statsListPart.get()) { - final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowId flowId = - new org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowId(generateFlowId(part).getValue()); - - statsList.add(new FlowAndStatisticsMapListBuilder(part) - .setKey(new FlowAndStatisticsMapListKey(flowId)) - .setFlowId(flowId) - .build()); - } - } - } - } - - return new GetFlowStatisticsOutputBuilder() - .setFlowAndStatisticsMapList(statsList) - .build(); - } - - @Override - protected void storeStatistics(GetFlowStatisticsOutput output) throws Exception { - final InstanceIdentifier nodePath = getDeviceInfo().getNodeInstanceIdentifier().augmentation(FlowCapableNode.class); - - for (final FlowAndStatisticsMapList flowStatistics : output.getFlowAndStatisticsMapList()) { - final FlowId flowId = generateFlowId(flowStatistics); - final FlowKey flowKey = new FlowKey(flowId); - - final FlowStatisticsDataBuilder flowStatisticsDataBld = new FlowStatisticsDataBuilder() - .setFlowStatistics(new FlowStatisticsBuilder(flowStatistics).build()); - - final FlowBuilder flowBuilder = new FlowBuilder(flowStatistics) - .addAugmentation(FlowStatisticsData.class, flowStatisticsDataBld.build()) - .setKey(flowKey); - - final InstanceIdentifier flowStatisticsPath = nodePath - .child(Table.class, new TableKey(flowStatistics.getTableId())) - .child(Flow.class, flowKey); - - getTxFacade().writeToTransactionWithParentsSlow(LogicalDatastoreType.OPERATIONAL, flowStatisticsPath, flowBuilder.build()); - } - } - - private FlowId generateFlowId(FlowAndStatisticsMapList flowStatistics) { - final FlowStatisticsDataBuilder flowStatisticsDataBld = new FlowStatisticsDataBuilder() - .setFlowStatistics(new FlowStatisticsBuilder(flowStatistics).build()); - - final FlowBuilder flowBuilder = new FlowBuilder(flowStatistics) - .addAugmentation(FlowStatisticsData.class, flowStatisticsDataBld.build()); - - final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(getVersion(), flowBuilder.build()); - return getDeviceRegistry().getDeviceFlowRegistry().storeIfNecessary(flowRegistryKey); - } -} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/GroupDirectStatisticsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/GroupDirectStatisticsService.java deleted file mode 100644 index 9a4925c8a9..0000000000 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/GroupDirectStatisticsService.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.openflowplugin.impl.statistics.services.direct; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.openflowplugin.api.OFConstants; -import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; -import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; -import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; -import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData; -import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatisticsInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatisticsOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatisticsOutputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.statistics.GroupStatistics; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.statistics.GroupStatisticsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.MultipartReplyGroup; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupCaseBuilder; -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; - -/** - * The Group direct statistics service. - */ -public class GroupDirectStatisticsService extends AbstractDirectStatisticsService { - private final VersionConvertorData data; - - /** - * Instantiates a new Group direct statistics service. - * @param requestContextStack the request context stack - * @param deviceContext the device context - * @param convertorExecutor - */ - public GroupDirectStatisticsService(RequestContextStack requestContextStack, DeviceContext deviceContext, ConvertorExecutor convertorExecutor) { - super(MultipartType.OFPMPGROUP, requestContextStack, deviceContext, convertorExecutor); - data = new VersionConvertorData(getVersion()); - } - - @Override - protected MultipartRequestBody buildRequestBody(GetGroupStatisticsInput input) { - final MultipartRequestGroupBuilder mprGroupBuild = new MultipartRequestGroupBuilder(); - - if (input.getGroupId() != null) { - mprGroupBuild.setGroupId(new GroupId(input.getGroupId().getValue())); - } else { - mprGroupBuild.setGroupId(new GroupId(OFConstants.OFPG_ALL)); - } - - return new MultipartRequestGroupCaseBuilder() - .setMultipartRequestGroup(mprGroupBuild.build()) - .build(); - } - - @Override - protected GetGroupStatisticsOutput buildReply(List input, boolean success) { - final List groupStats = new ArrayList<>(); - - if (success) { - for (final MultipartReply mpReply : input) { - final MultipartReplyGroupCase caseBody = (MultipartReplyGroupCase) mpReply.getMultipartReplyBody(); - final MultipartReplyGroup replyBody = caseBody.getMultipartReplyGroup(); - final Optional> groupStatsList = getConvertorExecutor().convert( - replyBody.getGroupStats(), data); - - if (groupStatsList.isPresent()) { - groupStats.addAll(groupStatsList.get()); - } - } - } - - return new GetGroupStatisticsOutputBuilder() - .setGroupStats(groupStats) - .build(); - } - - @Override - protected void storeStatistics(GetGroupStatisticsOutput output) throws Exception { - final InstanceIdentifier nodePath = getDeviceInfo().getNodeInstanceIdentifier().augmentation(FlowCapableNode.class); - - for (final GroupStats groupStatistics : output.getGroupStats()) { - final InstanceIdentifier groupStatisticsPath = nodePath - .child(Group.class, new GroupKey(groupStatistics.getGroupId())) - .augmentation(NodeGroupStatistics.class) - .child(GroupStatistics.class); - - final GroupStatistics stats = new GroupStatisticsBuilder(groupStatistics).build(); - getTxFacade().writeToTransactionWithParentsSlow(LogicalDatastoreType.OPERATIONAL, groupStatisticsPath, stats); - } - } -} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/MeterDirectStatisticsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/MeterDirectStatisticsService.java deleted file mode 100644 index 1e1146d711..0000000000 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/MeterDirectStatisticsService.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.openflowplugin.impl.statistics.services.direct; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.openflowplugin.api.OFConstants; -import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; -import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; -import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; -import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData; -import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatisticsInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatisticsOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatisticsOutputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatistics; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterStatistics; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterStatisticsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.MultipartReplyMeter; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterCaseBuilder; -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; - -/** - * The Meter direct statistics service. - */ -public class MeterDirectStatisticsService extends AbstractDirectStatisticsService { - private final VersionConvertorData data; - - /** - * Instantiates a new Meter direct statistics service. - * @param requestContextStack the request context stack - * @param deviceContext the device context - * @param convertorExecutor - */ - public MeterDirectStatisticsService(RequestContextStack requestContextStack, DeviceContext deviceContext, ConvertorExecutor convertorExecutor) { - super(MultipartType.OFPMPMETER, requestContextStack, deviceContext, convertorExecutor); - data = new VersionConvertorData(getVersion()); - } - - @Override - protected MultipartRequestBody buildRequestBody(GetMeterStatisticsInput input) { - final MultipartRequestMeterBuilder mprMeterBuild = new MultipartRequestMeterBuilder(); - - if (input.getMeterId() != null) { - mprMeterBuild.setMeterId(new MeterId(input.getMeterId().getValue())); - } else { - mprMeterBuild.setMeterId(new MeterId(OFConstants.OFPM_ALL)); - } - - return new MultipartRequestMeterCaseBuilder() - .setMultipartRequestMeter(mprMeterBuild.build()) - .build(); - } - - @Override - protected GetMeterStatisticsOutput buildReply(List input, boolean success) { - final List meterStats = new ArrayList<>(); - - if (success) { - for (final MultipartReply mpReply : input) { - final MultipartReplyMeterCase caseBody = (MultipartReplyMeterCase) mpReply.getMultipartReplyBody(); - final MultipartReplyMeter replyBody = caseBody.getMultipartReplyMeter(); - final Optional> meterStatsList = getConvertorExecutor().convert(replyBody.getMeterStats(), data); - - if (meterStatsList.isPresent()) { - meterStats.addAll(meterStatsList.get()); - } - } - } - - return new GetMeterStatisticsOutputBuilder() - .setMeterStats(meterStats) - .build(); - } - - @Override - protected void storeStatistics(GetMeterStatisticsOutput output) throws Exception { - final InstanceIdentifier nodePath = getDeviceInfo().getNodeInstanceIdentifier().augmentation(FlowCapableNode.class); - - for (final MeterStats meterStatistics : output.getMeterStats()) { - final InstanceIdentifier meterPath = nodePath - .child(Meter.class, new MeterKey(meterStatistics.getMeterId())) - .augmentation(NodeMeterStatistics.class) - .child(MeterStatistics.class); - - final MeterStatistics stats = new MeterStatisticsBuilder(meterStatistics).build(); - getTxFacade().writeToTransactionWithParentsSlow(LogicalDatastoreType.OPERATIONAL, meterPath, stats); - } - } -} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/NodeConnectorDirectStatisticsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/NodeConnectorDirectStatisticsService.java deleted file mode 100644 index 2efa1cf349..0000000000 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/NodeConnectorDirectStatisticsService.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.openflowplugin.impl.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; -import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; -import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; -import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32; -import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsOutputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; -import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.BytesBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.PacketsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStats; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.multipart.reply.port.stats.PortStats; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortStatsCaseBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.port.stats._case.MultipartRequestPortStatsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData; -import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.flow.capable.node.connector.statistics.FlowCapableNodeConnectorStatistics; -import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.flow.capable.node.connector.statistics.FlowCapableNodeConnectorStatisticsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap; -import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapBuilder; -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; - -/** - * The Node connector direct statistics service. - */ -public class NodeConnectorDirectStatisticsService extends AbstractDirectStatisticsService { - /** - * Instantiates a new Node connector direct statistics service. - * @param requestContextStack the request context stack - * @param deviceContext the device context - * @param convertorExecutor - */ - public NodeConnectorDirectStatisticsService(RequestContextStack requestContextStack, DeviceContext deviceContext, ConvertorExecutor convertorExecutor) { - super(MultipartType.OFPMPPORTSTATS, requestContextStack, deviceContext, convertorExecutor); - } - - @Override - protected MultipartRequestBody buildRequestBody(GetNodeConnectorStatisticsInput input) { - final MultipartRequestPortStatsBuilder mprPortStatsBuilder = new MultipartRequestPortStatsBuilder(); - - if (input.getNodeConnectorId() != null) { - mprPortStatsBuilder.setPortNo(InventoryDataServiceUtil.portNumberfromNodeConnectorId(getOfVersion(), input.getNodeConnectorId())); - } else { - mprPortStatsBuilder.setPortNo(OFConstants.OFPP_ANY); - } - - return new MultipartRequestPortStatsCaseBuilder() - .setMultipartRequestPortStats(mprPortStatsBuilder.build()) - .build(); - } - - @Override - protected GetNodeConnectorStatisticsOutput buildReply(List input, boolean success) { - final List nodeConnectorStatisticsAndPortNumberMap = new ArrayList<>(); - - if (success) { - for (final MultipartReply mpReply : input) { - final MultipartReplyPortStatsCase caseBody = (MultipartReplyPortStatsCase) mpReply.getMultipartReplyBody(); - final MultipartReplyPortStats replyBody = caseBody.getMultipartReplyPortStats(); - - for (final PortStats portStats : replyBody.getPortStats()) { - final NodeConnectorId nodeConnectorId = InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo( - getDatapathId(), portStats.getPortNo(), getOfVersion()); - - final BytesBuilder bytesBuilder = new BytesBuilder() - .setReceived(portStats.getRxBytes()) - .setTransmitted(portStats.getTxBytes()); - - final PacketsBuilder packetsBuilder = new PacketsBuilder() - .setReceived(portStats.getRxPackets()) - .setTransmitted(portStats.getTxPackets()); - - final DurationBuilder durationBuilder = new DurationBuilder(); - - if (portStats.getDurationSec() != null) { - durationBuilder.setSecond(new Counter32(portStats.getDurationSec())); - } - - if (portStats.getDurationNsec() != null) { - durationBuilder.setNanosecond(new Counter32(portStats.getDurationNsec())); - } - - final NodeConnectorStatisticsAndPortNumberMap stats = new NodeConnectorStatisticsAndPortNumberMapBuilder() - .setBytes(bytesBuilder.build()) - .setPackets(packetsBuilder.build()) - .setNodeConnectorId(nodeConnectorId) - .setDuration(durationBuilder.build()) - .setCollisionCount(portStats.getCollisions()) - .setKey(new NodeConnectorStatisticsAndPortNumberMapKey(nodeConnectorId)) - .setReceiveCrcError(portStats.getRxCrcErr()).setReceiveDrops(portStats.getRxDropped()) - .setReceiveErrors(portStats.getRxErrors()) - .setReceiveFrameError(portStats.getRxFrameErr()) - .setReceiveOverRunError(portStats.getRxOverErr()) - .setTransmitDrops(portStats.getTxDropped()) - .setTransmitErrors(portStats.getTxErrors()) - .build(); - - nodeConnectorStatisticsAndPortNumberMap.add(stats); - } - } - } - - return new GetNodeConnectorStatisticsOutputBuilder() - .setNodeConnectorStatisticsAndPortNumberMap(nodeConnectorStatisticsAndPortNumberMap) - .build(); - } - - @Override - protected void storeStatistics(GetNodeConnectorStatisticsOutput output) throws Exception { - final InstanceIdentifier nodePath = getDeviceInfo().getNodeInstanceIdentifier(); - - for (final NodeConnectorStatisticsAndPortNumberMap nodeConnectorStatistics : output.getNodeConnectorStatisticsAndPortNumberMap()) { - final InstanceIdentifier nodeConnectorPath = nodePath - .child(NodeConnector.class, new NodeConnectorKey(nodeConnectorStatistics.getNodeConnectorId())) - .augmentation(FlowCapableNodeConnectorStatisticsData.class) - .child(FlowCapableNodeConnectorStatistics.class); - - final FlowCapableNodeConnectorStatistics stats = new FlowCapableNodeConnectorStatisticsBuilder(nodeConnectorStatistics).build(); - getTxFacade().writeToTransactionWithParentsSlow(LogicalDatastoreType.OPERATIONAL, nodeConnectorPath, stats); - } - } -} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/OpendaylightDirectStatisticsServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/OpendaylightDirectStatisticsServiceImpl.java index 3f5af2f8e6..8e2cea384a 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/OpendaylightDirectStatisticsServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/OpendaylightDirectStatisticsServiceImpl.java @@ -8,7 +8,6 @@ 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; @@ -43,61 +42,46 @@ public class OpendaylightDirectStatisticsServiceImpl implements OpendaylightDire } @Override + @SuppressWarnings("unchecked") public Future> getGroupStatistics(GetGroupStatisticsInput input) { - final Optional service = provider.lookup(GroupDirectStatisticsService.class); - - if (!service.isPresent()) { - return missingImplementation(GroupDirectStatisticsService.class); - } - - return service.get().handleAndReply(input); + return provider.lookup(AbstractGroupDirectStatisticsService.class) + .map(service -> service.handleAndReply(input)) + .orElse(missingImplementation(AbstractGroupDirectStatisticsService.class)); } @Override + @SuppressWarnings("unchecked") public Future> getQueueStatistics(GetQueueStatisticsInput input) { - final Optional service = provider.lookup(QueueDirectStatisticsService.class); - - if (!service.isPresent()) { - return missingImplementation(QueueDirectStatisticsService.class); - } - - return service.get().handleAndReply(input); + return provider.lookup(AbstractQueueDirectStatisticsService.class) + .map(service -> service.handleAndReply(input)) + .orElse(missingImplementation(AbstractQueueDirectStatisticsService.class)); } @Override + @SuppressWarnings("unchecked") public Future> getFlowStatistics(GetFlowStatisticsInput input) { - final Optional service = provider.lookup(FlowDirectStatisticsService.class); - - if (!service.isPresent()) { - return missingImplementation(FlowDirectStatisticsService.class); - } - - return service.get().handleAndReply(input); + return provider.lookup(AbstractFlowDirectStatisticsService.class) + .map(service -> service.handleAndReply(input)) + .orElse(missingImplementation(AbstractFlowDirectStatisticsService.class)); } @Override + @SuppressWarnings("unchecked") public Future> getMeterStatistics(GetMeterStatisticsInput input) { - final Optional service = provider.lookup(MeterDirectStatisticsService.class); - - if (!service.isPresent()) { - return missingImplementation(MeterDirectStatisticsService.class); - } - - return service.get().handleAndReply(input); + return provider.lookup(AbstractMeterDirectStatisticsService.class) + .map(service -> service.handleAndReply(input)) + .orElse(missingImplementation(AbstractMeterDirectStatisticsService.class)); } @Override + @SuppressWarnings("unchecked") public Future> getNodeConnectorStatistics(GetNodeConnectorStatisticsInput input) { - final Optional service = provider.lookup(NodeConnectorDirectStatisticsService.class); - - if (!service.isPresent()) { - return missingImplementation(NodeConnectorDirectStatisticsService.class); - } - - return service.get().handleAndReply(input); + return provider.lookup(AbstractPortDirectStatisticsService.class) + .map(service -> service.handleAndReply(input)) + .orElse(missingImplementation(AbstractPortDirectStatisticsService.class)); } - private Future> missingImplementation(Class service) { + private static Future> missingImplementation(Class service) { return RpcResultBuilder.failed().withError( RpcError.ErrorType.APPLICATION, String.format("No implementation found for direct statistics service %s.", service.getCanonicalName())) diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/OpendaylightDirectStatisticsServiceProvider.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/OpendaylightDirectStatisticsServiceProvider.java index daecefb2fa..96b9b03758 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/OpendaylightDirectStatisticsServiceProvider.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/OpendaylightDirectStatisticsServiceProvider.java @@ -25,21 +25,16 @@ public class OpendaylightDirectStatisticsServiceProvider { * @param service the service instance */ public void register(Class type, AbstractDirectStatisticsService service) { - if (services.containsKey(type)) return; - services.put(type, service); } /** * Lookup direct statistics service. * - * @param the type parameter * @param type the service type * @return the service instance */ - public Optional lookup(Class type) { - if (!services.containsKey(type)) return Optional.empty(); - - return Optional.of(type.cast(services.get(type))); + public Optional lookup(Class type) { + return Optional.ofNullable(services.get(type)).map(type::cast); } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/QueueDirectStatisticsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/QueueDirectStatisticsService.java deleted file mode 100644 index 9ebbece586..0000000000 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/QueueDirectStatisticsService.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.openflowplugin.impl.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; -import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; -import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; -import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter64; -import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatisticsInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatisticsOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatisticsOutputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; -import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.MultipartReplyQueue; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStats; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueueCaseBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.queue._case.MultipartRequestQueueBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsData; -import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsDataBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.flow.capable.node.connector.queue.statistics.FlowCapableNodeConnectorQueueStatistics; -import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.flow.capable.node.connector.queue.statistics.FlowCapableNodeConnectorQueueStatisticsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap; -import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMapBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -/** - * The Queue direct statistics service. - */ -public class QueueDirectStatisticsService extends AbstractDirectStatisticsService { - /** - * Instantiates a new Queue direct statistics service. - * @param requestContextStack the request context stack - * @param deviceContext the device context - * @param convertorExecutor - */ - public QueueDirectStatisticsService(RequestContextStack requestContextStack, DeviceContext deviceContext, ConvertorExecutor convertorExecutor) { - super(MultipartType.OFPMPQUEUE, requestContextStack, deviceContext, convertorExecutor); - } - - @Override - protected MultipartRequestBody buildRequestBody(GetQueueStatisticsInput input) { - final MultipartRequestQueueBuilder mprQueueBuilder = new MultipartRequestQueueBuilder(); - - if (input.getQueueId() != null) { - mprQueueBuilder.setQueueId(input.getQueueId().getValue()); - } else { - mprQueueBuilder.setQueueId(OFConstants.OFPQ_ALL); - } - - if (input.getNodeConnectorId() != null) { - mprQueueBuilder.setPortNo(InventoryDataServiceUtil.portNumberfromNodeConnectorId(getOfVersion(), input.getNodeConnectorId())); - } else { - mprQueueBuilder.setPortNo(OFConstants.OFPP_ANY); - } - - return new MultipartRequestQueueCaseBuilder() - .setMultipartRequestQueue(mprQueueBuilder.build()) - .build(); - } - - @Override - protected GetQueueStatisticsOutput buildReply(List input, boolean success) { - final List queueIdAndStatisticsMap = new ArrayList<>(); - - if (success) { - for (final MultipartReply mpReply : input) { - final MultipartReplyQueueCase caseBody = (MultipartReplyQueueCase) mpReply.getMultipartReplyBody(); - final MultipartReplyQueue replyBody = caseBody.getMultipartReplyQueue(); - - for (final QueueStats queueStats : replyBody.getQueueStats()) { - final DurationBuilder durationBuilder = new DurationBuilder() - .setSecond(new Counter32(queueStats.getDurationSec())) - .setNanosecond(new Counter32(queueStats.getDurationNsec())); - - final QueueIdAndStatisticsMapBuilder statsBuilder = new QueueIdAndStatisticsMapBuilder() - .setNodeConnectorId(InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo( - getDatapathId(), queueStats.getPortNo(), getOfVersion())) - .setTransmissionErrors(new Counter64(queueStats.getTxErrors())) - .setTransmittedBytes(new Counter64(queueStats.getTxBytes())) - .setTransmittedPackets(new Counter64(queueStats.getTxPackets())) - .setQueueId(new QueueId(queueStats.getQueueId())) - .setDuration(durationBuilder.build()); - - queueIdAndStatisticsMap.add(statsBuilder.build()); - } - } - } - - return new GetQueueStatisticsOutputBuilder() - .setQueueIdAndStatisticsMap(queueIdAndStatisticsMap) - .build(); - } - - @Override - protected void storeStatistics(GetQueueStatisticsOutput output) throws Exception { - final InstanceIdentifier nodePath = getDeviceInfo().getNodeInstanceIdentifier(); - - for (final QueueIdAndStatisticsMap queueStatistics : output.getQueueIdAndStatisticsMap()) { - if (queueStatistics.getQueueId() != null) { - final QueueKey qKey = new QueueKey(queueStatistics.getQueueId()); - - final FlowCapableNodeConnectorQueueStatistics statChild = - new FlowCapableNodeConnectorQueueStatisticsBuilder(queueStatistics).build(); - - final FlowCapableNodeConnectorQueueStatisticsDataBuilder statBuild = - new FlowCapableNodeConnectorQueueStatisticsDataBuilder() - .setFlowCapableNodeConnectorQueueStatistics(statChild); - - final InstanceIdentifier queueStatisticsPath = nodePath - .child(NodeConnector.class, new NodeConnectorKey(queueStatistics.getNodeConnectorId())) - .augmentation(FlowCapableNodeConnector.class) - .child(Queue.class, qKey); - - final Queue stats = new QueueBuilder() - .setKey(qKey) - .setQueueId(queueStatistics.getQueueId()) - .addAugmentation(FlowCapableNodeConnectorQueueStatisticsData.class, statBuild.build()).build(); - - getTxFacade().writeToTransactionWithParentsSlow(LogicalDatastoreType.OPERATIONAL, queueStatisticsPath, stats); - } - } - } -} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/FlowDirectStatisticsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/FlowDirectStatisticsService.java new file mode 100644 index 0000000000..54e8cc5268 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/FlowDirectStatisticsService.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.extension.api.path.MatchPath; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractFlowDirectStatisticsService; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.FlowStatsResponseConvertorData; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.MultipartReplyFlow; + +public class FlowDirectStatisticsService extends AbstractFlowDirectStatisticsService { + + private final FlowStatsResponseConvertorData data; + + public FlowDirectStatisticsService(final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ConvertorExecutor convertorExecutor, + final MultipartWriterProvider statisticsWriterProvider) { + super(requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider); + data = new FlowStatsResponseConvertorData(getVersion()); + data.setDatapathId(getDatapathId()); + data.setMatchPath(MatchPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_MATCH); + } + + @Override + protected GetFlowStatisticsOutput buildReply(List input, boolean success) { + final List statsList = new ArrayList<>(); + + if (success) { + for (final MultipartReply mpReply : input) { + final MultipartReplyFlowCase caseBody = (MultipartReplyFlowCase) mpReply.getMultipartReplyBody(); + final MultipartReplyFlow replyBody = caseBody.getMultipartReplyFlow(); + final Optional> statsListPart = getConvertorExecutor().convert( + replyBody.getFlowStats(), data); + + if (statsListPart.isPresent()) { + for (final FlowAndStatisticsMapList part : statsListPart.get()) { + final FlowId flowId = new FlowId(generateFlowId(part).getValue()); + statsList.add(new FlowAndStatisticsMapListBuilder(part) + .setKey(new FlowAndStatisticsMapListKey(flowId)) + .setFlowId(flowId) + .build()); + } + } + } + } + + return new GetFlowStatisticsOutputBuilder() + .setFlowAndStatisticsMapList(statsList) + .build(); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/GroupDirectStatisticsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/GroupDirectStatisticsService.java new file mode 100644 index 0000000000..e1aeef6b22 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/GroupDirectStatisticsService.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractGroupDirectStatisticsService; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatisticsOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatisticsOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.MultipartReplyGroup; + +public class GroupDirectStatisticsService extends AbstractGroupDirectStatisticsService { + + private final VersionConvertorData data; + + public GroupDirectStatisticsService(final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ConvertorExecutor convertorExecutor, + final MultipartWriterProvider statisticsWriterProvider) { + super(requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider); + data = new VersionConvertorData(getVersion()); + } + + @Override + protected GetGroupStatisticsOutput buildReply(List input, boolean success) { + final List groupStats = new ArrayList<>(); + + if (success) { + for (final MultipartReply mpReply : input) { + final MultipartReplyGroupCase caseBody = (MultipartReplyGroupCase) mpReply.getMultipartReplyBody(); + final MultipartReplyGroup replyBody = caseBody.getMultipartReplyGroup(); + final Optional> groupStatsList = getConvertorExecutor().convert( + replyBody.getGroupStats(), data); + + groupStatsList.ifPresent(groupStats::addAll); + } + } + + return new GetGroupStatisticsOutputBuilder() + .setGroupStats(groupStats) + .build(); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/MeterDirectStatisticsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/MeterDirectStatisticsService.java new file mode 100644 index 0000000000..6b8c70c237 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/MeterDirectStatisticsService.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractMeterDirectStatisticsService; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatisticsOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatisticsOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.MultipartReplyMeter; + +public class MeterDirectStatisticsService extends AbstractMeterDirectStatisticsService { + + private final VersionConvertorData data; + + public MeterDirectStatisticsService(final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ConvertorExecutor convertorExecutor, + final MultipartWriterProvider statisticsWriterProvider) { + super(requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider); + data = new VersionConvertorData(getVersion()); + } + + @Override + protected GetMeterStatisticsOutput buildReply(List input, boolean success) { + final List meterStats = new ArrayList<>(); + + if (success) { + for (final MultipartReply mpReply : input) { + final MultipartReplyMeterCase caseBody = (MultipartReplyMeterCase) mpReply.getMultipartReplyBody(); + final MultipartReplyMeter replyBody = caseBody.getMultipartReplyMeter(); + final Optional> meterStatsList = getConvertorExecutor().convert(replyBody.getMeterStats(), data); + meterStatsList.ifPresent(meterStats::addAll); + } + } + + return new GetMeterStatisticsOutputBuilder() + .setMeterStats(meterStats) + .build(); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/MultiLayerDirectStatisticsProviderInitializer.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/MultiLayerDirectStatisticsProviderInitializer.java new file mode 100644 index 0000000000..c82643f098 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/MultiLayerDirectStatisticsProviderInitializer.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer; + +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractFlowDirectStatisticsService; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractGroupDirectStatisticsService; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractMeterDirectStatisticsService; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractPortDirectStatisticsService; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractQueueDirectStatisticsService; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.OpendaylightDirectStatisticsServiceProvider; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; + +/** + * Utility class for instantiating #{@link org.opendaylight.openflowplugin.impl.statistics.services.direct.OpendaylightDirectStatisticsServiceProvider} + * with all multi-layer services already in + */ +public class MultiLayerDirectStatisticsProviderInitializer { + + public static OpendaylightDirectStatisticsServiceProvider createProvider( + final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ConvertorExecutor convertorExecutor, + final MultipartWriterProvider statisticsWriterProvider) { + + final OpendaylightDirectStatisticsServiceProvider provider = new OpendaylightDirectStatisticsServiceProvider(); + + provider.register(AbstractFlowDirectStatisticsService.class, new FlowDirectStatisticsService( + requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider)); + provider.register(AbstractGroupDirectStatisticsService.class, new FlowDirectStatisticsService( + requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider)); + provider.register(AbstractMeterDirectStatisticsService.class, new MeterDirectStatisticsService( + requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider)); + provider.register(AbstractPortDirectStatisticsService.class, new PortDirectStatisticsService( + requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider)); + provider.register(AbstractQueueDirectStatisticsService.class, new QueueDirectStatisticsService( + requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider)); + + return provider; + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/PortDirectStatisticsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/PortDirectStatisticsService.java new file mode 100644 index 0000000000..2d447e9918 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/PortDirectStatisticsService.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer; + +import java.util.ArrayList; +import java.util.List; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractPortDirectStatisticsService; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.BytesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.PacketsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.multipart.reply.port.stats.PortStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap; +import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapKey; + +public class PortDirectStatisticsService extends AbstractPortDirectStatisticsService { + + public PortDirectStatisticsService(final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ConvertorExecutor convertorExecutor, + final MultipartWriterProvider statisticsWriterProvider) { + super(requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider); + } + + @Override + protected GetNodeConnectorStatisticsOutput buildReply(List input, boolean success) { + final List nodeConnectorStatisticsAndPortNumberMap = new ArrayList<>(); + + if (success) { + for (final MultipartReply mpReply : input) { + final MultipartReplyPortStatsCase caseBody = (MultipartReplyPortStatsCase) mpReply.getMultipartReplyBody(); + final MultipartReplyPortStats replyBody = caseBody.getMultipartReplyPortStats(); + + for (final PortStats portStats : replyBody.getPortStats()) { + final NodeConnectorId nodeConnectorId = InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo( + getDatapathId(), portStats.getPortNo(), getOfVersion()); + + final BytesBuilder bytesBuilder = new BytesBuilder() + .setReceived(portStats.getRxBytes()) + .setTransmitted(portStats.getTxBytes()); + + final PacketsBuilder packetsBuilder = new PacketsBuilder() + .setReceived(portStats.getRxPackets()) + .setTransmitted(portStats.getTxPackets()); + + final DurationBuilder durationBuilder = new DurationBuilder(); + + if (portStats.getDurationSec() != null) { + durationBuilder.setSecond(new Counter32(portStats.getDurationSec())); + } + + if (portStats.getDurationNsec() != null) { + durationBuilder.setNanosecond(new Counter32(portStats.getDurationNsec())); + } + + final NodeConnectorStatisticsAndPortNumberMap stats = new NodeConnectorStatisticsAndPortNumberMapBuilder() + .setBytes(bytesBuilder.build()) + .setPackets(packetsBuilder.build()) + .setNodeConnectorId(nodeConnectorId) + .setDuration(durationBuilder.build()) + .setCollisionCount(portStats.getCollisions()) + .setKey(new NodeConnectorStatisticsAndPortNumberMapKey(nodeConnectorId)) + .setReceiveCrcError(portStats.getRxCrcErr()).setReceiveDrops(portStats.getRxDropped()) + .setReceiveErrors(portStats.getRxErrors()) + .setReceiveFrameError(portStats.getRxFrameErr()) + .setReceiveOverRunError(portStats.getRxOverErr()) + .setTransmitDrops(portStats.getTxDropped()) + .setTransmitErrors(portStats.getTxErrors()) + .build(); + + nodeConnectorStatisticsAndPortNumberMap.add(stats); + } + } + } + + return new GetNodeConnectorStatisticsOutputBuilder() + .setNodeConnectorStatisticsAndPortNumberMap(nodeConnectorStatisticsAndPortNumberMap) + .build(); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/QueueDirectStatisticsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/QueueDirectStatisticsService.java new file mode 100644 index 0000000000..3fd141f1f4 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/QueueDirectStatisticsService.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer; + +import java.util.ArrayList; +import java.util.List; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractQueueDirectStatisticsService; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter64; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatisticsOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatisticsOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.MultipartReplyQueue; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap; +import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMapBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMapKey; + +public class QueueDirectStatisticsService extends AbstractQueueDirectStatisticsService { + + public QueueDirectStatisticsService(final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ConvertorExecutor convertorExecutor, + final MultipartWriterProvider statisticsWriterProvider) { + super(requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider); + } + + @Override + protected GetQueueStatisticsOutput buildReply(List input, boolean success) { + final List queueIdAndStatisticsMap = new ArrayList<>(); + + if (success) { + for (final MultipartReply mpReply : input) { + final MultipartReplyQueueCase caseBody = (MultipartReplyQueueCase) mpReply.getMultipartReplyBody(); + final MultipartReplyQueue replyBody = caseBody.getMultipartReplyQueue(); + + for (final QueueStats queueStats : replyBody.getQueueStats()) { + final DurationBuilder durationBuilder = new DurationBuilder() + .setSecond(new Counter32(queueStats.getDurationSec())) + .setNanosecond(new Counter32(queueStats.getDurationNsec())); + + final QueueId queueId = new QueueId(queueStats.getQueueId()); + final NodeConnectorId nodeConnectorId = InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo( + getDatapathId(), queueStats.getPortNo(), getOfVersion()); + + final QueueIdAndStatisticsMapBuilder statsBuilder = new QueueIdAndStatisticsMapBuilder() + .setKey(new QueueIdAndStatisticsMapKey(nodeConnectorId, queueId)) + .setNodeConnectorId(nodeConnectorId) + .setTransmissionErrors(new Counter64(queueStats.getTxErrors())) + .setTransmittedBytes(new Counter64(queueStats.getTxBytes())) + .setTransmittedPackets(new Counter64(queueStats.getTxPackets())) + .setQueueId(queueId) + .setDuration(durationBuilder.build()); + + queueIdAndStatisticsMap.add(statsBuilder.build()); + } + } + } + + return new GetQueueStatisticsOutputBuilder() + .setQueueIdAndStatisticsMap(queueIdAndStatisticsMap) + .build(); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/singlelayer/FlowDirectStatisticsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/singlelayer/FlowDirectStatisticsService.java new file mode 100644 index 0000000000..e2e47bed5b --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/singlelayer/FlowDirectStatisticsService.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.statistics.services.direct.singlelayer; + +import java.util.List; +import java.util.stream.Collectors; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractFlowDirectStatisticsService; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply; + +public class FlowDirectStatisticsService extends AbstractFlowDirectStatisticsService { + + public FlowDirectStatisticsService(final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ConvertorExecutor convertorExecutor, + final MultipartWriterProvider statisticsWriterProvider) { + super(requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider); } + + @Override + protected GetFlowStatisticsOutput buildReply(List input, boolean success) { + return new GetFlowStatisticsOutputBuilder() + .setFlowAndStatisticsMapList(input + .stream() + .flatMap(multipartReply -> MultipartReplyFlowStats.class + .cast(multipartReply.getMultipartReplyBody()) + .getFlowAndStatisticsMapList() + .stream()) + .map(flowAndStatisticsMapList -> { + final FlowId flowId = new FlowId(generateFlowId(flowAndStatisticsMapList)); + return new FlowAndStatisticsMapListBuilder(flowAndStatisticsMapList) + .setKey(new FlowAndStatisticsMapListKey(flowId)) + .setFlowId(flowId) + .build(); + }) + .collect(Collectors.toList())) + .build(); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/singlelayer/GroupDirectStatisticsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/singlelayer/GroupDirectStatisticsService.java new file mode 100644 index 0000000000..ec0a90662b --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/singlelayer/GroupDirectStatisticsService.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.statistics.services.direct.singlelayer; + +import java.util.List; +import java.util.stream.Collectors; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractGroupDirectStatisticsService; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatisticsOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatisticsOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyGroupStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply; + +public class GroupDirectStatisticsService extends AbstractGroupDirectStatisticsService { + + public GroupDirectStatisticsService(final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ConvertorExecutor convertorExecutor, + final MultipartWriterProvider statisticsWriterProvider) { + super(requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider); + } + + @Override + protected GetGroupStatisticsOutput buildReply(List input, boolean success) { + return new GetGroupStatisticsOutputBuilder() + .setGroupStats(input + .stream() + .flatMap(multipartReply -> MultipartReplyGroupStats.class + .cast(multipartReply.getMultipartReplyBody()) + .getGroupStats() + .stream()) + .collect(Collectors.toList())) + .build(); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/singlelayer/MeterDirectStatisticsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/singlelayer/MeterDirectStatisticsService.java new file mode 100644 index 0000000000..ba84ceaf10 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/singlelayer/MeterDirectStatisticsService.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.statistics.services.direct.singlelayer; + +import java.util.List; +import java.util.stream.Collectors; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractMeterDirectStatisticsService; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatisticsOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatisticsOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyMeterStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply; + +public class MeterDirectStatisticsService extends AbstractMeterDirectStatisticsService { + + public MeterDirectStatisticsService(final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ConvertorExecutor convertorExecutor, + final MultipartWriterProvider statisticsWriterProvider) { + super(requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider); + } + + @Override + protected GetMeterStatisticsOutput buildReply(List input, boolean success) { + return new GetMeterStatisticsOutputBuilder() + .setMeterStats(input + .stream() + .flatMap(multipartReply -> MultipartReplyMeterStats.class + .cast(multipartReply.getMultipartReplyBody()) + .getMeterStats() + .stream()) + .collect(Collectors.toList())) + .build(); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/singlelayer/PortDirectStatisticsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/singlelayer/PortDirectStatisticsService.java new file mode 100644 index 0000000000..a53a2ffbe8 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/singlelayer/PortDirectStatisticsService.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.statistics.services.direct.singlelayer; + +import java.util.List; +import java.util.stream.Collectors; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractPortDirectStatisticsService; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.multipart.reply.multipart.reply.body.MultipartReplyPortStats; + +public class PortDirectStatisticsService extends AbstractPortDirectStatisticsService { + + public PortDirectStatisticsService(final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ConvertorExecutor convertorExecutor, + final MultipartWriterProvider statisticsWriterProvider) { + super(requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider); + } + + @Override + protected GetNodeConnectorStatisticsOutput buildReply(List input, boolean success) { + return new GetNodeConnectorStatisticsOutputBuilder() + .setNodeConnectorStatisticsAndPortNumberMap(input + .stream() + .flatMap(multipartReply -> MultipartReplyPortStats.class + .cast(multipartReply.getMultipartReplyBody()) + .getNodeConnectorStatisticsAndPortNumberMap() + .stream()) + .collect(Collectors.toList())) + .build(); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/singlelayer/QueueDirectStatisticsService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/singlelayer/QueueDirectStatisticsService.java new file mode 100644 index 0000000000..ed6438f39b --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/singlelayer/QueueDirectStatisticsService.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.statistics.services.direct.singlelayer; + +import java.util.List; +import java.util.stream.Collectors; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractQueueDirectStatisticsService; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatisticsOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatisticsOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.multipart.reply.multipart.reply.body.MultipartReplyQueueStats; + +public class QueueDirectStatisticsService extends AbstractQueueDirectStatisticsService { + + public QueueDirectStatisticsService(final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ConvertorExecutor convertorExecutor, + final MultipartWriterProvider statisticsWriterProvider) { + super(requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider); + } + + @Override + protected GetQueueStatisticsOutput buildReply(List input, boolean success) { + return new GetQueueStatisticsOutputBuilder() + .setQueueIdAndStatisticsMap(input + .stream() + .flatMap(multipartReply -> MultipartReplyQueueStats.class + .cast(multipartReply.getMultipartReplyBody()) + .getQueueIdAndStatisticsMap() + .stream()) + .collect(Collectors.toList())) + .build(); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/singlelayer/SingleLayerDirectStatisticsProviderInitializer.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/singlelayer/SingleLayerDirectStatisticsProviderInitializer.java new file mode 100644 index 0000000000..9749940679 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/singlelayer/SingleLayerDirectStatisticsProviderInitializer.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowplugin.impl.statistics.services.direct.singlelayer; + +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractFlowDirectStatisticsService; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractGroupDirectStatisticsService; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractMeterDirectStatisticsService; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractPortDirectStatisticsService; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractQueueDirectStatisticsService; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.OpendaylightDirectStatisticsServiceProvider; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; + +/** + * Utility class for instantiating #{@link org.opendaylight.openflowplugin.impl.statistics.services.direct.OpendaylightDirectStatisticsServiceProvider} + * with all multi-layer services already in + */ +public class SingleLayerDirectStatisticsProviderInitializer { + + public static OpendaylightDirectStatisticsServiceProvider createProvider( + final RequestContextStack requestContextStack, + final DeviceContext deviceContext, + final ConvertorExecutor convertorExecutor, + final MultipartWriterProvider statisticsWriterProvider) { + + final OpendaylightDirectStatisticsServiceProvider provider = new OpendaylightDirectStatisticsServiceProvider(); + + provider.register(AbstractFlowDirectStatisticsService.class, new FlowDirectStatisticsService( + requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider)); + provider.register(AbstractGroupDirectStatisticsService.class, new FlowDirectStatisticsService( + requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider)); + provider.register(AbstractMeterDirectStatisticsService.class, new MeterDirectStatisticsService( + requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider)); + provider.register(AbstractPortDirectStatisticsService.class, new PortDirectStatisticsService( + requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider)); + provider.register(AbstractQueueDirectStatisticsService.class, new QueueDirectStatisticsService( + requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider)); + + return provider; + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/DeviceInitializationUtil.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/DeviceInitializationUtil.java new file mode 100644 index 0000000000..c5f2f44722 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/DeviceInitializationUtil.java @@ -0,0 +1,105 @@ +/* + * 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.impl.util; + +import java.net.InetSocketAddress; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo; +import org.opendaylight.openflowplugin.api.openflow.device.TxFacade; +import org.opendaylight.openflowplugin.openflow.md.core.sal.SwitchFeaturesUtil; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.flow.node.SwitchFeatures; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsDataBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutputBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DeviceInitializationUtil { + + private static final Logger LOG = LoggerFactory.getLogger(DeviceInitializationUtil.class); + + private DeviceInitializationUtil() { + // Hiding implicit constructor + } + + /** + * Create specified number of empty tables on device + * FIXME: remove after ovs table features fix + * @param txFacade transaction facade + * @param deviceInfo device info + * @param nrOfTables number of tables + */ + public static void makeEmptyTables(final TxFacade txFacade, final DeviceInfo deviceInfo, final Short nrOfTables) { + if (LOG.isDebugEnabled()) { + LOG.debug("About to create {} empty tables for node {}.", nrOfTables, deviceInfo.getLOGValue()); + } + + for (int i = 0; i < nrOfTables; i++) { + try { + txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, + deviceInfo + .getNodeInstanceIdentifier() + .augmentation(FlowCapableNode.class) + .child(Table.class, new TableKey((short) i)), + new TableBuilder() + .setId((short) i) + .addAugmentation( + FlowTableStatisticsData.class, + new FlowTableStatisticsDataBuilder().build()) + .build()); + } catch (final Exception e) { + LOG.debug("makeEmptyTables: Failed to write node {} to DS ", deviceInfo.getLOGValue(), e); + } + } + } + + /** + * Retrieve ip address from connection + * @param connectionContext connection context + * @param instanceIdentifier instance identifier + * @return ip adress + */ + public static IpAddress getIpAddress(final ConnectionContext connectionContext, + final InstanceIdentifier instanceIdentifier) { + final InetSocketAddress remoteAddress = connectionContext + .getConnectionAdapter() + .getRemoteAddress(); + + if (remoteAddress == null) { + LOG.warn("IP address of the node {} cannot be obtained. No connection with switch.", instanceIdentifier); + return null; + } + + LOG.info("IP address of the node {} is: {}", instanceIdentifier, remoteAddress); + return IetfInetUtil.INSTANCE.ipAddressFor(remoteAddress.getAddress()); + } + + /** + * Retrieve switch features from connection + * @param connectionContext connection context + * @return switch features + */ + public static SwitchFeatures getSwitchFeatures(final ConnectionContext connectionContext) { + return SwitchFeaturesUtil + .getInstance() + .buildSwitchFeatures(new GetFeaturesOutputBuilder(connectionContext + .getFeatures()) + .build()); + } + +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/DeviceInitializationUtils.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/DeviceInitializationUtils.java deleted file mode 100644 index 0bdbe08a9c..0000000000 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/DeviceInitializationUtils.java +++ /dev/null @@ -1,572 +0,0 @@ -/* - * 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.impl.util; - -import com.google.common.base.Preconditions; -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 com.google.common.util.concurrent.SettableFuture; -import java.math.BigInteger; -import java.net.InetSocketAddress; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.ExecutionException; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueue; -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; -import org.opendaylight.openflowplugin.api.openflow.device.Xid; -import org.opendaylight.openflowplugin.api.openflow.device.handlers.MultiMsgCollector; -import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey; -import org.opendaylight.openflowplugin.impl.common.MultipartRequestInputFactory; -import org.opendaylight.openflowplugin.impl.common.NodeStaticReplyTranslatorUtil; -import org.opendaylight.openflowplugin.impl.rpc.AbstractRequestContext; -import org.opendaylight.openflowplugin.openflow.md.core.sal.SwitchFeaturesUtil; -import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsDataBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeatures; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeatures; -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.CapabilitiesV10; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutputBuilder; -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.PortGrouping; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.MultipartReplyBody; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupFeaturesCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortDescCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableFeaturesCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.desc._case.MultipartReplyDesc; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.features._case.MultipartReplyGroupFeatures; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.features._case.MultipartReplyMeterFeatures; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc._case.MultipartReplyPortDesc; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.MultipartReplyTableFeatures; -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.table.types.rev131026.table.features.TableFeatures; -import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeaturesKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; -import org.opendaylight.yangtools.yang.common.RpcError; -import org.opendaylight.yangtools.yang.common.RpcResult; -import org.opendaylight.yangtools.yang.common.RpcResultBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DeviceInitializationUtils { - - private static final Logger LOG = LoggerFactory.getLogger(DeviceInitializationUtils.class); - - private DeviceInitializationUtils() { - // Hiding implicit constructor - } - - /** - * InitializationNodeInformation is good to call only for MASTER otherwise we will have not empty transaction - * for every Cluster Node (SLAVE too) and we will get race-condition by closing Connection. - * - * @param deviceContext - * @param switchFeaturesMandatory - * @param convertorExecutor - */ - public static void initializeNodeInformation(final DeviceContext deviceContext, final boolean switchFeaturesMandatory, final ConvertorExecutor convertorExecutor) throws ExecutionException, InterruptedException { - 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 = deviceInfo.getVersion(); - LOG.trace("initalizeNodeInformation for node {}", deviceInfo.getNodeId()); - final SettableFuture returnFuture = SettableFuture.create(); - addNodeToOperDS(deviceContext, returnFuture); - final ListenableFuture>>> deviceFeaturesFuture; - if (OFConstants.OFP_VERSION_1_0 == version) { - final CapabilitiesV10 capabilitiesV10 = connectionContext.getFeatures().getCapabilitiesV10(); - - DeviceStateUtil.setDeviceStateBasedOnV10Capabilities(deviceState, capabilitiesV10); - - deviceFeaturesFuture = createDeviceFeaturesForOF10(deviceContext); - // create empty tables after device description is processed - chainTableTrunkWriteOF10(deviceContext, deviceFeaturesFuture); - - final short ofVersion = deviceInfo.getVersion(); - final TranslatorKey translatorKey = new TranslatorKey(ofVersion, PortGrouping.class.getName()); - final MessageTranslator translator = deviceContext.oook() - .lookupTranslator(translatorKey); - final BigInteger dataPathId = deviceContext.getDeviceInfo().getDatapathId(); - - for (final PortGrouping port : connectionContext.getFeatures().getPhyPort()) { - final FlowCapableNodeConnector fcNodeConnector = translator.translate(port, deviceContext.getDeviceInfo(), null); - - final NodeConnectorId nodeConnectorId = NodeStaticReplyTranslatorUtil.nodeConnectorId( - dataPathId.toString(), port.getPortNo(), ofVersion); - final NodeConnectorBuilder ncBuilder = new NodeConnectorBuilder().setId(nodeConnectorId); - ncBuilder.addAugmentation(FlowCapableNodeConnector.class, fcNodeConnector); - ncBuilder.addAugmentation(FlowCapableNodeConnectorStatisticsData.class, - new FlowCapableNodeConnectorStatisticsDataBuilder().build()); - final NodeConnector connector = ncBuilder.build(); - final InstanceIdentifier connectorII = deviceInfo.getNodeInstanceIdentifier().child( - NodeConnector.class, connector.getKey()); - try { - deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, connectorII, connector); - } catch (final Exception e) { - LOG.debug("initializeNodeInformation: 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 {}", deviceInfo.getNodeId()); - DeviceStateUtil.setDeviceStateBasedOnV13Capabilities(deviceState, capabilities); - createDeviceFeaturesForOF13(deviceContext, switchFeaturesMandatory, convertorExecutor).get(); - } else { - throw new ExecutionException(new ConnectionException("Unsupported version " + version)); - } - - } - - private static void addNodeToOperDS(final DeviceContext deviceContext, final SettableFuture future) { - Preconditions.checkArgument(deviceContext != null); - final NodeBuilder nodeBuilder = new NodeBuilder().setId(deviceContext.getDeviceInfo().getNodeId()).setNodeConnector( - Collections.emptyList()); - try { - deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), - nodeBuilder.build()); - } catch (final Exception e) { - LOG.warn("addNodeToOperDS: Failed to write node {} to DS ", deviceContext.getDeviceInfo().getNodeId(), e); - future.cancel(true); - } - } - - private static ListenableFuture>>> createDeviceFeaturesForOF10( - final DeviceContext deviceContext) { - final ListenableFuture>> replyDesc = getNodeStaticInfo(MultipartType.OFPMPDESC, - deviceContext, deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), deviceContext.getDeviceInfo().getVersion()); - - return Futures.allAsList(Arrays.asList(replyDesc)); - } - - private static ListenableFuture>>> createDeviceFeaturesForOF13( - final DeviceContext deviceContext, final boolean switchFeaturesMandatory, final ConvertorExecutor convertorExecutor) { - - final ListenableFuture>> replyDesc = getNodeStaticInfo(MultipartType.OFPMPDESC, - 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, - new AsyncFunction>, List>>>() { - @Override - public ListenableFuture>>> apply( - final RpcResult> rpcResult) throws Exception { - - translateAndWriteReply(MultipartType.OFPMPDESC, deviceContext, - deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), rpcResult.getResult(), convertorExecutor); - - final ListenableFuture>> replyMeterFeature = getNodeStaticInfo( - MultipartType.OFPMPMETERFEATURES, deviceContext, - deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), deviceContext.getDeviceInfo().getVersion()); - - createSuccessProcessingCallback(MultipartType.OFPMPMETERFEATURES, deviceContext, - deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), replyMeterFeature, convertorExecutor); - - final ListenableFuture>> replyGroupFeatures = getNodeStaticInfo( - MultipartType.OFPMPGROUPFEATURES, deviceContext, - deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), deviceContext.getDeviceInfo().getVersion()); - createSuccessProcessingCallback(MultipartType.OFPMPGROUPFEATURES, deviceContext, - deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), replyGroupFeatures, convertorExecutor); - - final ListenableFuture>> replyTableFeatures; - - if (deviceContext.isSkipTableFeatures()) { - replyTableFeatures = RpcResultBuilder.>success().buildFuture(); - } else { - replyTableFeatures = getNodeStaticInfo( - MultipartType.OFPMPTABLEFEATURES, deviceContext, - deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), deviceContext.getDeviceInfo().getVersion()); - } - createSuccessProcessingCallback(MultipartType.OFPMPTABLEFEATURES, deviceContext, - deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), replyTableFeatures, convertorExecutor); - - final ListenableFuture>> replyPortDescription = getNodeStaticInfo( - MultipartType.OFPMPPORTDESC, deviceContext, deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), - deviceContext.getDeviceInfo().getVersion()); - createSuccessProcessingCallback(MultipartType.OFPMPPORTDESC, deviceContext, - deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), replyPortDescription, convertorExecutor); - if (switchFeaturesMandatory) { - return Futures.allAsList(Arrays.asList(replyMeterFeature, replyGroupFeatures, - replyTableFeatures, replyPortDescription)); - } else { - return Futures.successfulAsList(Arrays.asList(replyMeterFeature, replyGroupFeatures, - replyTableFeatures, replyPortDescription)); - } - } - }); - - } - - static void translateAndWriteReply(final MultipartType type, final DeviceContext dContext, - final InstanceIdentifier nodeII, final Collection result, - final ConvertorExecutor convertorExecutor) { - if (Objects.nonNull(result)) { - try { - result.stream() - .map(MultipartReply::getMultipartReplyBody) - .forEach(multipartReplyBody -> { - if (!(writeDesc(type, multipartReplyBody, dContext, nodeII) - || writeTableFeatures(type, multipartReplyBody, dContext, nodeII, convertorExecutor) - || writeMeterFeatures(type, multipartReplyBody, dContext, nodeII) - || writeGroupFeatures(type, multipartReplyBody, dContext, nodeII) - || writePortDesc(type, multipartReplyBody, dContext, nodeII))) { - throw new IllegalArgumentException("Unexpected MultipartType " + type); - } - }); - } catch (final Exception e) { - LOG.debug("translateAndWriteReply: Failed to write node {} to DS ", dContext.getDeviceInfo().getNodeId().toString(), e); - } - } else { - LOG.debug("translateAndWriteReply: Failed to write node {} to DS because we failed to gather device" + - "info.", - dContext.getDeviceInfo().getNodeId().toString()); - } - } - - private static boolean writeDesc(final MultipartType type, - final MultipartReplyBody body, - final DeviceContext dContext, - final InstanceIdentifier nodeII) { - if (!MultipartType.OFPMPDESC.equals(type)) { - return false; - } - - Preconditions.checkArgument(body instanceof MultipartReplyDescCase); - final MultipartReplyDesc replyDesc = ((MultipartReplyDescCase) body).getMultipartReplyDesc(); - final FlowCapableNode fcNode = NodeStaticReplyTranslatorUtil - .nodeDescTranslator(replyDesc, getIpAddressOf(dContext)) - .setSwitchFeatures(SwitchFeaturesUtil.getInstance().buildSwitchFeatures( - new GetFeaturesOutputBuilder(dContext.getPrimaryConnectionContext().getFeatures()).build())) - .build(); - - final InstanceIdentifier fNodeII = nodeII.augmentation(FlowCapableNode.class); - dContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, fNodeII, fcNode); - return true; - } - - private static boolean writeTableFeatures(final MultipartType type, - final MultipartReplyBody body, - final DeviceContext dContext, - final InstanceIdentifier nodeII, - final ConvertorExecutor convertorExecutor) { - if (!MultipartType.OFPMPTABLEFEATURES.equals(type)) { - return false; - } - - Preconditions.checkArgument(body instanceof MultipartReplyTableFeaturesCase); - final MultipartReplyTableFeatures tableFeaturesMP = ((MultipartReplyTableFeaturesCase) body) - .getMultipartReplyTableFeatures(); - final List tableFeatures = NodeStaticReplyTranslatorUtil - .nodeTableFeatureTranslator(tableFeaturesMP, dContext.getDeviceInfo().getVersion(), convertorExecutor); - for (final TableFeatures tableFeature : tableFeatures) { - final Short tableId = tableFeature.getTableId(); - final KeyedInstanceIdentifier tableFeaturesII = - nodeII.augmentation(FlowCapableNode.class) - .child(TableFeatures.class, new TableFeaturesKey(tableId)); - dContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, tableFeaturesII, tableFeature); - - // write parent for table statistics - final KeyedInstanceIdentifier tableII = - nodeII.augmentation(FlowCapableNode.class) - .child(Table.class, new TableKey(tableId)); - final TableBuilder tableBld = new TableBuilder().setId(tableId) - .addAugmentation(FlowTableStatisticsData.class, - new FlowTableStatisticsDataBuilder().build()); - - dContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, tableII, tableBld.build()); - } - - return true; - } - - private static boolean writeMeterFeatures(final MultipartType type, - final MultipartReplyBody body, - final DeviceContext dContext, - final InstanceIdentifier nodeII) { - if (!MultipartType.OFPMPMETERFEATURES.equals(type)) { - return false; - } - - Preconditions.checkArgument(body instanceof MultipartReplyMeterFeaturesCase); - final MultipartReplyMeterFeatures meterFeatures = ((MultipartReplyMeterFeaturesCase) body) - .getMultipartReplyMeterFeatures(); - final NodeMeterFeatures mFeature = NodeStaticReplyTranslatorUtil - .nodeMeterFeatureTranslator(meterFeatures); - final InstanceIdentifier mFeatureII = nodeII - .augmentation(NodeMeterFeatures.class); - dContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, mFeatureII, mFeature); - if (0L < mFeature.getMeterFeatures().getMaxMeter().getValue()) { - dContext.getDeviceState().setMeterAvailable(true); - } - - return true; - } - - private static boolean writeGroupFeatures(final MultipartType type, - final MultipartReplyBody body, - final DeviceContext dContext, - final InstanceIdentifier nodeII) { - if (!MultipartType.OFPMPGROUPFEATURES.equals(type)) { - return false; - } - - Preconditions.checkArgument(body instanceof MultipartReplyGroupFeaturesCase); - final MultipartReplyGroupFeatures groupFeatures = ((MultipartReplyGroupFeaturesCase) body) - .getMultipartReplyGroupFeatures(); - final NodeGroupFeatures gFeature = NodeStaticReplyTranslatorUtil - .nodeGroupFeatureTranslator(groupFeatures); - final InstanceIdentifier gFeatureII = nodeII - .augmentation(NodeGroupFeatures.class); - dContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, gFeatureII, gFeature); - - return true; - } - - private static boolean writePortDesc(final MultipartType type, - final MultipartReplyBody body, - final DeviceContext dContext, - final InstanceIdentifier nodeII) { - if (!MultipartType.OFPMPPORTDESC.equals(type)) { - return false; - } - - Preconditions.checkArgument(body instanceof MultipartReplyPortDescCase); - final MultipartReplyPortDesc portDesc = ((MultipartReplyPortDescCase) body) - .getMultipartReplyPortDesc(); - for (final PortGrouping port : portDesc.getPorts()) { - final short ofVersion = dContext.getDeviceInfo().getVersion(); - final TranslatorKey translatorKey = new TranslatorKey(ofVersion, PortGrouping.class.getName()); - final MessageTranslator translator = dContext.oook() - .lookupTranslator(translatorKey); - final FlowCapableNodeConnector fcNodeConnector = translator.translate(port, dContext.getDeviceInfo(), null); - - final BigInteger dataPathId = dContext.getPrimaryConnectionContext().getFeatures() - .getDatapathId(); - final NodeConnectorId nodeConnectorId = NodeStaticReplyTranslatorUtil.nodeConnectorId( - dataPathId.toString(), port.getPortNo(), ofVersion); - final NodeConnectorBuilder ncBuilder = new NodeConnectorBuilder().setId(nodeConnectorId); - ncBuilder.addAugmentation(FlowCapableNodeConnector.class, fcNodeConnector); - - ncBuilder.addAugmentation(FlowCapableNodeConnectorStatisticsData.class, - new FlowCapableNodeConnectorStatisticsDataBuilder().build()); - final NodeConnector connector = ncBuilder.build(); - - final InstanceIdentifier connectorII = nodeII.child(NodeConnector.class, - connector.getKey()); - dContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, connectorII, connector); - } - - return true; - } - - private static void createEmptyFlowCapableNodeInDs(final DeviceContext deviceContext) { - final FlowCapableNodeBuilder flowCapableNodeBuilder = new FlowCapableNodeBuilder(); - final InstanceIdentifier fNodeII = deviceContext.getDeviceInfo().getNodeInstanceIdentifier() - .augmentation(FlowCapableNode.class); - try { - deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, fNodeII, flowCapableNodeBuilder.build()); - } catch (final Exception e) { - LOG.debug("createEmptyFlowCapableNodeInDs: Failed to write node {} to DS ", deviceContext.getDeviceInfo().getNodeId().toString(), e); - } - } - - private static IpAddress getIpAddressOf(final DeviceContext deviceContext) { - - final InetSocketAddress remoteAddress = deviceContext.getPrimaryConnectionContext().getConnectionAdapter() - .getRemoteAddress(); - - if (remoteAddress == null) { - LOG.warn("IP address of the node {} cannot be obtained. No connection with switch.", deviceContext - .getDeviceInfo().getNodeId()); - return null; - } - LOG.info("IP address of switch is: {}", remoteAddress); - - return IetfInetUtil.INSTANCE.ipAddressFor(remoteAddress.getAddress()); - } - - // FIXME : remove after ovs tableFeatures fix - private static void makeEmptyTables(final DeviceContext dContext, final InstanceIdentifier nodeII, - final Short nrOfTables) { - if (LOG.isDebugEnabled()) { - LOG.debug("About to create {} empty tables.", nrOfTables); - } - for (int i = 0; i < nrOfTables; i++) { - final short tId = (short) i; - final InstanceIdentifier
tableII = nodeII.augmentation(FlowCapableNode.class).child(Table.class, - new TableKey(tId)); - final TableBuilder tableBuilder = new TableBuilder().setId(tId).addAugmentation( - FlowTableStatisticsData.class, new FlowTableStatisticsDataBuilder().build()); - - try { - dContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, tableII, tableBuilder.build()); - } catch (final Exception e) { - LOG.debug("makeEmptyTables: Failed to write node {} to DS ", dContext.getDeviceInfo().getNodeId().toString(), e); - } - - } - } - - static void createSuccessProcessingCallback(final MultipartType type, final DeviceContext deviceContext, - final InstanceIdentifier nodeII, - final ListenableFuture>> requestContextFuture, - final ConvertorExecutor convertorExecutor) { - Futures.addCallback(requestContextFuture, new FutureCallback>>() { - @Override - public void onSuccess(final RpcResult> rpcResult) { - final List result = rpcResult.getResult(); - if (result != null) { - LOG.info("Static node {} info: {} collected", deviceContext.getDeviceInfo().getNodeId(), type); - translateAndWriteReply(type, deviceContext, nodeII, result, convertorExecutor); - } else { - for (RpcError rpcError : rpcResult.getErrors()) { - LOG.info("Failed to retrieve static node {} info: {}", type, rpcError.getMessage()); - if (LOG.isTraceEnabled() && Objects.nonNull(rpcError.getCause())) { - LOG.trace("Detailed error:", rpcError.getCause()); - } - } - if (MultipartType.OFPMPTABLEFEATURES.equals(type)) { - makeEmptyTables(deviceContext, nodeII, deviceContext.getPrimaryConnectionContext() - .getFeatures().getTables()); - } - } - } - - @Override - public void onFailure(final Throwable throwable) { - LOG.info("Request of type {} for static info of node {} failed.", type, nodeII); - } - }); - } - - private static ListenableFuture>> getNodeStaticInfo(final MultipartType type, - final DeviceContext deviceContext, - final InstanceIdentifier nodeII, - final short version) { - - final OutboundQueue queue = deviceContext.getPrimaryConnectionContext().getOutboundQueueProvider(); - - final Long reserved = deviceContext.getDeviceInfo().reserveXidForDeviceMessage(); - final RequestContext> requestContext = new AbstractRequestContext>( - reserved) { - @Override - public void close() { - //NOOP - } - }; - - final Xid xid = requestContext.getXid(); - - if (Objects.isNull(xid)) { - LOG.debug("Xid is not present, so cancelling node static info gathering."); - return Futures.immediateCancelledFuture(); - } - - LOG.trace("Hooking xid {} to device context - precaution.", reserved); - - final MultiMsgCollector multiMsgCollector = deviceContext.getMultiMsgCollector(requestContext); - queue.commitEntry(xid.getValue(), - MultipartRequestInputFactory.makeMultipartRequestInput(xid.getValue(), version, type), - new FutureCallback() { - @Override - public void onSuccess(final OfHeader ofHeader) { - if (ofHeader instanceof MultipartReply) { - final MultipartReply multipartReply = (MultipartReply) ofHeader; - multiMsgCollector.addMultipartMsg(multipartReply); - } else if (null != ofHeader) { - LOG.info("Unexpected response type received {}.", ofHeader.getClass()); - } else { - multiMsgCollector.endCollecting(); - LOG.info("Response received is null."); - } - } - - @Override - public void onFailure(final Throwable t) { - LOG.info("Fail response from OutboundQueue for multipart type {}.", type); - final RpcResult> rpcResult = RpcResultBuilder - .>failed().build(); - requestContext.setResult(rpcResult); - if (MultipartType.OFPMPTABLEFEATURES.equals(type)) { - makeEmptyTables(deviceContext, nodeII, deviceContext.getPrimaryConnectionContext() - .getFeatures().getTables()); - } - requestContext.close(); - } - }); - - return requestContext.getFuture(); - } - - static void chainTableTrunkWriteOF10(final DeviceContext deviceContext, - final ListenableFuture>>> deviceFeaturesFuture) { - - try { - if (LOG.isTraceEnabled()) { - LOG.trace("Waiting for protocol version 1.0"); - } - List>> results = deviceFeaturesFuture.get(); - boolean allSucceeded = true; - for (final RpcResult> rpcResult : results) { - allSucceeded &= rpcResult.isSuccessful(); - } - if (allSucceeded) { - if (LOG.isDebugEnabled()) { - LOG.debug("Creating empty flow capable node: {}", deviceContext.getDeviceInfo().getLOGValue()); - } - createEmptyFlowCapableNodeInDs(deviceContext); - if (LOG.isDebugEnabled()) { - LOG.debug("Creating empty tables for {}", deviceContext.getDeviceInfo().getLOGValue()); - } - makeEmptyTables(deviceContext, deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), - deviceContext.getPrimaryConnectionContext().getFeatures().getTables()); - } - } catch (InterruptedException | ExecutionException e) { - LOG.warn("Error occurred in preparation node {} for protocol 1.0", deviceContext.getDeviceInfo().getLOGValue()); - if (LOG.isTraceEnabled()) { - LOG.trace("Error for node {} : ", deviceContext.getDeviceInfo().getLOGValue(), e); - } - } - } -} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MdSalRegistrationUtils.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MdSalRegistrationUtils.java index 781776ad70..aa11506cb3 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MdSalRegistrationUtils.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MdSalRegistrationUtils.java @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the @@ -16,21 +16,23 @@ 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; -import org.opendaylight.openflowplugin.impl.services.SalEchoServiceImpl; -import org.opendaylight.openflowplugin.impl.services.SalExperimenterMessageServiceImpl; -import org.opendaylight.openflowplugin.impl.services.SalExperimenterMpMessageServiceImpl; -import org.opendaylight.openflowplugin.impl.services.SalFlatBatchServiceImpl; -import org.opendaylight.openflowplugin.impl.services.SalFlowServiceImpl; -import org.opendaylight.openflowplugin.impl.services.SalFlowsBatchServiceImpl; -import org.opendaylight.openflowplugin.impl.services.SalGroupServiceImpl; -import org.opendaylight.openflowplugin.impl.services.SalGroupsBatchServiceImpl; -import org.opendaylight.openflowplugin.impl.services.SalMeterServiceImpl; -import org.opendaylight.openflowplugin.impl.services.SalMetersBatchServiceImpl; -import org.opendaylight.openflowplugin.impl.services.SalPortServiceImpl; -import org.opendaylight.openflowplugin.impl.services.SalTableServiceImpl; +import org.opendaylight.openflowplugin.impl.services.sal.FlowCapableTransactionServiceImpl; +import org.opendaylight.openflowplugin.impl.services.sal.NodeConfigServiceImpl; +import org.opendaylight.openflowplugin.impl.services.sal.PacketProcessingServiceImpl; +import org.opendaylight.openflowplugin.impl.services.sal.SalEchoServiceImpl; +import org.opendaylight.openflowplugin.impl.services.sal.SalExperimenterMessageServiceImpl; +import org.opendaylight.openflowplugin.impl.services.sal.SalExperimenterMpMessageServiceImpl; +import org.opendaylight.openflowplugin.impl.services.sal.SalFlatBatchServiceImpl; +import org.opendaylight.openflowplugin.impl.services.sal.SalFlowServiceImpl; +import org.opendaylight.openflowplugin.impl.services.sal.SalFlowsBatchServiceImpl; +import org.opendaylight.openflowplugin.impl.services.sal.SalGroupServiceImpl; +import org.opendaylight.openflowplugin.impl.services.sal.SalGroupsBatchServiceImpl; +import org.opendaylight.openflowplugin.impl.services.sal.SalMeterServiceImpl; +import org.opendaylight.openflowplugin.impl.services.sal.SalMetersBatchServiceImpl; +import org.opendaylight.openflowplugin.impl.services.sal.SalPortServiceImpl; +import org.opendaylight.openflowplugin.impl.services.sal.SalTableServiceImpl; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProviderFactory; import org.opendaylight.openflowplugin.impl.statistics.services.OpendaylightFlowStatisticsServiceImpl; import org.opendaylight.openflowplugin.impl.statistics.services.OpendaylightFlowTableStatisticsServiceImpl; import org.opendaylight.openflowplugin.impl.statistics.services.OpendaylightGroupStatisticsServiceImpl; @@ -38,13 +40,9 @@ import org.opendaylight.openflowplugin.impl.statistics.services.OpendaylightMete import org.opendaylight.openflowplugin.impl.statistics.services.OpendaylightPortStatisticsServiceImpl; import org.opendaylight.openflowplugin.impl.statistics.services.OpendaylightQueueStatisticsServiceImpl; import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.OpendaylightFlowStatisticsServiceDelegateImpl; -import org.opendaylight.openflowplugin.impl.statistics.services.direct.FlowDirectStatisticsService; -import org.opendaylight.openflowplugin.impl.statistics.services.direct.GroupDirectStatisticsService; -import org.opendaylight.openflowplugin.impl.statistics.services.direct.MeterDirectStatisticsService; -import org.opendaylight.openflowplugin.impl.statistics.services.direct.NodeConnectorDirectStatisticsService; import org.opendaylight.openflowplugin.impl.statistics.services.direct.OpendaylightDirectStatisticsServiceImpl; -import org.opendaylight.openflowplugin.impl.statistics.services.direct.OpendaylightDirectStatisticsServiceProvider; -import org.opendaylight.openflowplugin.impl.statistics.services.direct.QueueDirectStatisticsService; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer.MultiLayerDirectStatisticsProviderInitializer; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.singlelayer.SingleLayerDirectStatisticsProviderInitializer; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.OpendaylightDirectStatisticsService; import org.opendaylight.yang.gen.v1.urn.opendaylight.echo.service.rev150305.SalEchoService; @@ -84,7 +82,7 @@ public class MdSalRegistrationUtils { * Method registers all OF services for role {@link OfpRole#BECOMEMASTER} * @param rpcContext - registration processing is implemented in {@link org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext} * @param deviceContext - every service needs {@link org.opendaylight.openflowplugin.api.openflow.device.DeviceContext} as input parameter - * @param convertorExecutor + * @param convertorExecutor convertor executor */ public static void registerServices(@CheckForNull final RpcContext rpcContext, @CheckForNull final DeviceContext deviceContext, @@ -93,6 +91,10 @@ public class MdSalRegistrationUtils { Preconditions.checkArgument(rpcContext != null); Preconditions.checkArgument(deviceContext != null); + // TODO: Use multipart writer provider from device context + final MultipartWriterProvider multipartWriterProvider = MultipartWriterProviderFactory + .createDefaultProvider(deviceContext); + // create service instances final SalFlowServiceImpl salFlowService = new SalFlowServiceImpl(rpcContext, deviceContext, convertorExecutor); final FlowCapableTransactionServiceImpl flowCapableTransactionService = new FlowCapableTransactionServiceImpl(rpcContext, deviceContext); @@ -105,20 +107,19 @@ public class MdSalRegistrationUtils { rpcContext.registerRpcServiceImplementation(FlowCapableTransactionService.class, flowCapableTransactionService); rpcContext.registerRpcServiceImplementation(SalMeterService.class, salMeterService); rpcContext.registerRpcServiceImplementation(SalGroupService.class, salGroupService); - rpcContext.registerRpcServiceImplementation(SalTableService.class, new SalTableServiceImpl(rpcContext, deviceContext, convertorExecutor)); + rpcContext.registerRpcServiceImplementation(SalTableService.class, new SalTableServiceImpl(rpcContext, deviceContext, convertorExecutor, multipartWriterProvider)); rpcContext.registerRpcServiceImplementation(SalPortService.class, new SalPortServiceImpl(rpcContext, deviceContext, convertorExecutor)); rpcContext.registerRpcServiceImplementation(PacketProcessingService.class, new PacketProcessingServiceImpl(rpcContext, deviceContext, convertorExecutor)); rpcContext.registerRpcServiceImplementation(NodeConfigService.class, new NodeConfigServiceImpl(rpcContext, deviceContext)); rpcContext.registerRpcServiceImplementation(OpendaylightFlowStatisticsService.class, OpendaylightFlowStatisticsServiceImpl.createWithOook(rpcContext, deviceContext, convertorExecutor)); // register direct statistics gathering services - final OpendaylightDirectStatisticsServiceProvider statisticsProvider = new OpendaylightDirectStatisticsServiceProvider(); - statisticsProvider.register(FlowDirectStatisticsService.class, new FlowDirectStatisticsService(rpcContext, deviceContext, convertorExecutor)); - statisticsProvider.register(GroupDirectStatisticsService.class, new GroupDirectStatisticsService(rpcContext, deviceContext, convertorExecutor)); - statisticsProvider.register(MeterDirectStatisticsService.class, new MeterDirectStatisticsService(rpcContext, deviceContext, convertorExecutor)); - statisticsProvider.register(NodeConnectorDirectStatisticsService.class, new NodeConnectorDirectStatisticsService(rpcContext, deviceContext, convertorExecutor)); - statisticsProvider.register(QueueDirectStatisticsService.class, new QueueDirectStatisticsService(rpcContext, deviceContext, convertorExecutor)); - rpcContext.registerRpcServiceImplementation(OpendaylightDirectStatisticsService.class, new OpendaylightDirectStatisticsServiceImpl(statisticsProvider)); + rpcContext.registerRpcServiceImplementation(OpendaylightDirectStatisticsService.class, + new OpendaylightDirectStatisticsServiceImpl(deviceContext.canUseSingleLayerSerialization() + ? SingleLayerDirectStatisticsProviderInitializer + .createProvider(rpcContext, deviceContext, convertorExecutor, multipartWriterProvider) + : MultiLayerDirectStatisticsProviderInitializer + .createProvider(rpcContext, deviceContext, convertorExecutor, multipartWriterProvider))); // register flat batch services rpcContext.registerRpcServiceImplementation(SalFlatBatchService.class, new SalFlatBatchServiceImpl( @@ -137,7 +138,7 @@ public class MdSalRegistrationUtils { /** * Support deprecated statistic related services for backward compatibility. The only exception from deprecation is * the aggregated flow statistic with match criteria input. - * @param rpcContext + * @param rpcContext * @param deviceContext * @param notificationPublishService * @param convertorExecutor diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/common/NodeConnectorTranslatorUtilTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/common/NodeConnectorTranslatorUtilTest.java deleted file mode 100644 index 6fe1d302d7..0000000000 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/common/NodeConnectorTranslatorUtilTest.java +++ /dev/null @@ -1,323 +0,0 @@ -/** - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.openflowplugin.impl.common; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.math.BigInteger; -import java.util.Arrays; -import java.util.List; -import org.junit.Assert; -import org.junit.Test; -import org.opendaylight.openflowplugin.api.OFConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; -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.node.NodeConnectorKey; -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.PortConfig; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfigV10; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeatures; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeaturesV10; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortState; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortStateV10; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FeaturesReply; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.features.reply.PhyPort; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * openflowplugin-impl - * org.opendaylight.openflowplugin.impl.common - * - * Test class for testing {@link org.opendaylight.openflowplugin.impl.common.NodeConnectorTranslatorUtil} - * - * @author Vaclav Demcak - * - * Created: Mar 31, 2015 - */ -public class NodeConnectorTranslatorUtilTest { - - private static final Logger LOG = LoggerFactory.getLogger(NodeConnectorTranslatorUtilTest.class); - - private static final String MAC_ADDRESS = "00:01:02:03:04:05"; - private static final String NAME = "PortTranslatorTest"; - private final Boolean[] pfBls = {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false}; - private final boolean[] pfV10Bls = {false, false, false, false, false, false, false, false, false, false, false, false}; - private final boolean[] portCfgBools = {false, false, false, false}; - private final boolean[] portCfgV10bools = {false, false, false, false, false, false, false}; - private final boolean[] portStateBools = {false, false, false, false}; - private final Long currentSpeed = Long.decode("4294967295"); - private static final Long maxSpeed = Long.decode("4294967295"); - - /** - * Test method for {@link NodeConnectorTranslatorUtil#translateNodeConnectorFromFeaturesReply(FeaturesReply)}. - */ - @Test - public void testTranslateNodeConnectorFromFeaturesReply(){ - final FeaturesReply reply = mock(FeaturesReply.class); - final BigInteger dataPathId = BigInteger.valueOf(25L); - final List listPorts = Arrays.asList(mockPhyPortPort()); - when(reply.getPhyPort()).thenReturn(listPorts); - when(reply.getDatapathId()).thenReturn(dataPathId); - when(reply.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3); - final List nodeConnector = NodeConnectorTranslatorUtil.translateNodeConnectorFromFeaturesReply(reply); - Assert.assertNotNull(nodeConnector); - Assert.assertEquals(1, nodeConnector.size()); - } - - /** - * Test method for {@link NodeConnectorTranslatorUtil#translateNodeConnectorFromFeaturesReply(FeaturesReply)}. - * {@link IllegalArgumentException} - */ - @Test(expected=IllegalArgumentException.class) - public void testTranslateNodeConnectorFromFeaturesReplyNullPorts(){ - final FeaturesReply reply = mock(FeaturesReply.class); - when(reply.getPhyPort()).thenReturn(null); - NodeConnectorTranslatorUtil.translateNodeConnectorFromFeaturesReply(reply); - } - - /** - * Test method for {@link NodeConnectorTranslatorUtil#translateNodeConnectorFromFeaturesReply(FeaturesReply)}. - * {@link IllegalArgumentException} - */ - @Test(expected=IllegalArgumentException.class) - public void testTranslateNodeConnectorFromFeaturesReplyNullReplay(){ - NodeConnectorTranslatorUtil.translateNodeConnectorFromFeaturesReply(null); - } - - /** - * Test method for {@link NodeConnectorTranslatorUtil#translateFlowCapableNodeFromPhyPort(PhyPort, short)}. - */ - @Test - public void testTranslateFlowCapableNodeFromPhyPortOF10(){ - final PhyPort port = mockPhyPortPort(); - final FlowCapableNodeConnector flowCapableNodeConnector = NodeConnectorTranslatorUtil - .translateFlowCapableNodeFromPhyPort(port, OFConstants.OFP_VERSION_1_0); - Assert.assertNotNull(flowCapableNodeConnector); - Assert.assertEquals(port.getName(), flowCapableNodeConnector.getName()); - Assert.assertEquals(port.getPortNo(), flowCapableNodeConnector.getPortNumber().getUint32()); - Assert.assertEquals(port.getHwAddr().getValue(), flowCapableNodeConnector.getHardwareAddress().getValue()); - Assert.assertEquals(port.getCurrSpeed(), flowCapableNodeConnector.getCurrentSpeed()); - Assert.assertEquals(port.getMaxSpeed(), flowCapableNodeConnector.getMaximumSpeed()); - assertEqualsStateV10(port.getStateV10(), flowCapableNodeConnector.getState()); - assertEqualsPortFeaturesV10(port.getAdvertisedFeaturesV10(), flowCapableNodeConnector.getAdvertisedFeatures()); - assertEqualsPortFeaturesV10(port.getCurrentFeaturesV10(), flowCapableNodeConnector.getCurrentFeature()); - assertEqualsPortFeaturesV10(port.getPeerFeaturesV10(), flowCapableNodeConnector.getPeerFeatures()); - assertEqualsPortFeaturesV10(port.getSupportedFeaturesV10(), flowCapableNodeConnector.getSupported()); - - } - - /** - * Test method for {@link NodeConnectorTranslatorUtil#translateFlowCapableNodeFromPhyPort(PhyPort, short)}. - */ - @Test - public void testTranslateFlowCapableNodeFromPhyPortOF13(){ - final PhyPort port = mockPhyPortPort(); - final FlowCapableNodeConnector flowCapableNodeConnector = NodeConnectorTranslatorUtil - .translateFlowCapableNodeFromPhyPort(port, OFConstants.OFP_VERSION_1_3); - Assert.assertNotNull(flowCapableNodeConnector); - Assert.assertEquals(port.getName(), flowCapableNodeConnector.getName()); - Assert.assertEquals(port.getPortNo(), flowCapableNodeConnector.getPortNumber().getUint32()); - Assert.assertEquals(port.getHwAddr().getValue(), flowCapableNodeConnector.getHardwareAddress().getValue()); - Assert.assertEquals(port.getCurrSpeed(), flowCapableNodeConnector.getCurrentSpeed()); - Assert.assertEquals(port.getMaxSpeed(), flowCapableNodeConnector.getMaximumSpeed()); - assertEqualsState(port.getState(), flowCapableNodeConnector.getState()); - assertEqualsPortFeatures(port.getAdvertisedFeatures(), flowCapableNodeConnector.getAdvertisedFeatures()); - assertEqualsPortFeatures(port.getCurrentFeatures(), flowCapableNodeConnector.getCurrentFeature()); - assertEqualsPortFeatures(port.getPeerFeatures(), flowCapableNodeConnector.getPeerFeatures()); - assertEqualsPortFeatures(port.getSupportedFeatures(), flowCapableNodeConnector.getSupported()); - } - - /** - * Here unsupported version is used - * Test method for {@link NodeConnectorTranslatorUtil#translateFlowCapableNodeFromPhyPort(PhyPort, short)}. - */ - @Test - public void testTranslateFlowCapableNodeFromPhyPortOF12() { - final PhyPort port = mockPhyPortPort(); - try { - final FlowCapableNodeConnector flowCapableNodeConnector = NodeConnectorTranslatorUtil - .translateFlowCapableNodeFromPhyPort(port, (short) 0x03); - Assert.fail("port of version 0x03 (OF-1.2) should not be translated"); - } catch (Exception e) { - LOG.debug("expected exception: {}", e.getMessage()); - Assert.assertTrue(e instanceof IllegalArgumentException); - } - - } - - /** - * Test method for {@link NodeConnectorTranslatorUtil#makeNodeConnectorId(BigInteger, String, long)}. - */ - @Test - public void testMakeNodeConnectorId(){ - final BigInteger dataPathId = BigInteger.valueOf(25L); - final String logicalName = "testPort"; - final long portNo = 45L; - final NodeConnectorId nodeConnectorId = NodeConnectorTranslatorUtil.makeNodeConnectorId(dataPathId, logicalName, portNo); - Assert.assertNotNull(nodeConnectorId); - Assert.assertNotNull(nodeConnectorId.getValue()); - Assert.assertTrue(nodeConnectorId.getValue().contains(logicalName)); - Assert.assertTrue(nodeConnectorId.getValue().contains(dataPathId.toString())); - Assert.assertFalse(nodeConnectorId.getValue().contains(":" + portNo)); - } - - /** - * Test method for {@link NodeConnectorTranslatorUtil#makeNodeConnectorId(BigInteger, String, long)}. - */ - @Test - public void testMakeNodeConnectorIdNullLogicalName(){ - final BigInteger dataPathId = BigInteger.valueOf(25L); - final long portNo = 45L; - final NodeConnectorId nodeConnectorId = NodeConnectorTranslatorUtil.makeNodeConnectorId(dataPathId, null, portNo); - Assert.assertNotNull(nodeConnectorId); - Assert.assertNotNull(nodeConnectorId.getValue()); - Assert.assertTrue(nodeConnectorId.getValue().contains(dataPathId.toString())); - Assert.assertTrue(nodeConnectorId.getValue().contains(":" + portNo)); - } - - /** - * Test method for {@link NodeConnectorTranslatorUtil#makeNodeConnectorId(BigInteger, String, long)}. - * expect {@link IllegalArgumentException} - */ - @Test(expected=IllegalArgumentException.class) - public void testMakeNodeConnectorIdNullDataPath(){ - final long portNo = 45L; - NodeConnectorTranslatorUtil.makeNodeConnectorId(null, null, portNo); - } - - private PhyPort mockPhyPortPort() { - final PhyPort phyport = mock(PhyPort.class); - when(phyport.getAdvertisedFeatures()).thenReturn(getPortFeatures()); - when(phyport.getAdvertisedFeaturesV10()).thenReturn(getPortFeaturesV10()); - when(phyport.getConfig()).thenReturn(getPortConfig()); - when(phyport.getConfigV10()).thenReturn(getPortConfigV10()); - when(phyport.getCurrentFeatures()).thenReturn(getPortFeatures()); - when(phyport.getCurrentFeaturesV10()).thenReturn(getPortFeaturesV10()); - when(phyport.getCurrSpeed()).thenReturn(currentSpeed); - when(phyport.getHwAddr()).thenReturn(getMacAddress()); - when(phyport.getName()).thenReturn(NAME); - when(phyport.getMaxSpeed()).thenReturn(maxSpeed); - when(phyport.getPeerFeatures()).thenReturn(getPortFeatures()); - when(phyport.getPeerFeaturesV10()).thenReturn(getPortFeaturesV10()); - when(phyport.getPortNo()).thenReturn(Long.MAX_VALUE); - when(phyport.getState()).thenReturn(getPortState()); - when(phyport.getStateV10()).thenReturn(getPortStateV10()); - when(phyport.getSupportedFeatures()).thenReturn(getPortFeatures()); - when(phyport.getSupportedFeaturesV10()).thenReturn(getPortFeaturesV10()); - return phyport; - } - - private static PortStateV10 getPortStateV10() { - final PortStateV10 portState = new PortStateV10(Boolean.TRUE, Boolean.TRUE, Boolean.TRUE, Boolean.TRUE, Boolean.TRUE, Boolean.TRUE, Boolean.TRUE, Boolean.TRUE); - return portState; - } - - private PortState getPortState() { - final PortState portState = new PortState(portStateBools[0], portStateBools[1], portStateBools[2]); - return portState; - } - - private PortFeatures getPortFeatures() { - return new PortFeatures(pfBls[0], pfBls[1], pfBls[2], pfBls[3], pfBls[4], pfBls[5], pfBls[6], pfBls[7], pfBls[8], - pfBls[9], pfBls[10], pfBls[11], pfBls[12], pfBls[13], pfBls[14], pfBls[15]); - } - - private PortFeaturesV10 getPortFeaturesV10() { - return new PortFeaturesV10(pfV10Bls[0], pfV10Bls[1], pfV10Bls[2], pfV10Bls[3], pfV10Bls[4], pfV10Bls[5], pfV10Bls[6], - pfV10Bls[7], pfV10Bls[8], pfV10Bls[9], pfV10Bls[10], pfV10Bls[11]); - } - - private static MacAddress getMacAddress() { - return new MacAddress(MAC_ADDRESS); - } - - private PortConfigV10 getPortConfigV10() { - return new PortConfigV10(portCfgV10bools[0], portCfgV10bools[1], portCfgV10bools[2], portCfgV10bools[3], portCfgV10bools[4], portCfgV10bools[5], portCfgV10bools[6]); - } - - private PortConfig getPortConfig() { - return new PortConfig(portCfgBools[0], portCfgBools[1], portCfgBools[2], portCfgBools[3]); - } - - private static void assertEqualsStateV10(final PortStateV10 psV10, final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortState state) { - assertEquals(psV10.isBlocked(), state.isBlocked()); - assertEquals(psV10.isLinkDown(), state.isLinkDown()); - assertEquals(psV10.isLive(), state.isLive()); - } - - private static void assertEqualsState(final PortState ps, final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortState state) { - assertEquals(ps.isBlocked(), state.isBlocked()); - assertEquals(ps.isLinkDown(), state.isLinkDown()); - assertEquals(ps.isLive(), state.isLive()); - } - - private static void assertEqualsPortFeaturesV10(final PortFeaturesV10 apfV10, final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortFeatures npf) { - assertEquals(apfV10.is_100mbFd(), npf.isHundredMbFd()); - assertEquals(apfV10.is_100mbHd(), npf.isHundredMbHd()); - - assertEquals(apfV10.is_10gbFd(), npf.isTenGbFd()); - assertEquals(apfV10.is_10mbFd(), npf.isTenMbFd()); - assertEquals(apfV10.is_10mbHd(), npf.isTenMbHd()); - - assertEquals(apfV10.is_1gbFd(), npf.isOneGbFd()); - assertEquals(apfV10.is_1gbHd(), npf.isOneGbHd()); - - assertEquals(apfV10.isAutoneg(), npf.isAutoeng()); - assertEquals(apfV10.isCopper(), npf.isCopper()); - assertEquals(apfV10.isFiber(), npf.isFiber()); - assertEquals(apfV10.isPause(), npf.isPause()); - assertEquals(apfV10.isPauseAsym(), npf.isPauseAsym()); - } - - private static void assertEqualsPortFeatures(final PortFeatures apf, final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortFeatures npf) { - assertEquals(apf.is_100gbFd(), npf.isHundredGbFd()); - assertEquals(apf.is_100mbFd(), npf.isHundredMbFd()); - assertEquals(apf.is_100mbHd(), npf.isHundredMbHd()); - - assertEquals(apf.is_10gbFd(), npf.isTenGbFd()); - assertEquals(apf.is_10mbFd(), npf.isTenMbFd()); - assertEquals(apf.is_10mbHd(), npf.isTenMbHd()); - - assertEquals(apf.is_1gbFd(), npf.isOneGbFd()); - assertEquals(apf.is_1gbHd(), npf.isOneGbHd()); - assertEquals(apf.is_1tbFd(), npf.isOneTbFd()); - - assertEquals(apf.is_40gbFd(), npf.isFortyGbFd()); - - assertEquals(apf.isAutoneg(), npf.isAutoeng()); - assertEquals(apf.isCopper(), npf.isCopper()); - assertEquals(apf.isFiber(), npf.isFiber()); - assertEquals(apf.isOther(), npf.isOther()); - assertEquals(apf.isPause(), npf.isPause()); - assertEquals(apf.isPauseAsym(), npf.isPauseAsym()); - } - - static InstanceIdentifier createNodeConnectorId(String nodeKey, String nodeConnectorKey) { - return InstanceIdentifier.builder(Nodes.class) - .child(Node.class, new NodeKey(new NodeId(nodeKey))) - .child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId(nodeConnectorKey))) - .build(); - } - - @Test - public void testDummy() { - InstanceIdentifier id = createNodeConnectorId("openflow:1", "openflow:1:1"); - InstanceIdentifier nodeId = id.firstIdentifierOf(Node.class); - System.out.println(nodeId); - } -} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImplTest.java index ffba264ed4..c0657da199 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImplTest.java @@ -71,6 +71,7 @@ import org.opendaylight.openflowplugin.api.openflow.rpc.listener.ItemLifecycleLi import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy; import org.opendaylight.openflowplugin.extension.api.ConvertorMessageFromOFJava; import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider; +import org.opendaylight.openflowplugin.impl.device.initialization.DeviceInitializerProviderFactory; import org.opendaylight.openflowplugin.impl.registry.flow.FlowDescriptorFactory; import org.opendaylight.openflowplugin.impl.registry.flow.FlowRegistryKeyFactory; import org.opendaylight.openflowplugin.impl.util.DeviceStateUtil; @@ -230,7 +231,8 @@ public class DeviceContextImplTest { translatorLibrary, deviceManager, convertorExecutor, - false, timer, deviceManager, false); + false, timer, deviceManager, false, + DeviceInitializerProviderFactory.createDefaultProvider()); deviceContextSpy = Mockito.spy(deviceContext); xid = new Xid(atomicLong.incrementAndGet()); @@ -241,16 +243,6 @@ public class DeviceContextImplTest { } - @Test(expected = NullPointerException.class) - public void testDeviceContextImplConstructorNullDataBroker() throws Exception { - new DeviceContextImpl(connectionContext, null, null, translatorLibrary, deviceManager, convertorExecutor,false, timer, deviceManager, false).close(); - } - - @Test(expected = NullPointerException.class) - public void testDeviceContextImplConstructorNullTimer() throws Exception { - new DeviceContextImpl(null, dataBroker, null, translatorLibrary, deviceManager,convertorExecutor,false, timer, deviceManager, false).close(); - } - @Test public void testGetReadTransaction() { final ReadTransaction readTx = deviceContext.getReadTransaction(); @@ -362,10 +354,15 @@ public class DeviceContextImplTest { @Test public void testProcessReply2() { - final MultipartReply mockedMultipartReply = mock(MultipartReply.class); final Xid dummyXid = new Xid(DUMMY_XID); - deviceContext.processReply(dummyXid, Lists.newArrayList(mockedMultipartReply)); + + final Error mockedError = mock(Error.class); + deviceContext.processReply(dummyXid, Lists.newArrayList(mockedError)); verify(messageSpy).spyMessage(any(Class.class), eq(MessageSpy.STATISTIC_GROUP.FROM_SWITCH_PUBLISHED_FAILURE)); + + final MultipartReply mockedMultipartReply = mock(MultipartReply.class); + deviceContext.processReply(dummyXid, Lists.newArrayList(mockedMultipartReply)); + verify(messageSpy).spyMessage(any(Class.class), eq(MessageSpy.STATISTIC_GROUP.FROM_SWITCH_PUBLISHED_SUCCESS)); } @Test diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImplTest.java index 237839ad3d..c742b2cc91 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImplTest.java @@ -58,6 +58,7 @@ import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceTermin import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleService; import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey; import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageIntelligenceAgency; +import org.opendaylight.openflowplugin.impl.device.initialization.DeviceInitializerProviderFactory; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; @@ -145,19 +146,20 @@ public class DeviceManagerImplTest { when(mockedWriteTransaction.submit()).thenReturn(mockedFuture); final DeviceManagerImpl deviceManager = new DeviceManagerImpl( - mockedDataBroker, - TEST_VALUE_GLOBAL_NOTIFICATION_QUOTA, - false, - barrierIntervalNanos, - barrierCountLimit, - messageIntelligenceAgency, - true, - clusterSingletonServiceProvider, - null, - new HashedWheelTimer(), - convertorExecutor, - false, - false); + mockedDataBroker, + TEST_VALUE_GLOBAL_NOTIFICATION_QUOTA, + false, + barrierIntervalNanos, + barrierCountLimit, + messageIntelligenceAgency, + true, + clusterSingletonServiceProvider, + null, + new HashedWheelTimer(), + convertorExecutor, + false, + false, + DeviceInitializerProviderFactory.createDefaultProvider()); deviceManager.setDeviceInitializationPhaseHandler(deviceInitPhaseHandler); deviceManager.setDeviceTerminationPhaseHandler(deviceTerminationPhaseHandler); diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/listener/MultiMsgCollectorImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/listener/MultiMsgCollectorImplTest.java index f517c818f1..5e59a828d3 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/listener/MultiMsgCollectorImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/listener/MultiMsgCollectorImplTest.java @@ -45,7 +45,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731 @RunWith(MockitoJUnitRunner.class) public class MultiMsgCollectorImplTest { - private MultiMsgCollectorImpl collector; + private MultiMsgCollectorImpl collector; private Runnable cleanUpCheck; @Mock @@ -68,7 +68,7 @@ public class MultiMsgCollectorImplTest { @Before public void setUp() { - collector = new MultiMsgCollectorImpl(deviceProcessor, requestContext); + collector = new MultiMsgCollectorImpl<>(deviceProcessor, requestContext); cleanUpCheck = Runnables.doNothing(); Mockito.when(requestContext.getXid()).thenReturn(new Xid(xid)); } @@ -88,7 +88,7 @@ public class MultiMsgCollectorImplTest { */ @Test public void testAddMultipartMsgOne() { - collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, false).build()); + collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, false).build(), false, null); Mockito.verify(deviceProcessor).processReply(xidCaptor.capture(), mmCaptor.capture()); Assert.assertEquals(xid, xidCaptor.getValue().getValue()); @@ -104,8 +104,8 @@ public class MultiMsgCollectorImplTest { */ @Test public void testAddMultipartMsgTwo() { - collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, true).build()); - collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, false).build()); + collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, true).build(), true, null); + collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, false).build(), false, null); Mockito.verify(deviceProcessor).processReply(xidCaptor.capture(), mmCaptor.capture()); Assert.assertEquals(xid, xidCaptor.getValue().getValue()); @@ -124,7 +124,7 @@ public class MultiMsgCollectorImplTest { public void testAddMultipartMsgNotExpectedXid() { final Long dif_xid = 5L; final MultipartReplyMessage mrMsg = MsgGeneratorTestUtils.makeMultipartDescReply(dif_xid, hwTestValue, true).build(); - collector.addMultipartMsg(mrMsg); + collector.addMultipartMsg(mrMsg, true, null); } /** @@ -133,9 +133,9 @@ public class MultiMsgCollectorImplTest { */ @Test public void testAddMultipartMsgWrongType1() { - collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, true).build()); + collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, true).build(), true, null); collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, false) - .setType(MultipartType.OFPMPPORTDESC).build()); + .setType(MultipartType.OFPMPPORTDESC).build(), false, null); Mockito.verify(deviceProcessor).processReply(xidCaptor.capture(), mmCaptor.capture()); Assert.assertEquals(xid, xidCaptor.getValue().getValue()); @@ -158,10 +158,10 @@ public class MultiMsgCollectorImplTest { */ @Test public void testAddMultipartMsgWrongType2() { - collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, true).build()); + collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, true).build(), true, null); collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, true) - .setType(MultipartType.OFPMPPORTDESC).build()); - collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, false).build()); + .setType(MultipartType.OFPMPPORTDESC).build(), true, null); + collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, false).build(), false, null); Mockito.verify(deviceProcessor).processReply(xidCaptor.capture(), mmCaptor.capture()); Mockito.verify(deviceProcessor).processReply(xidCaptor.capture(), mmCaptor.capture()); @@ -185,10 +185,10 @@ public class MultiMsgCollectorImplTest { */ @Test public void testAddMultipartMsgWrongType3() { - collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, true).build()); + collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, true).build(), true, null); collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, true) - .setType(MultipartType.OFPMPPORTDESC).build()); - collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, false).build()); + .setType(MultipartType.OFPMPPORTDESC).build(), true, null); + collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, false).build(), false, null); Mockito.verify(deviceProcessor).processReply(xidCaptor.capture(), mmCaptor.capture()); Assert.assertEquals(xid, xidCaptor.getValue().getValue()); diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/protocol/deserialization/AbstractDeserializerTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/protocol/deserialization/AbstractDeserializerTest.java index 342d2218b4..41d48b2008 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/protocol/deserialization/AbstractDeserializerTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/protocol/deserialization/AbstractDeserializerTest.java @@ -40,6 +40,7 @@ public abstract class AbstractDeserializerTest { factory.setRegistry(registry); provider = new DeserializerExtensionProviderImpl(registry, factory); DeserializerInjector.injectDeserializers(provider); + MessageDeserializerInjector.injectDeserializers(provider); init(); } diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestCallbackTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestCallbackTest.java index 12f5de2af3..e7b2488f15 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestCallbackTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestCallbackTest.java @@ -19,11 +19,13 @@ import org.mockito.Matchers; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.stubbing.OngoingStubbing; import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; import org.opendaylight.openflowplugin.api.openflow.device.RequestContext; import org.opendaylight.openflowplugin.api.openflow.device.handlers.MultiMsgCollector; import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier; import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy; +import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerMultipartRequestCallback; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage; @@ -32,7 +34,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731 import org.opendaylight.yangtools.yang.common.RpcResult; /** - * Test for {@link MultipartRequestCallback}. + * Test for {@link org.opendaylight.openflowplugin.impl.services.AbstractMultipartRequestCallback}. */ @RunWith(MockitoJUnitRunner.class) public class MultipartRequestCallbackTest { @@ -44,18 +46,21 @@ public class MultipartRequestCallbackTest { @Mock private MessageSpy spy; @Mock - private MultiMsgCollector multiMsgCollector; + private MultiMsgCollector multiMsgCollector; @Captor private ArgumentCaptor>> rpcResultCapt; - private MultipartRequestCallback multipartRequestCallback; + private AbstractMultipartRequestCallback multipartRequestCallback; @Before public void setUp() throws Exception { Mockito.doNothing().when(requestContext).setResult(rpcResultCapt.capture()); Mockito.when(deviceContext.getMessageSpy()).thenReturn(spy); - Mockito.when(deviceContext.getMultiMsgCollector(Matchers.any())).thenReturn(multiMsgCollector); - multipartRequestCallback = new MultipartRequestCallback(requestContext, MultipartRequestInput.class, deviceContext); + + final OngoingStubbing> when = + Mockito.when(deviceContext.getMultiMsgCollector(Matchers.any())); + when.thenReturn(multiMsgCollector); + multipartRequestCallback = new MultiLayerMultipartRequestCallback<>(requestContext, MultipartRequestInput.class, deviceContext, null); } /** @@ -91,6 +96,6 @@ public class MultipartRequestCallbackTest { public void testOnSuccess3() throws Exception { final MultipartReplyMessage replyMessage = new MultipartReplyMessageBuilder().build(); multipartRequestCallback.onSuccess(replyMessage); - Mockito.verify(multiMsgCollector).addMultipartMsg(Matchers.eq(replyMessage), Matchers.any()); + Mockito.verify(multiMsgCollector).addMultipartMsg(Matchers.eq(replyMessage), Matchers.eq(false), Matchers.any()); } -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestOnTheFlyCallbackTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestOnTheFlyCallbackTest.java index 098ef4dd86..637c3b6023 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestOnTheFlyCallbackTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestOnTheFlyCallbackTest.java @@ -8,8 +8,8 @@ package org.opendaylight.openflowplugin.impl.services; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; @@ -43,7 +43,9 @@ import org.opendaylight.openflowplugin.api.openflow.registry.flow.DeviceFlowRegi import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowDescriptor; import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey; import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProviderFactory; import org.opendaylight.openflowplugin.impl.rpc.AbstractRequestContext; +import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerFlowMultipartRequestOnTheFlyCallback; import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.MessageIntelligenceAgencyImpl; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory; @@ -112,7 +114,7 @@ public class MultipartRequestOnTheFlyCallbackTest { private AbstractRequestContext> dummyRequestContext; private final EventIdentifier dummyEventIdentifier = new EventIdentifier(DUMMY_EVENT_NAME, DUMMY_DEVICE_ID); - private MultipartRequestOnTheFlyCallback multipartRequestOnTheFlyCallback; + private AbstractMultipartRequestOnTheFlyCallback multipartRequestOnTheFlyCallback; private final short tableId = 0; @Before @@ -156,9 +158,13 @@ public class MultipartRequestOnTheFlyCallbackTest { }; final ConvertorManager convertorManager = ConvertorManagerFactory.createDefaultManager(); - multipartRequestOnTheFlyCallback = new MultipartRequestOnTheFlyCallback(dummyRequestContext, String.class, - mockedDeviceContext.getMessageSpy(),dummyEventIdentifier, mockedDeviceInfo, - mockedDeviceContext.getDeviceFlowRegistry(), mockedDeviceContext, convertorManager); + multipartRequestOnTheFlyCallback = new MultiLayerFlowMultipartRequestOnTheFlyCallback<>( + dummyRequestContext, + String.class, + mockedDeviceContext, + dummyEventIdentifier, + MultipartWriterProviderFactory.createDefaultProvider(mockedDeviceContext), + convertorManager); } @@ -267,11 +273,10 @@ public class MultipartRequestOnTheFlyCallbackTest { multipartRequestOnTheFlyCallback.onSuccess(mpReplyMessage.build()); final RpcResult> actualResult = dummyRequestContext.getFuture().get(); - assertNotNull(actualResult.getErrors()); - assertTrue(actualResult.getErrors().isEmpty()); - assertNotNull(actualResult.getResult()); - assertTrue(actualResult.getResult().isEmpty()); + // Nothing else than flow is supported by on the fly callback + assertNotNull(actualResult.getErrors()); + assertFalse(actualResult.getErrors().isEmpty()); Mockito.verify(mockedFlowRegistry, Mockito.never()).storeIfNecessary(Matchers.any()); Mockito.verify(mockedDeviceContext, Mockito.never()).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.any(), Matchers.any()); diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalExperimenterMpMessageServiceImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalExperimenterMpMessageServiceImplTest.java index cf1d4601ff..d2717523dc 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalExperimenterMpMessageServiceImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalExperimenterMpMessageServiceImplTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Pantheon Technologies s.r.o. and others. All rights reserved. + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, @@ -19,6 +19,8 @@ import org.opendaylight.openflowplugin.api.openflow.device.Xid; import org.opendaylight.openflowplugin.extension.api.ConvertorMessageToOFJava; import org.opendaylight.openflowplugin.extension.api.TypeVersionKey; import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider; +import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerExperimenterMultipartService; +import org.opendaylight.openflowplugin.impl.services.sal.SalExperimenterMpMessageServiceImpl; import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef; @@ -75,7 +77,8 @@ public class SalExperimenterMpMessageServiceImplTest extends ServiceMocking { .setNode(new NodeRef(mockedDeviceInfo.getNodeInstanceIdentifier())) .build(); - final OfHeader ofHeader = salExperimenterMpMessageService.buildRequest(new Xid(DUMMY_ID), data); + final OfHeader ofHeader = new MultiLayerExperimenterMultipartService(mockedDeviceContext, mockedDeviceContext, mockedExtensionConverterProvider) + .buildRequest(new Xid(DUMMY_ID), data); verify(mockedExtensionConverter).convert(data.getExperimenterMessageOfChoice()); assertEquals(DUMMY_ID, (long) ofHeader.getXid()); assertEquals(mockedDeviceInfo.getVersion(), (short) ofHeader.getVersion()); @@ -98,4 +101,4 @@ public class SalExperimenterMpMessageServiceImplTest extends ServiceMocking { return DummyExperimenter.class; } } -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/FlowCapableTransactionServiceImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/FlowCapableTransactionServiceImplTest.java similarity index 83% rename from openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/FlowCapableTransactionServiceImplTest.java rename to openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/FlowCapableTransactionServiceImplTest.java index 8916519edd..0cc2673183 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/FlowCapableTransactionServiceImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/FlowCapableTransactionServiceImplTest.java @@ -1,12 +1,12 @@ /* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -14,6 +14,8 @@ import static org.mockito.Mockito.verify; import org.junit.Test; import org.opendaylight.openflowplugin.api.openflow.device.Xid; +import org.opendaylight.openflowplugin.impl.services.ServiceMocking; +import org.opendaylight.openflowplugin.impl.services.sal.FlowCapableTransactionServiceImpl; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.SendBarrierInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.SendBarrierInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef; @@ -21,7 +23,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; /** - * Test for {@link FlowCapableTransactionServiceImpl}. + * Test for {@link org.opendaylight.openflowplugin.impl.services.sal.FlowCapableTransactionServiceImpl}. */ public class FlowCapableTransactionServiceImplTest extends ServiceMocking { @@ -53,4 +55,4 @@ public class FlowCapableTransactionServiceImplTest extends ServiceMocking { return new SendBarrierInputBuilder() .setNode(new NodeRef(mockedDeviceInfo.getNodeInstanceIdentifier())).build(); } -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/NodeConfigServiceImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/NodeConfigServiceImplTest.java similarity index 87% rename from openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/NodeConfigServiceImplTest.java rename to openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/NodeConfigServiceImplTest.java index b33beb4055..e9b1a3c8a4 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/NodeConfigServiceImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/NodeConfigServiceImplTest.java @@ -1,12 +1,12 @@ /* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -14,12 +14,14 @@ import static org.mockito.Mockito.verify; import org.junit.Test; import org.opendaylight.openflowplugin.api.openflow.device.Xid; +import org.opendaylight.openflowplugin.impl.services.ServiceMocking; +import org.opendaylight.openflowplugin.impl.services.sal.NodeConfigServiceImpl; import org.opendaylight.yang.gen.v1.urn.opendaylight.module.config.rev141015.SetConfigInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.module.config.rev141015.SetConfigInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.SwitchConfigFlag; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; -public class NodeConfigServiceImplTest extends ServiceMocking{ +public class NodeConfigServiceImplTest extends ServiceMocking { private static final Long DUMMY_XID_VALUE = 150L; private static final SwitchConfigFlag DUMMY_FLAG = SwitchConfigFlag.FRAGNORMAL; diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/PacketProcessingServiceImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/PacketProcessingServiceImplTest.java similarity index 93% rename from openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/PacketProcessingServiceImplTest.java rename to openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/PacketProcessingServiceImplTest.java index 0168cda4f9..01473b12a4 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/PacketProcessingServiceImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/PacketProcessingServiceImplTest.java @@ -1,12 +1,12 @@ /* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -15,6 +15,7 @@ import static org.mockito.Mockito.verify; import org.junit.Test; import org.opendaylight.openflowplugin.api.OFConstants; import org.opendaylight.openflowplugin.api.openflow.device.Xid; +import org.opendaylight.openflowplugin.impl.services.ServiceMocking; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; @@ -34,7 +35,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.Tr import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; /** - * Test for {@link PacketProcessingServiceImpl}. + * Test for {@link org.opendaylight.openflowplugin.impl.services.sal.PacketProcessingServiceImpl}. */ public class PacketProcessingServiceImplTest extends ServiceMocking { @@ -85,4 +86,4 @@ public class PacketProcessingServiceImplTest extends ServiceMocking { .setEgress(new NodeConnectorRef(pathToNodeconnector)); return transmitPacketInputBld.build(); } -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalEchoServiceImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalEchoServiceImplTest.java similarity index 90% rename from openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalEchoServiceImplTest.java rename to openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalEchoServiceImplTest.java index 3564d2836a..17197e7433 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalEchoServiceImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalEchoServiceImplTest.java @@ -1,12 +1,12 @@ /* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import static org.mockito.Mockito.verify; @@ -18,6 +18,8 @@ import org.junit.Assert; import org.junit.Test; import org.mockito.Matchers; import org.mockito.Mockito; +import org.opendaylight.openflowplugin.impl.services.ServiceMocking; +import org.opendaylight.openflowplugin.impl.services.sal.SalEchoServiceImpl; import org.opendaylight.yang.gen.v1.urn.opendaylight.echo.service.rev150305.SendEchoInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.echo.service.rev150305.SendEchoInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.echo.service.rev150305.SendEchoOutput; @@ -57,4 +59,4 @@ public class SalEchoServiceImplTest extends ServiceMocking { verify(mockedRequestContextStack).createRequestContext(); verify(mockedOutboundQueue).commitEntry(Matchers.eq(2121L), Matchers.any(), Matchers.>any()); } -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalExperimenterMessageServiceImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalExperimenterMessageServiceImplTest.java similarity index 92% rename from openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalExperimenterMessageServiceImplTest.java rename to openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalExperimenterMessageServiceImplTest.java index d1760f0cda..8cd4a92017 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalExperimenterMessageServiceImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalExperimenterMessageServiceImplTest.java @@ -1,12 +1,12 @@ /* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -20,6 +20,7 @@ import org.opendaylight.openflowplugin.api.openflow.device.Xid; import org.opendaylight.openflowplugin.extension.api.ConvertorMessageToOFJava; import org.opendaylight.openflowplugin.extension.api.TypeVersionKey; import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider; +import org.opendaylight.openflowplugin.impl.services.ServiceMocking; import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.message.service.rev151020.SendExperimenterInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.message.service.rev151020.SendExperimenterInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef; @@ -30,7 +31,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.experimenter import org.opendaylight.yangtools.yang.binding.DataContainer; /** - * Test for {@link SalExperimenterMessageServiceImpl}. + * Test for {@link org.opendaylight.openflowplugin.impl.services.sal.SalExperimenterMessageServiceImpl}. */ public class SalExperimenterMessageServiceImplTest extends ServiceMocking { @@ -85,4 +86,4 @@ public class SalExperimenterMessageServiceImplTest extends ServiceMocking { } } -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalFlatBatchServiceImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalFlatBatchServiceImplTest.java similarity index 99% rename from openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalFlatBatchServiceImplTest.java rename to openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalFlatBatchServiceImplTest.java index 889ee00e5c..14df452cb1 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalFlatBatchServiceImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalFlatBatchServiceImplTest.java @@ -1,12 +1,12 @@ /* - * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import com.google.common.collect.Lists; import com.google.common.util.concurrent.AsyncFunction; @@ -102,7 +102,7 @@ import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; /** - * Test for {@link SalFlatBatchServiceImpl}. + * Test for {@link org.opendaylight.openflowplugin.impl.services.sal.SalFlatBatchServiceImpl}. */ @RunWith(MockitoJUnitRunner.class) public class SalFlatBatchServiceImplTest { @@ -555,4 +555,4 @@ public class SalFlatBatchServiceImplTest { Mockito.verify(salFlowsBatchService, Mockito.times(2)).addFlowsBatch(addFlowsBatchInputCpt.capture()); Assert.assertEquals(2, addFlowsBatchInputCpt.getValue().getBatchAddFlows().size()); } -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalFlowServiceImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalFlowServiceImplTest.java similarity index 98% rename from openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalFlowServiceImplTest.java rename to openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalFlowServiceImplTest.java index 46af7563d9..9918d9b953 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalFlowServiceImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalFlowServiceImplTest.java @@ -1,11 +1,11 @@ /* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import static org.mockito.Mockito.mock; @@ -39,6 +39,7 @@ import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowDescriptor import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey; import org.opendaylight.openflowplugin.api.openflow.rpc.listener.ItemLifecycleListener; import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy; +import org.opendaylight.openflowplugin.impl.services.sal.SalFlowServiceImpl; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; @@ -144,7 +145,7 @@ public class SalFlowServiceImplTest extends TestCase { when(mockedDeviceInfo.getVersion()).thenReturn(version); if (OFConstants.OFP_VERSION_1_3 >= version) { - when(mockedDeviceContext.isUseSingleLayerSerialization()).thenReturn(true); + when(mockedDeviceContext.canUseSingleLayerSerialization()).thenReturn(true); } final ConvertorManager convertorManager = ConvertorManagerFactory.createDefaultManager(); diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalFlowsBatchServiceImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalFlowsBatchServiceImplTest.java similarity index 98% rename from openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalFlowsBatchServiceImplTest.java rename to openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalFlowsBatchServiceImplTest.java index 15a9aa291e..bea9d1c9d8 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalFlowsBatchServiceImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalFlowsBatchServiceImplTest.java @@ -1,12 +1,12 @@ /* - * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import com.google.common.collect.Lists; import java.util.List; @@ -67,7 +67,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * Test for {@link SalFlowsBatchServiceImpl}. + * Test for {@link org.opendaylight.openflowplugin.impl.services.sal.SalFlowsBatchServiceImpl}. */ @RunWith(MockitoJUnitRunner.class) public class SalFlowsBatchServiceImplTest { @@ -336,4 +336,4 @@ public class SalFlowsBatchServiceImplTest { inOrder.verify(transactionService).sendBarrier(Matchers.any()); } -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalGroupServiceImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalGroupServiceImplTest.java similarity index 96% rename from openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalGroupServiceImplTest.java rename to openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalGroupServiceImplTest.java index f0814d8962..3581bf81aa 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalGroupServiceImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalGroupServiceImplTest.java @@ -1,11 +1,11 @@ /* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; @@ -17,6 +17,7 @@ import org.mockito.Matchers; import org.mockito.Mock; import org.opendaylight.openflowplugin.api.openflow.registry.group.DeviceGroupRegistry; import org.opendaylight.openflowplugin.api.openflow.rpc.listener.ItemLifecycleListener; +import org.opendaylight.openflowplugin.impl.services.ServiceMocking; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput; diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalGroupsBatchServiceImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalGroupsBatchServiceImplTest.java similarity index 98% rename from openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalGroupsBatchServiceImplTest.java rename to openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalGroupsBatchServiceImplTest.java index a0daaa4db6..5341126ba7 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalGroupsBatchServiceImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalGroupsBatchServiceImplTest.java @@ -1,12 +1,12 @@ /* - * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import com.google.common.collect.Lists; import java.util.List; @@ -23,6 +23,7 @@ import org.mockito.Matchers; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; +import org.opendaylight.openflowplugin.impl.services.sal.SalGroupsBatchServiceImpl; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.FlowCapableTransactionService; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.SendBarrierInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput; @@ -64,7 +65,7 @@ import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; /** - * Test for {@link SalGroupsBatchServiceImpl}. + * Test for {@link org.opendaylight.openflowplugin.impl.services.sal.SalGroupsBatchServiceImpl}. */ @RunWith(MockitoJUnitRunner.class) public class SalGroupsBatchServiceImplTest { @@ -311,4 +312,4 @@ public class SalGroupsBatchServiceImplTest { .setUpdatedBatchedGroup(new UpdatedBatchedGroupBuilder(createEmptyBatchAddGroup(groupIdValue+1)).build()) .build(); } -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalMeterServiceImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalMeterServiceImplTest.java similarity index 96% rename from openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalMeterServiceImplTest.java rename to openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalMeterServiceImplTest.java index ea20a88647..75debf6b46 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalMeterServiceImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalMeterServiceImplTest.java @@ -1,11 +1,11 @@ /* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; @@ -17,6 +17,7 @@ import org.mockito.Matchers; import org.mockito.Mock; import org.opendaylight.openflowplugin.api.openflow.registry.meter.DeviceMeterRegistry; import org.opendaylight.openflowplugin.api.openflow.rpc.listener.ItemLifecycleListener; +import org.opendaylight.openflowplugin.impl.services.ServiceMocking; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter; diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalMetersBatchServiceImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalMetersBatchServiceImplTest.java similarity index 98% rename from openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalMetersBatchServiceImplTest.java rename to openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalMetersBatchServiceImplTest.java index 6873615013..3e8bed9c2a 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalMetersBatchServiceImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalMetersBatchServiceImplTest.java @@ -1,12 +1,12 @@ /* - * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import com.google.common.collect.Lists; import java.util.List; @@ -23,6 +23,7 @@ import org.mockito.Matchers; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; +import org.opendaylight.openflowplugin.impl.services.sal.SalMetersBatchServiceImpl; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.FlowCapableTransactionService; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.SendBarrierInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; @@ -64,7 +65,7 @@ import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; /** - * Test for {@link SalMetersBatchServiceImpl}. + * Test for {@link org.opendaylight.openflowplugin.impl.services.sal.SalMetersBatchServiceImpl}. */ @RunWith(MockitoJUnitRunner.class) public class SalMetersBatchServiceImplTest { @@ -310,4 +311,4 @@ public class SalMetersBatchServiceImplTest { .setUpdatedBatchedMeter(new UpdatedBatchedMeterBuilder(createEmptyBatchAddMeter(groupIdValue + 1)).build()) .build(); } -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalPortServiceImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalPortServiceImplTest.java similarity index 93% rename from openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalPortServiceImplTest.java rename to openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalPortServiceImplTest.java index c0d55986fc..dd8ae67e42 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalPortServiceImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalPortServiceImplTest.java @@ -1,11 +1,11 @@ /* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import static org.mockito.Mockito.verify; @@ -15,6 +15,8 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.runners.MockitoJUnitRunner; import org.opendaylight.openflowplugin.api.openflow.device.Xid; +import org.opendaylight.openflowplugin.impl.services.ServiceMocking; +import org.opendaylight.openflowplugin.impl.services.sal.SalPortServiceImpl; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalRoleServiceImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalRoleServiceImplTest.java similarity index 97% rename from openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalRoleServiceImplTest.java rename to openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalRoleServiceImplTest.java index 0c7d7586e4..74ec78da76 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalRoleServiceImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalRoleServiceImplTest.java @@ -1,11 +1,11 @@ -/** - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -30,6 +30,7 @@ import org.opendaylight.openflowplugin.api.openflow.device.RequestContext; import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack; import org.opendaylight.openflowplugin.api.openflow.device.Xid; import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy; +import org.opendaylight.openflowplugin.impl.services.sal.SalRoleServiceImpl; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef; diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalTableServiceImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalTableServiceImplTest.java similarity index 95% rename from openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalTableServiceImplTest.java rename to openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalTableServiceImplTest.java index 3bf020e83e..1810e8b429 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/SalTableServiceImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/sal/SalTableServiceImplTest.java @@ -1,11 +1,11 @@ /* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.services; +package org.opendaylight.openflowplugin.impl.services.sal; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -27,6 +27,8 @@ import org.mockito.stubbing.Answer; import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; import org.opendaylight.openflowplugin.api.OFConstants; import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProviderFactory; +import org.opendaylight.openflowplugin.impl.services.ServiceMocking; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; @@ -74,7 +76,7 @@ public class SalTableServiceImplTest extends ServiceMocking { final ConvertorManager convertorManager = ConvertorManagerFactory.createDefaultManager(); salTableService = new SalTableServiceImpl(mockedRequestContextStack, mockedDeviceContext, - convertorManager); + convertorManager, MultipartWriterProviderFactory.createDefaultProvider(mockedDeviceContext)); } @Test diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/SinglePurposeMultipartReplyTranslatorTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/MultipartReplyTranslatorTest.java similarity index 80% rename from openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/SinglePurposeMultipartReplyTranslatorTest.java rename to openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/MultipartReplyTranslatorTest.java index b531cbd950..107a78574e 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/SinglePurposeMultipartReplyTranslatorTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/MultipartReplyTranslatorTest.java @@ -21,16 +21,16 @@ import org.junit.Test; 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.impl.common.MultipartReplyTranslatorUtil; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdate; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionAware; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupDescStatsUpdated; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupStatisticsUpdated; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowAndStatisticsMapList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupDescStatsReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupStatisticsReply; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.AggregateFlowStatistics; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupId; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupType; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; @@ -54,15 +54,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc._case.multipart.reply.group.desc.GroupDescBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStatsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.multipart.reply.port.stats.PortStatsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdate; import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap; -import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.DataContainer; -public class SinglePurposeMultipartReplyTranslatorTest { +public class MultipartReplyTranslatorTest { private static final BigInteger DUMMY_DATAPATH_ID = new BigInteger("21"); private static final Long DUMMY_XID = 1L; - private SinglePurposeMultipartReplyTranslator singlePurposeMultipartReplyTranslator; private static final BigInteger DUMMY_BYTE_COUNT = new BigInteger("31"); private static final BigInteger DUMMY_PACKET_COUNT = new BigInteger("41"); private static final Long DUMMY_FLOW_COUNT = 51L; @@ -85,11 +83,10 @@ public class SinglePurposeMultipartReplyTranslatorTest { private static final Long DUMMY_REF_COUNT = 1234L; private static final GroupTypes DUMMY_GROUPS_TYPE = GroupTypes.GroupAll; private static final GroupType DUMMY_GROUP_TYPE = GroupType.OFPGTALL; + private static final ConvertorManager convertorManager = ConvertorManagerFactory.createDefaultManager(); @Before public void setUp() { - final ConvertorManager convertorManager = ConvertorManagerFactory.createDefaultManager(); - singlePurposeMultipartReplyTranslator = new SinglePurposeMultipartReplyTranslator(convertorManager); } @Test @@ -98,13 +95,14 @@ public class SinglePurposeMultipartReplyTranslatorTest { MultipartReplyMessage multipartReplyMessage = prepareMocks(mockedDeviceContext, prepareMultipartReplyFlow(), MultipartType.OFPMPFLOW); - List result = singlePurposeMultipartReplyTranslator.translate( - mockedDeviceContext.getPrimaryConnectionContext().getFeatures().getDatapathId(), - mockedDeviceContext.getPrimaryConnectionContext().getFeatures().getVersion(), - multipartReplyMessage); + DataContainer result = MultipartReplyTranslatorUtil.translate( + multipartReplyMessage, + mockedDeviceContext.getDeviceInfo(), + convertorManager, + mockedDeviceContext.oook()).get(); - DataObject dataObject = validateOutput(result); - assertTrue(dataObject instanceof FlowsStatisticsUpdate); + DataContainer dataObject = validateOutput(result); + assertTrue(dataObject instanceof FlowAndStatisticsMapList); } @Test @@ -113,14 +111,15 @@ public class SinglePurposeMultipartReplyTranslatorTest { MultipartReplyMessage multipartReplyMessage = prepareMocks(mockedDeviceContext, prepareMultipartReplyAggregate(), MultipartType.OFPMPAGGREGATE); - List result = singlePurposeMultipartReplyTranslator.translate( - mockedDeviceContext.getPrimaryConnectionContext().getFeatures().getDatapathId(), - mockedDeviceContext.getPrimaryConnectionContext().getFeatures().getVersion(), - multipartReplyMessage); + DataContainer result = MultipartReplyTranslatorUtil.translate( + multipartReplyMessage, + mockedDeviceContext.getDeviceInfo(), + convertorManager, + mockedDeviceContext.oook()).get(); - DataObject dataObject = validateOutput(result); - assertTrue(dataObject instanceof AggregateFlowStatisticsUpdate); - AggregateFlowStatisticsUpdate message = (AggregateFlowStatisticsUpdate)dataObject; + DataContainer dataObject = validateOutput(result); + assertTrue(dataObject instanceof AggregateFlowStatistics); + AggregateFlowStatistics message = (AggregateFlowStatistics)dataObject; assertEquals(DUMMY_BYTE_COUNT, message.getByteCount().getValue()); assertEquals(DUMMY_PACKET_COUNT, message.getPacketCount().getValue()); assertEquals(DUMMY_FLOW_COUNT, message.getFlowCount().getValue()); @@ -132,14 +131,15 @@ public class SinglePurposeMultipartReplyTranslatorTest { MultipartReplyMessage multipartReplyMessage = prepareMocks(mockedDeviceContext, prepareMultipartReplyPortStats(), MultipartType.OFPMPPORTSTATS); - List result = singlePurposeMultipartReplyTranslator.translate( - mockedDeviceContext.getPrimaryConnectionContext().getFeatures().getDatapathId(), - mockedDeviceContext.getPrimaryConnectionContext().getFeatures().getVersion(), - multipartReplyMessage); + DataContainer result = MultipartReplyTranslatorUtil.translate( + multipartReplyMessage, + mockedDeviceContext.getDeviceInfo(), + convertorManager, + mockedDeviceContext.oook()).get(); - DataObject dataObject = validateOutput(result); - assertTrue(dataObject instanceof NodeConnectorStatisticsUpdate); - NodeConnectorStatisticsUpdate nodeConnectorStatisticsUpdate = (NodeConnectorStatisticsUpdate)dataObject; + DataContainer dataObject = validateOutput(result); + assertTrue(dataObject instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsAndPortNumberMap); + org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsAndPortNumberMap nodeConnectorStatisticsUpdate = (org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsAndPortNumberMap)dataObject; List nodeConnectorStatisticsAndPortNumberMaps = nodeConnectorStatisticsUpdate.getNodeConnectorStatisticsAndPortNumberMap(); assertEquals(1, nodeConnectorStatisticsAndPortNumberMaps.size()); NodeConnectorStatisticsAndPortNumberMap nodeConnectorStatisticsAndPortNumberMap = nodeConnectorStatisticsAndPortNumberMaps.get(0); @@ -164,14 +164,15 @@ public class SinglePurposeMultipartReplyTranslatorTest { MultipartReplyMessage multipartReplyMessage = prepareMocks(mockedDeviceContext, prepareMultipartReplyGroup(), MultipartType.OFPMPGROUP); - List result = singlePurposeMultipartReplyTranslator.translate( - mockedDeviceContext.getPrimaryConnectionContext().getFeatures().getDatapathId(), - mockedDeviceContext.getPrimaryConnectionContext().getFeatures().getVersion(), - multipartReplyMessage); + DataContainer result = MultipartReplyTranslatorUtil.translate( + multipartReplyMessage, + mockedDeviceContext.getDeviceInfo(), + convertorManager, + mockedDeviceContext.oook()).get(); - DataObject dataObject = validateOutput(result); - assertTrue(dataObject instanceof GroupStatisticsUpdated); - GroupStatisticsUpdated groupStatisticsUpdate = (GroupStatisticsUpdated)dataObject; + DataContainer dataObject = validateOutput(result); + assertTrue(dataObject instanceof GroupStatisticsReply); + GroupStatisticsReply groupStatisticsUpdate = (GroupStatisticsReply)dataObject; List groupStats = groupStatisticsUpdate.getGroupStats(); assertEquals(1, groupStats.size()); org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats groupStat = groupStats.get(0); @@ -190,14 +191,15 @@ public class SinglePurposeMultipartReplyTranslatorTest { MultipartReplyMessage multipartReplyMessage = prepareMocks(mockedDeviceContext, prepareMultipartReplyGroupDesc(), MultipartType.OFPMPGROUPDESC); - List result = singlePurposeMultipartReplyTranslator.translate( - mockedDeviceContext.getPrimaryConnectionContext().getFeatures().getDatapathId(), - mockedDeviceContext.getPrimaryConnectionContext().getFeatures().getVersion(), - multipartReplyMessage); + DataContainer result = MultipartReplyTranslatorUtil.translate( + multipartReplyMessage, + mockedDeviceContext.getDeviceInfo(), + convertorManager, + mockedDeviceContext.oook()).get(); - DataObject dataObject = validateOutput(result); - assertTrue(dataObject instanceof GroupDescStatsUpdated); - GroupDescStatsUpdated groupStatistics = (GroupDescStatsUpdated) dataObject; + DataContainer dataObject = validateOutput(result); + assertTrue(dataObject instanceof GroupDescStatsReply); + GroupDescStatsReply groupStatistics = (GroupDescStatsReply) dataObject; List groupDescStats = groupStatistics.getGroupDescStats(); assertEquals(1, groupDescStats.size()); GroupDescStats groupDescStat = groupDescStats.get(0); @@ -283,6 +285,12 @@ public class SinglePurposeMultipartReplyTranslatorTest { when(mockedFeaturesReply.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3); when(mockedFeaturesReply.getDatapathId()).thenReturn(DUMMY_DATAPATH_ID); + DeviceInfo deviceInfo = mock(DeviceInfo.class); + when(deviceInfo.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3); + when(deviceInfo.getDatapathId()).thenReturn(DUMMY_DATAPATH_ID); + when(deviceInfo.getLOGValue()).thenReturn(DUMMY_DATAPATH_ID.toString()); + when(mockedDeviceContext.getDeviceInfo()).thenReturn(deviceInfo); + when(mockedConnectionContext.getFeatures()).thenReturn(mockedFeaturesReply); when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(mockedConnectionContext); @@ -295,13 +303,7 @@ public class SinglePurposeMultipartReplyTranslatorTest { } - private DataObject validateOutput(List input) { - assertEquals(input.size(), 1); - DataObject dataObject = input.get(0); - assertTrue(dataObject instanceof Node); - assertEquals("openflow:" + DUMMY_DATAPATH_ID, ((Node) dataObject).getId().getValue()); - assertTrue(dataObject instanceof TransactionAware); - assertEquals(new BigInteger(DUMMY_XID.toString()), ((TransactionAware) dataObject).getTransactionId().getValue()); + private DataContainer validateOutput(DataContainer dataObject) { return dataObject; } } diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpMockInitiation.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpMockInitiation.java index 55b18f5600..f45f98d022 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpMockInitiation.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpMockInitiation.java @@ -29,6 +29,7 @@ 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.MultipartReply; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; @@ -44,8 +45,8 @@ class StatisticsContextImpMockInitiation { protected DeviceContext mockedDeviceContext; protected DeviceState mockedDeviceState; - StatisticsGatheringService mockedStatisticsGatheringService; - StatisticsGatheringOnTheFlyService mockedStatisticsOnFlyGatheringService; + StatisticsGatheringService mockedStatisticsGatheringService; + StatisticsGatheringOnTheFlyService mockedStatisticsOnFlyGatheringService; ConnectionContext mockedConnectionContext; DeviceInfo mockedDeviceInfo; StatisticsManager mockedStatisticsManager; diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImplParamTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImplParamTest.java index 3df476ab35..7cc74efbd1 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImplParamTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImplParamTest.java @@ -23,6 +23,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProviderFactory; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; @@ -67,7 +68,8 @@ public class StatisticsContextImplParamTest extends StatisticsContextImpMockInit when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState); final ConvertorManager convertorManager = ConvertorManagerFactory.createDefaultManager(); - final StatisticsContextImpl statisticsContext = new StatisticsContextImpl(mockedDeviceInfo, true, lifecycleService ,convertorManager, mockedStatisticsManager); + final StatisticsContextImpl statisticsContext = new StatisticsContextImpl<>(mockedDeviceInfo, true, lifecycleService ,convertorManager, mockedStatisticsManager, + MultipartWriterProviderFactory.createDefaultProvider(mockedDeviceContext)); final ListenableFuture>> rpcResult = immediateFuture(RpcResultBuilder.success(Collections.emptyList()).build()); when(mockedStatisticsGatheringService.getStatisticsOfType(any(EventIdentifier.class), any(MultipartType diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImplTest.java index c31e57286b..11e0371032 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImplTest.java @@ -28,6 +28,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.openflowplugin.impl.datastore.MultipartWriterProviderFactory; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; @@ -43,7 +44,7 @@ public class StatisticsContextImplTest extends StatisticsContextImpMockInitiatio private static final Logger LOG = LoggerFactory.getLogger(StatisticsContextImplTest.class); private static final Long TEST_XID = 55L; - private StatisticsContextImpl statisticsContext; + private StatisticsContextImpl statisticsContext; private ConvertorManager convertorManager; @Before @@ -56,7 +57,9 @@ public class StatisticsContextImplTest extends StatisticsContextImpMockInitiatio } private void initStatisticsContext() { - statisticsContext = new StatisticsContextImpl(mockedDeviceInfo, true, lifecycleService, convertorManager, mockedStatisticsManager); + statisticsContext = new StatisticsContextImpl<>(mockedDeviceInfo, true, lifecycleService, convertorManager, mockedStatisticsManager, + MultipartWriterProviderFactory.createDefaultProvider(mockedDeviceContext)); + statisticsContext.setStatisticsGatheringService(mockedStatisticsGatheringService); statisticsContext.setStatisticsGatheringOnTheFlyService(mockedStatisticsOnFlyGatheringService); } @@ -74,7 +77,9 @@ public class StatisticsContextImplTest extends StatisticsContextImpMockInitiatio */ @Test public void testClose() throws Exception { - final StatisticsContextImpl statisticsContext = new StatisticsContextImpl(mockedDeviceInfo, true, lifecycleService, convertorManager, mockedStatisticsManager); + final StatisticsContextImpl statisticsContext = new StatisticsContextImpl<>(mockedDeviceInfo, true, lifecycleService, convertorManager, mockedStatisticsManager, + MultipartWriterProviderFactory.createDefaultProvider(mockedDeviceContext)); + final RequestContext requestContext = statisticsContext.createRequestContext(); statisticsContext.close(); try { diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsGatheringUtilsTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsGatheringUtilsTest.java index e6d11dae11..9635fc23ed 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsGatheringUtilsTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsGatheringUtilsTest.java @@ -40,7 +40,6 @@ 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.FlowDescriptor; import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey; @@ -48,8 +47,8 @@ import org.opendaylight.openflowplugin.api.openflow.registry.group.DeviceGroupRe 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; -import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProviderFactory; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder; @@ -164,18 +163,14 @@ public class StatisticsGatheringUtilsTest { @Mock private ConnectionContext connectionAdapter; @Mock - private StatisticsGatherer statisticsService; + private StatisticsGatherer statisticsService; @Mock private DeviceInfo deviceInfo; - @Mock - private TxFacade txFacade; - private SinglePurposeMultipartReplyTranslator singlePurposeMultipartReplyTranslator; + private MultipartWriterProvider provider; @Before public void setUp() throws Exception { - final ConvertorManager convertorManager = ConvertorManagerFactory.createDefaultManager(); - singlePurposeMultipartReplyTranslator = new SinglePurposeMultipartReplyTranslator(convertorManager); when(deviceContext.getDeviceState()).thenReturn(deviceState); when(deviceContext.getDeviceInfo()).thenReturn(deviceInfo); when(deviceContext.getDeviceFlowRegistry()).thenReturn(deviceFlowRegistry); @@ -183,17 +178,17 @@ public class StatisticsGatheringUtilsTest { when(deviceContext.getDeviceMeterRegistry()).thenReturn(deviceMeterRegistry); when(deviceFlowRegistry.retrieveIdForFlow(Matchers.any(FlowRegistryKey.class))).thenReturn(flowDescriptor); when(deviceContext.getReadTransaction()).thenReturn(readTx); - when(txFacade.getReadTransaction()).thenReturn(readTx); + when(deviceContext.getReadTransaction()).thenReturn(readTx); when(deviceContext.getPrimaryConnectionContext()).thenReturn(connectionAdapter); when(connectionAdapter.getNodeId()).thenReturn(DUMMY_NODE_ID); when(connectionAdapter.getFeatures()).thenReturn(features); when(features.getDatapathId()).thenReturn(BigInteger.ONE); when(features.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3); - 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); + provider = MultipartWriterProviderFactory.createDefaultProvider(deviceContext); } @Test @@ -202,8 +197,7 @@ public class StatisticsGatheringUtilsTest { final ArgumentCaptor flowPath = ArgumentCaptor.forClass(InstanceIdentifier.class); final ArgumentCaptor flow = ArgumentCaptor.forClass(Flow.class); - StatisticsGatheringUtils.writeFlowStatistics(prepareFlowStatisticsData(), - deviceInfo, deviceContext.getDeviceFlowRegistry(), deviceContext); + provider.lookup(MultipartType.OFPMPFLOW).get().write(prepareFlowStatisticsData().iterator().next(), false); Mockito.verify(deviceContext).writeToTransaction( dataStoreType.capture(), flowPath.capture(), flow.capture()); @@ -252,7 +246,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(txFacade).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL), + verify(deviceContext).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.eq(groupPath), Matchers.any(GroupStatistics.class)); } @@ -283,7 +277,7 @@ public class StatisticsGatheringUtilsTest { verify(deviceContext, Mockito.never()).addDeleteToTxChain(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.> any()); verify(deviceGroupRegistry).removeMarked(); verify(deviceGroupRegistry).store(storedGroupId); - verify(txFacade).writeToTransaction( + verify(deviceContext).writeToTransaction( Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.eq(groupPath), Matchers.any(Group.class)); } @@ -317,7 +311,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(txFacade).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL), + verify(deviceContext).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.eq(meterPath), Matchers.any(MeterStatistics.class)); } @@ -341,7 +335,7 @@ public class StatisticsGatheringUtilsTest { .child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId("openflow:" + DUMMY_NODE_ID_VALUE + ":11"))) .augmentation(FlowCapableNodeConnectorStatisticsData.class) .child(FlowCapableNodeConnectorStatistics.class); - verify(txFacade).writeToTransaction( + verify(deviceContext).writeToTransaction( Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.eq(portPath), Matchers.any(FlowCapableNodeConnectorStatistics.class)); @@ -371,7 +365,7 @@ public class StatisticsGatheringUtilsTest { .child(Table.class, new TableKey((short) 0)) .augmentation(FlowTableStatisticsData.class) .child(FlowTableStatistics.class); - verify(txFacade).writeToTransaction( + verify(deviceContext).writeToTransaction( Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.eq(tablePath), Matchers.any(FlowTableStatistics.class)); @@ -405,7 +399,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(txFacade).writeToTransaction( + verify(deviceContext).writeToTransaction( Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.eq(queuePath), Matchers.any(Queue.class)); @@ -456,8 +450,8 @@ public class StatisticsGatheringUtilsTest { verify(deviceContext, Mockito.never()).addDeleteToTxChain(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.>any()); - final InOrder inOrder = Mockito.inOrder(txFacade); - inOrder.verify(txFacade).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.eq(tablePath), Matchers.any(Table.class)); + final InOrder inOrder = Mockito.inOrder(deviceContext); + inOrder.verify(deviceContext).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.eq(tablePath), Matchers.any(Table.class)); } @Test @@ -486,7 +480,7 @@ public class StatisticsGatheringUtilsTest { .child(Meter.class, new MeterKey(meterId)); verify(deviceContext, Mockito.never()).addDeleteToTxChain(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.>any()); verify(deviceMeterRegistry).store(meterId); - verify(txFacade).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.eq(meterPath), Matchers.any(Meter.class)); + verify(deviceContext).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.eq(meterPath), Matchers.any(Meter.class)); } private void fireAndCheck(final MultipartType type, final List statsData) throws InterruptedException, ExecutionException, TimeoutException { @@ -494,15 +488,17 @@ public class StatisticsGatheringUtilsTest { .thenReturn(Futures.immediateFuture(RpcResultBuilder.success(statsData).build())); final ListenableFuture gatherStatisticsResult = StatisticsGatheringUtils.gatherStatistics( - statisticsService, - deviceInfo, - type, - txFacade, - deviceContext, - false, - singlePurposeMultipartReplyTranslator); - Assert.assertTrue(gatherStatisticsResult.get(1, TimeUnit.SECONDS).booleanValue()); - verify(txFacade).submitTransaction(); + statisticsService, + deviceInfo, + type, + deviceContext, + deviceContext, + false, + ConvertorManagerFactory.createDefaultManager(), + provider); + + Assert.assertTrue(gatherStatisticsResult.get(1, TimeUnit.SECONDS)); + verify(deviceContext).submitTransaction(); } private static MultipartReplyMessage assembleMPReplyMessage(final MultipartType type, final MultipartReplyBody mpReplyGroupCaseBld) { @@ -532,10 +528,10 @@ public class StatisticsGatheringUtilsTest { final KeyedInstanceIdentifier tablePath = deviceInfo.getNodeInstanceIdentifier() .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(tableId)); - StatisticsGatheringUtils.deleteAllKnownFlows(deviceInfo, - deviceContext.getDeviceFlowRegistry(), txFacade); + StatisticsGatheringUtils.deleteAllKnownFlows(deviceContext, deviceInfo.getNodeInstanceIdentifier() + .augmentation(FlowCapableNode.class), false); - verify(txFacade).writeToTransaction( + verify(deviceContext).writeToTransaction( LogicalDatastoreType.OPERATIONAL, tablePath, tableDataBld.setFlow(Collections.emptyList()).build()); diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/AbstractSingleStatsServiceTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/AbstractSingleStatsServiceTest.java index 8140e84d59..7cb1ab1a15 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/AbstractSingleStatsServiceTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/AbstractSingleStatsServiceTest.java @@ -50,7 +50,7 @@ public abstract class AbstractSingleStatsServiceTest extends AbstractStatsServic }; Mockito.when(rqContextStack.createRequestContext()).thenReturn(rqContext); - Mockito.doAnswer(closeRequestFutureAnswer).when(multiMsgCollector).endCollecting(); + Mockito.doAnswer(closeRequestFutureAnswer).when(multiMsgCollector).endCollecting(null); Mockito.doAnswer(closeRequestFutureAnswer).when(multiMsgCollector).endCollecting(Matchers.any(EventIdentifier.class)); } } diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/AbstractCompatibleStatServiceTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/AbstractCompatibleStatServiceTest.java index fa05edea0e..b208416adf 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/AbstractCompatibleStatServiceTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/compatibility/AbstractCompatibleStatServiceTest.java @@ -101,7 +101,7 @@ public class AbstractCompatibleStatServiceTest extends AbstractStatsServiceTest 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(null); Mockito.doAnswer(closeRequestFutureAnswer).when(multiMsgCollector).endCollecting(Matchers.any(EventIdentifier.class)); Mockito.doAnswer(answerVoidToCallback).when(outboundQueueProvider) diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/dedicated/StatisticsGatheringOnTheFlyServiceTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/dedicated/StatisticsGatheringOnTheFlyServiceTest.java index dd292d112d..905f8a2c88 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/dedicated/StatisticsGatheringOnTheFlyServiceTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/dedicated/StatisticsGatheringOnTheFlyServiceTest.java @@ -13,11 +13,13 @@ import org.junit.Test; import org.mockito.Mockito; import org.opendaylight.openflowplugin.api.openflow.device.Xid; import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProviderFactory; import org.opendaylight.openflowplugin.impl.services.ServiceMocking; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory; 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.MultipartReply; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; @@ -27,12 +29,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731 public class StatisticsGatheringOnTheFlyServiceTest extends ServiceMocking { public static final NodeId NODE_ID = new NodeId(DUMMY_NODE_ID); - private StatisticsGatheringOnTheFlyService statisticsGatheringService; + private StatisticsGatheringOnTheFlyService statisticsGatheringService; @Override protected void setup() { final ConvertorManager convertorManager = ConvertorManagerFactory.createDefaultManager(); - statisticsGatheringService = new StatisticsGatheringOnTheFlyService(mockedRequestContextStack, mockedDeviceContext, convertorManager); + statisticsGatheringService = new StatisticsGatheringOnTheFlyService<>(mockedRequestContextStack, mockedDeviceContext, convertorManager, MultipartWriterProviderFactory.createDefaultProvider(mockedDeviceContext)); Mockito.doReturn(NODE_ID).when(mockedPrimConnectionContext).getNodeId(); Mockito.when(mockedDeviceInfo.getNodeId()).thenReturn(NODE_ID); Mockito.when(mockedDeviceContext.getDeviceInfo().getNodeId()).thenReturn(NODE_ID); @@ -54,4 +56,4 @@ public class StatisticsGatheringOnTheFlyServiceTest extends ServiceMocking { Assert.assertEquals(xidValue, request.getXid().longValue()); Assert.assertNotNull(request); } -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractDirectStatisticsServiceTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractDirectStatisticsServiceTest.java index 16929cacb7..f9f367bebe 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractDirectStatisticsServiceTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/AbstractDirectStatisticsServiceTest.java @@ -28,6 +28,8 @@ import org.opendaylight.openflowplugin.api.openflow.device.TranslatorLibrary; import org.opendaylight.openflowplugin.api.openflow.device.handlers.MultiMsgCollector; import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion; import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; +import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProviderFactory; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory; import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil; @@ -75,7 +77,7 @@ public abstract class AbstractDirectStatisticsServiceTest { protected NodeConnectorId nodeConnectorId; protected KeyedInstanceIdentifier nodeInstanceIdentifier; protected ConvertorManager convertorManager; - + protected MultipartWriterProvider multipartWriterProvider; protected static NodeRef createNodeRef(String nodeIdValue) { InstanceIdentifier nodePath = InstanceIdentifier.create(Nodes.class) .child(Node.class, new NodeKey(new NodeId(nodeIdValue))); @@ -93,7 +95,6 @@ public abstract class AbstractDirectStatisticsServiceTest { .child(Node.class, new NodeKey(new NodeId(NODE_ID))); convertorManager = ConvertorManagerFactory.createDefaultManager(); - when(deviceContext.getPrimaryConnectionContext()).thenReturn(connectionContext); when(deviceContext.getMessageSpy()).thenReturn(messageSpy); when(deviceContext.getMultiMsgCollector(any())).thenReturn(multiMsgCollector); @@ -110,6 +111,7 @@ public abstract class AbstractDirectStatisticsServiceTest { when(connectionContext.getOutboundQueueProvider()).thenReturn(outboundQueueProvider); when(features.getVersion()).thenReturn(OF_VERSION); when(features.getDatapathId()).thenReturn(DATAPATH_ID); + multipartWriterProvider = MultipartWriterProviderFactory.createDefaultProvider(deviceContext); setUp(); } @@ -123,4 +125,4 @@ public abstract class AbstractDirectStatisticsServiceTest { @Test public abstract void testStoreStatistics() throws Exception; -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/OpendaylightDirectStatisticsServiceImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/OpendaylightDirectStatisticsServiceImplTest.java index 33b0746aa9..73ef8601bd 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/OpendaylightDirectStatisticsServiceImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/OpendaylightDirectStatisticsServiceImplTest.java @@ -35,15 +35,15 @@ import org.opendaylight.yangtools.yang.common.RpcResult; @RunWith(MockitoJUnitRunner.class) public class OpendaylightDirectStatisticsServiceImplTest { @Mock - FlowDirectStatisticsService flowDirectStatisticsService; + AbstractFlowDirectStatisticsService flowDirectStatisticsService; @Mock - GroupDirectStatisticsService groupDirectStatisticsService; + AbstractGroupDirectStatisticsService groupDirectStatisticsService; @Mock - MeterDirectStatisticsService meterDirectStatisticsService; + AbstractMeterDirectStatisticsService meterDirectStatisticsService; @Mock - NodeConnectorDirectStatisticsService nodeConnectorDirectStatisticsService; + AbstractPortDirectStatisticsService nodeConnectorDirectStatisticsService; @Mock - QueueDirectStatisticsService queueDirectStatisticsService; + AbstractQueueDirectStatisticsService queueDirectStatisticsService; @Mock GetGroupStatisticsInput getGroupStatisticsInput; @@ -55,18 +55,18 @@ public class OpendaylightDirectStatisticsServiceImplTest { GetMeterStatisticsInput getMeterStatisticsInput; @Mock GetNodeConnectorStatisticsInput getNodeConnectorStatisticsInput; - + private OpendaylightDirectStatisticsService service; private OpendaylightDirectStatisticsService emptyService; @Before public void setUp() throws Exception { final OpendaylightDirectStatisticsServiceProvider provider = new OpendaylightDirectStatisticsServiceProvider(); - provider.register(FlowDirectStatisticsService.class, flowDirectStatisticsService); - provider.register(GroupDirectStatisticsService.class, groupDirectStatisticsService); - provider.register(MeterDirectStatisticsService.class, meterDirectStatisticsService); - provider.register(NodeConnectorDirectStatisticsService.class, nodeConnectorDirectStatisticsService); - provider.register(QueueDirectStatisticsService.class, queueDirectStatisticsService); + provider.register(AbstractFlowDirectStatisticsService.class, flowDirectStatisticsService); + provider.register(AbstractGroupDirectStatisticsService.class, groupDirectStatisticsService); + provider.register(AbstractMeterDirectStatisticsService.class, meterDirectStatisticsService); + provider.register(AbstractPortDirectStatisticsService.class, nodeConnectorDirectStatisticsService); + provider.register(AbstractQueueDirectStatisticsService.class, queueDirectStatisticsService); service = new OpendaylightDirectStatisticsServiceImpl(provider); emptyService = new OpendaylightDirectStatisticsServiceImpl(new OpendaylightDirectStatisticsServiceProvider()); @@ -87,7 +87,7 @@ public class OpendaylightDirectStatisticsServiceImplTest { assertFalse(result.isSuccessful()); for (RpcError error : result.getErrors()) { - assertTrue(error.getMessage().contains(GroupDirectStatisticsService.class.getSimpleName())); + assertTrue(error.getMessage().contains(AbstractGroupDirectStatisticsService.class.getSimpleName())); } verify(groupDirectStatisticsService, times(0)).handleAndReply(getGroupStatisticsInput); @@ -108,7 +108,7 @@ public class OpendaylightDirectStatisticsServiceImplTest { assertFalse(result.isSuccessful()); for (RpcError error : result.getErrors()) { - assertTrue(error.getMessage().contains(QueueDirectStatisticsService.class.getSimpleName())); + assertTrue(error.getMessage().contains(AbstractQueueDirectStatisticsService.class.getSimpleName())); } verify(queueDirectStatisticsService, times(0)).handleAndReply(getQueueStatisticsInput); @@ -129,7 +129,7 @@ public class OpendaylightDirectStatisticsServiceImplTest { assertFalse(result.isSuccessful()); for (RpcError error : result.getErrors()) { - assertTrue(error.getMessage().contains(FlowDirectStatisticsService.class.getSimpleName())); + assertTrue(error.getMessage().contains(AbstractFlowDirectStatisticsService.class.getSimpleName())); } verify(flowDirectStatisticsService, times(0)).handleAndReply(getFlowStatisticsInput); @@ -150,7 +150,7 @@ public class OpendaylightDirectStatisticsServiceImplTest { assertFalse(result.isSuccessful()); for (RpcError error : result.getErrors()) { - assertTrue(error.getMessage().contains(MeterDirectStatisticsService.class.getSimpleName())); + assertTrue(error.getMessage().contains(AbstractMeterDirectStatisticsService.class.getSimpleName())); } verify(meterDirectStatisticsService, times(0)).handleAndReply(getMeterStatisticsInput); @@ -171,9 +171,9 @@ public class OpendaylightDirectStatisticsServiceImplTest { assertFalse(result.isSuccessful()); for (RpcError error : result.getErrors()) { - assertTrue(error.getMessage().contains(NodeConnectorDirectStatisticsService.class.getSimpleName())); + assertTrue(error.getMessage().contains(AbstractPortDirectStatisticsService.class.getSimpleName())); } verify(nodeConnectorDirectStatisticsService, times(0)).handleAndReply(getNodeConnectorStatisticsInput); } -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/FlowDirectStatisticsServiceTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/FlowDirectStatisticsServiceTest.java similarity index 92% rename from openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/FlowDirectStatisticsServiceTest.java rename to openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/FlowDirectStatisticsServiceTest.java index 9dd7d6aaf9..e8c734777a 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/FlowDirectStatisticsServiceTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/FlowDirectStatisticsServiceTest.java @@ -1,12 +1,12 @@ /* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.statistics.services.direct; +package org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -22,6 +22,7 @@ import java.util.Collections; import java.util.List; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.openflowplugin.api.openflow.registry.flow.DeviceFlowRegistry; +import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractDirectStatisticsServiceTest; import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; @@ -29,6 +30,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.F import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.MultipartReplyFlow; @@ -43,7 +45,7 @@ public class FlowDirectStatisticsServiceTest extends AbstractDirectStatisticsSer @Override public void setUp() throws Exception { - service = new FlowDirectStatisticsService(requestContextStack, deviceContext, convertorManager); + service = new FlowDirectStatisticsService(requestContextStack, deviceContext, convertorManager, multipartWriterProvider); final DeviceFlowRegistry registry = mock(DeviceFlowRegistry.class); when(registry.storeIfNecessary(any())).thenReturn(new FlowId("1")); when(deviceContext.getDeviceFlowRegistry()).thenReturn(registry); @@ -104,7 +106,7 @@ public class FlowDirectStatisticsServiceTest extends AbstractDirectStatisticsSer final GetFlowStatisticsOutput output = mock(GetFlowStatisticsOutput.class); when(output.getFlowAndStatisticsMapList()).thenReturn(stats); - service.storeStatistics(output); + multipartWriterProvider.lookup(MultipartType.OFPMPFLOW).get().write(output, true); verify(deviceContext).writeToTransactionWithParentsSlow(eq(LogicalDatastoreType.OPERATIONAL), any(), any()); } -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/GroupDirectStatisticsServiceTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/GroupDirectStatisticsServiceTest.java similarity index 91% rename from openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/GroupDirectStatisticsServiceTest.java rename to openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/GroupDirectStatisticsServiceTest.java index ab8cd6072b..e666a16e50 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/GroupDirectStatisticsServiceTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/GroupDirectStatisticsServiceTest.java @@ -1,12 +1,12 @@ /* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.statistics.services.direct; +package org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -21,9 +21,11 @@ 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.impl.statistics.services.direct.AbstractDirectStatisticsServiceTest; import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatisticsInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatisticsOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.MultipartReplyGroup; @@ -38,7 +40,7 @@ public class GroupDirectStatisticsServiceTest extends AbstractDirectStatisticsSe @Override public void setUp() throws Exception { - service = new GroupDirectStatisticsService(requestContextStack, deviceContext, convertorManager); + service = new GroupDirectStatisticsService(requestContextStack, deviceContext, convertorManager, multipartWriterProvider); } @Override @@ -94,7 +96,7 @@ public class GroupDirectStatisticsServiceTest extends AbstractDirectStatisticsSe final GetGroupStatisticsOutput output = mock(GetGroupStatisticsOutput.class); when(output.getGroupStats()).thenReturn(stats); - service.storeStatistics(output); + multipartWriterProvider.lookup(MultipartType.OFPMPGROUP).get().write(output, true); verify(deviceContext).writeToTransactionWithParentsSlow(eq(LogicalDatastoreType.OPERATIONAL), any(), any()); } -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/MeterDirectStatisticsServiceTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/MeterDirectStatisticsServiceTest.java similarity index 91% rename from openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/MeterDirectStatisticsServiceTest.java rename to openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/MeterDirectStatisticsServiceTest.java index ed96db005f..43689cfe21 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/MeterDirectStatisticsServiceTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/MeterDirectStatisticsServiceTest.java @@ -1,12 +1,12 @@ /* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.statistics.services.direct; +package org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -21,9 +21,11 @@ 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.impl.statistics.services.direct.AbstractDirectStatisticsServiceTest; import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatisticsInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatisticsOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.MultipartReplyMeter; @@ -38,7 +40,7 @@ public class MeterDirectStatisticsServiceTest extends AbstractDirectStatisticsSe @Override public void setUp() throws Exception { - service = new MeterDirectStatisticsService(requestContextStack, deviceContext, convertorManager); + service = new MeterDirectStatisticsService(requestContextStack, deviceContext, convertorManager, multipartWriterProvider); } @Override @@ -94,7 +96,7 @@ public class MeterDirectStatisticsServiceTest extends AbstractDirectStatisticsSe final GetMeterStatisticsOutput output = mock(GetMeterStatisticsOutput.class); when(output.getMeterStats()).thenReturn(stats); - service.storeStatistics(output); + multipartWriterProvider.lookup(MultipartType.OFPMPMETER).get().write(output, true); verify(deviceContext).writeToTransactionWithParentsSlow(eq(LogicalDatastoreType.OPERATIONAL), any(), any()); } -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/NodeConnectorDirectStatisticsServiceTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/NodeConnectorDirectStatisticsServiceTest.java similarity index 90% rename from openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/NodeConnectorDirectStatisticsServiceTest.java rename to openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/NodeConnectorDirectStatisticsServiceTest.java index aaaeb7548d..3ab23d9c7f 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/NodeConnectorDirectStatisticsServiceTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/NodeConnectorDirectStatisticsServiceTest.java @@ -1,12 +1,12 @@ /* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.statistics.services.direct; +package org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -20,8 +20,10 @@ 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.openflowplugin.impl.statistics.services.direct.AbstractDirectStatisticsServiceTest; import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStats; @@ -31,11 +33,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap; public class NodeConnectorDirectStatisticsServiceTest extends AbstractDirectStatisticsServiceTest { - private NodeConnectorDirectStatisticsService service; + private PortDirectStatisticsService service; @Override public void setUp() throws Exception { - service = new NodeConnectorDirectStatisticsService(requestContextStack, deviceContext, convertorManager); + service = new PortDirectStatisticsService(requestContextStack, deviceContext, convertorManager, multipartWriterProvider); } @Override @@ -95,7 +97,7 @@ public class NodeConnectorDirectStatisticsServiceTest extends AbstractDirectStat final GetNodeConnectorStatisticsOutput output = mock(GetNodeConnectorStatisticsOutput.class); when(output.getNodeConnectorStatisticsAndPortNumberMap()).thenReturn(stats); - service.storeStatistics(output); + multipartWriterProvider.lookup(MultipartType.OFPMPPORTSTATS).get().write(output, true); verify(deviceContext).writeToTransactionWithParentsSlow(eq(LogicalDatastoreType.OPERATIONAL), any(), any()); } -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/QueueDirectStatisticsServiceTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/QueueDirectStatisticsServiceTest.java similarity index 91% rename from openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/QueueDirectStatisticsServiceTest.java rename to openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/QueueDirectStatisticsServiceTest.java index 388f736303..acca1a4b52 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/QueueDirectStatisticsServiceTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/services/direct/multilayer/QueueDirectStatisticsServiceTest.java @@ -1,12 +1,12 @@ /* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowplugin.impl.statistics.services.direct; +package org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -20,10 +20,12 @@ 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.openflowplugin.impl.statistics.services.direct.AbstractDirectStatisticsServiceTest; import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatisticsInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatisticsOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.MultipartReplyQueue; @@ -38,7 +40,7 @@ public class QueueDirectStatisticsServiceTest extends AbstractDirectStatisticsSe @Override public void setUp() throws Exception { - service = new QueueDirectStatisticsService(requestContextStack, deviceContext, convertorManager); + service = new QueueDirectStatisticsService(requestContextStack, deviceContext, convertorManager, multipartWriterProvider); } @Override @@ -92,7 +94,7 @@ public class QueueDirectStatisticsServiceTest extends AbstractDirectStatisticsSe final GetQueueStatisticsOutput output = mock(GetQueueStatisticsOutput.class); when(output.getQueueIdAndStatisticsMap()).thenReturn(maps); - service.storeStatistics(output); + multipartWriterProvider.lookup(MultipartType.OFPMPQUEUE).get().write(output, true); verify(deviceContext).writeToTransactionWithParentsSlow(eq(LogicalDatastoreType.OPERATIONAL), any(), any()); } -} \ No newline at end of file +} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/util/DeviceInitializationUtilsTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/util/DeviceInitializationUtilsTest.java deleted file mode 100644 index cc6e509e51..0000000000 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/util/DeviceInitializationUtilsTest.java +++ /dev/null @@ -1,370 +0,0 @@ -/* - * 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.impl.util; - -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -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.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 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.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.controller.md.sal.common.api.data.TransactionCommitFailedException; -import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter; -import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueue; -import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueHandler; -import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueHandlerRegistration; -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; -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.MultiMsgCollector; -import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey; -import org.opendaylight.openflowplugin.impl.device.DeviceContextImpl; -import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager; -import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeatures; -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.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeatures; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionType; -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.CapabilitiesV10; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupCapabilities; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupTypes; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterBandTypeBitmap; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterFlags; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FeaturesReply; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessageBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCaseBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupFeaturesCaseBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesCaseBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortDescCaseBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableFeaturesCaseBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.desc._case.MultipartReplyDesc; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.desc._case.MultipartReplyDescBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.features._case.MultipartReplyGroupFeatures; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.features._case.MultipartReplyGroupFeaturesBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.features._case.MultipartReplyMeterFeaturesBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc._case.MultipartReplyPortDescBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc._case.multipart.reply.port.desc.PortsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.MultipartReplyTableFeatures; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.MultipartReplyTableFeaturesBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.multipart.reply.table.features.TableFeatures; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.multipart.reply.table.features.TableFeaturesBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; -import org.opendaylight.yangtools.yang.common.RpcError; -import org.opendaylight.yangtools.yang.common.RpcResult; -import org.opendaylight.yangtools.yang.common.RpcResultBuilder; - -@RunWith(MockitoJUnitRunner.class) -public class DeviceInitializationUtilsTest { - - public static final String DUMMY_NODE_ID = "dummyNodeId"; - public static final NodeId NODE_ID = new NodeId(DUMMY_NODE_ID); - private static final KeyedInstanceIdentifier DUMMY_NODE_II = InstanceIdentifier.create(Nodes.class) - .child(Node.class, new NodeKey(new NodeId(DUMMY_NODE_ID))); - private static final Short DUMMY_TABLE_ID = 1; - private static final Long DUMMY_MAX_METER = 544L; - private static final String DUMMY_DATAPATH_ID = "44"; - private static final Long DUMMY_PORT_NUMBER = 21L; - - @Mock - CheckedFuture mockedFuture; - @Mock - private FeaturesReply mockFeatures; - @Mock - private OutboundQueue outboundQueueProvider; - @Mock - private DeviceInitializationPhaseHandler deviceInitPhaseHandler; - @Mock - private TranslatorLibrary translatorLibrary; - @Mock - private ConnectionContext mockConnectionContext; - @Mock - private ConnectionAdapter mockedConnectionAdapter; - @Mock - private DeviceContextImpl mockedDeviceContext; - @Mock - private DeviceInfo mockedDeviceInfo; - @Mock - private DeviceInitializationUtils deviceInitializationUtils; - @Mock - private DeviceInfo deviceInfo; - - private ConvertorManager convertorManager; - - @Before - public void setUp() throws Exception { - convertorManager = ConvertorManagerFactory.createDefaultManager(); - - when(mockConnectionContext.getNodeId()).thenReturn(NODE_ID); - when(mockConnectionContext.getFeatures()).thenReturn(mockFeatures); - when(mockConnectionContext.getConnectionAdapter()).thenReturn(mockedConnectionAdapter); - when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(mockConnectionContext); - when(mockedDeviceContext.getDeviceInfo()).thenReturn(mockedDeviceInfo); - when(mockedDeviceInfo.getNodeId()).thenReturn(NODE_ID); - - final Capabilities capabilitiesV13 = mock(Capabilities.class); - final CapabilitiesV10 capabilitiesV10 = mock(CapabilitiesV10.class); - when(mockFeatures.getCapabilities()).thenReturn(capabilitiesV13); - when(mockFeatures.getCapabilitiesV10()).thenReturn(capabilitiesV10); - when(mockFeatures.getDatapathId()).thenReturn(BigInteger.valueOf(21L)); - } - - //TODO: need to be rewritten with power mock to properly test statis class - @Test - public void initializeNodeInformationTest() throws Exception { - DeviceState mockedDeviceState = mock(DeviceState.class); - MultiMsgCollector msgCollector = mock(MultiMsgCollector.class); - TranslatorLibrary tLibrary = mock(TranslatorLibrary.class); - - GetFeaturesOutput mockedFeatures = mock(GetFeaturesOutput.class); - when(mockedFeatures.getTables()).thenReturn((short) 2); - when(mockedDeviceInfo.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_0); - - 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); - - final ConnectionContext connectionContext = buildMockConnectionContext(OFConstants.OFP_VERSION_1_0); - when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(connectionContext); - } - - @Test - public void chainTableTrunkWriteOF10Test() throws Exception { - DeviceState mockedDeviceState = mock(DeviceState.class); - - final GetFeaturesOutput mockedFeatures = mock(GetFeaturesOutput.class); - when(mockedFeatures.getTables()).thenReturn((short) 2); - when(mockConnectionContext.getFeatures()).thenReturn(mockedFeatures); - - when(mockedDeviceInfo.getNodeInstanceIdentifier()).thenReturn(DUMMY_NODE_II); - when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState); - - final RpcResult> mockedRpcResult = mock(RpcResult.class); - when(mockedRpcResult.isSuccessful()).thenReturn(true); - final List>> data = new ArrayList>>(); - data.add(mockedRpcResult); - data.add(mockedRpcResult); - - DeviceInitializationUtils.chainTableTrunkWriteOF10(mockedDeviceContext, Futures.immediateFuture(data)); - verify(mockedDeviceContext, times(3)).writeToTransaction(any(LogicalDatastoreType.class), - Matchers.> any(), any(FlowCapableNode.class)); - } - - @Test - public void testTranslateAndWriteReplyTypeDesc() throws Exception { - final ConnectionContext connectionContext = buildMockConnectionContext(OFConstants.OFP_VERSION_1_3); - when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(connectionContext); - final DeviceState deviceState = mock(DeviceState.class); - when(mockedDeviceContext.getDeviceState()).thenReturn(deviceState); - - final Collection multipartReplyMessages = prepareDataforTypeDesc(mockedDeviceContext); - - DeviceInitializationUtils.translateAndWriteReply(MultipartType.OFPMPDESC, mockedDeviceContext, DUMMY_NODE_II, multipartReplyMessages, convertorManager); - verify(mockedDeviceContext) - .writeToTransaction(eq(LogicalDatastoreType.OPERATIONAL), eq(DUMMY_NODE_II.augmentation(FlowCapableNode.class)), any(FlowCapableNode.class)); - } - - @Test - public void translateAndWriteReplyTypeTableFeatures() throws Exception { - when(mockedDeviceInfo.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3); - TableFeaturesBuilder tableFeature = new TableFeaturesBuilder(); - tableFeature.setTableId(DUMMY_TABLE_ID); - final List tableFeatures = new ArrayList<>(); - tableFeatures.add(tableFeature.build()); - - final MultipartReplyTableFeatures multipartReplyTableFeatures = new MultipartReplyTableFeaturesBuilder().setTableFeatures(tableFeatures).build(); - final MultipartReplyTableFeaturesCaseBuilder multipartReplyTableFeaturesCaseBuilder = new MultipartReplyTableFeaturesCaseBuilder(); - multipartReplyTableFeaturesCaseBuilder.setMultipartReplyTableFeatures(multipartReplyTableFeatures); - - final MultipartReplyMessage multipartReplyMessage = new MultipartReplyMessageBuilder().setMultipartReplyBody(multipartReplyTableFeaturesCaseBuilder.build()).build(); - final Set multipartReplyMessages = Collections.singleton(multipartReplyMessage); - DeviceInitializationUtils.translateAndWriteReply(MultipartType.OFPMPTABLEFEATURES, mockedDeviceContext, DUMMY_NODE_II, multipartReplyMessages, convertorManager); - verify(mockedDeviceContext) - .writeToTransaction(eq(LogicalDatastoreType.OPERATIONAL), - eq(DUMMY_NODE_II.augmentation(FlowCapableNode.class).child(Table.class, new TableKey(DUMMY_TABLE_ID))), any(Table.class)); - - } - - @Test - public void translateAndWriteReplyTypeMeterFeatures() throws Exception { - DeviceState mockedDeviceState = mock(DeviceState.class); - when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState); - - final MultipartReplyMeterFeaturesBuilder multipartReplyMeterFeaturesBuilder = new MultipartReplyMeterFeaturesBuilder(); - multipartReplyMeterFeaturesBuilder.setBandTypes(new MeterBandTypeBitmap(true, true)); - multipartReplyMeterFeaturesBuilder.setCapabilities(new MeterFlags(true, true, true, true)); - multipartReplyMeterFeaturesBuilder.setMaxMeter(DUMMY_MAX_METER); - - final MultipartReplyMeterFeaturesCaseBuilder multipartReplyMeterFeaturesCaseBuilder = new MultipartReplyMeterFeaturesCaseBuilder(); - multipartReplyMeterFeaturesCaseBuilder.setMultipartReplyMeterFeatures(multipartReplyMeterFeaturesBuilder.build()); - - final MultipartReplyMessage multipartReplyMessage = new MultipartReplyMessageBuilder().setMultipartReplyBody(multipartReplyMeterFeaturesCaseBuilder.build()).build(); - final Set multipartReplyMessages = Collections.singleton(multipartReplyMessage); - DeviceInitializationUtils.translateAndWriteReply(MultipartType.OFPMPMETERFEATURES, mockedDeviceContext, DUMMY_NODE_II, multipartReplyMessages, convertorManager); - verify(mockedDeviceContext) - .writeToTransaction(eq(LogicalDatastoreType.OPERATIONAL), eq(DUMMY_NODE_II.augmentation(NodeMeterFeatures.class)), any(NodeMeterFeatures.class)); - verify(mockedDeviceState).setMeterAvailable(eq(true)); - } - - @Test - public void translateAndWriteReplyTypeGroupFeatures() throws Exception { - MultipartReplyGroupFeaturesBuilder multipartReplyGroupFeaturesBuilder = new MultipartReplyGroupFeaturesBuilder(); - multipartReplyGroupFeaturesBuilder.setTypes(new GroupTypes(true, true, true, true)); - multipartReplyGroupFeaturesBuilder.setCapabilities(new GroupCapabilities(true, true, true, true)); - final ActionType actionType = new ActionType(true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true); - multipartReplyGroupFeaturesBuilder.setActionsBitmap(Lists.newArrayList(actionType)); - - final MultipartReplyGroupFeatures multipartReplyGroupFeatures = multipartReplyGroupFeaturesBuilder.build(); - - final MultipartReplyGroupFeaturesCaseBuilder multipartReplyGroupFeaturesCaseBuilder = new MultipartReplyGroupFeaturesCaseBuilder(); - multipartReplyGroupFeaturesCaseBuilder.setMultipartReplyGroupFeatures(multipartReplyGroupFeatures); - - final MultipartReplyMessage multipartReplyMessage = new MultipartReplyMessageBuilder().setMultipartReplyBody(multipartReplyGroupFeaturesCaseBuilder.build()).build(); - final Set multipartReplyMessages = Collections.singleton(multipartReplyMessage); - - DeviceInitializationUtils.translateAndWriteReply(MultipartType.OFPMPGROUPFEATURES, mockedDeviceContext, DUMMY_NODE_II, multipartReplyMessages, convertorManager); - verify(mockedDeviceContext) - .writeToTransaction(eq(LogicalDatastoreType.OPERATIONAL), eq(DUMMY_NODE_II.augmentation(NodeGroupFeatures.class)), any(NodeGroupFeatures.class)); - } - - - @Test - public void translateAndWriteReplyTypePortDesc() throws Exception { - ConnectionContext mockedPrimaryConnectionContext = mock(ConnectionContext.class); - FeaturesReply mockedFeatures = mock(FeaturesReply.class); - when(mockedFeatures.getDatapathId()).thenReturn(new BigInteger(DUMMY_DATAPATH_ID)); - when(mockedPrimaryConnectionContext.getFeatures()).thenReturn(mockedFeatures); - when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(mockedPrimaryConnectionContext); - final DeviceState mockedDeviceState = mock(DeviceState.class); - 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); - when(mockedDeviceContext.oook()).thenReturn(translatorLibrary); - - final MultipartReplyPortDescBuilder multipartReplyPortDescBuilder = new MultipartReplyPortDescBuilder(); - - final PortsBuilder portsBuilder = new PortsBuilder(); - portsBuilder.setPortNo(DUMMY_PORT_NUMBER); - - multipartReplyPortDescBuilder.setPorts(Lists.newArrayList(portsBuilder.build())); - - final MultipartReplyPortDescCaseBuilder multipartReplyPortDescCaseBuilder = new MultipartReplyPortDescCaseBuilder(); - multipartReplyPortDescCaseBuilder.setMultipartReplyPortDesc(multipartReplyPortDescBuilder.build()); - - final MultipartReplyMessage multipartReplyMessage = new MultipartReplyMessageBuilder().setMultipartReplyBody(multipartReplyPortDescCaseBuilder.build()).build(); - final Set multipartReplyMessages = Collections.singleton(multipartReplyMessage); - - DeviceInitializationUtils.translateAndWriteReply(MultipartType.OFPMPPORTDESC, mockedDeviceContext, DUMMY_NODE_II, multipartReplyMessages, convertorManager); - verify(mockedDeviceContext).writeToTransaction(eq(LogicalDatastoreType.OPERATIONAL), - Matchers.> any(), any(NodeConnector.class)); - } - - @Test - public void createSuccessProcessingCallbackTest() throws Exception { - DeviceState mockedDeviceState = mock(DeviceState.class); - when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState); - - final ConnectionContext connectionContext = buildMockConnectionContext(OFConstants.OFP_VERSION_1_3); - - final List multipartReplies = new ArrayList<>(prepareDataforTypeDesc(mockedDeviceContext)); - final RpcResult> result = RpcResultBuilder.>success(multipartReplies).build(); - ListenableFuture>> mockedRequestContextFuture = Futures.immediateFuture(result); - - DeviceInitializationUtils.createSuccessProcessingCallback(MultipartType.OFPMPDESC, mockedDeviceContext, DUMMY_NODE_II, mockedRequestContextFuture, convertorManager); - verify(mockedDeviceContext).writeToTransaction(eq(LogicalDatastoreType.OPERATIONAL), eq(DUMMY_NODE_II.augmentation(FlowCapableNode.class)), any(FlowCapableNode.class)); - - final RpcResult> rpcResult = RpcResultBuilder.>failed().withError(RpcError.ErrorType.PROTOCOL, "dummy error").build(); - mockedRequestContextFuture = Futures.immediateFuture(rpcResult); - DeviceInitializationUtils.createSuccessProcessingCallback(MultipartType.OFPMPDESC, mockedDeviceContext, DUMMY_NODE_II, mockedRequestContextFuture, convertorManager); - verify(mockedDeviceContext).writeToTransaction(eq(LogicalDatastoreType.OPERATIONAL), eq(DUMMY_NODE_II.augmentation(FlowCapableNode.class)), any(FlowCapableNode.class)); - } - - private Collection prepareDataforTypeDesc(final DeviceContext mockedDeviceContext) { - final MultipartReplyDesc multipartReplyDesc = new MultipartReplyDescBuilder().build(); - - final MultipartReplyDescCaseBuilder multipartReplyDescCaseBuilder = new MultipartReplyDescCaseBuilder(); - multipartReplyDescCaseBuilder.setMultipartReplyDesc(multipartReplyDesc); - - final MultipartReplyMessage multipartReplyMessage = new MultipartReplyMessageBuilder().setMultipartReplyBody(multipartReplyDescCaseBuilder.build()).build(); - return Collections.singleton(multipartReplyMessage); - - } - - protected ConnectionContext buildMockConnectionContext(final short ofpVersion) { - when(mockFeatures.getVersion()).thenReturn(ofpVersion); - when(outboundQueueProvider.reserveEntry()).thenReturn(43L); - Mockito.doAnswer(new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) throws Throwable { - final FutureCallback callBack = (FutureCallback) invocation.getArguments()[2]; - callBack.onSuccess(null); - return null; - } - }) - .when(outboundQueueProvider) - .commitEntry(Matchers.anyLong(), Matchers.any(), Matchers.>any()); - - when(mockedConnectionAdapter.registerOutboundQueueHandler(Matchers.any(), Matchers.anyInt(), Matchers.anyLong())) - .thenAnswer(new Answer>() { - @Override - public OutboundQueueHandlerRegistration answer(final InvocationOnMock invocation) throws Throwable { - final OutboundQueueHandler handler = (OutboundQueueHandler) invocation.getArguments()[0]; - handler.onConnectionQueueChanged(outboundQueueProvider); - return null; - } - }); - - when(mockConnectionContext.getOutboundQueueProvider()).thenReturn(outboundQueueProvider); - return mockConnectionContext; - } -} -- 2.36.6