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 if (context != null && context.getUserPrincipal() != null) 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
119 * http://localhost:8080/controller/nb/v2/statistics/default/flow
123 * "flowStatistics": [
126 * "id":"00:00:00:00:00:00:00:02",
139 * "mask": "255.255.255.255",
149 * "id":"00:00:00:00:00:00:00:02",
157 * "idleTimeout": "0",
158 * "hardTimeout": "0",
162 * "durationSeconds": "1828",
163 * "durationNanoseconds": "397000000",
164 * "packetCount": "0",
169 * { flow statistics of another node
172 * ......................
179 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
181 * <flowStatistics>
183 * <id>00:00:00:00:00:00:00:02</id>
184 * <type>OF</type>
186 * <flowStatistic>
190 * <type>DL_TYPE</type>
191 * <value>2048</value>
192 * </matchField>
194 * <mask>255.255.255.255</mask>
195 * <type>NW_DST</type>
196 * <value>1.1.1.2</value>
197 * </matchField>
200 * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="output">
203 * <id>00:00:00:00:00:00:00:02</id>
204 * <type>OF</type>
206 * <id>3</id>
207 * <type>OF</type>
210 * <priority>1</priority>
211 * <idleTimeout>0</idleTimeout>
212 * <hardTimeout>0</hardTimeout>
213 * <id>0</id>
215 * <tableId>0</tableId>
216 * <durationSeconds>337</durationSeconds>
217 * <durationNanoseconds>149000000</durationNanoseconds>
218 * <packetCount>0</packetCount>
219 * <byteCount>0</byteCount>
220 * </flowStatistic>
221 * </flowStatistics>
222 * <flowStatistics>
223 * flow statistics for another node
226 * .....................
227 * </flowStatistics>
232 @Path("/{containerName}/flow")
234 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
235 @TypeHint(AllFlowStatistics.class)
237 @ResponseCode(code = 200, condition = "Operation successful"),
238 @ResponseCode(code = 404, condition = "The containerName is not found"),
239 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
240 public AllFlowStatistics getFlowStatistics(
241 @PathParam("containerName") String containerName) {
242 if (!NorthboundUtils.isAuthorized(
243 getUserName(), containerName, Privilege.READ, this)) {
244 throw new UnauthorizedException(
245 "User is not authorized to perform this operation on container "
248 IStatisticsManager statisticsManager = getStatisticsService(containerName);
249 if (statisticsManager == null) {
250 throw new ServiceUnavailableException("Statistics "
251 + RestMessages.SERVICEUNAVAILABLE.toString());
254 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
255 .getInstance(ISwitchManager.class, containerName, this);
256 if (switchManager == null) {
257 throw new ServiceUnavailableException("Switch manager "
258 + RestMessages.SERVICEUNAVAILABLE.toString());
261 List<FlowStatistics> statistics = new ArrayList<FlowStatistics>();
262 for (Node node : switchManager.getNodes()) {
263 List<FlowOnNode> flowStats = new ArrayList<FlowOnNode>();
265 List<FlowOnNode> flows = statisticsManager.getFlows(node);
266 for (FlowOnNode flowOnSwitch : flows) {
267 flowStats.add(flowOnSwitch);
269 FlowStatistics stat = new FlowStatistics(node, flowStats);
270 statistics.add(stat);
272 return new AllFlowStatistics(statistics);
276 * Returns a list of Flow Statistics for a given Node.
278 * @param containerName
279 * Name of the Container. The Container name for the base
280 * controller is "default".
282 * Node Type as specifid in {@link org.opendaylight.controller.sal.core.Node} class
285 * @return List of Flow Statistics for a given Node. *
292 * http://localhost:8080/controller/nb/v2/statistics/default/flow/node/OF/00:00:00:00:00:00:00:01
297 * "id":"00:00:00:00:00:00:00:01",
310 * "mask": "255.255.255.255",
318 * "@type": "setDlDst",
319 * "address": "52d28b0f76ec"
325 * "id":"00:00:00:00:00:00:00:01",
334 * "idleTimeout": "0",
335 * "hardTimeout": "0",
339 * "durationSeconds": "2089",
340 * "durationNanoseconds": "538000000",
341 * "packetCount": "0",
348 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
349 * <nodeFlowStatistics>
351 * <id>00:00:00:00:00:00:00:02</id>
352 * <type>OF</type>
354 * <flowStatistic>
358 * <type>DL_TYPE</type>
359 * <value>2048</value>
360 * </matchField>
362 * <mask>255.255.255.255</mask>
363 * <type>NW_DST</type>
364 * <value>1.1.1.2</value>
365 * </matchField>
368 * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="output">
371 * <id>00:00:00:00:00:00:00:02</id>
372 * <type>OF</type>
374 * <id>3</id>
375 * <type>OF</type>
378 * <priority>1</priority>
379 * <idleTimeout>0</idleTimeout>
380 * <hardTimeout>0</hardTimeout>
381 * <id>0</id>
383 * <tableId>0</tableId>
384 * <durationSeconds>337</durationSeconds>
385 * <durationNanoseconds>149000000</durationNanoseconds>
386 * <packetCount>0</packetCount>
387 * <byteCount>0</byteCount>
388 * </flowStatistic>
389 * <flowStatistic>
393 * <type>DL_TYPE</type>
394 * <value>2048</value>
395 * </matchField>
397 * <mask>255.255.255.255</mask>
398 * <type>NW_DST</type>
399 * <value>1.1.1.1</value>
400 * </matchField>
403 * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="output">
406 * <id>00:00:00:00:00:00:00:02</id>
407 * <type>OF</type>
409 * <id>3</id>
410 * <type>OF</type>
413 * <priority>1</priority>
414 * <idleTimeout>0</idleTimeout>
415 * <hardTimeout>0</hardTimeout>
416 * <id>0</id>
418 * <tableId>0</tableId>
419 * <durationSeconds>337</durationSeconds>
420 * <durationNanoseconds>208000000</durationNanoseconds>
421 * <packetCount>0</packetCount>
422 * <byteCount>0</byteCount>
423 * </flowStatistic>
424 * </nodeFlowStatistics>
427 @Path("/{containerName}/flow/node/{nodeType}/{nodeId}")
429 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
430 @TypeHint(FlowStatistics.class)
432 @ResponseCode(code = 200, condition = "Operation successful"),
433 @ResponseCode(code = 404, condition = "The containerName is not found"),
434 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
435 public FlowStatistics getFlowStatistics(
436 @PathParam("containerName") String containerName,
437 @PathParam("nodeType") String nodeType,
438 @PathParam("nodeId") String nodeId) {
439 if (!NorthboundUtils.isAuthorized(
440 getUserName(), containerName, Privilege.READ, this)) {
441 throw new UnauthorizedException(
442 "User is not authorized to perform this operation on container "
445 handleDefaultDisabled(containerName);
447 IStatisticsManager statisticsManager = getStatisticsService(containerName);
448 if (statisticsManager == null) {
449 throw new ServiceUnavailableException("Statistics "
450 + RestMessages.SERVICEUNAVAILABLE.toString());
453 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
454 .getInstance(ISwitchManager.class, containerName, this);
455 if (switchManager == null) {
456 throw new ServiceUnavailableException("Switch manager "
457 + RestMessages.SERVICEUNAVAILABLE.toString());
460 Node node = handleNodeAvailability(containerName, nodeType, nodeId);
461 return new FlowStatistics(node, statisticsManager.getFlows(node));
465 * Returns a list of all the Port Statistics across all the NodeConnectors
468 * @param containerName
469 * Name of the Container. The Container name for the base
470 * controller is "default".
471 * @return List of all the Port Statistics across all the NodeConnectors on
479 * http://localhost:8080/controller/nb/v2/statistics/default/port
483 * "portStatistics": [
486 * "id":"00:00:00:00:00:00:00:02",
493 * "id":"00:00:00:00:00:00:00:02",
499 * "receivePackets": "182",
500 * "transmitPackets": "173",
501 * "receiveBytes": "12740",
502 * "transmitBytes": "12110",
503 * "receiveDrops": "0",
504 * "transmitDrops": "0",
505 * "receiveErrors": "0",
506 * "transmitErrors": "0",
507 * "receiveFrameError": "0",
508 * "receiveOverRunError": "0",
509 * "receiveCrcError": "0",
510 * "collisionCount": "0"
515 * "id":"00:00:00:00:00:00:00:02",
521 * "receivePackets": "174",
522 * "transmitPackets": "181",
523 * "receiveBytes": "12180",
524 * "transmitBytes": "12670",
525 * "receiveDrops": "0",
526 * "transmitDrops": "0",
527 * "receiveErrors": "0",
528 * "transmitErrors": "0",
529 * "receiveFrameError": "0",
530 * "receiveOverRunError": "0",
531 * "receiveCrcError": "0",
532 * "collisionCount": "0"
539 * "id":"00:00:00:00:00:00:00:03",
544 * .......................
545 * ..........................
552 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
554 * <portStatistics>
556 * <id>00:00:00:00:00:00:00:02</id>
557 * <type>OF</type>
559 * <portStatistic>
560 * <nodeConnector>
562 * <id>00:00:00:00:00:00:00:02</id>
563 * <type>OF</type>
565 * <id>3</id>
566 * <type>OF</type>
567 * </nodeConnector>
568 * <receivePackets>181</receivePackets>
569 * <transmitPackets>172</transmitPackets>
570 * <receiveBytes>12670</receiveBytes>
571 * <transmitBytes>12040</transmitBytes>
572 * <receiveDrops>0</receiveDrops>
573 * <transmitDrops>0</transmitDrops>
574 * <receiveErrors>0</receiveErrors>
575 * <transmitErrors>0</transmitErrors>
576 * <receiveFrameError>0</receiveFrameError>
577 * <receiveOverRunError>0</receiveOverRunError>
578 * <receiveCrcError>0</receiveCrcError>
579 * <collisionCount>0</collisionCount>
580 * </portStatistic>
581 * <portStatistic>
582 * <nodeConnector>
584 * <id>00:00:00:00:00:00:00:02</id>
585 * <type>OF</type>
587 * <id>2</id>
588 * <type>OF</type>
589 * </nodeConnector>
590 * <receivePackets>173</receivePackets>
591 * <transmitPackets>180</transmitPackets>
592 * <receiveBytes>12110</receiveBytes>
593 * <transmitBytes>12600</transmitBytes>
594 * <receiveDrops>0</receiveDrops>
595 * <transmitDrops>0</transmitDrops>
596 * <receiveErrors>0</receiveErrors>
597 * <transmitErrors>0</transmitErrors>
598 * <receiveFrameError>0</receiveFrameError>
599 * <receiveOverRunError>0</receiveOverRunError>
600 * <receiveCrcError>0</receiveCrcError>
601 * <collisionCount>0</collisionCount>
602 * </portStatistic>
603 * </portStatistics>
608 @Path("/{containerName}/port")
610 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
611 @TypeHint(AllPortStatistics.class)
613 @ResponseCode(code = 200, condition = "Operation successful"),
614 @ResponseCode(code = 404, condition = "The containerName is not found"),
615 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
616 public AllPortStatistics getPortStatistics(
617 @PathParam("containerName") String containerName) {
619 if (!NorthboundUtils.isAuthorized(
620 getUserName(), containerName, Privilege.READ, this)) {
621 throw new UnauthorizedException(
622 "User is not authorized to perform this operation on container "
625 IStatisticsManager statisticsManager = getStatisticsService(containerName);
626 if (statisticsManager == null) {
627 throw new ServiceUnavailableException("Statistics "
628 + RestMessages.SERVICEUNAVAILABLE.toString());
631 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
632 .getInstance(ISwitchManager.class, containerName, this);
633 if (switchManager == null) {
634 throw new ServiceUnavailableException("Switch manager "
635 + RestMessages.SERVICEUNAVAILABLE.toString());
638 List<PortStatistics> statistics = new ArrayList<PortStatistics>();
639 for (Node node : switchManager.getNodes()) {
640 List<NodeConnectorStatistics> stat = statisticsManager
641 .getNodeConnectorStatistics(node);
642 PortStatistics portStat = new PortStatistics(node, stat);
643 statistics.add(portStat);
645 return new AllPortStatistics(statistics);
649 * Returns a list of all the Port Statistics across all the NodeConnectors
652 * @param containerName
653 * Name of the Container. The Container name for the base
654 * controller is "default".
656 * Node Type as specifid in {@link org.opendaylight.controller.sal.core.Node} class
658 * Identifier (e.g. MAC address)
659 * @return Returns a list of all the Port Statistics across all the
660 * NodeConnectors in a given Node.
667 * http://localhost:8080/controller/nb/v2/statistics/default/port/node/OF/00:00:00:00:00:00:00:01
672 * "id":"00:00:00:00:00:00:00:01",
679 * "id":"00:00:00:00:00:00:00:01",
685 * "receivePackets": "171",
686 * "transmitPackets": "2451",
687 * "receiveBytes": "11970",
688 * "transmitBytes": "235186",
689 * "receiveDrops": "0",
690 * "transmitDrops": "0",
691 * "receiveErrors": "0",
692 * "transmitErrors": "0",
693 * "receiveFrameError": "0",
694 * "receiveOverRunError": "0",
695 * "receiveCrcError": "0",
696 * "collisionCount": "0"
701 * "id":"00:00:00:00:00:00:00:01",
707 * "receivePackets": "179",
708 * "transmitPackets": "2443",
709 * "receiveBytes": "12530",
710 * "transmitBytes": "234626",
711 * "receiveDrops": "0",
712 * "transmitDrops": "0",
713 * "receiveErrors": "0",
714 * "transmitErrors": "0",
715 * "receiveFrameError": "0",
716 * "receiveOverRunError": "0",
717 * "receiveCrcError": "0",
718 * "collisionCount": "0"
724 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
725 * <nodePortStatistics>
727 * <id>00:00:00:00:00:00:00:01</id>
728 * <type>OF</type>
730 * <portStatistic>
731 * <nodeConnector>
733 * <id>00:00:00:00:00:00:00:01</id>
734 * <type>OF</type>
736 * <id>2</id>
737 * <type>OF</type>
738 * </nodeConnector>
739 * <receivePackets>180</receivePackets>
740 * <transmitPackets>2594</transmitPackets>
741 * <receiveBytes>12600</receiveBytes>
742 * <transmitBytes>249396</transmitBytes>
743 * <receiveDrops>0</receiveDrops>
744 * <transmitDrops>0</transmitDrops>
745 * <receiveErrors>0</receiveErrors>
746 * <transmitErrors>0</transmitErrors>
747 * <receiveFrameError>0</receiveFrameError>
748 * <receiveOverRunError>0</receiveOverRunError>
749 * <receiveCrcError>0</receiveCrcError>
750 * <collisionCount>0</collisionCount>
751 * </portStatistic>
752 * <portStatistic>
753 * <nodeConnector>
755 * <id>00:00:00:00:00:00:00:01</id>
756 * <type>OF</type>
758 * <id>5</id>
759 * <type>OF</type>
760 * </nodeConnector>
761 * <receivePackets>2542</receivePackets>
762 * <transmitPackets>2719</transmitPackets>
763 * <receiveBytes>243012</receiveBytes>
764 * <transmitBytes>255374</transmitBytes>
765 * <receiveDrops>0</receiveDrops>
766 * <transmitDrops>0</transmitDrops>
767 * <receiveErrors>0</receiveErrors>
768 * <transmitErrors>0</transmitErrors>
769 * <receiveFrameError>0</receiveFrameError>
770 * <receiveOverRunError>0</receiveOverRunError>
771 * <receiveCrcError>0</receiveCrcError>
772 * <collisionCount>0</collisionCount>
773 * </portStatistic>
774 * </nodePortStatistics>
777 @Path("/{containerName}/port/node/{nodeType}/{nodeId}")
779 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
780 @TypeHint(PortStatistics.class)
782 @ResponseCode(code = 200, condition = "Operation successful"),
783 @ResponseCode(code = 404, condition = "The containerName is not found"),
784 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
785 public PortStatistics getPortStatistics(
786 @PathParam("containerName") String containerName,
787 @PathParam("nodeType") String nodeType,
788 @PathParam("nodeId") String nodeId) {
790 if (!NorthboundUtils.isAuthorized(
791 getUserName(), containerName, Privilege.READ, this)) {
792 throw new UnauthorizedException(
793 "User is not authorized to perform this operation on container "
796 handleDefaultDisabled(containerName);
798 IStatisticsManager statisticsManager = getStatisticsService(containerName);
799 if (statisticsManager == null) {
800 throw new ServiceUnavailableException("Statistics "
801 + RestMessages.SERVICEUNAVAILABLE.toString());
804 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
805 .getInstance(ISwitchManager.class, containerName, this);
806 if (switchManager == null) {
807 throw new ServiceUnavailableException("Switch manager "
808 + RestMessages.SERVICEUNAVAILABLE.toString());
811 Node node = handleNodeAvailability(containerName, nodeType, nodeId);
812 return new PortStatistics(node,
813 statisticsManager.getNodeConnectorStatistics(node));
817 * Returns a list of all the Table Statistics on all Nodes.
819 * @param containerName
820 * Name of the Container. The Container name for the base
821 * controller is "default".
823 * @return Returns a list of all the Table Statistics in a given Node.
830 * http://localhost:8080/controller/nb/v2/statistics/default/table
834 * "tableStatistics": [
837 * "id":"00:00:00:00:00:00:00:02",
840 * "tableStatistic": [
844 * "id":"00:00:00:00:00:00:00:02",
849 * "activeCount": "11",
850 * "lookupCount": "816",
851 * "matchedCount": "220"
865 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
867 * <tableStatistics>
869 * <id>00:00:00:00:00:00:00:01</id>
870 * <type>OF</type>
872 * <tableStatistic>
875 * <id>00:00:00:00:00:00:00:01</id>
876 * <type>OF</type>
878 * <id>0</id>
880 * <activeCount>12</activeCount>
881 * <lookupCount>10935</lookupCount>
882 * <matchedCount>10084</matchedCount>
883 * </tableStatistic>
884 * <tableStatistic>
887 * <id>00:00:00:00:00:00:00:01</id>
888 * <type>OF</type>
890 * <id>1</id>
892 * <activeCount>0</activeCount>
893 * <lookupCount>0</lookupCount>
894 * <matchedCount>0</matchedCount>
895 * </tableStatistic>
896 * <tableStatistic>
899 * <id>00:00:00:00:00:00:00:01</id>
900 * <type>OF</type>
902 * <id>2</id>
904 * <activeCount>0</activeCount>
905 * <lookupCount>0</lookupCount>
906 * <matchedCount>0</matchedCount>
907 * </tableStatistic>
908 * </tableStatistics>
909 * <tableStatistics>
913 * </tableStatistics>
918 @Path("/{containerName}/table")
920 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
921 @TypeHint(AllTableStatistics.class)
923 @ResponseCode(code = 200, condition = "Operation successful"),
924 @ResponseCode(code = 404, condition = "The containerName is not found"),
925 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
926 public AllTableStatistics getTableStatistics(
927 @PathParam("containerName") String containerName) {
929 if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) {
930 throw new UnauthorizedException("User is not authorized to perform this operation on container "
933 handleDefaultDisabled(containerName);
935 IStatisticsManager statisticsManager = getStatisticsService(containerName);
936 if (statisticsManager == null) {
937 throw new ServiceUnavailableException("Statistics manager"
938 + RestMessages.SERVICEUNAVAILABLE.toString());
941 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
942 .getInstance(ISwitchManager.class, containerName, this);
943 if (switchManager == null) {
944 throw new ServiceUnavailableException("Switch manager "
945 + RestMessages.SERVICEUNAVAILABLE.toString());
948 List<TableStatistics> statistics = new ArrayList<TableStatistics>();
949 for (Node node : switchManager.getNodes()) {
950 List<NodeTableStatistics> stat = statisticsManager
951 .getNodeTableStatistics(node);
952 TableStatistics tableStat = new TableStatistics(node, stat);
953 statistics.add(tableStat);
955 return new AllTableStatistics(statistics);
959 * Returns a list of all the Table Statistics on a specific node.
961 * @param containerName
962 * Name of the Container. The Container name for the base
963 * controller is "default".
965 * Node Type as specified in {@link org.opendaylight.controller.sal.core.Node} class (e.g. OF for Openflow)
967 * Identifier (e.g. MAC address)
968 * @return Returns a list of all the Table Statistics in a given Node.
975 * http://localhost:8080/controller/nb/v2/statistics/default/table/node/OF/00:00:00:00:00:00:00:01
980 * "id":"00:00:00:00:00:00:00:01",
983 * "tableStatistic": [
987 * "id":"00:00:00:00:00:00:00:01",
992 * "activeCount": "12",
993 * "lookupCount": "11382",
994 * "matchedCount": "10524"
999 * "id":"00:00:00:00:00:00:00:01",
1004 * "activeCount": "0",
1005 * "lookupCount": "0",
1006 * "matchedCount": "0"
1012 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
1013 * <nodeTableStatistics>
1015 * <id>00:00:00:00:00:00:00:01</id>
1016 * <type>OF</type>
1018 * <tableStatistic>
1021 * <id>00:00:00:00:00:00:00:01</id>
1022 * <type>OF</type>
1024 * <id>0</id>
1025 * </nodeTable>
1026 * <activeCount>12</activeCount>
1027 * <lookupCount>10935</lookupCount>
1028 * <matchedCount>10084</matchedCount>
1029 * </tableStatistic>
1030 * <tableStatistic>
1033 * <id>00:00:00:00:00:00:00:01</id>
1034 * <type>OF</type>
1036 * <id>1</id>
1037 * </nodeTable>
1038 * <activeCount>0</activeCount>
1039 * <lookupCount>0</lookupCount>
1040 * <matchedCount>0</matchedCount>
1041 * </tableStatistic>
1042 * <tableStatistic>
1045 * <id>00:00:00:00:00:00:00:01</id>
1046 * <type>OF</type>
1048 * <id>2</id>
1049 * </nodeTable>
1050 * <activeCount>0</activeCount>
1051 * <lookupCount>0</lookupCount>
1052 * <matchedCount>0</matchedCount>
1053 * </tableStatistic>
1054 * </nodeTableStatistics>
1058 @Path("/{containerName}/table/node/{nodeType}/{nodeId}")
1060 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
1061 @TypeHint(TableStatistics.class)
1063 @ResponseCode(code = 200, condition = "Operation successful"),
1064 @ResponseCode(code = 404, condition = "The containerName is not found"),
1065 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
1066 public TableStatistics getTableStatistics(
1067 @PathParam("containerName") String containerName,
1068 @PathParam("nodeType") String nodeType,
1069 @PathParam("nodeId") String nodeId) {
1071 if (!NorthboundUtils.isAuthorized(
1072 getUserName(), containerName, Privilege.READ, this)) {
1073 throw new UnauthorizedException(
1074 "User is not authorized to perform this operation on container "
1077 handleDefaultDisabled(containerName);
1079 IStatisticsManager statisticsManager = getStatisticsService(containerName);
1080 if (statisticsManager == null) {
1081 throw new ServiceUnavailableException("Statistics "
1082 + RestMessages.SERVICEUNAVAILABLE.toString());
1085 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
1086 .getInstance(ISwitchManager.class, containerName, this);
1087 if (switchManager == null) {
1088 throw new ServiceUnavailableException("Switch manager "
1089 + RestMessages.SERVICEUNAVAILABLE.toString());
1092 Node node = handleNodeAvailability(containerName, nodeType, nodeId);
1093 return new TableStatistics(node,
1094 statisticsManager.getNodeTableStatistics(node));
1097 private void handleDefaultDisabled(String containerName) {
1098 IContainerManager containerManager = (IContainerManager) ServiceHelper
1099 .getGlobalInstance(IContainerManager.class, this);
1100 if (containerManager == null) {
1101 throw new InternalServerErrorException(
1102 RestMessages.INTERNALERROR.toString());
1104 if (containerName.equals(GlobalConstants.DEFAULT.toString())
1105 && containerManager.hasNonDefaultContainer()) {
1106 throw new ResourceConflictException(
1107 RestMessages.DEFAULTDISABLED.toString());
1111 private Node handleNodeAvailability(String containerName, String nodeType,
1114 Node node = Node.fromString(nodeType, nodeId);
1116 throw new ResourceNotFoundException(nodeId + " : "
1117 + RestMessages.NONODE.toString());
1120 ISwitchManager sm = (ISwitchManager) ServiceHelper.getInstance(
1121 ISwitchManager.class, containerName, this);
1124 throw new ServiceUnavailableException("Switch Manager "
1125 + RestMessages.SERVICEUNAVAILABLE.toString());
1128 if (!sm.getNodes().contains(node)) {
1129 throw new ResourceNotFoundException(node.toString() + " : "
1130 + RestMessages.NONODE.toString());