MD-SAL Statistics Manager - Implemented rpc/notification for 32/3732/1
authorAnilkumar Vishnoi <avishnoi@in.ibm.com>
Sat, 14 Dec 2013 14:29:45 +0000 (19:59 +0530)
committerAnilkumar Vishnoi <avishnoi@in.ibm.com>
Sat, 14 Dec 2013 22:15:08 +0000 (03:45 +0530)
port statistics and flow table statistics
This gerrit is dependent on following controller gerrit
http://git.opendaylight.org/gerrit/3731

Change-Id: Idd175add3bbdb289b61ac7689b5a366e8adbd166
Signed-off-by: Anilkumar Vishnoi <avishnoi@in.ibm.com>
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/ModelDrivenSwitch.java
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/MDController.java
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/AbstractModelDrivenSwitch.java
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/ModelDrivenSwitchImpl.java
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/translator/MultipartReplyTranslator.java
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/util/InventoryDataServiceUtil.java

index aa5e2b7543187b3894d1578176ecc043874cab5a..9b8c463f9f0bb529006a2eb548ab34a471a7f1a6 100644 (file)
@@ -11,6 +11,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalF
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInput;
@@ -35,6 +36,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.GetP
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.SalPortService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService;
 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;
@@ -53,6 +55,8 @@ public interface ModelDrivenSwitch extends //
         OpendaylightGroupStatisticsService, //
         OpendaylightMeterStatisticsService, //
         OpendaylightFlowStatisticsService, //
+        OpendaylightPortStatisticsService, //
+        OpendaylightFlowTableStatisticsService, //
         Identifiable<InstanceIdentifier<Node>> {
 
     CompositeObjectRegistration<ModelDrivenSwitch> register(ProviderContext ctx);
index 8ad873d8eb323ce62c2187ebac9ba1b8ce6ef2b8..96c12df72bb3d65a8caf635566f4ef8fbd923b7f 100644 (file)
@@ -38,6 +38,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.Swit
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeErrorNotification;
 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.table.statistics.rev131215.FlowTableStatisticsUpdate;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupDescStatsUpdated;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupFeaturesUpdated;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupStatisticsUpdated;
@@ -54,6 +55,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.PortStatisticsUpdate;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.TableUpdated;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.slf4j.Logger;
@@ -117,9 +119,11 @@ public class MDController implements IMDController {
 
         addMessagePopListener(SwitchFlowRemoved.class, notificationPopListener);
         addMessagePopListener(TableUpdated.class, notificationPopListener);
+        
         //Notification registration for flow statistics
         addMessagePopListener(FlowsStatisticsUpdate.class, notificationPopListener);
         addMessagePopListener(AggregateFlowStatisticsUpdate.class, notificationPopListener);
+        
         //Notification registrations for group-statistics
         addMessagePopListener(GroupStatisticsUpdated.class, notificationPopListener);
         addMessagePopListener(GroupFeaturesUpdated.class, notificationPopListener);
@@ -130,7 +134,12 @@ public class MDController implements IMDController {
         addMessagePopListener(MeterConfigStatsUpdated.class, notificationPopListener);
         addMessagePopListener(MeterFeaturesUpdated.class, notificationPopListener);
 
-
+        //Notification registration for port-statistics
+        addMessagePopListener(PortStatisticsUpdate.class, notificationPopListener);
+        
+        //Notification registration for flow-table statistics
+        addMessagePopListener(FlowTableStatisticsUpdate.class, notificationPopListener);
+        
         // Push the updated Listeners to Session Manager which will be then picked up by ConnectionConductor eventually
         OFSessionUtil.getSessionManager().setTranslatorMapping(messageTranslators);
         OFSessionUtil.getSessionManager().setPopListenerMapping(popListeners);
index fbe73c9ea9a771344a25df8678f51b2ea81b85d3..9ad8770147351231564bb293b35f5eef6ee5466f 100644 (file)
@@ -13,6 +13,7 @@ import org.opendaylight.openflowplugin.openflow.md.ModelDrivenSwitch;
 import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeContext;
@@ -20,6 +21,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.N
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService;
 import org.opendaylight.yangtools.concepts.CompositeObjectRegistration;
 import org.opendaylight.yangtools.concepts.CompositeObjectRegistration.CompositeObjectRegistrationBuilder;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -45,6 +47,10 @@ public abstract class AbstractModelDrivenSwitch implements ModelDrivenSwitch {
 
     private RoutedRpcRegistration<OpendaylightMeterStatisticsService> meterStatisticsRegistration;
 
+    private RoutedRpcRegistration<OpendaylightPortStatisticsService> portStatisticsRegistration;
+
+    private RoutedRpcRegistration<OpendaylightFlowTableStatisticsService> flowTableStatisticsRegistration;
+
     protected final SessionContext sessionContext;
 
     protected AbstractModelDrivenSwitch(InstanceIdentifier<Node> identifier,SessionContext conductor) {
@@ -90,6 +96,14 @@ public abstract class AbstractModelDrivenSwitch implements ModelDrivenSwitch {
         meterStatisticsRegistration.registerPath(NodeContext.class, getIdentifier());
         builder.add(meterStatisticsRegistration);
 
+        portStatisticsRegistration = ctx.addRoutedRpcImplementation(OpendaylightPortStatisticsService.class, this);
+        portStatisticsRegistration.registerPath(NodeContext.class, getIdentifier());
+        builder.add(portStatisticsRegistration);
+
+        flowTableStatisticsRegistration = ctx.addRoutedRpcImplementation(OpendaylightFlowTableStatisticsService.class, this);
+        flowTableStatisticsRegistration.registerPath(NodeContext.class, getIdentifier());
+        builder.add(flowTableStatisticsRegistration);
+        
         return builder.toInstance();
     }
 
index f659fd54c31683bc9e91416d5658b963832d23e9..fa69121535ee2734b4254cd4cd08ce204670bae3 100644 (file)
@@ -27,6 +27,7 @@ import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.TableFeatu
 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchReactor;
 import org.opendaylight.openflowplugin.openflow.md.core.session.IMessageDispatchService;
 import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext;
+import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutputBuilder;
@@ -62,6 +63,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.G
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetNodeConnectorStatisticsInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetNodeConnectorStatisticsOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsOutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.port.mod.port.Port;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
@@ -135,12 +139,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterConfigCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterFeaturesCaseBuilder;
+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.MultipartRequestTableCaseBuilder;
 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.aggregate._case.MultipartRequestAggregateBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.flow._case.MultipartRequestFlowBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.group._case.MultipartRequestGroupBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter._case.MultipartRequestMeterBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter.config._case.MultipartRequestMeterConfigBuilder;
+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.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table._case.MultipartRequestTableBuilder;
 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.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features.TableFeatures;
@@ -149,6 +157,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.GetP
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllPortsStatisticsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllPortsStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllPortsStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetPortStatisticsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetPortStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetPortStatisticsOutputBuilder;
 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;
@@ -840,6 +854,83 @@ public class ModelDrivenSwitchImpl extends AbstractModelDrivenSwitch {
         RpcResult<GetMeterStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
         return Futures.immediateFuture(rpcResult);
     }
+    
+    @Override
+    public Future<RpcResult<GetAllPortsStatisticsOutput>> getAllPortsStatistics(GetAllPortsStatisticsInput arg0) {
+
+        //Generate xid to associate it with the request
+        Long xid = this.getSessionContext().getNextXid();
+
+        LOG.info("Prepare port statistics request for all ports of node {} - TrasactionId - {}",arg0.getNode().getValue(),xid);
+
+        // Create multipart request header
+        MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
+        mprInput.setType(MultipartType.OFPMPPORTSTATS);
+        mprInput.setVersion(version);
+        mprInput.setXid(xid);
+        mprInput.setFlags(new MultipartRequestFlags(false));
+
+        // Create multipart request body to fetch stats for all the port of the node
+        MultipartRequestPortStatsCaseBuilder caseBuilder = new MultipartRequestPortStatsCaseBuilder();
+        MultipartRequestPortStatsBuilder mprPortStatsBuilder = new MultipartRequestPortStatsBuilder();
+        //Select all ports 
+        //TODO :need to change once i rebase on latest code.
+        mprPortStatsBuilder.setPortNo(OpenflowEnumConstant.OFPP_ANY);
+        caseBuilder.setMultipartRequestPortStats(mprPortStatsBuilder.build());
+        
+        //Set request body to main multipart request
+        mprInput.setMultipartRequestBody(caseBuilder.build());
+
+        //Send the request, no cookies associated, use any connection
+        LOG.debug("Send port statistics request :{}",mprPortStatsBuilder.build().toString());
+        this.messageService.multipartRequest(mprInput.build(), null);
+
+        // Prepare rpc return output. Set xid and send it back.
+        GetAllPortsStatisticsOutputBuilder output = new GetAllPortsStatisticsOutputBuilder();
+        output.setTransactionId(generateTransactionId(xid));
+
+        Collection<RpcError> errors = Collections.emptyList();
+        RpcResult<GetAllPortsStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
+        return Futures.immediateFuture(rpcResult);
+    }
+
+    @Override
+    public Future<RpcResult<GetPortStatisticsOutput>> getPortStatistics(GetPortStatisticsInput arg0) {
+        //Generate xid to associate it with the request
+        Long xid = this.getSessionContext().getNextXid();
+
+        LOG.info("Prepare port statistics request for port {} of node {} - TrasactionId - {}",arg0.getNodeConnectorId(), arg0.getNode().getValue(),xid);
+
+        // Create multipart request header
+        MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
+        mprInput.setType(MultipartType.OFPMPPORTSTATS);
+        mprInput.setVersion(version);
+        mprInput.setXid(xid);
+        mprInput.setFlags(new MultipartRequestFlags(false));
+
+        // Create multipart request body to fetch stats for all the port of the node
+        MultipartRequestPortStatsCaseBuilder caseBuilder = new MultipartRequestPortStatsCaseBuilder();
+        MultipartRequestPortStatsBuilder mprPortStatsBuilder = new MultipartRequestPortStatsBuilder();
+
+        //Set specific port 
+        mprPortStatsBuilder.setPortNo(InventoryDataServiceUtil.portNumberfromNodeConnectorId(arg0.getNodeConnectorId()));
+        caseBuilder.setMultipartRequestPortStats(mprPortStatsBuilder.build());
+        
+        //Set request body to main multipart request
+        mprInput.setMultipartRequestBody(caseBuilder.build());
+
+        //Send the request, no cookies associated, use any connection
+        LOG.debug("Send port statistics request :{}",mprPortStatsBuilder.build().toString());
+        this.messageService.multipartRequest(mprInput.build(), null);
+
+        // Prepare rpc return output. Set xid and send it back.
+        GetPortStatisticsOutputBuilder output = new GetPortStatisticsOutputBuilder();
+        output.setTransactionId(generateTransactionId(xid));
+
+        Collection<RpcError> errors = Collections.emptyList();
+        RpcResult<GetPortStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
+        return Futures.immediateFuture(rpcResult);
+    }
 
     private TransactionId generateTransactionId(Long xid){
         String stringXid =xid.toString();
@@ -984,7 +1075,6 @@ public class ModelDrivenSwitchImpl extends AbstractModelDrivenSwitch {
         Collection<RpcError> errors = Collections.emptyList();
         RpcResult<UpdateTableOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
         return Futures.immediateFuture(rpcResult);
-
     }
 
     @Override
@@ -1105,7 +1195,7 @@ public class ModelDrivenSwitchImpl extends AbstractModelDrivenSwitch {
         //Generate xid to associate it with the request
         Long xid = this.getSessionContext().getNextXid();
 
-        LOG.debug("Prepare statistics request to get stats for flow {} for switch tables {} - Transaction id - {}"
+        LOG.info("Prepare statistics request to get stats for flow {} for switch tables {} - Transaction id - {}"
                 ,arg0.getMatch().toString(),arg0.getTableId(),xid);
 
         // Create multipart request header
@@ -1166,7 +1256,7 @@ public class ModelDrivenSwitchImpl extends AbstractModelDrivenSwitch {
         //Generate xid to associate it with the request
         Long xid = this.getSessionContext().getNextXid();
 
-        LOG.debug("Prepare aggregate flow statistics request to get aggregate flow stats for all the flow installed on switch table {} - Transaction id - {}"
+        LOG.info("Prepare aggregate flow statistics request to get aggregate flow stats for all the flow installed on switch table {} - Transaction id - {}"
                 ,arg0.getTableId().getValue(),xid);
 
         // Create multipart request header
@@ -1261,7 +1351,7 @@ public class ModelDrivenSwitchImpl extends AbstractModelDrivenSwitch {
         mprInput.setMultipartRequestBody(multipartRequestAggregateCaseBuilder.build());
 
         //Send the request, no cookies associated, use any connection
-        LOG.debug("Send request for to the switch :{}",multipartRequestAggregateCaseBuilder.build().toString());
+        LOG.debug("Send request to the switch :{}",multipartRequestAggregateCaseBuilder.build().toString());
         this.messageService.multipartRequest(mprInput.build(), null);
 
         // Prepare rpc return output. Set xid and send it back.
@@ -1274,6 +1364,43 @@ public class ModelDrivenSwitchImpl extends AbstractModelDrivenSwitch {
         return Futures.immediateFuture(rpcResult);
     }
 
+    @Override
+    public Future<RpcResult<GetFlowTablesStatisticsOutput>> getFlowTablesStatistics(GetFlowTablesStatisticsInput arg0) {
+        //Generate xid to associate it with the request
+        Long xid = this.getSessionContext().getNextXid();
+
+        LOG.info("Prepare flow table statistics request to get flow table stats for all tables " +
+                       "from node {}- Transaction id - {}",arg0.getNode(),xid);
+
+        // Create multipart request header
+        MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
+        mprInput.setType(MultipartType.OFPMPTABLE);
+        mprInput.setVersion(version);
+        mprInput.setXid(xid);
+        mprInput.setFlags(new MultipartRequestFlags(false));
+
+        // Create multipart request body for fetch all the group stats
+        MultipartRequestTableCaseBuilder multipartRequestTableCaseBuilder  = new MultipartRequestTableCaseBuilder (); 
+        MultipartRequestTableBuilder multipartRequestTableBuilder = new MultipartRequestTableBuilder();
+        multipartRequestTableBuilder.setEmpty(true);
+        multipartRequestTableCaseBuilder.setMultipartRequestTable(multipartRequestTableBuilder.build());
+        
+        //Set request body to main multipart request
+        mprInput.setMultipartRequestBody(multipartRequestTableCaseBuilder.build());
+
+        //Send the request, no cookies associated, use any connection
+        LOG.debug("Send request to the switch :{}",multipartRequestTableCaseBuilder.build().toString());
+        this.messageService.multipartRequest(mprInput.build(), null);
+
+        // Prepare rpc return output. Set xid and send it back.
+        GetFlowTablesStatisticsOutputBuilder output = new GetFlowTablesStatisticsOutputBuilder();
+        output.setTransactionId(generateTransactionId(xid));
+
+        Collection<RpcError> errors = Collections.emptyList();
+        RpcResult<GetFlowTablesStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
+        return Futures.immediateFuture(rpcResult);
+    }
+
     @Override
     public Future<RpcResult<GetAllFlowStatisticsOutput>> getAllFlowStatistics(GetAllFlowStatisticsInput arg0) {
         //TODO: Depricated, need to clean it up. Sal-Compatibility layes is dependent on it.
index bed00bf975d99dd1dfdae6d917be13d9e17225c9..30cddf403eddfe1231ffd88d88948726fc60ad7a 100644 (file)
@@ -18,10 +18,14 @@ import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.FlowStatsR
 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.GroupStatsResponseConvertor;
 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.MeterStatsResponseConvertor;
 import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext;
+import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.Counter32;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.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.table.statistics.rev131215.FlowTableStatisticsUpdateBuilder;
+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.rev131103.TransactionId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupDescStatsUpdatedBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupFeaturesUpdatedBuilder;
@@ -48,6 +52,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.Meter
 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.model.statistics.types.rev130925.node.connector.statistics.BytesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.DurationBuilder;
+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.MultipartReplyMessage;
 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.MultipartReplyAggregateCase;
@@ -58,14 +65,26 @@ 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.MultipartReplyTableCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableCaseBuilder;
 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.flow._case.MultipartReplyFlow;
+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.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;
 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._case.MultipartReplyMeter;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.MultipartReplyMeterConfig;
 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.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.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.PortStatisticsUpdateBuilder;
+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.table.types.rev131026.TableId;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -125,7 +144,61 @@ public class MultipartReplyTranslator implements IMDMessageTranslator<OfHeader,
                 logger.info("Converted aggregate flow statistics : {}",message.build().toString());
                 listDataObject.add(message.build());
                 return listDataObject;
+            }
+            case OFPMPPORTSTATS: {
+
+                logger.info("Received port statistics multipart response");
+                
+                PortStatisticsUpdateBuilder message = new PortStatisticsUpdateBuilder();
+                message.setId(node);
+                message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
+                message.setTransactionId(generateTransactionId(mpReply.getXid()));
+
+                MultipartReplyPortStatsCase caseBody = (MultipartReplyPortStatsCase)mpReply.getMultipartReplyBody();
+                MultipartReplyPortStats replyBody = caseBody.getMultipartReplyPortStats();
                 
+                List<NodeConnectorStatisticsAndPortNumberMap> statsMap = 
+                        new ArrayList<NodeConnectorStatisticsAndPortNumberMap>();
+                for (PortStats portStats: replyBody.getPortStats()){
+                    
+                    NodeConnectorStatisticsAndPortNumberMapBuilder statsBuilder = 
+                            new NodeConnectorStatisticsAndPortNumberMapBuilder();
+                    statsBuilder.setNodeConnectorId(
+                            InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(sc.getFeatures().getDatapathId(),
+                                    portStats.getPortNo()));
+                    
+                    BytesBuilder bytesBuilder = new BytesBuilder();
+                    bytesBuilder.setReceived(portStats.getRxBytes());
+                    bytesBuilder.setTransmitted(portStats.getTxBytes());
+                    statsBuilder.setBytes(bytesBuilder.build());
+                    
+                    PacketsBuilder packetsBuilder = new PacketsBuilder();
+                    packetsBuilder.setReceived(portStats.getRxPackets());
+                    packetsBuilder.setTransmitted(portStats.getTxPackets());
+                    statsBuilder.setPackets(packetsBuilder.build());
+                    
+                    DurationBuilder durationBuilder = new DurationBuilder();
+                    durationBuilder.setSecond(new Counter32(portStats.getDurationSec()));
+                    durationBuilder.setNanosecond(new Counter32(portStats.getDurationNsec()));
+                    statsBuilder.setDuration(durationBuilder.build());
+                    
+                    statsBuilder.setCollisionCount(portStats.getCollisions());
+                    statsBuilder.setKey(new NodeConnectorStatisticsAndPortNumberMapKey(statsBuilder.getNodeConnectorId()));
+                    statsBuilder.setReceiveCrcError(portStats.getRxCrcErr());
+                    statsBuilder.setReceiveDrops(portStats.getRxDropped());
+                    statsBuilder.setReceiveErrors(portStats.getRxErrors());
+                    statsBuilder.setReceiveFrameError(portStats.getRxFrameErr());
+                    statsBuilder.setReceiveOverRunError(portStats.getRxOverErr());
+                    statsBuilder.setTransmitDrops(portStats.getTxDropped());
+                    statsBuilder.setTransmitErrors(portStats.getTxErrors());
+                    statsMap.add(statsBuilder.build());
+                }
+                message.setNodeConnectorStatisticsAndPortNumberMap(statsMap);
+
+                logger.debug("Converted ports statistics : {}",message.build().toString());
+
+                listDataObject.add(message.build());
+                return listDataObject;
             }
             case OFPMPGROUP:{
                 logger.info("Received group statistics multipart reponse");
@@ -287,6 +360,36 @@ public class MultipartReplyTranslator implements IMDMessageTranslator<OfHeader,
                 //Send update notification to all the listeners 
                 return listDataObject;
             }
+            case OFPMPTABLE: {
+                logger.info("Received flow table statistics reponse from openflow {} switch",msg.getVersion()==1?"1.0":"1.3+");
+                
+                FlowTableStatisticsUpdateBuilder message = new FlowTableStatisticsUpdateBuilder();
+                message.setId(node);
+                message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
+                message.setTransactionId(generateTransactionId(mpReply.getXid()));
+                
+                MultipartReplyTableCase caseBody = (MultipartReplyTableCase)mpReply.getMultipartReplyBody();
+                MultipartReplyTable replyBody = caseBody.getMultipartReplyTable();
+                List<TableStats> swTablesStats = replyBody.getTableStats();
+                
+                List<FlowTableAndStatisticsMap> salFlowStats = new ArrayList<FlowTableAndStatisticsMap>(); 
+                for(TableStats swTableStats : swTablesStats){
+                    FlowTableAndStatisticsMapBuilder statisticsBuilder  = new FlowTableAndStatisticsMapBuilder();
+                    
+                    statisticsBuilder.setActiveFlows(new Counter32(swTableStats.getActiveCount()));
+                    statisticsBuilder.setPacketsLookedUp(new Counter64(swTableStats.getLookupCount()));
+                    statisticsBuilder.setPacketsMatched(new Counter64(swTableStats.getMatchedCount()));
+                    statisticsBuilder.setTableId(new TableId(swTableStats.getTableId()));
+                    salFlowStats.add(statisticsBuilder.build());
+                }
+                
+                message.setFlowTableAndStatisticsMap(salFlowStats);
+                
+                logger.info("Converted flow table statistics : {}",message.build().toString());
+                listDataObject.add(message.build());
+                return listDataObject;
+            }
+
             default:
                 return listDataObject;
             }
index d2f6229ee51622fd347868f1ac9726c1cb508333..fb6532c71fc72681d4f36170340fddad1f345cf7 100644 (file)
@@ -142,6 +142,12 @@ public class InventoryDataServiceUtil {
     public static NodeConnectorId nodeConnectorIdfromDatapathPortNo(BigInteger datapathid, Long portNo) {
         return new NodeConnectorId(OF_URI_PREFIX + datapathid + ":" + portNo);
     }
+    
+    public static Long portNumberfromNodeConnectorId(NodeConnectorId ncId) {
+        String[] split = ncId.getValue().split(":");
+        return Long.getLong(split[split.length-1]);
+    }
+
 
     public static NodeConnectorRef nodeConnectorRefFromDatapathIdPortno(BigInteger datapathId, Long portNo) {
         return new NodeConnectorRef(nodeConnectorInstanceIdentifierFromDatapathIdPortno(datapathId, portNo));