1c3fd1cf2ea10d32b148aec6d8dbb2fb2fab357a
[controller.git] / opendaylight / northbound / statistics / src / main / java / org / opendaylight / controller / statistics / northbound / StatisticsNorthbound.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.controller.statistics.northbound;
10
11 import java.util.ArrayList;
12 import java.util.List;
13
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;
21
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;
42
43 /**
44  * Northbound APIs that returns various Statistics exposed by the Southbound
45  * protocol plugins such as Openflow.
46  *
47  * <br>
48  * <br>
49  * Authentication scheme : <b>HTTP Basic</b><br>
50  * Authentication realm : <b>opendaylight</b><br>
51  * Transport : <b>HTTP and HTTPS</b><br>
52  * <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>
56  * More info :
57  * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
58  *
59  */
60 @Path("/")
61 public class StatisticsNorthbound {
62
63     private String username;
64
65     @Context
66     public void setSecurityContext(SecurityContext context) {
67         username = context.getUserPrincipal().getName();
68     }
69
70     protected String getUserName() {
71         return username;
72     }
73
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());
80         }
81
82         boolean found = false;
83         List<String> containerNames = containerManager.getContainerNames();
84         for (String cName : containerNames) {
85             if (cName.trim().equalsIgnoreCase(containerName.trim())) {
86                 found = true;
87             }
88         }
89
90         if (found == false) {
91             throw new ResourceNotFoundException(containerName + " "
92                     + RestMessages.NOCONTAINER.toString());
93         }
94
95         IStatisticsManager statsManager = (IStatisticsManager) ServiceHelper
96                 .getInstance(IStatisticsManager.class, containerName, this);
97
98         if (statsManager == null) {
99             throw new ServiceUnavailableException("Statistics "
100                     + RestMessages.SERVICEUNAVAILABLE.toString());
101         }
102
103         return statsManager;
104     }
105
106     /**
107      * Returns a list of all Flow Statistics from all the Nodes.
108      *
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
113      *
114      *         <pre>
115      * Example:
116      * Request URL: localhost:8080/controller/nb/v2/statistics/default/flow
117      *
118      * Response in JSON:
119      * {
120      *     "flowStatistics": [
121      *         {
122      *             "node": {
123      *                 "@type": "OF",
124      *                 "@id": "00:00:00:00:00:00:00:02"
125      *             },
126      *             "flowStatistic": [
127      *                 {
128      *                     "flow": {
129      *                         "match": {
130      *                             "matchField": [
131      *                                 {
132      *                                     "type": "DL_TYPE",
133      *                                     "value": "2048"
134      *                                 },
135      *                                 {
136      *                                     "mask": "255.255.255.255",
137      *                                     "type": "NW_DST",
138      *                                     "value": "1.1.1.1"
139      *                                 }
140      *                             ]
141      *                         },
142      *                         "actions": {
143      *                             "@type": "output",
144      *                             "port": {
145      *                                 "@type": "OF",
146      *                                 "@id": "3",
147      *                                 "node": {
148      *                                     "@type": "OF",
149      *                                     "@id": "00:00:00:00:00:00:00:02"
150      *                                 }
151      *                             }
152      *                         },
153      *                         "priority": "1",
154      *                         "idleTimeout": "0",
155      *                         "hardTimeout": "0",
156      *                         "id": "0"
157      *                     },
158      *                     "tableId": "0",
159      *                     "durationSeconds": "1828",
160      *                     "durationNanoseconds": "397000000",
161      *                     "packetCount": "0",
162      *                     "byteCount": "0"
163      *                 }
164      *             ]
165      *         },
166      *         {   flow statistics of another node
167      *             ............
168      *             ................
169      *             ......................
170      *         }
171      *
172      *     ]
173      * }
174      * Response in XML:
175      * &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&gt;
176      * &lt;list&gt;
177      *     &lt;flowStatistics&gt;
178      *         &lt;node type=&quot;OF&quot; id=&quot;00:00:00:00:00:00:00:02&quot;/&gt;
179      *         &lt;flowStatistic&gt;
180      *             &lt;flow&gt;
181      *                 &lt;match&gt;
182      *                     &lt;matchField&gt;
183      *                         &lt;type&gt;DL_TYPE&lt;/type&gt;
184      *                         &lt;value&gt;2048&lt;/value&gt;
185      *                     &lt;/matchField&gt;
186      *                     &lt;matchField&gt;
187      *                         &lt;mask&gt;255.255.255.255&lt;/mask&gt;
188      *                         &lt;type&gt;NW_DST&lt;/type&gt;
189      *                         &lt;value&gt;1.1.1.2&lt;/value&gt;
190      *                     &lt;/matchField&gt;
191      *                 &lt;/match&gt;
192      *                 &lt;actions
193      *                     xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:type=&quot;output&quot;&gt;
194      *                     &lt;port type=&quot;OF&quot; id=&quot;3&quot;&gt;
195      *                         &lt;node type=&quot;OF&quot; id=&quot;00:00:00:00:00:00:00:02&quot;/&gt;
196      *                     &lt;/port&gt;
197      *                 &lt;/actions&gt;
198      *                 &lt;priority&gt;1&lt;/priority&gt;
199      *                 &lt;idleTimeout&gt;0&lt;/idleTimeout&gt;
200      *                 &lt;hardTimeout&gt;0&lt;/hardTimeout&gt;
201      *                 &lt;id&gt;0&lt;/id&gt;
202      *             &lt;/flow&gt;
203      *             &lt;tableId&gt;0&lt;/tableId&gt;
204      *             &lt;durationSeconds&gt;337&lt;/durationSeconds&gt;
205      *             &lt;durationNanoseconds&gt;149000000&lt;/durationNanoseconds&gt;
206      *             &lt;packetCount&gt;0&lt;/packetCount&gt;
207      *             &lt;byteCount&gt;0&lt;/byteCount&gt;
208      *         &lt;/flowStatistic&gt;
209      *     &lt;/flowStatistics&gt;
210      *     &lt;flowStatistics&gt;
211      *          flow statistics for another node
212      *          ..........
213      *          ................
214      *          .....................
215      *     &lt;/flowStatistics&gt;
216      * &lt;/list&gt;
217      * </pre>
218      */
219
220     @Path("/{containerName}/flow")
221     @GET
222     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
223     @TypeHint(AllFlowStatistics.class)
224     @StatusCodes({
225         @ResponseCode(code = 200, condition = "Operation successful"),
226         @ResponseCode(code = 404, condition = "The containerName is not found"),
227         @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
228     public AllFlowStatistics getFlowStatistics(
229             @PathParam("containerName") String containerName) {
230         if (!NorthboundUtils.isAuthorized(
231                 getUserName(), containerName, Privilege.READ, this)) {
232             throw new UnauthorizedException(
233                     "User is not authorized to perform this operation on container "
234                             + containerName);
235         }
236         IStatisticsManager statisticsManager = getStatisticsService(containerName);
237         if (statisticsManager == null) {
238             throw new ServiceUnavailableException("Statistics "
239                     + RestMessages.SERVICEUNAVAILABLE.toString());
240         }
241
242         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
243                 .getInstance(ISwitchManager.class, containerName, this);
244         if (switchManager == null) {
245             throw new ServiceUnavailableException("Switch manager "
246                     + RestMessages.SERVICEUNAVAILABLE.toString());
247         }
248
249         List<FlowStatistics> statistics = new ArrayList<FlowStatistics>();
250         for (Node node : switchManager.getNodes()) {
251             List<FlowOnNode> flowStats = new ArrayList<FlowOnNode>();
252
253             List<FlowOnNode> flows = statisticsManager.getFlows(node);
254             for (FlowOnNode flowOnSwitch : flows) {
255                 flowStats.add(flowOnSwitch);
256             }
257             FlowStatistics stat = new FlowStatistics(node, flowStats);
258             statistics.add(stat);
259         }
260         return new AllFlowStatistics(statistics);
261     }
262
263     /**
264      * Returns a list of Flow Statistics for a given Node.
265      *
266      * @param containerName
267      *            Name of the Container. The Container name for the base
268      *            controller is "default".
269      * @param nodeType
270      *            Node Type as specifid in {@link org.opendaylight.controller.sal.core.Node} class
271      * @param nodeId
272      *            Node Identifier
273      * @return List of Flow Statistics for a given Node. *
274      *
275      *         <pre>
276      * Example:
277      * Request URL:
278      * http://host:8080/controller/nb/v2/statistics/default/flow/node/OF/00:00:00:00:00:00:00:01
279      *
280      * Response in JSON:
281      * {
282      *     "node": {
283      *         "@type": "OF",
284      *         "@id": "00:00:00:00:00:00:00:01"
285      *     },
286      *     "flowStatistic": [
287      *         {
288      *             "flow": {
289      *                 "match": {
290      *                     "matchField": [
291      *                         {
292      *                             "type": "DL_TYPE",
293      *                             "value": "2048"
294      *                         },
295      *                         {
296      *                             "mask": "255.255.255.255",
297      *                             "type": "NW_DST",
298      *                             "value": "1.1.1.2"
299      *                         }
300      *                     ]
301      *                 },
302      *                 "actions": [
303      *                     {
304      *                         "@type": "setDlDst",
305      *                         "address": "52d28b0f76ec"
306      *                     },
307      *                     {
308      *                         "@type": "output",
309      *                         "port": {
310      *                             "@type": "OF",
311      *                             "@id": "5",
312      *                             "node": {
313      *                                 "@type": "OF",
314      *                                 "@id": "00:00:00:00:00:00:00:01"
315      *                             }
316      *                         }
317      *                     }
318      *                 ],
319      *                 "priority": "1",
320      *                 "idleTimeout": "0",
321      *                 "hardTimeout": "0",
322      *                 "id": "0"
323      *             },
324      *             "tableId": "0",
325      *             "durationSeconds": "2089",
326      *             "durationNanoseconds": "538000000",
327      *             "packetCount": "0",
328      *             "byteCount": "0"
329      *         }
330      *     ]
331      * }
332      *
333      *
334      * Response in XML:
335      * &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&gt;
336      *     &lt;nodeFlowStatistics&gt;
337      *         &lt;node type=&quot;OF&quot; id=&quot;00:00:00:00:00:00:00:02&quot;/&gt;
338      *         &lt;flowStatistic&gt;
339      *             &lt;flow&gt;
340      *                 &lt;match&gt;
341      *                     &lt;matchField&gt;
342      *                         &lt;type&gt;DL_TYPE&lt;/type&gt;
343      *                         &lt;value&gt;2048&lt;/value&gt;
344      *                     &lt;/matchField&gt;
345      *                     &lt;matchField&gt;
346      *                         &lt;mask&gt;255.255.255.255&lt;/mask&gt;
347      *                         &lt;type&gt;NW_DST&lt;/type&gt;
348      *                         &lt;value&gt;1.1.1.2&lt;/value&gt;
349      *                     &lt;/matchField&gt;
350      *                 &lt;/match&gt;
351      *                 &lt;actions
352      *                     xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:type=&quot;output&quot;&gt;
353      *                     &lt;port type=&quot;OF&quot; id=&quot;3&quot;&gt;
354      *                         &lt;node type=&quot;OF&quot; id=&quot;00:00:00:00:00:00:00:02&quot;/&gt;
355      *                     &lt;/port&gt;
356      *                 &lt;/actions&gt;
357      *                 &lt;priority&gt;1&lt;/priority&gt;
358      *                 &lt;idleTimeout&gt;0&lt;/idleTimeout&gt;
359      *                 &lt;hardTimeout&gt;0&lt;/hardTimeout&gt;
360      *                 &lt;id&gt;0&lt;/id&gt;
361      *             &lt;/flow&gt;
362      *             &lt;tableId&gt;0&lt;/tableId&gt;
363      *             &lt;durationSeconds&gt;337&lt;/durationSeconds&gt;
364      *             &lt;durationNanoseconds&gt;149000000&lt;/durationNanoseconds&gt;
365      *             &lt;packetCount&gt;0&lt;/packetCount&gt;
366      *             &lt;byteCount&gt;0&lt;/byteCount&gt;
367      *         &lt;/flowStatistic&gt;
368      *         &lt;flowStatistic&gt;
369      *             &lt;flow&gt;
370      *                 &lt;match&gt;
371      *                     &lt;matchField&gt;
372      *                         &lt;type&gt;DL_TYPE&lt;/type&gt;
373      *                         &lt;value&gt;2048&lt;/value&gt;
374      *                     &lt;/matchField&gt;
375      *                     &lt;matchField&gt;
376      *                         &lt;mask&gt;255.255.255.255&lt;/mask&gt;
377      *                         &lt;type&gt;NW_DST&lt;/type&gt;
378      *                         &lt;value&gt;1.1.1.1&lt;/value&gt;
379      *                     &lt;/matchField&gt;
380      *                 &lt;/match&gt;
381      *                 &lt;actions
382      *                     xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:type=&quot;output&quot;&gt;
383      *                     &lt;port type=&quot;OF&quot; id=&quot;3&quot;&gt;
384      *                         &lt;node type=&quot;OF&quot; id=&quot;00:00:00:00:00:00:00:02&quot;/&gt;
385      *                     &lt;/port&gt;
386      *                 &lt;/actions&gt;
387      *                 &lt;priority&gt;1&lt;/priority&gt;
388      *                 &lt;idleTimeout&gt;0&lt;/idleTimeout&gt;
389      *                 &lt;hardTimeout&gt;0&lt;/hardTimeout&gt;
390      *                 &lt;id&gt;0&lt;/id&gt;
391      *             &lt;/flow&gt;
392      *             &lt;tableId&gt;0&lt;/tableId&gt;
393      *             &lt;durationSeconds&gt;337&lt;/durationSeconds&gt;
394      *             &lt;durationNanoseconds&gt;208000000&lt;/durationNanoseconds&gt;
395      *             &lt;packetCount&gt;0&lt;/packetCount&gt;
396      *             &lt;byteCount&gt;0&lt;/byteCount&gt;
397      *         &lt;/flowStatistic&gt;
398      *     &lt;/nodeFlowStatistics&gt;
399      * </pre>
400      */
401     @Path("/{containerName}/flow/node/{nodeType}/{nodeId}")
402     @GET
403     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
404     @TypeHint(FlowStatistics.class)
405     @StatusCodes({
406         @ResponseCode(code = 200, condition = "Operation successful"),
407         @ResponseCode(code = 404, condition = "The containerName is not found"),
408         @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
409     public FlowStatistics getFlowStatistics(
410             @PathParam("containerName") String containerName,
411             @PathParam("nodeType") String nodeType,
412             @PathParam("nodeId") String nodeId) {
413         if (!NorthboundUtils.isAuthorized(
414                 getUserName(), containerName, Privilege.READ, this)) {
415             throw new UnauthorizedException(
416                     "User is not authorized to perform this operation on container "
417                             + containerName);
418         }
419         handleDefaultDisabled(containerName);
420
421         IStatisticsManager statisticsManager = getStatisticsService(containerName);
422         if (statisticsManager == null) {
423             throw new ServiceUnavailableException("Statistics "
424                     + RestMessages.SERVICEUNAVAILABLE.toString());
425         }
426
427         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
428                 .getInstance(ISwitchManager.class, containerName, this);
429         if (switchManager == null) {
430             throw new ServiceUnavailableException("Switch manager "
431                     + RestMessages.SERVICEUNAVAILABLE.toString());
432         }
433
434         Node node = handleNodeAvailability(containerName, nodeType, nodeId);
435         return new FlowStatistics(node, statisticsManager.getFlows(node));
436     }
437
438     /**
439      * Returns a list of all the Port Statistics across all the NodeConnectors
440      * on all the Nodes.
441      *
442      * @param containerName
443      *            Name of the Container. The Container name for the base
444      *            controller is "default".
445      * @return List of all the Port Statistics across all the NodeConnectors on
446      *         all the Nodes.
447      *
448      *         <pre>
449      * Example:
450      *
451      * Requset URL: http://host:8080/controller/nb/v2/statistics/default/port
452      *
453      * Response in JSON:
454      * {
455      *     "portStatistics": [
456      *         {
457      *             "node": {
458      *                 "@type": "OF",
459      *                 "@id": "00:00:00:00:00:00:00:02"
460      *             },
461      *             "portStatistic": [
462      *                 {
463      *                     "nodeConnector": {
464      *                         "@type": "OF",
465      *                         "@id": "3",
466      *                         "node": {
467      *                             "@type": "OF",
468      *                             "@id": "00:00:00:00:00:00:00:02"
469      *                         }
470      *                     },
471      *                     "receivePackets": "182",
472      *                     "transmitPackets": "173",
473      *                     "receiveBytes": "12740",
474      *                     "transmitBytes": "12110",
475      *                     "receiveDrops": "0",
476      *                     "transmitDrops": "0",
477      *                     "receiveErrors": "0",
478      *                     "transmitErrors": "0",
479      *                     "receiveFrameError": "0",
480      *                     "receiveOverRunError": "0",
481      *                     "receiveCrcError": "0",
482      *                     "collisionCount": "0"
483      *                 },
484      *                 {
485      *                     "nodeConnector": {
486      *                         "@type": "OF",
487      *                         "@id": "2",
488      *                         "node": {
489      *                             "@type": "OF",
490      *                             "@id": "00:00:00:00:00:00:00:02"
491      *                         }
492      *                     },
493      *                     "receivePackets": "174",
494      *                     "transmitPackets": "181",
495      *                     "receiveBytes": "12180",
496      *                     "transmitBytes": "12670",
497      *                     "receiveDrops": "0",
498      *                     "transmitDrops": "0",
499      *                     "receiveErrors": "0",
500      *                     "transmitErrors": "0",
501      *                     "receiveFrameError": "0",
502      *                     "receiveOverRunError": "0",
503      *                     "receiveCrcError": "0",
504      *                     "collisionCount": "0"
505      *                 },
506      *
507      *             ]
508      *         },
509      *         {
510      *             "node": {
511      *                 "@type": "OF",
512      *                 "@id": "00:00:00:00:00:00:00:03"
513      *             },
514      *             "portStatistic": [
515      *                  ..................
516      *                  .......................
517      *                  ..........................
518      *             ]
519      *         }
520      *     ]
521      * }
522      *
523      * Response in XML:
524      * &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&gt;
525      * &lt;list&gt;
526      *     &lt;portStatistics&gt;
527      *         &lt;node type=&quot;OF&quot; id=&quot;00:00:00:00:00:00:00:02&quot;/&gt;
528      *         &lt;portStatistic&gt;
529      *             &lt;nodeConnector type=&quot;OF&quot; id=&quot;3&quot;&gt;
530      *                 &lt;node type=&quot;OF&quot; id=&quot;00:00:00:00:00:00:00:02&quot;/&gt;
531      *             &lt;/nodeConnector&gt;
532      *             &lt;receivePackets&gt;181&lt;/receivePackets&gt;
533      *             &lt;transmitPackets&gt;172&lt;/transmitPackets&gt;
534      *             &lt;receiveBytes&gt;12670&lt;/receiveBytes&gt;
535      *             &lt;transmitBytes&gt;12040&lt;/transmitBytes&gt;
536      *             &lt;receiveDrops&gt;0&lt;/receiveDrops&gt;
537      *             &lt;transmitDrops&gt;0&lt;/transmitDrops&gt;
538      *             &lt;receiveErrors&gt;0&lt;/receiveErrors&gt;
539      *             &lt;transmitErrors&gt;0&lt;/transmitErrors&gt;
540      *             &lt;receiveFrameError&gt;0&lt;/receiveFrameError&gt;
541      *             &lt;receiveOverRunError&gt;0&lt;/receiveOverRunError&gt;
542      *             &lt;receiveCrcError&gt;0&lt;/receiveCrcError&gt;
543      *             &lt;collisionCount&gt;0&lt;/collisionCount&gt;
544      *         &lt;/portStatistic&gt;
545      *         &lt;portStatistic&gt;
546      *             &lt;nodeConnector type=&quot;OF&quot; id=&quot;2&quot;&gt;
547      *                 &lt;node type=&quot;OF&quot; id=&quot;00:00:00:00:00:00:00:02&quot;/&gt;
548      *             &lt;/nodeConnector&gt;
549      *             &lt;receivePackets&gt;173&lt;/receivePackets&gt;
550      *             &lt;transmitPackets&gt;180&lt;/transmitPackets&gt;
551      *             &lt;receiveBytes&gt;12110&lt;/receiveBytes&gt;
552      *             &lt;transmitBytes&gt;12600&lt;/transmitBytes&gt;
553      *             &lt;receiveDrops&gt;0&lt;/receiveDrops&gt;
554      *             &lt;transmitDrops&gt;0&lt;/transmitDrops&gt;
555      *             &lt;receiveErrors&gt;0&lt;/receiveErrors&gt;
556      *             &lt;transmitErrors&gt;0&lt;/transmitErrors&gt;
557      *             &lt;receiveFrameError&gt;0&lt;/receiveFrameError&gt;
558      *             &lt;receiveOverRunError&gt;0&lt;/receiveOverRunError&gt;
559      *             &lt;receiveCrcError&gt;0&lt;/receiveCrcError&gt;
560      *             &lt;collisionCount&gt;0&lt;/collisionCount&gt;
561      *         &lt;/portStatistic&gt;
562      *
563      *     &lt;/portStatistics&gt;
564      * &lt;/list&gt;
565      * </pre>
566      */
567
568     @Path("/{containerName}/port")
569     @GET
570     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
571     @TypeHint(AllPortStatistics.class)
572     @StatusCodes({
573         @ResponseCode(code = 200, condition = "Operation successful"),
574         @ResponseCode(code = 404, condition = "The containerName is not found"),
575         @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
576     public AllPortStatistics getPortStatistics(
577             @PathParam("containerName") String containerName) {
578
579         if (!NorthboundUtils.isAuthorized(
580                 getUserName(), containerName, Privilege.READ, this)) {
581             throw new UnauthorizedException(
582                     "User is not authorized to perform this operation on container "
583                             + containerName);
584         }
585         IStatisticsManager statisticsManager = getStatisticsService(containerName);
586         if (statisticsManager == null) {
587             throw new ServiceUnavailableException("Statistics "
588                     + RestMessages.SERVICEUNAVAILABLE.toString());
589         }
590
591         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
592                 .getInstance(ISwitchManager.class, containerName, this);
593         if (switchManager == null) {
594             throw new ServiceUnavailableException("Switch manager "
595                     + RestMessages.SERVICEUNAVAILABLE.toString());
596         }
597
598         List<PortStatistics> statistics = new ArrayList<PortStatistics>();
599         for (Node node : switchManager.getNodes()) {
600             List<NodeConnectorStatistics> stat = statisticsManager
601                     .getNodeConnectorStatistics(node);
602             PortStatistics portStat = new PortStatistics(node, stat);
603             statistics.add(portStat);
604         }
605         return new AllPortStatistics(statistics);
606     }
607
608     /**
609      * Returns a list of all the Port Statistics across all the NodeConnectors
610      * in a given Node.
611      *
612      * @param containerName
613      *            Name of the Container. The Container name for the base
614      *            controller is "default".
615      * @param nodeType
616      *            Node Type as specifid in {@link org.opendaylight.controller.sal.core.Node} class
617      * @param Node
618      *            Identifier (e.g. MAC address)
619      * @return Returns a list of all the Port Statistics across all the
620      *         NodeConnectors in a given Node.
621      *
622      *         <pre>
623      * Example:
624      *
625      * Request URL:
626      * http://host:8080/controller/nb/v2/statistics/default/port/node/OF/00:00:00:00:00:00:00:01
627      *
628      * Response in JSON:
629      * {
630      *     "node": {
631      *         "@type": "OF",
632      *         "@id": "00:00:00:00:00:00:00:01"
633      *     },
634      *     "portStatistic": [
635      *         {
636      *             "nodeConnector": {
637      *                 "@type": "OF",
638      *                 "@id": "3",
639      *                 "node": {
640      *                     "@type": "OF",
641      *                     "@id": "00:00:00:00:00:00:00:01"
642      *                 }
643      *             },
644      *             "receivePackets": "171",
645      *             "transmitPackets": "2451",
646      *             "receiveBytes": "11970",
647      *             "transmitBytes": "235186",
648      *             "receiveDrops": "0",
649      *             "transmitDrops": "0",
650      *             "receiveErrors": "0",
651      *             "transmitErrors": "0",
652      *             "receiveFrameError": "0",
653      *             "receiveOverRunError": "0",
654      *             "receiveCrcError": "0",
655      *             "collisionCount": "0"
656      *         },
657      *         {
658      *             "nodeConnector": {
659      *                 "@type": "OF",
660      *                 "@id": "2",
661      *                 "node": {
662      *                     "@type": "OF",
663      *                     "@id": "00:00:00:00:00:00:00:01"
664      *                 }
665      *             },
666      *             "receivePackets": "179",
667      *             "transmitPackets": "2443",
668      *             "receiveBytes": "12530",
669      *             "transmitBytes": "234626",
670      *             "receiveDrops": "0",
671      *             "transmitDrops": "0",
672      *             "receiveErrors": "0",
673      *             "transmitErrors": "0",
674      *             "receiveFrameError": "0",
675      *             "receiveOverRunError": "0",
676      *             "receiveCrcError": "0",
677      *             "collisionCount": "0"
678      *         }
679      *     ]
680      * }
681      *
682      * Response in XML:
683      * &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&gt;
684      * &lt;nodePortStatistics&gt;
685      *     &lt;node type=&quot;OF&quot; id=&quot;00:00:00:00:00:00:00:01&quot;/&gt;
686      *     &lt;portStatistic&gt;
687      *         &lt;nodeConnector type=&quot;OF&quot; id=&quot;2&quot;&gt;
688      *             &lt;node type=&quot;OF&quot; id=&quot;00:00:00:00:00:00:00:01&quot;/&gt;
689      *         &lt;/nodeConnector&gt;
690      *         &lt;receivePackets&gt;180&lt;/receivePackets&gt;
691      *         &lt;transmitPackets&gt;2594&lt;/transmitPackets&gt;
692      *         &lt;receiveBytes&gt;12600&lt;/receiveBytes&gt;
693      *         &lt;transmitBytes&gt;249396&lt;/transmitBytes&gt;
694      *         &lt;receiveDrops&gt;0&lt;/receiveDrops&gt;
695      *         &lt;transmitDrops&gt;0&lt;/transmitDrops&gt;
696      *         &lt;receiveErrors&gt;0&lt;/receiveErrors&gt;
697      *         &lt;transmitErrors&gt;0&lt;/transmitErrors&gt;
698      *         &lt;receiveFrameError&gt;0&lt;/receiveFrameError&gt;
699      *         &lt;receiveOverRunError&gt;0&lt;/receiveOverRunError&gt;
700      *         &lt;receiveCrcError&gt;0&lt;/receiveCrcError&gt;
701      *         &lt;collisionCount&gt;0&lt;/collisionCount&gt;
702      *     &lt;/portStatistic&gt;
703      *     &lt;portStatistic&gt;
704      *         &lt;nodeConnector type=&quot;OF&quot; id=&quot;5&quot;&gt;
705      *             &lt;node type=&quot;OF&quot; id=&quot;00:00:00:00:00:00:00:01&quot;/&gt;
706      *         &lt;/nodeConnector&gt;
707      *         &lt;receivePackets&gt;2542&lt;/receivePackets&gt;
708      *         &lt;transmitPackets&gt;2719&lt;/transmitPackets&gt;
709      *         &lt;receiveBytes&gt;243012&lt;/receiveBytes&gt;
710      *         &lt;transmitBytes&gt;255374&lt;/transmitBytes&gt;
711      *         &lt;receiveDrops&gt;0&lt;/receiveDrops&gt;
712      *         &lt;transmitDrops&gt;0&lt;/transmitDrops&gt;
713      *         &lt;receiveErrors&gt;0&lt;/receiveErrors&gt;
714      *         &lt;transmitErrors&gt;0&lt;/transmitErrors&gt;
715      *         &lt;receiveFrameError&gt;0&lt;/receiveFrameError&gt;
716      *         &lt;receiveOverRunError&gt;0&lt;/receiveOverRunError&gt;
717      *         &lt;receiveCrcError&gt;0&lt;/receiveCrcError&gt;
718      *         &lt;collisionCount&gt;0&lt;/collisionCount&gt;
719      *     &lt;/portStatistic&gt;
720      * &lt;/nodePortStatistics&gt;
721      * </pre>
722      */
723     @Path("/{containerName}/port/node/{nodeType}/{nodeId}")
724     @GET
725     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
726     @TypeHint(PortStatistics.class)
727     @StatusCodes({
728         @ResponseCode(code = 200, condition = "Operation successful"),
729         @ResponseCode(code = 404, condition = "The containerName is not found"),
730         @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
731     public PortStatistics getPortStatistics(
732             @PathParam("containerName") String containerName,
733             @PathParam("nodeType") String nodeType,
734             @PathParam("nodeId") String nodeId) {
735
736         if (!NorthboundUtils.isAuthorized(
737                 getUserName(), containerName, Privilege.READ, this)) {
738             throw new UnauthorizedException(
739                     "User is not authorized to perform this operation on container "
740                             + containerName);
741         }
742         handleDefaultDisabled(containerName);
743
744         IStatisticsManager statisticsManager = getStatisticsService(containerName);
745         if (statisticsManager == null) {
746             throw new ServiceUnavailableException("Statistics "
747                     + RestMessages.SERVICEUNAVAILABLE.toString());
748         }
749
750         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
751                 .getInstance(ISwitchManager.class, containerName, this);
752         if (switchManager == null) {
753             throw new ServiceUnavailableException("Switch manager "
754                     + RestMessages.SERVICEUNAVAILABLE.toString());
755         }
756
757         Node node = handleNodeAvailability(containerName, nodeType, nodeId);
758         return new PortStatistics(node,
759                 statisticsManager.getNodeConnectorStatistics(node));
760     }
761
762     /**
763      * Returns a list of all the Table Statistics on all Nodes.
764      *
765      * @param containerName
766      *            Name of the Container. The Container name for the base
767      *            controller is "default".
768      *
769      * @return Returns a list of all the Table Statistics in a given Node.
770      *
771      *         <pre>
772      *
773      *  Example:
774      *
775      *  Request URL:
776      *  http://host:8080/controller/nb/v2/statistics/default/table
777      *
778      *  Response in JSON:
779      *
780      * {
781      *     "tableStatistics": [
782      *         {
783      *             "node": {
784      *                 "@type": "OF",
785      *                 "@id": "00:00:00:00:00:00:00:02"
786      *             },
787      *             "tableStatistic": [
788      *                 {
789      *                     "nodeTable": {
790      *                         "@id": "0",
791      *                         "node": {
792      *                             "@type": "OF",
793      *                             "@id": "00:00:00:00:00:00:00:02"
794      *                         }
795      *                     },
796      *                     "activeCount": "11",
797      *                     "lookupCount": "816",
798      *                     "matchedCount": "220"
799      *                 },
800      *                 {
801      *                     ...another table
802      *                     .....
803      *                     ........
804      *                 }
805      *
806      *             ]
807      *         }
808      *     ]
809      * }
810      *
811      *
812      *  Response in XML:
813      *  &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&gt;
814      *  &lt;list&gt;
815      *  &lt;tableStatistics&gt;
816      *      &lt;node type=&quot;OF&quot; id=&quot;00:00:00:00:00:00:00:01&quot;/&gt;
817      *      &lt;tableStatistic&gt;
818      *          &lt;nodeTable id=&quot;0&quot;&gt;
819      *              &lt;node type=&quot;OF&quot; id=&quot;00:00:00:00:00:00:00:01&quot;/&gt;
820      *          &lt;/nodeTable&gt;
821      *          &lt;activeCount&gt;12&lt;/activeCount&gt;
822      *          &lt;lookupCount&gt;10935&lt;/lookupCount&gt;
823      *          &lt;matchedCount&gt;10084&lt;/matchedCount&gt;
824      *      &lt;/tableStatistic&gt;
825      *      &lt;tableStatistic&gt;
826      *          &lt;nodeTable id=&quot;1&quot;&gt;
827      *              &lt;node type=&quot;OF&quot; id=&quot;00:00:00:00:00:00:00:01&quot;/&gt;
828      *          &lt;/nodeTable&gt;
829      *          &lt;activeCount&gt;0&lt;/activeCount&gt;
830      *          &lt;lookupCount&gt;0&lt;/lookupCount&gt;
831      *          &lt;matchedCount&gt;0&lt;/matchedCount&gt;
832      *      &lt;/tableStatistic&gt;
833      *      &lt;tableStatistic&gt;
834      *          &lt;nodeTable id=&quot;2&quot;&gt;
835      *              &lt;node type=&quot;OF&quot; id=&quot;00:00:00:00:00:00:00:01&quot;/&gt;
836      *          &lt;/nodeTable&gt;
837      *          &lt;activeCount&gt;0&lt;/activeCount&gt;
838      *          &lt;lookupCount&gt;0&lt;/lookupCount&gt;
839      *          &lt;matchedCount&gt;0&lt;/matchedCount&gt;
840      *      &lt;/tableStatistic&gt;
841      *  &lt;/tableStatistics&gt;
842      *  &lt;tableStatistics&gt;
843      *  ...
844      *  ......
845      *  ........
846      *  &lt;/tableStatistics&gt;
847      *  &lt;/list&gt;
848      *
849      * </pre>
850      */
851     @Path("/{containerName}/table")
852     @GET
853     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
854     @TypeHint(AllTableStatistics.class)
855     @StatusCodes({
856         @ResponseCode(code = 200, condition = "Operation successful"),
857         @ResponseCode(code = 404, condition = "The containerName is not found"),
858         @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
859     public AllTableStatistics getTableStatistics(
860             @PathParam("containerName") String containerName) {
861
862         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) {
863             throw new UnauthorizedException("User is not authorized to perform this operation on container "
864                     + containerName);
865         }
866         handleDefaultDisabled(containerName);
867
868         IStatisticsManager statisticsManager = getStatisticsService(containerName);
869         if (statisticsManager == null) {
870             throw new ServiceUnavailableException("Statistics manager"
871                     + RestMessages.SERVICEUNAVAILABLE.toString());
872         }
873
874         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
875                 .getInstance(ISwitchManager.class, containerName, this);
876         if (switchManager == null) {
877             throw new ServiceUnavailableException("Switch manager "
878                     + RestMessages.SERVICEUNAVAILABLE.toString());
879         }
880
881         List<TableStatistics> statistics = new ArrayList<TableStatistics>();
882         for (Node node : switchManager.getNodes()) {
883             List<NodeTableStatistics> stat = statisticsManager
884                     .getNodeTableStatistics(node);
885             TableStatistics tableStat = new TableStatistics(node, stat);
886             statistics.add(tableStat);
887         }
888         return new AllTableStatistics(statistics);
889     }
890
891     /**
892      * Returns a list of all the Table Statistics on a specific node.
893      *
894      * @param containerName
895      *            Name of the Container. The Container name for the base
896      *            controller is "default".
897      * @param nodeType
898      *            Node Type as specified in {@link org.opendaylight.controller.sal.core.Node} class (e.g. OF for Openflow)
899      * @param Node
900      *            Identifier (e.g. MAC address)
901      * @return Returns a list of all the Table Statistics in a given Node.
902      *
903      *         <pre>
904      *
905      * Example:
906      *
907      * Request URL:
908      * http://host:8080/controller/nb/v2/statistics/default/table/node/OF/00:00:00:00:00:00:00:01
909      *
910      * Response in JSON:
911      * {
912      *     "node": {
913      *         "@type": "OF",
914      *         "@id": "00:00:00:00:00:00:00:01"
915      *     },
916      *     "tableStatistic": [
917      *         {
918      *             "nodeTable": {
919      *                 "@id": "0",
920      *                 "node": {
921      *                     "@type": "OF",
922      *                     "@id": "00:00:00:00:00:00:00:01"
923      *                 }
924      *             },
925      *             "activeCount": "12",
926      *             "lookupCount": "11382",
927      *             "matchedCount": "10524"
928      *         },
929      *         {
930      *             "nodeTable": {
931      *                 "@id": "1",
932      *                 "node": {
933      *                     "@type": "OF",
934      *                     "@id": "00:00:00:00:00:00:00:01"
935      *                 }
936      *             },
937      *             "activeCount": "0",
938      *             "lookupCount": "0",
939      *             "matchedCount": "0"
940      *         }
941      *    ]
942      * }
943      *
944      * Response in XML:
945      * &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&gt;
946      * &lt;nodeTableStatistics&gt;
947      *     &lt;node type=&quot;OF&quot; id=&quot;00:00:00:00:00:00:00:01&quot;/&gt;
948      *     &lt;tableStatistic&gt;
949      *         &lt;nodeTable id=&quot;0&quot;&gt;
950      *             &lt;node type=&quot;OF&quot; id=&quot;00:00:00:00:00:00:00:01&quot;/&gt;
951      *         &lt;/nodeTable&gt;
952      *         &lt;activeCount&gt;12&lt;/activeCount&gt;
953      *         &lt;lookupCount&gt;10935&lt;/lookupCount&gt;
954      *         &lt;matchedCount&gt;10084&lt;/matchedCount&gt;
955      *     &lt;/tableStatistic&gt;
956      *     &lt;tableStatistic&gt;
957      *         &lt;nodeTable id=&quot;1&quot;&gt;
958      *             &lt;node type=&quot;OF&quot; id=&quot;00:00:00:00:00:00:00:01&quot;/&gt;
959      *         &lt;/nodeTable&gt;
960      *         &lt;activeCount&gt;0&lt;/activeCount&gt;
961      *         &lt;lookupCount&gt;0&lt;/lookupCount&gt;
962      *         &lt;matchedCount&gt;0&lt;/matchedCount&gt;
963      *     &lt;/tableStatistic&gt;
964      *     &lt;tableStatistic&gt;
965      *         &lt;nodeTable id=&quot;2&quot;&gt;
966      *             &lt;node type=&quot;OF&quot; id=&quot;00:00:00:00:00:00:00:01&quot;/&gt;
967      *         &lt;/nodeTable&gt;
968      *         &lt;activeCount&gt;0&lt;/activeCount&gt;
969      *         &lt;lookupCount&gt;0&lt;/lookupCount&gt;
970      *         &lt;matchedCount&gt;0&lt;/matchedCount&gt;
971      *     &lt;/tableStatistic&gt;
972      * &lt;/nodeTableStatistics&gt;
973      *
974      *
975      * </pre>
976      */
977     @Path("/{containerName}/table/node/{nodeType}/{nodeId}")
978     @GET
979     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
980     @TypeHint(TableStatistics.class)
981     @StatusCodes({
982         @ResponseCode(code = 200, condition = "Operation successful"),
983         @ResponseCode(code = 404, condition = "The containerName is not found"),
984         @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
985     public TableStatistics getTableStatistics(
986             @PathParam("containerName") String containerName,
987             @PathParam("nodeType") String nodeType,
988             @PathParam("nodeId") String nodeId) {
989
990         if (!NorthboundUtils.isAuthorized(
991                 getUserName(), containerName, Privilege.READ, this)) {
992             throw new UnauthorizedException(
993                     "User is not authorized to perform this operation on container "
994                             + containerName);
995         }
996         handleDefaultDisabled(containerName);
997
998         IStatisticsManager statisticsManager = getStatisticsService(containerName);
999         if (statisticsManager == null) {
1000             throw new ServiceUnavailableException("Statistics "
1001                     + RestMessages.SERVICEUNAVAILABLE.toString());
1002         }
1003
1004         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
1005                 .getInstance(ISwitchManager.class, containerName, this);
1006         if (switchManager == null) {
1007             throw new ServiceUnavailableException("Switch manager "
1008                     + RestMessages.SERVICEUNAVAILABLE.toString());
1009         }
1010
1011         Node node = handleNodeAvailability(containerName, nodeType, nodeId);
1012         return new TableStatistics(node,
1013                 statisticsManager.getNodeTableStatistics(node));
1014     }
1015
1016     private void handleDefaultDisabled(String containerName) {
1017         IContainerManager containerManager = (IContainerManager) ServiceHelper
1018                 .getGlobalInstance(IContainerManager.class, this);
1019         if (containerManager == null) {
1020             throw new InternalServerErrorException(
1021                     RestMessages.INTERNALERROR.toString());
1022         }
1023         if (containerName.equals(GlobalConstants.DEFAULT.toString())
1024                 && containerManager.hasNonDefaultContainer()) {
1025             throw new ResourceConflictException(
1026                     RestMessages.DEFAULTDISABLED.toString());
1027         }
1028     }
1029
1030     private Node handleNodeAvailability(String containerName, String nodeType,
1031             String nodeId) {
1032
1033         Node node = Node.fromString(nodeType, nodeId);
1034         if (node == null) {
1035             throw new ResourceNotFoundException(nodeId + " : "
1036                     + RestMessages.NONODE.toString());
1037         }
1038
1039         ISwitchManager sm = (ISwitchManager) ServiceHelper.getInstance(
1040                 ISwitchManager.class, containerName, this);
1041
1042         if (sm == null) {
1043             throw new ServiceUnavailableException("Switch Manager "
1044                     + RestMessages.SERVICEUNAVAILABLE.toString());
1045         }
1046
1047         if (!sm.getNodes().contains(node)) {
1048             throw new ResourceNotFoundException(node.toString() + " : "
1049                     + RestMessages.NONODE.toString());
1050         }
1051         return node;
1052     }
1053
1054 }