2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.controller.statistics.northbound;
11 import java.util.ArrayList;
12 import java.util.List;
14 import javax.ws.rs.GET;
15 import javax.ws.rs.Path;
16 import javax.ws.rs.PathParam;
17 import javax.ws.rs.Produces;
18 import javax.ws.rs.core.Context;
19 import javax.ws.rs.core.MediaType;
20 import javax.ws.rs.core.SecurityContext;
22 import org.codehaus.enunciate.jaxrs.ResponseCode;
23 import org.codehaus.enunciate.jaxrs.StatusCodes;
24 import org.codehaus.enunciate.jaxrs.TypeHint;
25 import org.opendaylight.controller.containermanager.IContainerManager;
26 import org.opendaylight.controller.northbound.commons.RestMessages;
27 import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;
28 import org.opendaylight.controller.northbound.commons.exception.ResourceConflictException;
29 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
30 import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
31 import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException;
32 import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
33 import org.opendaylight.controller.sal.authorization.Privilege;
34 import org.opendaylight.controller.sal.core.Node;
35 import org.opendaylight.controller.sal.reader.FlowOnNode;
36 import org.opendaylight.controller.sal.reader.NodeConnectorStatistics;
37 import org.opendaylight.controller.sal.reader.NodeTableStatistics;
38 import org.opendaylight.controller.sal.utils.GlobalConstants;
39 import org.opendaylight.controller.sal.utils.ServiceHelper;
40 import org.opendaylight.controller.statisticsmanager.IStatisticsManager;
41 import org.opendaylight.controller.switchmanager.ISwitchManager;
44 * Northbound APIs that returns various Statistics exposed by the Southbound
45 * protocol plugins such as Openflow.
49 * Authentication scheme : <b>HTTP Basic</b><br>
50 * Authentication realm : <b>opendaylight</b><br>
51 * Transport : <b>HTTP and HTTPS</b><br>
53 * HTTPS Authentication is disabled by default. Administrator can enable it in
54 * tomcat-server.xml after adding a proper keystore / SSL certificate from a
55 * trusted authority.<br>
57 * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
61 public class StatisticsNorthbound {
63 private String username;
66 public void setSecurityContext(SecurityContext context) {
67 username = context.getUserPrincipal().getName();
70 protected String getUserName() {
74 private IStatisticsManager getStatisticsService(String containerName) {
75 IContainerManager containerManager = (IContainerManager) ServiceHelper
76 .getGlobalInstance(IContainerManager.class, this);
77 if (containerManager == null) {
78 throw new ServiceUnavailableException("Container "
79 + RestMessages.SERVICEUNAVAILABLE.toString());
82 boolean found = false;
83 List<String> containerNames = containerManager.getContainerNames();
84 for (String cName : containerNames) {
85 if (cName.trim().equalsIgnoreCase(containerName.trim())) {
91 throw new ResourceNotFoundException(containerName + " "
92 + RestMessages.NOCONTAINER.toString());
95 IStatisticsManager statsManager = (IStatisticsManager) ServiceHelper
96 .getInstance(IStatisticsManager.class, containerName, this);
98 if (statsManager == null) {
99 throw new ServiceUnavailableException("Statistics "
100 + RestMessages.SERVICEUNAVAILABLE.toString());
107 * Returns a list of all Flow Statistics from all the Nodes.
109 * @param containerName
110 * Name of the Container. The Container name for the base
111 * controller is "default".
112 * @return List of FlowStatistics from all the Nodes
116 * Request URL: localhost:8080/controller/nb/v2/statistics/default/flow
120 * "flowStatistics": [
124 * "@id": "00:00:00:00:00:00:00:02"
136 * "mask": "255.255.255.255",
149 * "@id": "00:00:00:00:00:00:00:02"
154 * "idleTimeout": "0",
155 * "hardTimeout": "0",
159 * "durationSeconds": "1828",
160 * "durationNanoseconds": "397000000",
161 * "packetCount": "0",
166 * { flow statistics of another node
169 * ......................
175 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
177 * <flowStatistics>
178 * <node type="OF" id="00:00:00:00:00:00:00:02"/>
179 * <flowStatistic>
183 * <type>DL_TYPE</type>
184 * <value>2048</value>
185 * </matchField>
187 * <mask>255.255.255.255</mask>
188 * <type>NW_DST</type>
189 * <value>1.1.1.2</value>
190 * </matchField>
193 * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="output">
194 * <port type="OF" id="3">
195 * <node type="OF" id="00:00:00:00:00:00:00:02"/>
198 * <priority>1</priority>
199 * <idleTimeout>0</idleTimeout>
200 * <hardTimeout>0</hardTimeout>
201 * <id>0</id>
203 * <tableId>0</tableId>
204 * <durationSeconds>337</durationSeconds>
205 * <durationNanoseconds>149000000</durationNanoseconds>
206 * <packetCount>0</packetCount>
207 * <byteCount>0</byteCount>
208 * </flowStatistic>
209 * </flowStatistics>
210 * <flowStatistics>
211 * flow statistics for another node
214 * .....................
215 * </flowStatistics>
220 @Path("/{containerName}/flow")
222 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
223 @TypeHint(AllFlowStatistics.class)
225 @ResponseCode(code = 200, condition = "Operation successful"),
226 @ResponseCode(code = 404, condition = "The containerName is not found"),
227 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
228 public AllFlowStatistics getFlowStatistics(
229 @PathParam("containerName") String containerName) {
230 if (!NorthboundUtils.isAuthorized(
231 getUserName(), containerName, Privilege.READ, this)) {
232 throw new UnauthorizedException(
233 "User is not authorized to perform this operation on container "
236 IStatisticsManager statisticsManager = getStatisticsService(containerName);
237 if (statisticsManager == null) {
238 throw new ServiceUnavailableException("Statistics "
239 + RestMessages.SERVICEUNAVAILABLE.toString());
242 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
243 .getInstance(ISwitchManager.class, containerName, this);
244 if (switchManager == null) {
245 throw new ServiceUnavailableException("Switch manager "
246 + RestMessages.SERVICEUNAVAILABLE.toString());
249 List<FlowStatistics> statistics = new ArrayList<FlowStatistics>();
250 for (Node node : switchManager.getNodes()) {
251 List<FlowOnNode> flowStats = new ArrayList<FlowOnNode>();
253 List<FlowOnNode> flows = statisticsManager.getFlows(node);
254 for (FlowOnNode flowOnSwitch : flows) {
255 flowStats.add(flowOnSwitch);
257 FlowStatistics stat = new FlowStatistics(node, flowStats);
258 statistics.add(stat);
260 return new AllFlowStatistics(statistics);
264 * Returns a list of Flow Statistics for a given Node.
266 * @param containerName
267 * Name of the Container. The Container name for the base
268 * controller is "default".
270 * Node Type as specifid in {@link org.opendaylight.controller.sal.core.Node} class
273 * @return List of Flow Statistics for a given Node. *
278 * http://host:8080/controller/nb/v2/statistics/default/flow/node/OF/00:00:00:00:00:00:00:01
284 * "@id": "00:00:00:00:00:00:00:01"
296 * "mask": "255.255.255.255",
304 * "@type": "setDlDst",
305 * "address": "52d28b0f76ec"
314 * "@id": "00:00:00:00:00:00:00:01"
320 * "idleTimeout": "0",
321 * "hardTimeout": "0",
325 * "durationSeconds": "2089",
326 * "durationNanoseconds": "538000000",
327 * "packetCount": "0",
335 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
336 * <nodeFlowStatistics>
337 * <node type="OF" id="00:00:00:00:00:00:00:02"/>
338 * <flowStatistic>
342 * <type>DL_TYPE</type>
343 * <value>2048</value>
344 * </matchField>
346 * <mask>255.255.255.255</mask>
347 * <type>NW_DST</type>
348 * <value>1.1.1.2</value>
349 * </matchField>
352 * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="output">
353 * <port type="OF" id="3">
354 * <node type="OF" id="00:00:00:00:00:00:00:02"/>
357 * <priority>1</priority>
358 * <idleTimeout>0</idleTimeout>
359 * <hardTimeout>0</hardTimeout>
360 * <id>0</id>
362 * <tableId>0</tableId>
363 * <durationSeconds>337</durationSeconds>
364 * <durationNanoseconds>149000000</durationNanoseconds>
365 * <packetCount>0</packetCount>
366 * <byteCount>0</byteCount>
367 * </flowStatistic>
368 * <flowStatistic>
372 * <type>DL_TYPE</type>
373 * <value>2048</value>
374 * </matchField>
376 * <mask>255.255.255.255</mask>
377 * <type>NW_DST</type>
378 * <value>1.1.1.1</value>
379 * </matchField>
382 * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="output">
383 * <port type="OF" id="3">
384 * <node type="OF" id="00:00:00:00:00:00:00:02"/>
387 * <priority>1</priority>
388 * <idleTimeout>0</idleTimeout>
389 * <hardTimeout>0</hardTimeout>
390 * <id>0</id>
392 * <tableId>0</tableId>
393 * <durationSeconds>337</durationSeconds>
394 * <durationNanoseconds>208000000</durationNanoseconds>
395 * <packetCount>0</packetCount>
396 * <byteCount>0</byteCount>
397 * </flowStatistic>
398 * </nodeFlowStatistics>
401 @Path("/{containerName}/flow/node/{nodeType}/{nodeId}")
403 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
404 @TypeHint(FlowStatistics.class)
406 @ResponseCode(code = 200, condition = "Operation successful"),
407 @ResponseCode(code = 404, condition = "The containerName is not found"),
408 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
409 public FlowStatistics getFlowStatistics(
410 @PathParam("containerName") String containerName,
411 @PathParam("nodeType") String nodeType,
412 @PathParam("nodeId") String nodeId) {
413 if (!NorthboundUtils.isAuthorized(
414 getUserName(), containerName, Privilege.READ, this)) {
415 throw new UnauthorizedException(
416 "User is not authorized to perform this operation on container "
419 handleDefaultDisabled(containerName);
421 IStatisticsManager statisticsManager = getStatisticsService(containerName);
422 if (statisticsManager == null) {
423 throw new ServiceUnavailableException("Statistics "
424 + RestMessages.SERVICEUNAVAILABLE.toString());
427 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
428 .getInstance(ISwitchManager.class, containerName, this);
429 if (switchManager == null) {
430 throw new ServiceUnavailableException("Switch manager "
431 + RestMessages.SERVICEUNAVAILABLE.toString());
434 Node node = handleNodeAvailability(containerName, nodeType, nodeId);
435 return new FlowStatistics(node, statisticsManager.getFlows(node));
439 * Returns a list of all the Port Statistics across all the NodeConnectors
442 * @param containerName
443 * Name of the Container. The Container name for the base
444 * controller is "default".
445 * @return List of all the Port Statistics across all the NodeConnectors on
451 * Requset URL: http://host:8080/controller/nb/v2/statistics/default/port
455 * "portStatistics": [
459 * "@id": "00:00:00:00:00:00:00:02"
468 * "@id": "00:00:00:00:00:00:00:02"
471 * "receivePackets": "182",
472 * "transmitPackets": "173",
473 * "receiveBytes": "12740",
474 * "transmitBytes": "12110",
475 * "receiveDrops": "0",
476 * "transmitDrops": "0",
477 * "receiveErrors": "0",
478 * "transmitErrors": "0",
479 * "receiveFrameError": "0",
480 * "receiveOverRunError": "0",
481 * "receiveCrcError": "0",
482 * "collisionCount": "0"
490 * "@id": "00:00:00:00:00:00:00:02"
493 * "receivePackets": "174",
494 * "transmitPackets": "181",
495 * "receiveBytes": "12180",
496 * "transmitBytes": "12670",
497 * "receiveDrops": "0",
498 * "transmitDrops": "0",
499 * "receiveErrors": "0",
500 * "transmitErrors": "0",
501 * "receiveFrameError": "0",
502 * "receiveOverRunError": "0",
503 * "receiveCrcError": "0",
504 * "collisionCount": "0"
512 * "@id": "00:00:00:00:00:00:00:03"
516 * .......................
517 * ..........................
524 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
526 * <portStatistics>
527 * <node type="OF" id="00:00:00:00:00:00:00:02"/>
528 * <portStatistic>
529 * <nodeConnector type="OF" id="3">
530 * <node type="OF" id="00:00:00:00:00:00:00:02"/>
531 * </nodeConnector>
532 * <receivePackets>181</receivePackets>
533 * <transmitPackets>172</transmitPackets>
534 * <receiveBytes>12670</receiveBytes>
535 * <transmitBytes>12040</transmitBytes>
536 * <receiveDrops>0</receiveDrops>
537 * <transmitDrops>0</transmitDrops>
538 * <receiveErrors>0</receiveErrors>
539 * <transmitErrors>0</transmitErrors>
540 * <receiveFrameError>0</receiveFrameError>
541 * <receiveOverRunError>0</receiveOverRunError>
542 * <receiveCrcError>0</receiveCrcError>
543 * <collisionCount>0</collisionCount>
544 * </portStatistic>
545 * <portStatistic>
546 * <nodeConnector type="OF" id="2">
547 * <node type="OF" id="00:00:00:00:00:00:00:02"/>
548 * </nodeConnector>
549 * <receivePackets>173</receivePackets>
550 * <transmitPackets>180</transmitPackets>
551 * <receiveBytes>12110</receiveBytes>
552 * <transmitBytes>12600</transmitBytes>
553 * <receiveDrops>0</receiveDrops>
554 * <transmitDrops>0</transmitDrops>
555 * <receiveErrors>0</receiveErrors>
556 * <transmitErrors>0</transmitErrors>
557 * <receiveFrameError>0</receiveFrameError>
558 * <receiveOverRunError>0</receiveOverRunError>
559 * <receiveCrcError>0</receiveCrcError>
560 * <collisionCount>0</collisionCount>
561 * </portStatistic>
563 * </portStatistics>
568 @Path("/{containerName}/port")
570 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
571 @TypeHint(AllPortStatistics.class)
573 @ResponseCode(code = 200, condition = "Operation successful"),
574 @ResponseCode(code = 404, condition = "The containerName is not found"),
575 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
576 public AllPortStatistics getPortStatistics(
577 @PathParam("containerName") String containerName) {
579 if (!NorthboundUtils.isAuthorized(
580 getUserName(), containerName, Privilege.READ, this)) {
581 throw new UnauthorizedException(
582 "User is not authorized to perform this operation on container "
585 IStatisticsManager statisticsManager = getStatisticsService(containerName);
586 if (statisticsManager == null) {
587 throw new ServiceUnavailableException("Statistics "
588 + RestMessages.SERVICEUNAVAILABLE.toString());
591 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
592 .getInstance(ISwitchManager.class, containerName, this);
593 if (switchManager == null) {
594 throw new ServiceUnavailableException("Switch manager "
595 + RestMessages.SERVICEUNAVAILABLE.toString());
598 List<PortStatistics> statistics = new ArrayList<PortStatistics>();
599 for (Node node : switchManager.getNodes()) {
600 List<NodeConnectorStatistics> stat = statisticsManager
601 .getNodeConnectorStatistics(node);
602 PortStatistics portStat = new PortStatistics(node, stat);
603 statistics.add(portStat);
605 return new AllPortStatistics(statistics);
609 * Returns a list of all the Port Statistics across all the NodeConnectors
612 * @param containerName
613 * Name of the Container. The Container name for the base
614 * controller is "default".
616 * Node Type as specifid in {@link org.opendaylight.controller.sal.core.Node} class
618 * Identifier (e.g. MAC address)
619 * @return Returns a list of all the Port Statistics across all the
620 * NodeConnectors in a given Node.
626 * http://host:8080/controller/nb/v2/statistics/default/port/node/OF/00:00:00:00:00:00:00:01
632 * "@id": "00:00:00:00:00:00:00:01"
641 * "@id": "00:00:00:00:00:00:00:01"
644 * "receivePackets": "171",
645 * "transmitPackets": "2451",
646 * "receiveBytes": "11970",
647 * "transmitBytes": "235186",
648 * "receiveDrops": "0",
649 * "transmitDrops": "0",
650 * "receiveErrors": "0",
651 * "transmitErrors": "0",
652 * "receiveFrameError": "0",
653 * "receiveOverRunError": "0",
654 * "receiveCrcError": "0",
655 * "collisionCount": "0"
663 * "@id": "00:00:00:00:00:00:00:01"
666 * "receivePackets": "179",
667 * "transmitPackets": "2443",
668 * "receiveBytes": "12530",
669 * "transmitBytes": "234626",
670 * "receiveDrops": "0",
671 * "transmitDrops": "0",
672 * "receiveErrors": "0",
673 * "transmitErrors": "0",
674 * "receiveFrameError": "0",
675 * "receiveOverRunError": "0",
676 * "receiveCrcError": "0",
677 * "collisionCount": "0"
683 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
684 * <nodePortStatistics>
685 * <node type="OF" id="00:00:00:00:00:00:00:01"/>
686 * <portStatistic>
687 * <nodeConnector type="OF" id="2">
688 * <node type="OF" id="00:00:00:00:00:00:00:01"/>
689 * </nodeConnector>
690 * <receivePackets>180</receivePackets>
691 * <transmitPackets>2594</transmitPackets>
692 * <receiveBytes>12600</receiveBytes>
693 * <transmitBytes>249396</transmitBytes>
694 * <receiveDrops>0</receiveDrops>
695 * <transmitDrops>0</transmitDrops>
696 * <receiveErrors>0</receiveErrors>
697 * <transmitErrors>0</transmitErrors>
698 * <receiveFrameError>0</receiveFrameError>
699 * <receiveOverRunError>0</receiveOverRunError>
700 * <receiveCrcError>0</receiveCrcError>
701 * <collisionCount>0</collisionCount>
702 * </portStatistic>
703 * <portStatistic>
704 * <nodeConnector type="OF" id="5">
705 * <node type="OF" id="00:00:00:00:00:00:00:01"/>
706 * </nodeConnector>
707 * <receivePackets>2542</receivePackets>
708 * <transmitPackets>2719</transmitPackets>
709 * <receiveBytes>243012</receiveBytes>
710 * <transmitBytes>255374</transmitBytes>
711 * <receiveDrops>0</receiveDrops>
712 * <transmitDrops>0</transmitDrops>
713 * <receiveErrors>0</receiveErrors>
714 * <transmitErrors>0</transmitErrors>
715 * <receiveFrameError>0</receiveFrameError>
716 * <receiveOverRunError>0</receiveOverRunError>
717 * <receiveCrcError>0</receiveCrcError>
718 * <collisionCount>0</collisionCount>
719 * </portStatistic>
720 * </nodePortStatistics>
723 @Path("/{containerName}/port/node/{nodeType}/{nodeId}")
725 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
726 @TypeHint(PortStatistics.class)
728 @ResponseCode(code = 200, condition = "Operation successful"),
729 @ResponseCode(code = 404, condition = "The containerName is not found"),
730 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
731 public PortStatistics getPortStatistics(
732 @PathParam("containerName") String containerName,
733 @PathParam("nodeType") String nodeType,
734 @PathParam("nodeId") String nodeId) {
736 if (!NorthboundUtils.isAuthorized(
737 getUserName(), containerName, Privilege.READ, this)) {
738 throw new UnauthorizedException(
739 "User is not authorized to perform this operation on container "
742 handleDefaultDisabled(containerName);
744 IStatisticsManager statisticsManager = getStatisticsService(containerName);
745 if (statisticsManager == null) {
746 throw new ServiceUnavailableException("Statistics "
747 + RestMessages.SERVICEUNAVAILABLE.toString());
750 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
751 .getInstance(ISwitchManager.class, containerName, this);
752 if (switchManager == null) {
753 throw new ServiceUnavailableException("Switch manager "
754 + RestMessages.SERVICEUNAVAILABLE.toString());
757 Node node = handleNodeAvailability(containerName, nodeType, nodeId);
758 return new PortStatistics(node,
759 statisticsManager.getNodeConnectorStatistics(node));
763 * Returns a list of all the Table Statistics on all Nodes.
765 * @param containerName
766 * Name of the Container. The Container name for the base
767 * controller is "default".
769 * @return Returns a list of all the Table Statistics in a given Node.
776 * http://host:8080/controller/nb/v2/statistics/default/table
781 * "tableStatistics": [
785 * "@id": "00:00:00:00:00:00:00:02"
787 * "tableStatistic": [
793 * "@id": "00:00:00:00:00:00:00:02"
796 * "activeCount": "11",
797 * "lookupCount": "816",
798 * "matchedCount": "220"
813 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
815 * <tableStatistics>
816 * <node type="OF" id="00:00:00:00:00:00:00:01"/>
817 * <tableStatistic>
818 * <nodeTable id="0">
819 * <node type="OF" id="00:00:00:00:00:00:00:01"/>
821 * <activeCount>12</activeCount>
822 * <lookupCount>10935</lookupCount>
823 * <matchedCount>10084</matchedCount>
824 * </tableStatistic>
825 * <tableStatistic>
826 * <nodeTable id="1">
827 * <node type="OF" id="00:00:00:00:00:00:00:01"/>
829 * <activeCount>0</activeCount>
830 * <lookupCount>0</lookupCount>
831 * <matchedCount>0</matchedCount>
832 * </tableStatistic>
833 * <tableStatistic>
834 * <nodeTable id="2">
835 * <node type="OF" id="00:00:00:00:00:00:00:01"/>
837 * <activeCount>0</activeCount>
838 * <lookupCount>0</lookupCount>
839 * <matchedCount>0</matchedCount>
840 * </tableStatistic>
841 * </tableStatistics>
842 * <tableStatistics>
846 * </tableStatistics>
851 @Path("/{containerName}/table")
853 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
854 @TypeHint(AllTableStatistics.class)
856 @ResponseCode(code = 200, condition = "Operation successful"),
857 @ResponseCode(code = 404, condition = "The containerName is not found"),
858 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
859 public AllTableStatistics getTableStatistics(
860 @PathParam("containerName") String containerName) {
862 if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) {
863 throw new UnauthorizedException("User is not authorized to perform this operation on container "
866 handleDefaultDisabled(containerName);
868 IStatisticsManager statisticsManager = getStatisticsService(containerName);
869 if (statisticsManager == null) {
870 throw new ServiceUnavailableException("Statistics manager"
871 + RestMessages.SERVICEUNAVAILABLE.toString());
874 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
875 .getInstance(ISwitchManager.class, containerName, this);
876 if (switchManager == null) {
877 throw new ServiceUnavailableException("Switch manager "
878 + RestMessages.SERVICEUNAVAILABLE.toString());
881 List<TableStatistics> statistics = new ArrayList<TableStatistics>();
882 for (Node node : switchManager.getNodes()) {
883 List<NodeTableStatistics> stat = statisticsManager
884 .getNodeTableStatistics(node);
885 TableStatistics tableStat = new TableStatistics(node, stat);
886 statistics.add(tableStat);
888 return new AllTableStatistics(statistics);
892 * Returns a list of all the Table Statistics on a specific node.
894 * @param containerName
895 * Name of the Container. The Container name for the base
896 * controller is "default".
898 * Node Type as specified in {@link org.opendaylight.controller.sal.core.Node} class (e.g. OF for Openflow)
900 * Identifier (e.g. MAC address)
901 * @return Returns a list of all the Table Statistics in a given Node.
908 * http://host:8080/controller/nb/v2/statistics/default/table/node/OF/00:00:00:00:00:00:00:01
914 * "@id": "00:00:00:00:00:00:00:01"
916 * "tableStatistic": [
922 * "@id": "00:00:00:00:00:00:00:01"
925 * "activeCount": "12",
926 * "lookupCount": "11382",
927 * "matchedCount": "10524"
934 * "@id": "00:00:00:00:00:00:00:01"
937 * "activeCount": "0",
938 * "lookupCount": "0",
939 * "matchedCount": "0"
945 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
946 * <nodeTableStatistics>
947 * <node type="OF" id="00:00:00:00:00:00:00:01"/>
948 * <tableStatistic>
949 * <nodeTable id="0">
950 * <node type="OF" id="00:00:00:00:00:00:00:01"/>
952 * <activeCount>12</activeCount>
953 * <lookupCount>10935</lookupCount>
954 * <matchedCount>10084</matchedCount>
955 * </tableStatistic>
956 * <tableStatistic>
957 * <nodeTable id="1">
958 * <node type="OF" id="00:00:00:00:00:00:00:01"/>
960 * <activeCount>0</activeCount>
961 * <lookupCount>0</lookupCount>
962 * <matchedCount>0</matchedCount>
963 * </tableStatistic>
964 * <tableStatistic>
965 * <nodeTable id="2">
966 * <node type="OF" id="00:00:00:00:00:00:00:01"/>
968 * <activeCount>0</activeCount>
969 * <lookupCount>0</lookupCount>
970 * <matchedCount>0</matchedCount>
971 * </tableStatistic>
972 * </nodeTableStatistics>
977 @Path("/{containerName}/table/node/{nodeType}/{nodeId}")
979 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
980 @TypeHint(TableStatistics.class)
982 @ResponseCode(code = 200, condition = "Operation successful"),
983 @ResponseCode(code = 404, condition = "The containerName is not found"),
984 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
985 public TableStatistics getTableStatistics(
986 @PathParam("containerName") String containerName,
987 @PathParam("nodeType") String nodeType,
988 @PathParam("nodeId") String nodeId) {
990 if (!NorthboundUtils.isAuthorized(
991 getUserName(), containerName, Privilege.READ, this)) {
992 throw new UnauthorizedException(
993 "User is not authorized to perform this operation on container "
996 handleDefaultDisabled(containerName);
998 IStatisticsManager statisticsManager = getStatisticsService(containerName);
999 if (statisticsManager == null) {
1000 throw new ServiceUnavailableException("Statistics "
1001 + RestMessages.SERVICEUNAVAILABLE.toString());
1004 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
1005 .getInstance(ISwitchManager.class, containerName, this);
1006 if (switchManager == null) {
1007 throw new ServiceUnavailableException("Switch manager "
1008 + RestMessages.SERVICEUNAVAILABLE.toString());
1011 Node node = handleNodeAvailability(containerName, nodeType, nodeId);
1012 return new TableStatistics(node,
1013 statisticsManager.getNodeTableStatistics(node));
1016 private void handleDefaultDisabled(String containerName) {
1017 IContainerManager containerManager = (IContainerManager) ServiceHelper
1018 .getGlobalInstance(IContainerManager.class, this);
1019 if (containerManager == null) {
1020 throw new InternalServerErrorException(
1021 RestMessages.INTERNALERROR.toString());
1023 if (containerName.equals(GlobalConstants.DEFAULT.toString())
1024 && containerManager.hasNonDefaultContainer()) {
1025 throw new ResourceConflictException(
1026 RestMessages.DEFAULTDISABLED.toString());
1030 private Node handleNodeAvailability(String containerName, String nodeType,
1033 Node node = Node.fromString(nodeType, nodeId);
1035 throw new ResourceNotFoundException(nodeId + " : "
1036 + RestMessages.NONODE.toString());
1039 ISwitchManager sm = (ISwitchManager) ServiceHelper.getInstance(
1040 ISwitchManager.class, containerName, this);
1043 throw new ServiceUnavailableException("Switch Manager "
1044 + RestMessages.SERVICEUNAVAILABLE.toString());
1047 if (!sm.getNodes().contains(node)) {
1048 throw new ResourceNotFoundException(node.toString() + " : "
1049 + RestMessages.NONODE.toString());