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.
57 public class StatisticsNorthbound {
59 private String username;
62 public void setSecurityContext(SecurityContext context) {
63 if (context != null && context.getUserPrincipal() != null) username = context.getUserPrincipal().getName();
66 protected String getUserName() {
70 private IStatisticsManager getStatisticsService(String containerName) {
71 IContainerManager containerManager = (IContainerManager) ServiceHelper
72 .getGlobalInstance(IContainerManager.class, this);
73 if (containerManager == null) {
74 throw new ServiceUnavailableException("Container "
75 + RestMessages.SERVICEUNAVAILABLE.toString());
78 boolean found = false;
79 List<String> containerNames = containerManager.getContainerNames();
80 for (String cName : containerNames) {
81 if (cName.trim().equalsIgnoreCase(containerName.trim())) {
87 throw new ResourceNotFoundException(containerName + " "
88 + RestMessages.NOCONTAINER.toString());
91 IStatisticsManager statsManager = (IStatisticsManager) ServiceHelper
92 .getInstance(IStatisticsManager.class, containerName, this);
94 if (statsManager == null) {
95 throw new ServiceUnavailableException("Statistics "
96 + RestMessages.SERVICEUNAVAILABLE.toString());
103 * Returns a list of all Flow Statistics from all the Nodes.
105 * @param containerName
106 * Name of the Container. The Container name for the base
107 * controller is "default".
108 * @return List of FlowStatistics from all the Nodes
115 * http://localhost:8080/controller/nb/v2/statistics/default/flow
117 * Response body in JSON:
119 * "flowStatistics": [
122 * "id":"00:00:00:00:00:00:00:02",
135 * "mask": "255.255.255.255",
145 * "id":"00:00:00:00:00:00:00:02",
153 * "idleTimeout": "0",
154 * "hardTimeout": "0",
158 * "durationSeconds": "1828",
159 * "durationNanoseconds": "397000000",
160 * "packetCount": "0",
165 * { flow statistics of another node
168 * ......................
174 * Response body in XML:
175 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
177 * <flowStatistics>
179 * <id>00:00:00:00:00:00:00:02</id>
180 * <type>OF</type>
182 * <flowStatistic>
186 * <type>DL_TYPE</type>
187 * <value>2048</value>
188 * </matchField>
190 * <mask>255.255.255.255</mask>
191 * <type>NW_DST</type>
192 * <value>1.1.1.2</value>
193 * </matchField>
196 * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="output">
199 * <id>00:00:00:00:00:00:00:02</id>
200 * <type>OF</type>
202 * <id>3</id>
203 * <type>OF</type>
206 * <priority>1</priority>
207 * <idleTimeout>0</idleTimeout>
208 * <hardTimeout>0</hardTimeout>
209 * <id>0</id>
211 * <tableId>0</tableId>
212 * <durationSeconds>337</durationSeconds>
213 * <durationNanoseconds>149000000</durationNanoseconds>
214 * <packetCount>0</packetCount>
215 * <byteCount>0</byteCount>
216 * </flowStatistic>
217 * </flowStatistics>
218 * <flowStatistics>
219 * flow statistics for another node
222 * .....................
223 * </flowStatistics>
228 @Path("/{containerName}/flow")
230 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
231 @TypeHint(AllFlowStatistics.class)
233 @ResponseCode(code = 200, condition = "Operation successful"),
234 @ResponseCode(code = 404, condition = "The containerName is not found"),
235 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
236 public AllFlowStatistics getFlowStatistics(
237 @PathParam("containerName") String containerName) {
238 if (!NorthboundUtils.isAuthorized(
239 getUserName(), containerName, Privilege.READ, this)) {
240 throw new UnauthorizedException(
241 "User is not authorized to perform this operation on container "
244 IStatisticsManager statisticsManager = getStatisticsService(containerName);
245 if (statisticsManager == null) {
246 throw new ServiceUnavailableException("Statistics "
247 + RestMessages.SERVICEUNAVAILABLE.toString());
250 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
251 .getInstance(ISwitchManager.class, containerName, this);
252 if (switchManager == null) {
253 throw new ServiceUnavailableException("Switch manager "
254 + RestMessages.SERVICEUNAVAILABLE.toString());
257 List<FlowStatistics> statistics = new ArrayList<FlowStatistics>();
258 for (Node node : switchManager.getNodes()) {
259 List<FlowOnNode> flowStats = new ArrayList<FlowOnNode>();
261 List<FlowOnNode> flows = statisticsManager.getFlows(node);
262 for (FlowOnNode flowOnSwitch : flows) {
263 flowStats.add(flowOnSwitch);
265 FlowStatistics stat = new FlowStatistics(node, flowStats);
266 statistics.add(stat);
268 return new AllFlowStatistics(statistics);
272 * Returns a list of Flow Statistics for a given Node.
274 * @param containerName
275 * Name of the Container. The Container name for the base
276 * controller is "default".
278 * Node Type as specifid in {@link org.opendaylight.controller.sal.core.Node} class
281 * @return List of Flow Statistics for a given Node. *
288 * http://localhost:8080/controller/nb/v2/statistics/default/flow/node/OF/00:00:00:00:00:00:00:01
290 * Response body in JSON:
293 * "id":"00:00:00:00:00:00:00:01",
306 * "mask": "255.255.255.255",
314 * "@type": "setDlDst",
315 * "address": "52d28b0f76ec"
321 * "id":"00:00:00:00:00:00:00:01",
330 * "idleTimeout": "0",
331 * "hardTimeout": "0",
335 * "durationSeconds": "2089",
336 * "durationNanoseconds": "538000000",
337 * "packetCount": "0",
343 * Response body in XML:
344 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
345 * <nodeFlowStatistics>
347 * <id>00:00:00:00:00:00:00:02</id>
348 * <type>OF</type>
350 * <flowStatistic>
354 * <type>DL_TYPE</type>
355 * <value>2048</value>
356 * </matchField>
358 * <mask>255.255.255.255</mask>
359 * <type>NW_DST</type>
360 * <value>1.1.1.2</value>
361 * </matchField>
364 * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="output">
367 * <id>00:00:00:00:00:00:00:02</id>
368 * <type>OF</type>
370 * <id>3</id>
371 * <type>OF</type>
374 * <priority>1</priority>
375 * <idleTimeout>0</idleTimeout>
376 * <hardTimeout>0</hardTimeout>
377 * <id>0</id>
379 * <tableId>0</tableId>
380 * <durationSeconds>337</durationSeconds>
381 * <durationNanoseconds>149000000</durationNanoseconds>
382 * <packetCount>0</packetCount>
383 * <byteCount>0</byteCount>
384 * </flowStatistic>
385 * <flowStatistic>
389 * <type>DL_TYPE</type>
390 * <value>2048</value>
391 * </matchField>
393 * <mask>255.255.255.255</mask>
394 * <type>NW_DST</type>
395 * <value>1.1.1.1</value>
396 * </matchField>
399 * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="output">
402 * <id>00:00:00:00:00:00:00:02</id>
403 * <type>OF</type>
405 * <id>3</id>
406 * <type>OF</type>
409 * <priority>1</priority>
410 * <idleTimeout>0</idleTimeout>
411 * <hardTimeout>0</hardTimeout>
412 * <id>0</id>
414 * <tableId>0</tableId>
415 * <durationSeconds>337</durationSeconds>
416 * <durationNanoseconds>208000000</durationNanoseconds>
417 * <packetCount>0</packetCount>
418 * <byteCount>0</byteCount>
419 * </flowStatistic>
420 * </nodeFlowStatistics>
423 @Path("/{containerName}/flow/node/{nodeType}/{nodeId}")
425 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
426 @TypeHint(FlowStatistics.class)
428 @ResponseCode(code = 200, condition = "Operation successful"),
429 @ResponseCode(code = 404, condition = "The containerName is not found"),
430 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
431 public FlowStatistics getFlowStatistics(
432 @PathParam("containerName") String containerName,
433 @PathParam("nodeType") String nodeType,
434 @PathParam("nodeId") String nodeId) {
435 if (!NorthboundUtils.isAuthorized(
436 getUserName(), containerName, Privilege.READ, this)) {
437 throw new UnauthorizedException(
438 "User is not authorized to perform this operation on container "
441 handleDefaultDisabled(containerName);
443 IStatisticsManager statisticsManager = getStatisticsService(containerName);
444 if (statisticsManager == null) {
445 throw new ServiceUnavailableException("Statistics "
446 + RestMessages.SERVICEUNAVAILABLE.toString());
449 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
450 .getInstance(ISwitchManager.class, containerName, this);
451 if (switchManager == null) {
452 throw new ServiceUnavailableException("Switch manager "
453 + RestMessages.SERVICEUNAVAILABLE.toString());
456 Node node = handleNodeAvailability(containerName, nodeType, nodeId);
457 return new FlowStatistics(node, statisticsManager.getFlows(node));
461 * Returns a list of all the Port Statistics across all the NodeConnectors
464 * @param containerName
465 * Name of the Container. The Container name for the base
466 * controller is "default".
467 * @return List of all the Port Statistics across all the NodeConnectors on
475 * http://localhost:8080/controller/nb/v2/statistics/default/port
477 * Response body in JSON:
479 * "portStatistics": [
482 * "id":"00:00:00:00:00:00:00:02",
489 * "id":"00:00:00:00:00:00:00:02",
495 * "receivePackets": "182",
496 * "transmitPackets": "173",
497 * "receiveBytes": "12740",
498 * "transmitBytes": "12110",
499 * "receiveDrops": "0",
500 * "transmitDrops": "0",
501 * "receiveErrors": "0",
502 * "transmitErrors": "0",
503 * "receiveFrameError": "0",
504 * "receiveOverRunError": "0",
505 * "receiveCrcError": "0",
506 * "collisionCount": "0"
511 * "id":"00:00:00:00:00:00:00:02",
517 * "receivePackets": "174",
518 * "transmitPackets": "181",
519 * "receiveBytes": "12180",
520 * "transmitBytes": "12670",
521 * "receiveDrops": "0",
522 * "transmitDrops": "0",
523 * "receiveErrors": "0",
524 * "transmitErrors": "0",
525 * "receiveFrameError": "0",
526 * "receiveOverRunError": "0",
527 * "receiveCrcError": "0",
528 * "collisionCount": "0"
535 * "id":"00:00:00:00:00:00:00:03",
540 * .......................
541 * ..........................
547 * Response body in XML:
548 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
550 * <portStatistics>
552 * <id>00:00:00:00:00:00:00:02</id>
553 * <type>OF</type>
555 * <portStatistic>
556 * <nodeConnector>
558 * <id>00:00:00:00:00:00:00:02</id>
559 * <type>OF</type>
561 * <id>3</id>
562 * <type>OF</type>
563 * </nodeConnector>
564 * <receivePackets>181</receivePackets>
565 * <transmitPackets>172</transmitPackets>
566 * <receiveBytes>12670</receiveBytes>
567 * <transmitBytes>12040</transmitBytes>
568 * <receiveDrops>0</receiveDrops>
569 * <transmitDrops>0</transmitDrops>
570 * <receiveErrors>0</receiveErrors>
571 * <transmitErrors>0</transmitErrors>
572 * <receiveFrameError>0</receiveFrameError>
573 * <receiveOverRunError>0</receiveOverRunError>
574 * <receiveCrcError>0</receiveCrcError>
575 * <collisionCount>0</collisionCount>
576 * </portStatistic>
577 * <portStatistic>
578 * <nodeConnector>
580 * <id>00:00:00:00:00:00:00:02</id>
581 * <type>OF</type>
583 * <id>2</id>
584 * <type>OF</type>
585 * </nodeConnector>
586 * <receivePackets>173</receivePackets>
587 * <transmitPackets>180</transmitPackets>
588 * <receiveBytes>12110</receiveBytes>
589 * <transmitBytes>12600</transmitBytes>
590 * <receiveDrops>0</receiveDrops>
591 * <transmitDrops>0</transmitDrops>
592 * <receiveErrors>0</receiveErrors>
593 * <transmitErrors>0</transmitErrors>
594 * <receiveFrameError>0</receiveFrameError>
595 * <receiveOverRunError>0</receiveOverRunError>
596 * <receiveCrcError>0</receiveCrcError>
597 * <collisionCount>0</collisionCount>
598 * </portStatistic>
599 * </portStatistics>
604 @Path("/{containerName}/port")
606 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
607 @TypeHint(AllPortStatistics.class)
609 @ResponseCode(code = 200, condition = "Operation successful"),
610 @ResponseCode(code = 404, condition = "The containerName is not found"),
611 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
612 public AllPortStatistics getPortStatistics(
613 @PathParam("containerName") String containerName) {
615 if (!NorthboundUtils.isAuthorized(
616 getUserName(), containerName, Privilege.READ, this)) {
617 throw new UnauthorizedException(
618 "User is not authorized to perform this operation on container "
621 IStatisticsManager statisticsManager = getStatisticsService(containerName);
622 if (statisticsManager == null) {
623 throw new ServiceUnavailableException("Statistics "
624 + RestMessages.SERVICEUNAVAILABLE.toString());
627 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
628 .getInstance(ISwitchManager.class, containerName, this);
629 if (switchManager == null) {
630 throw new ServiceUnavailableException("Switch manager "
631 + RestMessages.SERVICEUNAVAILABLE.toString());
634 List<PortStatistics> statistics = new ArrayList<PortStatistics>();
635 for (Node node : switchManager.getNodes()) {
636 List<NodeConnectorStatistics> stat = statisticsManager
637 .getNodeConnectorStatistics(node);
638 PortStatistics portStat = new PortStatistics(node, stat);
639 statistics.add(portStat);
641 return new AllPortStatistics(statistics);
645 * Returns a list of all the Port Statistics across all the NodeConnectors
648 * @param containerName
649 * Name of the Container. The Container name for the base
650 * controller is "default".
652 * Node Type as specifid in {@link org.opendaylight.controller.sal.core.Node} class
654 * Identifier (e.g. MAC address)
655 * @return Returns a list of all the Port Statistics across all the
656 * NodeConnectors in a given Node.
663 * http://localhost:8080/controller/nb/v2/statistics/default/port/node/OF/00:00:00:00:00:00:00:01
665 * Response body in JSON:
668 * "id":"00:00:00:00:00:00:00:01",
675 * "id":"00:00:00:00:00:00:00:01",
681 * "receivePackets": "171",
682 * "transmitPackets": "2451",
683 * "receiveBytes": "11970",
684 * "transmitBytes": "235186",
685 * "receiveDrops": "0",
686 * "transmitDrops": "0",
687 * "receiveErrors": "0",
688 * "transmitErrors": "0",
689 * "receiveFrameError": "0",
690 * "receiveOverRunError": "0",
691 * "receiveCrcError": "0",
692 * "collisionCount": "0"
697 * "id":"00:00:00:00:00:00:00:01",
703 * "receivePackets": "179",
704 * "transmitPackets": "2443",
705 * "receiveBytes": "12530",
706 * "transmitBytes": "234626",
707 * "receiveDrops": "0",
708 * "transmitDrops": "0",
709 * "receiveErrors": "0",
710 * "transmitErrors": "0",
711 * "receiveFrameError": "0",
712 * "receiveOverRunError": "0",
713 * "receiveCrcError": "0",
714 * "collisionCount": "0"
719 * Response body in XML:
720 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
721 * <nodePortStatistics>
723 * <id>00:00:00:00:00:00:00:01</id>
724 * <type>OF</type>
726 * <portStatistic>
727 * <nodeConnector>
729 * <id>00:00:00:00:00:00:00:01</id>
730 * <type>OF</type>
732 * <id>2</id>
733 * <type>OF</type>
734 * </nodeConnector>
735 * <receivePackets>180</receivePackets>
736 * <transmitPackets>2594</transmitPackets>
737 * <receiveBytes>12600</receiveBytes>
738 * <transmitBytes>249396</transmitBytes>
739 * <receiveDrops>0</receiveDrops>
740 * <transmitDrops>0</transmitDrops>
741 * <receiveErrors>0</receiveErrors>
742 * <transmitErrors>0</transmitErrors>
743 * <receiveFrameError>0</receiveFrameError>
744 * <receiveOverRunError>0</receiveOverRunError>
745 * <receiveCrcError>0</receiveCrcError>
746 * <collisionCount>0</collisionCount>
747 * </portStatistic>
748 * <portStatistic>
749 * <nodeConnector>
751 * <id>00:00:00:00:00:00:00:01</id>
752 * <type>OF</type>
754 * <id>5</id>
755 * <type>OF</type>
756 * </nodeConnector>
757 * <receivePackets>2542</receivePackets>
758 * <transmitPackets>2719</transmitPackets>
759 * <receiveBytes>243012</receiveBytes>
760 * <transmitBytes>255374</transmitBytes>
761 * <receiveDrops>0</receiveDrops>
762 * <transmitDrops>0</transmitDrops>
763 * <receiveErrors>0</receiveErrors>
764 * <transmitErrors>0</transmitErrors>
765 * <receiveFrameError>0</receiveFrameError>
766 * <receiveOverRunError>0</receiveOverRunError>
767 * <receiveCrcError>0</receiveCrcError>
768 * <collisionCount>0</collisionCount>
769 * </portStatistic>
770 * </nodePortStatistics>
773 @Path("/{containerName}/port/node/{nodeType}/{nodeId}")
775 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
776 @TypeHint(PortStatistics.class)
778 @ResponseCode(code = 200, condition = "Operation successful"),
779 @ResponseCode(code = 404, condition = "The containerName is not found"),
780 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
781 public PortStatistics getPortStatistics(
782 @PathParam("containerName") String containerName,
783 @PathParam("nodeType") String nodeType,
784 @PathParam("nodeId") String nodeId) {
786 if (!NorthboundUtils.isAuthorized(
787 getUserName(), containerName, Privilege.READ, this)) {
788 throw new UnauthorizedException(
789 "User is not authorized to perform this operation on container "
792 handleDefaultDisabled(containerName);
794 IStatisticsManager statisticsManager = getStatisticsService(containerName);
795 if (statisticsManager == null) {
796 throw new ServiceUnavailableException("Statistics "
797 + RestMessages.SERVICEUNAVAILABLE.toString());
800 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
801 .getInstance(ISwitchManager.class, containerName, this);
802 if (switchManager == null) {
803 throw new ServiceUnavailableException("Switch manager "
804 + RestMessages.SERVICEUNAVAILABLE.toString());
807 Node node = handleNodeAvailability(containerName, nodeType, nodeId);
808 return new PortStatistics(node,
809 statisticsManager.getNodeConnectorStatistics(node));
813 * Returns a list of all the Table Statistics on all Nodes.
815 * @param containerName
816 * Name of the Container. The Container name for the base
817 * controller is "default".
819 * @return Returns a list of all the Table Statistics in a given Node.
826 * http://localhost:8080/controller/nb/v2/statistics/default/table
828 * Response body in JSON:
830 * "tableStatistics": [
833 * "id":"00:00:00:00:00:00:00:02",
836 * "tableStatistic": [
840 * "id":"00:00:00:00:00:00:00:02",
845 * "activeCount": "11",
846 * "lookupCount": "816",
847 * "matchedCount": "220",
848 * "maximumEntries": "1000"
861 * Response body in XML:
862 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
864 * <tableStatistics>
866 * <id>00:00:00:00:00:00:00:01</id>
867 * <type>OF</type>
869 * <tableStatistic>
872 * <id>00:00:00:00:00:00:00:01</id>
873 * <type>OF</type>
875 * <id>0</id>
877 * <activeCount>12</activeCount>
878 * <lookupCount>10935</lookupCount>
879 * <matchedCount>10084</matchedCount>
880 * <maximumEntries>1000</maximumEntries>
881 * </tableStatistic>
882 * <tableStatistic>
885 * <id>00:00:00:00:00:00:00:01</id>
886 * <type>OF</type>
888 * <id>1</id>
890 * <activeCount>0</activeCount>
891 * <lookupCount>0</lookupCount>
892 * <matchedCount>0</matchedCount>
893 * <maximumEntries>0</maximumEntries>
894 * </tableStatistic>
895 * <tableStatistic>
898 * <id>00:00:00:00:00:00:00:01</id>
899 * <type>OF</type>
901 * <id>2</id>
903 * <activeCount>0</activeCount>
904 * <lookupCount>0</lookupCount>
905 * <matchedCount>0</matchedCount>
906 * <maximumEntries>0</maximumEntries>
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
977 * Response body in JSON:
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",
995 * "maximumEntries": "1000"
1000 * "id":"00:00:00:00:00:00:00:01",
1005 * "activeCount": "0",
1006 * "lookupCount": "0",
1007 * "matchedCount": "0",
1008 * "maximumEntries": "0"
1013 * Response body in XML:
1014 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
1015 * <nodeTableStatistics>
1017 * <id>00:00:00:00:00:00:00:01</id>
1018 * <type>OF</type>
1020 * <tableStatistic>
1023 * <id>00:00:00:00:00:00:00:01</id>
1024 * <type>OF</type>
1026 * <id>0</id>
1027 * </nodeTable>
1028 * <activeCount>12</activeCount>
1029 * <lookupCount>10935</lookupCount>
1030 * <matchedCount>10084</matchedCount>
1031 * <maximumEntries>1000</maximumEntries>
1032 * </tableStatistic>
1033 * <tableStatistic>
1036 * <id>00:00:00:00:00:00:00:01</id>
1037 * <type>OF</type>
1039 * <id>1</id>
1040 * </nodeTable>
1041 * <activeCount>0</activeCount>
1042 * <lookupCount>0</lookupCount>
1043 * <matchedCount>0</matchedCount>
1044 * <maximumEntries>0</maximumEntries>
1045 * </tableStatistic>
1046 * <tableStatistic>
1049 * <id>00:00:00:00:00:00:00:01</id>
1050 * <type>OF</type>
1052 * <id>2</id>
1053 * </nodeTable>
1054 * <activeCount>0</activeCount>
1055 * <lookupCount>0</lookupCount>
1056 * <matchedCount>0</matchedCount>
1057 * <maximumEntries>0</maximumEntries>
1058 * </tableStatistic>
1059 * </nodeTableStatistics>
1063 @Path("/{containerName}/table/node/{nodeType}/{nodeId}")
1065 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
1066 @TypeHint(TableStatistics.class)
1068 @ResponseCode(code = 200, condition = "Operation successful"),
1069 @ResponseCode(code = 404, condition = "The containerName is not found"),
1070 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
1071 public TableStatistics getTableStatistics(
1072 @PathParam("containerName") String containerName,
1073 @PathParam("nodeType") String nodeType,
1074 @PathParam("nodeId") String nodeId) {
1076 if (!NorthboundUtils.isAuthorized(
1077 getUserName(), containerName, Privilege.READ, this)) {
1078 throw new UnauthorizedException(
1079 "User is not authorized to perform this operation on container "
1082 handleDefaultDisabled(containerName);
1084 IStatisticsManager statisticsManager = getStatisticsService(containerName);
1085 if (statisticsManager == null) {
1086 throw new ServiceUnavailableException("Statistics "
1087 + RestMessages.SERVICEUNAVAILABLE.toString());
1090 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
1091 .getInstance(ISwitchManager.class, containerName, this);
1092 if (switchManager == null) {
1093 throw new ServiceUnavailableException("Switch manager "
1094 + RestMessages.SERVICEUNAVAILABLE.toString());
1097 Node node = handleNodeAvailability(containerName, nodeType, nodeId);
1098 return new TableStatistics(node,
1099 statisticsManager.getNodeTableStatistics(node));
1102 private void handleDefaultDisabled(String containerName) {
1103 IContainerManager containerManager = (IContainerManager) ServiceHelper
1104 .getGlobalInstance(IContainerManager.class, this);
1105 if (containerManager == null) {
1106 throw new InternalServerErrorException(
1107 RestMessages.INTERNALERROR.toString());
1109 if (containerName.equals(GlobalConstants.DEFAULT.toString())
1110 && containerManager.hasNonDefaultContainer()) {
1111 throw new ResourceConflictException(
1112 RestMessages.DEFAULTDISABLED.toString());
1116 private Node handleNodeAvailability(String containerName, String nodeType,
1119 Node node = Node.fromString(nodeType, nodeId);
1121 throw new ResourceNotFoundException(nodeId + " : "
1122 + RestMessages.NONODE.toString());
1125 ISwitchManager sm = (ISwitchManager) ServiceHelper.getInstance(
1126 ISwitchManager.class, containerName, this);
1129 throw new ServiceUnavailableException("Switch Manager "
1130 + RestMessages.SERVICEUNAVAILABLE.toString());
1133 if (!sm.getNodes().contains(node)) {
1134 throw new ResourceNotFoundException(node.toString() + " : "
1135 + RestMessages.NONODE.toString());