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.QueryParam;
19 import javax.ws.rs.core.Context;
20 import javax.ws.rs.core.MediaType;
21 import javax.ws.rs.core.SecurityContext;
22 import javax.ws.rs.ext.ContextResolver;
24 import org.codehaus.enunciate.jaxrs.ResponseCode;
25 import org.codehaus.enunciate.jaxrs.StatusCodes;
26 import org.codehaus.enunciate.jaxrs.TypeHint;
27 import org.opendaylight.controller.containermanager.IContainerManager;
28 import org.opendaylight.controller.northbound.commons.RestMessages;
29 import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;
30 import org.opendaylight.controller.northbound.commons.exception.ResourceConflictException;
31 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
32 import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
33 import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException;
34 import org.opendaylight.controller.northbound.commons.query.QueryContext;
35 import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
36 import org.opendaylight.controller.sal.authorization.Privilege;
37 import org.opendaylight.controller.sal.core.Node;
38 import org.opendaylight.controller.sal.reader.FlowOnNode;
39 import org.opendaylight.controller.sal.reader.NodeConnectorStatistics;
40 import org.opendaylight.controller.sal.reader.NodeTableStatistics;
41 import org.opendaylight.controller.sal.utils.GlobalConstants;
42 import org.opendaylight.controller.sal.utils.ServiceHelper;
43 import org.opendaylight.controller.statisticsmanager.IStatisticsManager;
44 import org.opendaylight.controller.switchmanager.ISwitchManager;
47 * Northbound APIs that returns various Statistics exposed by the Southbound
48 * protocol plugins such as Openflow.
52 * Authentication scheme : <b>HTTP Basic</b><br>
53 * Authentication realm : <b>opendaylight</b><br>
54 * Transport : <b>HTTP and HTTPS</b><br>
56 * HTTPS Authentication is disabled by default.
60 public class StatisticsNorthbound {
62 private String username;
63 private QueryContext queryContext;
66 public void setQueryContext(ContextResolver<QueryContext> queryCtxResolver) {
67 if (queryCtxResolver != null) {
68 queryContext = queryCtxResolver.getContext(QueryContext.class);
72 public void setSecurityContext(SecurityContext context) {
73 if (context != null && context.getUserPrincipal() != null) username = context.getUserPrincipal().getName();
76 protected String getUserName() {
80 private IStatisticsManager getStatisticsService(String containerName) {
81 IContainerManager containerManager = (IContainerManager) ServiceHelper
82 .getGlobalInstance(IContainerManager.class, this);
83 if (containerManager == null) {
84 throw new ServiceUnavailableException("Container "
85 + RestMessages.SERVICEUNAVAILABLE.toString());
88 boolean found = false;
89 List<String> containerNames = containerManager.getContainerNames();
90 for (String cName : containerNames) {
91 if (cName.trim().equalsIgnoreCase(containerName.trim())) {
97 throw new ResourceNotFoundException(containerName + " "
98 + RestMessages.NOCONTAINER.toString());
101 IStatisticsManager statsManager = (IStatisticsManager) ServiceHelper
102 .getInstance(IStatisticsManager.class, containerName, this);
104 if (statsManager == null) {
105 throw new ServiceUnavailableException("Statistics "
106 + RestMessages.SERVICEUNAVAILABLE.toString());
113 * Returns a list of all Flow Statistics from all the Nodes.
115 * @param containerName
116 * Name of the Container. The Container name for the base
117 * controller is "default".
118 * @return List of FlowStatistics from all the Nodes
125 * http://localhost:8080/controller/nb/v2/statistics/default/flow
127 * Response body in JSON:
129 * "flowStatistics": [
132 * "id":"00:00:00:00:00:00:00:02",
145 * "mask": "255.255.255.255",
155 * "id":"00:00:00:00:00:00:00:02",
163 * "idleTimeout": "0",
164 * "hardTimeout": "0",
168 * "durationSeconds": "1828",
169 * "durationNanoseconds": "397000000",
170 * "packetCount": "0",
175 * { flow statistics of another node
178 * ......................
184 * Response body in XML:
185 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
187 * <flowStatistics>
189 * <id>00:00:00:00:00:00:00:02</id>
190 * <type>OF</type>
192 * <flowStatistic>
196 * <type>DL_TYPE</type>
197 * <value>2048</value>
198 * </matchField>
200 * <mask>255.255.255.255</mask>
201 * <type>NW_DST</type>
202 * <value>1.1.1.2</value>
203 * </matchField>
206 * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="output">
209 * <id>00:00:00:00:00:00:00:02</id>
210 * <type>OF</type>
212 * <id>3</id>
213 * <type>OF</type>
216 * <priority>1</priority>
217 * <idleTimeout>0</idleTimeout>
218 * <hardTimeout>0</hardTimeout>
219 * <id>0</id>
221 * <tableId>0</tableId>
222 * <durationSeconds>337</durationSeconds>
223 * <durationNanoseconds>149000000</durationNanoseconds>
224 * <packetCount>0</packetCount>
225 * <byteCount>0</byteCount>
226 * </flowStatistic>
227 * </flowStatistics>
228 * <flowStatistics>
229 * flow statistics for another node
232 * .....................
233 * </flowStatistics>
238 @Path("/{containerName}/flow")
240 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
241 @TypeHint(AllFlowStatistics.class)
243 @ResponseCode(code = 200, condition = "Operation successful"),
244 @ResponseCode(code = 404, condition = "The containerName is not found"),
245 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
246 public AllFlowStatistics getFlowStatistics(
247 @PathParam("containerName") String containerName,
248 @QueryParam("_q") String queryString) {
249 if (!NorthboundUtils.isAuthorized(
250 getUserName(), containerName, Privilege.READ, this)) {
251 throw new UnauthorizedException(
252 "User is not authorized to perform this operation on container "
255 IStatisticsManager statisticsManager = getStatisticsService(containerName);
256 if (statisticsManager == null) {
257 throw new ServiceUnavailableException("Statistics "
258 + RestMessages.SERVICEUNAVAILABLE.toString());
261 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
262 .getInstance(ISwitchManager.class, containerName, this);
263 if (switchManager == null) {
264 throw new ServiceUnavailableException("Switch manager "
265 + RestMessages.SERVICEUNAVAILABLE.toString());
268 List<FlowStatistics> statistics = new ArrayList<FlowStatistics>();
269 for (Node node : switchManager.getNodes()) {
270 List<FlowOnNode> flowStats = new ArrayList<FlowOnNode>();
272 List<FlowOnNode> flows = statisticsManager.getFlows(node);
273 for (FlowOnNode flowOnSwitch : flows) {
274 flowStats.add(flowOnSwitch);
276 FlowStatistics stat = new FlowStatistics(node, flowStats);
277 statistics.add(stat);
279 AllFlowStatistics result = new AllFlowStatistics(statistics);
280 if (queryString != null) {
281 queryContext.createQuery(queryString, AllFlowStatistics.class)
282 .filter(result, FlowStatistics.class);
288 * Returns a list of Flow Statistics for a given Node.
290 * @param containerName
291 * Name of the Container. The Container name for the base
292 * controller is "default".
294 * Node Type as specifid in {@link org.opendaylight.controller.sal.core.Node} class
297 * @return List of Flow Statistics for a given Node. *
304 * http://localhost:8080/controller/nb/v2/statistics/default/flow/node/OF/00:00:00:00:00:00:00:01
306 * Response body in JSON:
309 * "id":"00:00:00:00:00:00:00:01",
322 * "mask": "255.255.255.255",
330 * "@type": "setDlDst",
331 * "address": "52d28b0f76ec"
337 * "id":"00:00:00:00:00:00:00:01",
346 * "idleTimeout": "0",
347 * "hardTimeout": "0",
351 * "durationSeconds": "2089",
352 * "durationNanoseconds": "538000000",
353 * "packetCount": "0",
359 * Response body in XML:
360 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
361 * <nodeFlowStatistics>
363 * <id>00:00:00:00:00:00:00:02</id>
364 * <type>OF</type>
366 * <flowStatistic>
370 * <type>DL_TYPE</type>
371 * <value>2048</value>
372 * </matchField>
374 * <mask>255.255.255.255</mask>
375 * <type>NW_DST</type>
376 * <value>1.1.1.2</value>
377 * </matchField>
380 * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="output">
383 * <id>00:00:00:00:00:00:00:02</id>
384 * <type>OF</type>
386 * <id>3</id>
387 * <type>OF</type>
390 * <priority>1</priority>
391 * <idleTimeout>0</idleTimeout>
392 * <hardTimeout>0</hardTimeout>
393 * <id>0</id>
395 * <tableId>0</tableId>
396 * <durationSeconds>337</durationSeconds>
397 * <durationNanoseconds>149000000</durationNanoseconds>
398 * <packetCount>0</packetCount>
399 * <byteCount>0</byteCount>
400 * </flowStatistic>
401 * <flowStatistic>
405 * <type>DL_TYPE</type>
406 * <value>2048</value>
407 * </matchField>
409 * <mask>255.255.255.255</mask>
410 * <type>NW_DST</type>
411 * <value>1.1.1.1</value>
412 * </matchField>
415 * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="output">
418 * <id>00:00:00:00:00:00:00:02</id>
419 * <type>OF</type>
421 * <id>3</id>
422 * <type>OF</type>
425 * <priority>1</priority>
426 * <idleTimeout>0</idleTimeout>
427 * <hardTimeout>0</hardTimeout>
428 * <id>0</id>
430 * <tableId>0</tableId>
431 * <durationSeconds>337</durationSeconds>
432 * <durationNanoseconds>208000000</durationNanoseconds>
433 * <packetCount>0</packetCount>
434 * <byteCount>0</byteCount>
435 * </flowStatistic>
436 * </nodeFlowStatistics>
439 @Path("/{containerName}/flow/node/{nodeType}/{nodeId}")
441 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
442 @TypeHint(FlowStatistics.class)
444 @ResponseCode(code = 200, condition = "Operation successful"),
445 @ResponseCode(code = 404, condition = "The containerName is not found"),
446 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
447 public FlowStatistics getFlowStatistics(
448 @PathParam("containerName") String containerName,
449 @PathParam("nodeType") String nodeType,
450 @PathParam("nodeId") String nodeId) {
451 if (!NorthboundUtils.isAuthorized(
452 getUserName(), containerName, Privilege.READ, this)) {
453 throw new UnauthorizedException(
454 "User is not authorized to perform this operation on container "
457 handleDefaultDisabled(containerName);
459 IStatisticsManager statisticsManager = getStatisticsService(containerName);
460 if (statisticsManager == null) {
461 throw new ServiceUnavailableException("Statistics "
462 + RestMessages.SERVICEUNAVAILABLE.toString());
465 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
466 .getInstance(ISwitchManager.class, containerName, this);
467 if (switchManager == null) {
468 throw new ServiceUnavailableException("Switch manager "
469 + RestMessages.SERVICEUNAVAILABLE.toString());
472 Node node = handleNodeAvailability(containerName, nodeType, nodeId);
473 return new FlowStatistics(node, statisticsManager.getFlows(node));
477 * Returns a list of all the Port Statistics across all the NodeConnectors
480 * @param containerName
481 * Name of the Container. The Container name for the base
482 * controller is "default".
483 * @return List of all the Port Statistics across all the NodeConnectors on
491 * http://localhost:8080/controller/nb/v2/statistics/default/port
493 * Response body in JSON:
495 * "portStatistics": [
498 * "id":"00:00:00:00:00:00:00:02",
505 * "id":"00:00:00:00:00:00:00:02",
511 * "receivePackets": "182",
512 * "transmitPackets": "173",
513 * "receiveBytes": "12740",
514 * "transmitBytes": "12110",
515 * "receiveDrops": "0",
516 * "transmitDrops": "0",
517 * "receiveErrors": "0",
518 * "transmitErrors": "0",
519 * "receiveFrameError": "0",
520 * "receiveOverRunError": "0",
521 * "receiveCrcError": "0",
522 * "collisionCount": "0"
527 * "id":"00:00:00:00:00:00:00:02",
533 * "receivePackets": "174",
534 * "transmitPackets": "181",
535 * "receiveBytes": "12180",
536 * "transmitBytes": "12670",
537 * "receiveDrops": "0",
538 * "transmitDrops": "0",
539 * "receiveErrors": "0",
540 * "transmitErrors": "0",
541 * "receiveFrameError": "0",
542 * "receiveOverRunError": "0",
543 * "receiveCrcError": "0",
544 * "collisionCount": "0"
551 * "id":"00:00:00:00:00:00:00:03",
556 * .......................
557 * ..........................
563 * Response body in XML:
564 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
566 * <portStatistics>
568 * <id>00:00:00:00:00:00:00:02</id>
569 * <type>OF</type>
571 * <portStatistic>
572 * <nodeConnector>
574 * <id>00:00:00:00:00:00:00:02</id>
575 * <type>OF</type>
577 * <id>3</id>
578 * <type>OF</type>
579 * </nodeConnector>
580 * <receivePackets>181</receivePackets>
581 * <transmitPackets>172</transmitPackets>
582 * <receiveBytes>12670</receiveBytes>
583 * <transmitBytes>12040</transmitBytes>
584 * <receiveDrops>0</receiveDrops>
585 * <transmitDrops>0</transmitDrops>
586 * <receiveErrors>0</receiveErrors>
587 * <transmitErrors>0</transmitErrors>
588 * <receiveFrameError>0</receiveFrameError>
589 * <receiveOverRunError>0</receiveOverRunError>
590 * <receiveCrcError>0</receiveCrcError>
591 * <collisionCount>0</collisionCount>
592 * </portStatistic>
593 * <portStatistic>
594 * <nodeConnector>
596 * <id>00:00:00:00:00:00:00:02</id>
597 * <type>OF</type>
599 * <id>2</id>
600 * <type>OF</type>
601 * </nodeConnector>
602 * <receivePackets>173</receivePackets>
603 * <transmitPackets>180</transmitPackets>
604 * <receiveBytes>12110</receiveBytes>
605 * <transmitBytes>12600</transmitBytes>
606 * <receiveDrops>0</receiveDrops>
607 * <transmitDrops>0</transmitDrops>
608 * <receiveErrors>0</receiveErrors>
609 * <transmitErrors>0</transmitErrors>
610 * <receiveFrameError>0</receiveFrameError>
611 * <receiveOverRunError>0</receiveOverRunError>
612 * <receiveCrcError>0</receiveCrcError>
613 * <collisionCount>0</collisionCount>
614 * </portStatistic>
615 * </portStatistics>
620 @Path("/{containerName}/port")
622 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
623 @TypeHint(AllPortStatistics.class)
625 @ResponseCode(code = 200, condition = "Operation successful"),
626 @ResponseCode(code = 404, condition = "The containerName is not found"),
627 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
628 public AllPortStatistics getPortStatistics(
629 @PathParam("containerName") String containerName,
630 @QueryParam("_q") String queryString) {
632 if (!NorthboundUtils.isAuthorized(
633 getUserName(), containerName, Privilege.READ, this)) {
634 throw new UnauthorizedException(
635 "User is not authorized to perform this operation on container "
638 IStatisticsManager statisticsManager = getStatisticsService(containerName);
639 if (statisticsManager == null) {
640 throw new ServiceUnavailableException("Statistics "
641 + RestMessages.SERVICEUNAVAILABLE.toString());
644 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
645 .getInstance(ISwitchManager.class, containerName, this);
646 if (switchManager == null) {
647 throw new ServiceUnavailableException("Switch manager "
648 + RestMessages.SERVICEUNAVAILABLE.toString());
651 List<PortStatistics> statistics = new ArrayList<PortStatistics>();
652 for (Node node : switchManager.getNodes()) {
653 List<NodeConnectorStatistics> stat = statisticsManager
654 .getNodeConnectorStatistics(node);
655 PortStatistics portStat = new PortStatistics(node, stat);
656 statistics.add(portStat);
659 AllPortStatistics result = new AllPortStatistics(statistics);
660 if (queryString != null) {
661 queryContext.createQuery(queryString, AllPortStatistics.class)
662 .filter(result, PortStatistics.class);
668 * Returns a list of all the Port Statistics across all the NodeConnectors
671 * @param containerName
672 * Name of the Container. The Container name for the base
673 * controller is "default".
675 * Node Type as specifid in {@link org.opendaylight.controller.sal.core.Node} class
677 * Identifier (e.g. MAC address)
678 * @return Returns a list of all the Port Statistics across all the
679 * NodeConnectors in a given Node.
686 * http://localhost:8080/controller/nb/v2/statistics/default/port/node/OF/00:00:00:00:00:00:00:01
688 * Response body in JSON:
691 * "id":"00:00:00:00:00:00:00:01",
698 * "id":"00:00:00:00:00:00:00:01",
704 * "receivePackets": "171",
705 * "transmitPackets": "2451",
706 * "receiveBytes": "11970",
707 * "transmitBytes": "235186",
708 * "receiveDrops": "0",
709 * "transmitDrops": "0",
710 * "receiveErrors": "0",
711 * "transmitErrors": "0",
712 * "receiveFrameError": "0",
713 * "receiveOverRunError": "0",
714 * "receiveCrcError": "0",
715 * "collisionCount": "0"
720 * "id":"00:00:00:00:00:00:00:01",
726 * "receivePackets": "179",
727 * "transmitPackets": "2443",
728 * "receiveBytes": "12530",
729 * "transmitBytes": "234626",
730 * "receiveDrops": "0",
731 * "transmitDrops": "0",
732 * "receiveErrors": "0",
733 * "transmitErrors": "0",
734 * "receiveFrameError": "0",
735 * "receiveOverRunError": "0",
736 * "receiveCrcError": "0",
737 * "collisionCount": "0"
742 * Response body in XML:
743 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
744 * <nodePortStatistics>
746 * <id>00:00:00:00:00:00:00:01</id>
747 * <type>OF</type>
749 * <portStatistic>
750 * <nodeConnector>
752 * <id>00:00:00:00:00:00:00:01</id>
753 * <type>OF</type>
755 * <id>2</id>
756 * <type>OF</type>
757 * </nodeConnector>
758 * <receivePackets>180</receivePackets>
759 * <transmitPackets>2594</transmitPackets>
760 * <receiveBytes>12600</receiveBytes>
761 * <transmitBytes>249396</transmitBytes>
762 * <receiveDrops>0</receiveDrops>
763 * <transmitDrops>0</transmitDrops>
764 * <receiveErrors>0</receiveErrors>
765 * <transmitErrors>0</transmitErrors>
766 * <receiveFrameError>0</receiveFrameError>
767 * <receiveOverRunError>0</receiveOverRunError>
768 * <receiveCrcError>0</receiveCrcError>
769 * <collisionCount>0</collisionCount>
770 * </portStatistic>
771 * <portStatistic>
772 * <nodeConnector>
774 * <id>00:00:00:00:00:00:00:01</id>
775 * <type>OF</type>
777 * <id>5</id>
778 * <type>OF</type>
779 * </nodeConnector>
780 * <receivePackets>2542</receivePackets>
781 * <transmitPackets>2719</transmitPackets>
782 * <receiveBytes>243012</receiveBytes>
783 * <transmitBytes>255374</transmitBytes>
784 * <receiveDrops>0</receiveDrops>
785 * <transmitDrops>0</transmitDrops>
786 * <receiveErrors>0</receiveErrors>
787 * <transmitErrors>0</transmitErrors>
788 * <receiveFrameError>0</receiveFrameError>
789 * <receiveOverRunError>0</receiveOverRunError>
790 * <receiveCrcError>0</receiveCrcError>
791 * <collisionCount>0</collisionCount>
792 * </portStatistic>
793 * </nodePortStatistics>
796 @Path("/{containerName}/port/node/{nodeType}/{nodeId}")
798 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
799 @TypeHint(PortStatistics.class)
801 @ResponseCode(code = 200, condition = "Operation successful"),
802 @ResponseCode(code = 404, condition = "The containerName is not found"),
803 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
804 public PortStatistics getPortStatistics(
805 @PathParam("containerName") String containerName,
806 @PathParam("nodeType") String nodeType,
807 @PathParam("nodeId") String nodeId) {
809 if (!NorthboundUtils.isAuthorized(
810 getUserName(), containerName, Privilege.READ, this)) {
811 throw new UnauthorizedException(
812 "User is not authorized to perform this operation on container "
815 handleDefaultDisabled(containerName);
817 IStatisticsManager statisticsManager = getStatisticsService(containerName);
818 if (statisticsManager == null) {
819 throw new ServiceUnavailableException("Statistics "
820 + RestMessages.SERVICEUNAVAILABLE.toString());
823 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
824 .getInstance(ISwitchManager.class, containerName, this);
825 if (switchManager == null) {
826 throw new ServiceUnavailableException("Switch manager "
827 + RestMessages.SERVICEUNAVAILABLE.toString());
830 Node node = handleNodeAvailability(containerName, nodeType, nodeId);
831 return new PortStatistics(node,
832 statisticsManager.getNodeConnectorStatistics(node));
836 * Returns a list of all the Table Statistics on all Nodes.
838 * @param containerName
839 * Name of the Container. The Container name for the base
840 * controller is "default".
842 * @return Returns a list of all the Table Statistics in a given Node.
849 * http://localhost:8080/controller/nb/v2/statistics/default/table
851 * Response body in JSON:
853 * "tableStatistics": [
856 * "id":"00:00:00:00:00:00:00:02",
859 * "tableStatistic": [
863 * "id":"00:00:00:00:00:00:00:02",
868 * "activeCount": "11",
869 * "lookupCount": "816",
870 * "matchedCount": "220",
871 * "maximumEntries": "1000"
884 * Response body in XML:
885 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
887 * <tableStatistics>
889 * <id>00:00:00:00:00:00:00:01</id>
890 * <type>OF</type>
892 * <tableStatistic>
895 * <id>00:00:00:00:00:00:00:01</id>
896 * <type>OF</type>
898 * <id>0</id>
900 * <activeCount>12</activeCount>
901 * <lookupCount>10935</lookupCount>
902 * <matchedCount>10084</matchedCount>
903 * <maximumEntries>1000</maximumEntries>
904 * </tableStatistic>
905 * <tableStatistic>
908 * <id>00:00:00:00:00:00:00:01</id>
909 * <type>OF</type>
911 * <id>1</id>
913 * <activeCount>0</activeCount>
914 * <lookupCount>0</lookupCount>
915 * <matchedCount>0</matchedCount>
916 * <maximumEntries>0</maximumEntries>
917 * </tableStatistic>
918 * <tableStatistic>
921 * <id>00:00:00:00:00:00:00:01</id>
922 * <type>OF</type>
924 * <id>2</id>
926 * <activeCount>0</activeCount>
927 * <lookupCount>0</lookupCount>
928 * <matchedCount>0</matchedCount>
929 * <maximumEntries>0</maximumEntries>
930 * </tableStatistic>
931 * </tableStatistics>
932 * <tableStatistics>
936 * </tableStatistics>
941 @Path("/{containerName}/table")
943 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
944 @TypeHint(AllTableStatistics.class)
946 @ResponseCode(code = 200, condition = "Operation successful"),
947 @ResponseCode(code = 404, condition = "The containerName is not found"),
948 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
949 public AllTableStatistics getTableStatistics(
950 @PathParam("containerName") String containerName,
951 @QueryParam("_q") String queryString) {
953 if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) {
954 throw new UnauthorizedException("User is not authorized to perform this operation on container "
957 handleDefaultDisabled(containerName);
959 IStatisticsManager statisticsManager = getStatisticsService(containerName);
960 if (statisticsManager == null) {
961 throw new ServiceUnavailableException("Statistics manager"
962 + RestMessages.SERVICEUNAVAILABLE.toString());
965 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
966 .getInstance(ISwitchManager.class, containerName, this);
967 if (switchManager == null) {
968 throw new ServiceUnavailableException("Switch manager "
969 + RestMessages.SERVICEUNAVAILABLE.toString());
972 List<TableStatistics> statistics = new ArrayList<TableStatistics>();
973 for (Node node : switchManager.getNodes()) {
974 List<NodeTableStatistics> stat = statisticsManager
975 .getNodeTableStatistics(node);
976 TableStatistics tableStat = new TableStatistics(node, stat);
977 statistics.add(tableStat);
979 AllTableStatistics allstats = new AllTableStatistics(statistics);
980 if (queryString != null) {
981 queryContext.createQuery(queryString, AllTableStatistics.class)
982 .filter(allstats, TableStatistics.class);
988 * Returns a list of all the Table Statistics on a specific node.
990 * @param containerName
991 * Name of the Container. The Container name for the base
992 * controller is "default".
994 * Node Type as specified in {@link org.opendaylight.controller.sal.core.Node} class (e.g. OF for Openflow)
996 * Identifier (e.g. MAC address)
997 * @return Returns a list of all the Table Statistics in a given Node.
1004 * http://localhost:8080/controller/nb/v2/statistics/default/table/node/OF/00:00:00:00:00:00:00:01
1006 * Response body in JSON:
1009 * "id":"00:00:00:00:00:00:00:01",
1012 * "tableStatistic": [
1016 * "id":"00:00:00:00:00:00:00:01",
1021 * "activeCount": "12",
1022 * "lookupCount": "11382",
1023 * "matchedCount": "10524",
1024 * "maximumEntries": "1000"
1029 * "id":"00:00:00:00:00:00:00:01",
1034 * "activeCount": "0",
1035 * "lookupCount": "0",
1036 * "matchedCount": "0",
1037 * "maximumEntries": "0"
1042 * Response body in XML:
1043 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
1044 * <nodeTableStatistics>
1046 * <id>00:00:00:00:00:00:00:01</id>
1047 * <type>OF</type>
1049 * <tableStatistic>
1052 * <id>00:00:00:00:00:00:00:01</id>
1053 * <type>OF</type>
1055 * <id>0</id>
1056 * </nodeTable>
1057 * <activeCount>12</activeCount>
1058 * <lookupCount>10935</lookupCount>
1059 * <matchedCount>10084</matchedCount>
1060 * <maximumEntries>1000</maximumEntries>
1061 * </tableStatistic>
1062 * <tableStatistic>
1065 * <id>00:00:00:00:00:00:00:01</id>
1066 * <type>OF</type>
1068 * <id>1</id>
1069 * </nodeTable>
1070 * <activeCount>0</activeCount>
1071 * <lookupCount>0</lookupCount>
1072 * <matchedCount>0</matchedCount>
1073 * <maximumEntries>0</maximumEntries>
1074 * </tableStatistic>
1075 * <tableStatistic>
1078 * <id>00:00:00:00:00:00:00:01</id>
1079 * <type>OF</type>
1081 * <id>2</id>
1082 * </nodeTable>
1083 * <activeCount>0</activeCount>
1084 * <lookupCount>0</lookupCount>
1085 * <matchedCount>0</matchedCount>
1086 * <maximumEntries>0</maximumEntries>
1087 * </tableStatistic>
1088 * </nodeTableStatistics>
1092 @Path("/{containerName}/table/node/{nodeType}/{nodeId}")
1094 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
1095 @TypeHint(TableStatistics.class)
1097 @ResponseCode(code = 200, condition = "Operation successful"),
1098 @ResponseCode(code = 404, condition = "The containerName is not found"),
1099 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
1100 public TableStatistics getTableStatistics(
1101 @PathParam("containerName") String containerName,
1102 @PathParam("nodeType") String nodeType,
1103 @PathParam("nodeId") String nodeId) {
1105 if (!NorthboundUtils.isAuthorized(
1106 getUserName(), containerName, Privilege.READ, this)) {
1107 throw new UnauthorizedException(
1108 "User is not authorized to perform this operation on container "
1111 handleDefaultDisabled(containerName);
1113 IStatisticsManager statisticsManager = getStatisticsService(containerName);
1114 if (statisticsManager == null) {
1115 throw new ServiceUnavailableException("Statistics "
1116 + RestMessages.SERVICEUNAVAILABLE.toString());
1119 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
1120 .getInstance(ISwitchManager.class, containerName, this);
1121 if (switchManager == null) {
1122 throw new ServiceUnavailableException("Switch manager "
1123 + RestMessages.SERVICEUNAVAILABLE.toString());
1126 Node node = handleNodeAvailability(containerName, nodeType, nodeId);
1127 return new TableStatistics(node,
1128 statisticsManager.getNodeTableStatistics(node));
1131 private void handleDefaultDisabled(String containerName) {
1132 IContainerManager containerManager = (IContainerManager) ServiceHelper
1133 .getGlobalInstance(IContainerManager.class, this);
1134 if (containerManager == null) {
1135 throw new InternalServerErrorException(
1136 RestMessages.INTERNALERROR.toString());
1138 if (containerName.equals(GlobalConstants.DEFAULT.toString())
1139 && containerManager.hasNonDefaultContainer()) {
1140 throw new ResourceConflictException(
1141 RestMessages.DEFAULTDISABLED.toString());
1145 private Node handleNodeAvailability(String containerName, String nodeType,
1148 Node node = Node.fromString(nodeType, nodeId);
1150 throw new ResourceNotFoundException(nodeId + " : "
1151 + RestMessages.NONODE.toString());
1154 ISwitchManager sm = (ISwitchManager) ServiceHelper.getInstance(
1155 ISwitchManager.class, containerName, this);
1158 throw new ServiceUnavailableException("Switch Manager "
1159 + RestMessages.SERVICEUNAVAILABLE.toString());
1162 if (!sm.getNodes().contains(node)) {
1163 throw new ResourceNotFoundException(node.toString() + " : "
1164 + RestMessages.NONODE.toString());