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