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) {
74 username = context.getUserPrincipal().getName();
78 protected String getUserName() {
82 private IStatisticsManager getStatisticsService(String containerName) {
83 IContainerManager containerManager = (IContainerManager) ServiceHelper
84 .getGlobalInstance(IContainerManager.class, this);
85 if (containerManager == null) {
86 throw new ServiceUnavailableException("Container "
87 + RestMessages.SERVICEUNAVAILABLE.toString());
90 boolean found = false;
91 List<String> containerNames = containerManager.getContainerNames();
92 for (String cName : containerNames) {
93 if (cName.trim().equalsIgnoreCase(containerName.trim())) {
99 throw new ResourceNotFoundException(containerName + " "
100 + RestMessages.NOCONTAINER.toString());
103 IStatisticsManager statsManager = (IStatisticsManager) ServiceHelper
104 .getInstance(IStatisticsManager.class, containerName, this);
106 if (statsManager == null) {
107 throw new ServiceUnavailableException("Statistics "
108 + RestMessages.SERVICEUNAVAILABLE.toString());
115 * Returns a list of all Flow Statistics from all the Nodes.
117 * @param containerName
118 * Name of the Container. The Container name for the base
119 * controller is "default".
120 * @return List of FlowStatistics from all the Nodes
127 * http://localhost:8080/controller/nb/v2/statistics/default/flow
129 * Response body in JSON:
131 * "flowStatistics": [
134 * "id":"00:00:00:00:00:00:00:02",
147 * "mask": "255.255.255.255",
157 * "id":"00:00:00:00:00:00:00:02",
165 * "idleTimeout": "0",
166 * "hardTimeout": "0",
170 * "durationSeconds": "1828",
171 * "durationNanoseconds": "397000000",
172 * "packetCount": "0",
177 * { flow statistics of another node
180 * ......................
186 * Response body in XML:
187 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
189 * <flowStatistics>
191 * <id>00:00:00:00:00:00:00:02</id>
192 * <type>OF</type>
194 * <flowStatistic>
198 * <type>DL_TYPE</type>
199 * <value>2048</value>
200 * </matchField>
202 * <mask>255.255.255.255</mask>
203 * <type>NW_DST</type>
204 * <value>1.1.1.2</value>
205 * </matchField>
208 * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="output">
211 * <id>00:00:00:00:00:00:00:02</id>
212 * <type>OF</type>
214 * <id>3</id>
215 * <type>OF</type>
218 * <priority>1</priority>
219 * <idleTimeout>0</idleTimeout>
220 * <hardTimeout>0</hardTimeout>
221 * <id>0</id>
223 * <tableId>0</tableId>
224 * <durationSeconds>337</durationSeconds>
225 * <durationNanoseconds>149000000</durationNanoseconds>
226 * <packetCount>0</packetCount>
227 * <byteCount>0</byteCount>
228 * </flowStatistic>
229 * </flowStatistics>
230 * <flowStatistics>
231 * flow statistics for another node
234 * .....................
235 * </flowStatistics>
240 @Path("/{containerName}/flow")
242 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
243 @TypeHint(AllFlowStatistics.class)
245 @ResponseCode(code = 200, condition = "Operation successful"),
246 @ResponseCode(code = 404, condition = "The containerName is not found"),
247 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
248 public AllFlowStatistics getFlowStatistics(
249 @PathParam("containerName") String containerName,
250 @QueryParam("_q") String queryString) {
251 if (!NorthboundUtils.isAuthorized(
252 getUserName(), containerName, Privilege.READ, this)) {
253 throw new UnauthorizedException(
254 "User is not authorized to perform this operation on container "
257 IStatisticsManager statisticsManager = getStatisticsService(containerName);
258 if (statisticsManager == null) {
259 throw new ServiceUnavailableException("Statistics "
260 + RestMessages.SERVICEUNAVAILABLE.toString());
263 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
264 .getInstance(ISwitchManager.class, containerName, this);
265 if (switchManager == null) {
266 throw new ServiceUnavailableException("Switch manager "
267 + RestMessages.SERVICEUNAVAILABLE.toString());
270 List<FlowStatistics> statistics = new ArrayList<FlowStatistics>();
271 for (Node node : switchManager.getNodes()) {
272 List<FlowOnNode> flowStats = new ArrayList<FlowOnNode>();
274 List<FlowOnNode> flows = statisticsManager.getFlows(node);
275 for (FlowOnNode flowOnSwitch : flows) {
276 flowStats.add(flowOnSwitch);
278 FlowStatistics stat = new FlowStatistics(node, flowStats);
279 statistics.add(stat);
281 AllFlowStatistics result = new AllFlowStatistics(statistics);
282 if (queryString != null) {
283 queryContext.createQuery(queryString, AllFlowStatistics.class)
284 .filter(result, FlowStatistics.class);
290 * Returns a list of Flow Statistics for a given Node.
292 * @param containerName
293 * Name of the Container. The Container name for the base
294 * controller is "default".
296 * Node Type as specifid in {@link org.opendaylight.controller.sal.core.Node} class
299 * @return List of Flow Statistics for a given Node. *
306 * http://localhost:8080/controller/nb/v2/statistics/default/flow/node/OF/00:00:00:00:00:00:00:01
308 * Response body in JSON:
311 * "id":"00:00:00:00:00:00:00:01",
324 * "mask": "255.255.255.255",
332 * "@type": "setDlDst",
333 * "address": "52d28b0f76ec"
339 * "id":"00:00:00:00:00:00:00:01",
348 * "idleTimeout": "0",
349 * "hardTimeout": "0",
353 * "durationSeconds": "2089",
354 * "durationNanoseconds": "538000000",
355 * "packetCount": "0",
361 * Response body in XML:
362 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
363 * <nodeFlowStatistics>
365 * <id>00:00:00:00:00:00:00:02</id>
366 * <type>OF</type>
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.2</value>
379 * </matchField>
382 * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="output">
385 * <id>00:00:00:00:00:00:00:02</id>
386 * <type>OF</type>
388 * <id>3</id>
389 * <type>OF</type>
392 * <priority>1</priority>
393 * <idleTimeout>0</idleTimeout>
394 * <hardTimeout>0</hardTimeout>
395 * <id>0</id>
397 * <tableId>0</tableId>
398 * <durationSeconds>337</durationSeconds>
399 * <durationNanoseconds>149000000</durationNanoseconds>
400 * <packetCount>0</packetCount>
401 * <byteCount>0</byteCount>
402 * </flowStatistic>
403 * <flowStatistic>
407 * <type>DL_TYPE</type>
408 * <value>2048</value>
409 * </matchField>
411 * <mask>255.255.255.255</mask>
412 * <type>NW_DST</type>
413 * <value>1.1.1.1</value>
414 * </matchField>
417 * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="output">
420 * <id>00:00:00:00:00:00:00:02</id>
421 * <type>OF</type>
423 * <id>3</id>
424 * <type>OF</type>
427 * <priority>1</priority>
428 * <idleTimeout>0</idleTimeout>
429 * <hardTimeout>0</hardTimeout>
430 * <id>0</id>
432 * <tableId>0</tableId>
433 * <durationSeconds>337</durationSeconds>
434 * <durationNanoseconds>208000000</durationNanoseconds>
435 * <packetCount>0</packetCount>
436 * <byteCount>0</byteCount>
437 * </flowStatistic>
438 * </nodeFlowStatistics>
441 @Path("/{containerName}/flow/node/{nodeType}/{nodeId}")
443 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
444 @TypeHint(FlowStatistics.class)
446 @ResponseCode(code = 200, condition = "Operation successful"),
447 @ResponseCode(code = 404, condition = "The containerName is not found"),
448 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
449 public FlowStatistics getFlowStatistics(
450 @PathParam("containerName") String containerName,
451 @PathParam("nodeType") String nodeType,
452 @PathParam("nodeId") String nodeId) {
453 if (!NorthboundUtils.isAuthorized(
454 getUserName(), containerName, Privilege.READ, this)) {
455 throw new UnauthorizedException(
456 "User is not authorized to perform this operation on container "
459 handleDefaultDisabled(containerName);
461 IStatisticsManager statisticsManager = getStatisticsService(containerName);
462 if (statisticsManager == null) {
463 throw new ServiceUnavailableException("Statistics "
464 + RestMessages.SERVICEUNAVAILABLE.toString());
467 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
468 .getInstance(ISwitchManager.class, containerName, this);
469 if (switchManager == null) {
470 throw new ServiceUnavailableException("Switch manager "
471 + RestMessages.SERVICEUNAVAILABLE.toString());
474 Node node = handleNodeAvailability(containerName, nodeType, nodeId);
475 return new FlowStatistics(node, statisticsManager.getFlows(node));
479 * Returns a list of all the Port Statistics across all the NodeConnectors
482 * @param containerName
483 * Name of the Container. The Container name for the base
484 * controller is "default".
485 * @return List of all the Port Statistics across all the NodeConnectors on
493 * http://localhost:8080/controller/nb/v2/statistics/default/port
495 * Response body in JSON:
497 * "portStatistics": [
500 * "id":"00:00:00:00:00:00:00:02",
507 * "id":"00:00:00:00:00:00:00:02",
513 * "receivePackets": "182",
514 * "transmitPackets": "173",
515 * "receiveBytes": "12740",
516 * "transmitBytes": "12110",
517 * "receiveDrops": "0",
518 * "transmitDrops": "0",
519 * "receiveErrors": "0",
520 * "transmitErrors": "0",
521 * "receiveFrameError": "0",
522 * "receiveOverRunError": "0",
523 * "receiveCrcError": "0",
524 * "collisionCount": "0"
529 * "id":"00:00:00:00:00:00:00:02",
535 * "receivePackets": "174",
536 * "transmitPackets": "181",
537 * "receiveBytes": "12180",
538 * "transmitBytes": "12670",
539 * "receiveDrops": "0",
540 * "transmitDrops": "0",
541 * "receiveErrors": "0",
542 * "transmitErrors": "0",
543 * "receiveFrameError": "0",
544 * "receiveOverRunError": "0",
545 * "receiveCrcError": "0",
546 * "collisionCount": "0"
553 * "id":"00:00:00:00:00:00:00:03",
558 * .......................
559 * ..........................
565 * Response body in XML:
566 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
568 * <portStatistics>
570 * <id>00:00:00:00:00:00:00:02</id>
571 * <type>OF</type>
573 * <portStatistic>
574 * <nodeConnector>
576 * <id>00:00:00:00:00:00:00:02</id>
577 * <type>OF</type>
579 * <id>3</id>
580 * <type>OF</type>
581 * </nodeConnector>
582 * <receivePackets>181</receivePackets>
583 * <transmitPackets>172</transmitPackets>
584 * <receiveBytes>12670</receiveBytes>
585 * <transmitBytes>12040</transmitBytes>
586 * <receiveDrops>0</receiveDrops>
587 * <transmitDrops>0</transmitDrops>
588 * <receiveErrors>0</receiveErrors>
589 * <transmitErrors>0</transmitErrors>
590 * <receiveFrameError>0</receiveFrameError>
591 * <receiveOverRunError>0</receiveOverRunError>
592 * <receiveCrcError>0</receiveCrcError>
593 * <collisionCount>0</collisionCount>
594 * </portStatistic>
595 * <portStatistic>
596 * <nodeConnector>
598 * <id>00:00:00:00:00:00:00:02</id>
599 * <type>OF</type>
601 * <id>2</id>
602 * <type>OF</type>
603 * </nodeConnector>
604 * <receivePackets>173</receivePackets>
605 * <transmitPackets>180</transmitPackets>
606 * <receiveBytes>12110</receiveBytes>
607 * <transmitBytes>12600</transmitBytes>
608 * <receiveDrops>0</receiveDrops>
609 * <transmitDrops>0</transmitDrops>
610 * <receiveErrors>0</receiveErrors>
611 * <transmitErrors>0</transmitErrors>
612 * <receiveFrameError>0</receiveFrameError>
613 * <receiveOverRunError>0</receiveOverRunError>
614 * <receiveCrcError>0</receiveCrcError>
615 * <collisionCount>0</collisionCount>
616 * </portStatistic>
617 * </portStatistics>
622 @Path("/{containerName}/port")
624 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
625 @TypeHint(AllPortStatistics.class)
627 @ResponseCode(code = 200, condition = "Operation successful"),
628 @ResponseCode(code = 404, condition = "The containerName is not found"),
629 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
630 public AllPortStatistics getPortStatistics(
631 @PathParam("containerName") String containerName,
632 @QueryParam("_q") String queryString) {
634 if (!NorthboundUtils.isAuthorized(
635 getUserName(), containerName, Privilege.READ, this)) {
636 throw new UnauthorizedException(
637 "User is not authorized to perform this operation on container "
640 IStatisticsManager statisticsManager = getStatisticsService(containerName);
641 if (statisticsManager == null) {
642 throw new ServiceUnavailableException("Statistics "
643 + RestMessages.SERVICEUNAVAILABLE.toString());
646 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
647 .getInstance(ISwitchManager.class, containerName, this);
648 if (switchManager == null) {
649 throw new ServiceUnavailableException("Switch manager "
650 + RestMessages.SERVICEUNAVAILABLE.toString());
653 List<PortStatistics> statistics = new ArrayList<PortStatistics>();
654 for (Node node : switchManager.getNodes()) {
655 List<NodeConnectorStatistics> stat = statisticsManager
656 .getNodeConnectorStatistics(node);
657 PortStatistics portStat = new PortStatistics(node, stat);
658 statistics.add(portStat);
661 AllPortStatistics result = new AllPortStatistics(statistics);
662 if (queryString != null) {
663 queryContext.createQuery(queryString, AllPortStatistics.class)
664 .filter(result, PortStatistics.class);
670 * Returns a list of all the Port Statistics across all the NodeConnectors
673 * @param containerName
674 * Name of the Container. The Container name for the base
675 * controller is "default".
677 * Node Type as specifid in {@link org.opendaylight.controller.sal.core.Node} class
679 * Identifier (e.g. MAC address)
680 * @return Returns a list of all the Port Statistics across all the
681 * NodeConnectors in a given Node.
688 * http://localhost:8080/controller/nb/v2/statistics/default/port/node/OF/00:00:00:00:00:00:00:01
690 * Response body in JSON:
693 * "id":"00:00:00:00:00:00:00:01",
700 * "id":"00:00:00:00:00:00:00:01",
706 * "receivePackets": "171",
707 * "transmitPackets": "2451",
708 * "receiveBytes": "11970",
709 * "transmitBytes": "235186",
710 * "receiveDrops": "0",
711 * "transmitDrops": "0",
712 * "receiveErrors": "0",
713 * "transmitErrors": "0",
714 * "receiveFrameError": "0",
715 * "receiveOverRunError": "0",
716 * "receiveCrcError": "0",
717 * "collisionCount": "0"
722 * "id":"00:00:00:00:00:00:00:01",
728 * "receivePackets": "179",
729 * "transmitPackets": "2443",
730 * "receiveBytes": "12530",
731 * "transmitBytes": "234626",
732 * "receiveDrops": "0",
733 * "transmitDrops": "0",
734 * "receiveErrors": "0",
735 * "transmitErrors": "0",
736 * "receiveFrameError": "0",
737 * "receiveOverRunError": "0",
738 * "receiveCrcError": "0",
739 * "collisionCount": "0"
744 * Response body in XML:
745 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
746 * <nodePortStatistics>
748 * <id>00:00:00:00:00:00:00:01</id>
749 * <type>OF</type>
751 * <portStatistic>
752 * <nodeConnector>
754 * <id>00:00:00:00:00:00:00:01</id>
755 * <type>OF</type>
757 * <id>2</id>
758 * <type>OF</type>
759 * </nodeConnector>
760 * <receivePackets>180</receivePackets>
761 * <transmitPackets>2594</transmitPackets>
762 * <receiveBytes>12600</receiveBytes>
763 * <transmitBytes>249396</transmitBytes>
764 * <receiveDrops>0</receiveDrops>
765 * <transmitDrops>0</transmitDrops>
766 * <receiveErrors>0</receiveErrors>
767 * <transmitErrors>0</transmitErrors>
768 * <receiveFrameError>0</receiveFrameError>
769 * <receiveOverRunError>0</receiveOverRunError>
770 * <receiveCrcError>0</receiveCrcError>
771 * <collisionCount>0</collisionCount>
772 * </portStatistic>
773 * <portStatistic>
774 * <nodeConnector>
776 * <id>00:00:00:00:00:00:00:01</id>
777 * <type>OF</type>
779 * <id>5</id>
780 * <type>OF</type>
781 * </nodeConnector>
782 * <receivePackets>2542</receivePackets>
783 * <transmitPackets>2719</transmitPackets>
784 * <receiveBytes>243012</receiveBytes>
785 * <transmitBytes>255374</transmitBytes>
786 * <receiveDrops>0</receiveDrops>
787 * <transmitDrops>0</transmitDrops>
788 * <receiveErrors>0</receiveErrors>
789 * <transmitErrors>0</transmitErrors>
790 * <receiveFrameError>0</receiveFrameError>
791 * <receiveOverRunError>0</receiveOverRunError>
792 * <receiveCrcError>0</receiveCrcError>
793 * <collisionCount>0</collisionCount>
794 * </portStatistic>
795 * </nodePortStatistics>
798 @Path("/{containerName}/port/node/{nodeType}/{nodeId}")
800 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
801 @TypeHint(PortStatistics.class)
803 @ResponseCode(code = 200, condition = "Operation successful"),
804 @ResponseCode(code = 404, condition = "The containerName is not found"),
805 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
806 public PortStatistics getPortStatistics(
807 @PathParam("containerName") String containerName,
808 @PathParam("nodeType") String nodeType,
809 @PathParam("nodeId") String nodeId) {
811 if (!NorthboundUtils.isAuthorized(
812 getUserName(), containerName, Privilege.READ, this)) {
813 throw new UnauthorizedException(
814 "User is not authorized to perform this operation on container "
817 handleDefaultDisabled(containerName);
819 IStatisticsManager statisticsManager = getStatisticsService(containerName);
820 if (statisticsManager == null) {
821 throw new ServiceUnavailableException("Statistics "
822 + RestMessages.SERVICEUNAVAILABLE.toString());
825 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
826 .getInstance(ISwitchManager.class, containerName, this);
827 if (switchManager == null) {
828 throw new ServiceUnavailableException("Switch manager "
829 + RestMessages.SERVICEUNAVAILABLE.toString());
832 Node node = handleNodeAvailability(containerName, nodeType, nodeId);
833 return new PortStatistics(node,
834 statisticsManager.getNodeConnectorStatistics(node));
838 * Returns a list of all the Table Statistics on all Nodes.
840 * @param containerName
841 * Name of the Container. The Container name for the base
842 * controller is "default".
844 * @return Returns a list of all the Table Statistics in a given Node.
851 * http://localhost:8080/controller/nb/v2/statistics/default/table
853 * Response body in JSON:
855 * "tableStatistics": [
858 * "id":"00:00:00:00:00:00:00:02",
861 * "tableStatistic": [
865 * "id":"00:00:00:00:00:00:00:02",
870 * "activeCount": "11",
871 * "lookupCount": "816",
872 * "matchedCount": "220",
873 * "maximumEntries": "1000"
886 * Response body in XML:
887 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
889 * <tableStatistics>
891 * <id>00:00:00:00:00:00:00:01</id>
892 * <type>OF</type>
894 * <tableStatistic>
897 * <id>00:00:00:00:00:00:00:01</id>
898 * <type>OF</type>
900 * <id>0</id>
902 * <activeCount>12</activeCount>
903 * <lookupCount>10935</lookupCount>
904 * <matchedCount>10084</matchedCount>
905 * <maximumEntries>1000</maximumEntries>
906 * </tableStatistic>
907 * <tableStatistic>
910 * <id>00:00:00:00:00:00:00:01</id>
911 * <type>OF</type>
913 * <id>1</id>
915 * <activeCount>0</activeCount>
916 * <lookupCount>0</lookupCount>
917 * <matchedCount>0</matchedCount>
918 * <maximumEntries>0</maximumEntries>
919 * </tableStatistic>
920 * <tableStatistic>
923 * <id>00:00:00:00:00:00:00:01</id>
924 * <type>OF</type>
926 * <id>2</id>
928 * <activeCount>0</activeCount>
929 * <lookupCount>0</lookupCount>
930 * <matchedCount>0</matchedCount>
931 * <maximumEntries>0</maximumEntries>
932 * </tableStatistic>
933 * </tableStatistics>
934 * <tableStatistics>
938 * </tableStatistics>
943 @Path("/{containerName}/table")
945 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
946 @TypeHint(AllTableStatistics.class)
948 @ResponseCode(code = 200, condition = "Operation successful"),
949 @ResponseCode(code = 404, condition = "The containerName is not found"),
950 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
951 public AllTableStatistics getTableStatistics(
952 @PathParam("containerName") String containerName,
953 @QueryParam("_q") String queryString) {
955 if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) {
956 throw new UnauthorizedException("User is not authorized to perform this operation on container "
959 handleDefaultDisabled(containerName);
961 IStatisticsManager statisticsManager = getStatisticsService(containerName);
962 if (statisticsManager == null) {
963 throw new ServiceUnavailableException("Statistics manager"
964 + RestMessages.SERVICEUNAVAILABLE.toString());
967 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
968 .getInstance(ISwitchManager.class, containerName, this);
969 if (switchManager == null) {
970 throw new ServiceUnavailableException("Switch manager "
971 + RestMessages.SERVICEUNAVAILABLE.toString());
974 List<TableStatistics> statistics = new ArrayList<TableStatistics>();
975 for (Node node : switchManager.getNodes()) {
976 List<NodeTableStatistics> stat = statisticsManager
977 .getNodeTableStatistics(node);
978 TableStatistics tableStat = new TableStatistics(node, stat);
979 statistics.add(tableStat);
981 AllTableStatistics allstats = new AllTableStatistics(statistics);
982 if (queryString != null) {
983 queryContext.createQuery(queryString, AllTableStatistics.class)
984 .filter(allstats, TableStatistics.class);
990 * Returns a list of all the Table Statistics on a specific node.
992 * @param containerName
993 * Name of the Container. The Container name for the base
994 * controller is "default".
996 * Node Type as specified in {@link org.opendaylight.controller.sal.core.Node} class (e.g. OF for Openflow)
998 * Identifier (e.g. MAC address)
999 * @return Returns a list of all the Table Statistics in a given Node.
1006 * http://localhost:8080/controller/nb/v2/statistics/default/table/node/OF/00:00:00:00:00:00:00:01
1008 * Response body in JSON:
1011 * "id":"00:00:00:00:00:00:00:01",
1014 * "tableStatistic": [
1018 * "id":"00:00:00:00:00:00:00:01",
1023 * "activeCount": "12",
1024 * "lookupCount": "11382",
1025 * "matchedCount": "10524",
1026 * "maximumEntries": "1000"
1031 * "id":"00:00:00:00:00:00:00:01",
1036 * "activeCount": "0",
1037 * "lookupCount": "0",
1038 * "matchedCount": "0",
1039 * "maximumEntries": "0"
1044 * Response body in XML:
1045 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
1046 * <nodeTableStatistics>
1048 * <id>00:00:00:00:00:00:00:01</id>
1049 * <type>OF</type>
1051 * <tableStatistic>
1054 * <id>00:00:00:00:00:00:00:01</id>
1055 * <type>OF</type>
1057 * <id>0</id>
1058 * </nodeTable>
1059 * <activeCount>12</activeCount>
1060 * <lookupCount>10935</lookupCount>
1061 * <matchedCount>10084</matchedCount>
1062 * <maximumEntries>1000</maximumEntries>
1063 * </tableStatistic>
1064 * <tableStatistic>
1067 * <id>00:00:00:00:00:00:00:01</id>
1068 * <type>OF</type>
1070 * <id>1</id>
1071 * </nodeTable>
1072 * <activeCount>0</activeCount>
1073 * <lookupCount>0</lookupCount>
1074 * <matchedCount>0</matchedCount>
1075 * <maximumEntries>0</maximumEntries>
1076 * </tableStatistic>
1077 * <tableStatistic>
1080 * <id>00:00:00:00:00:00:00:01</id>
1081 * <type>OF</type>
1083 * <id>2</id>
1084 * </nodeTable>
1085 * <activeCount>0</activeCount>
1086 * <lookupCount>0</lookupCount>
1087 * <matchedCount>0</matchedCount>
1088 * <maximumEntries>0</maximumEntries>
1089 * </tableStatistic>
1090 * </nodeTableStatistics>
1094 @Path("/{containerName}/table/node/{nodeType}/{nodeId}")
1096 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
1097 @TypeHint(TableStatistics.class)
1099 @ResponseCode(code = 200, condition = "Operation successful"),
1100 @ResponseCode(code = 404, condition = "The containerName is not found"),
1101 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
1102 public TableStatistics getTableStatistics(
1103 @PathParam("containerName") String containerName,
1104 @PathParam("nodeType") String nodeType,
1105 @PathParam("nodeId") String nodeId) {
1107 if (!NorthboundUtils.isAuthorized(
1108 getUserName(), containerName, Privilege.READ, this)) {
1109 throw new UnauthorizedException(
1110 "User is not authorized to perform this operation on container "
1113 handleDefaultDisabled(containerName);
1115 IStatisticsManager statisticsManager = getStatisticsService(containerName);
1116 if (statisticsManager == null) {
1117 throw new ServiceUnavailableException("Statistics "
1118 + RestMessages.SERVICEUNAVAILABLE.toString());
1121 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
1122 .getInstance(ISwitchManager.class, containerName, this);
1123 if (switchManager == null) {
1124 throw new ServiceUnavailableException("Switch manager "
1125 + RestMessages.SERVICEUNAVAILABLE.toString());
1128 Node node = handleNodeAvailability(containerName, nodeType, nodeId);
1129 return new TableStatistics(node,
1130 statisticsManager.getNodeTableStatistics(node));
1133 private void handleDefaultDisabled(String containerName) {
1134 IContainerManager containerManager = (IContainerManager) ServiceHelper
1135 .getGlobalInstance(IContainerManager.class, this);
1136 if (containerManager == null) {
1137 throw new InternalServerErrorException(
1138 RestMessages.INTERNALERROR.toString());
1140 if (containerName.equals(GlobalConstants.DEFAULT.toString())
1141 && containerManager.hasNonDefaultContainer()) {
1142 throw new ResourceConflictException(
1143 RestMessages.DEFAULTDISABLED.toString());
1147 private Node handleNodeAvailability(String containerName, String nodeType,
1150 Node node = Node.fromString(nodeType, nodeId);
1152 throw new ResourceNotFoundException(nodeId + " : "
1153 + RestMessages.NONODE.toString());
1156 ISwitchManager sm = (ISwitchManager) ServiceHelper.getInstance(
1157 ISwitchManager.class, containerName, this);
1160 throw new ServiceUnavailableException("Switch Manager "
1161 + RestMessages.SERVICEUNAVAILABLE.toString());
1164 if (!sm.getNodes().contains(node)) {
1165 throw new ResourceNotFoundException(node.toString() + " : "
1166 + RestMessages.NONODE.toString());