2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.controller.statistics.northbound;
11 import java.util.ArrayList;
12 import java.util.List;
14 import javax.ws.rs.GET;
15 import javax.ws.rs.Path;
16 import javax.ws.rs.PathParam;
17 import javax.ws.rs.Produces;
18 import javax.ws.rs.core.MediaType;
20 import org.codehaus.enunciate.jaxrs.ResponseCode;
21 import org.codehaus.enunciate.jaxrs.StatusCodes;
22 import org.codehaus.enunciate.jaxrs.TypeHint;
23 import org.opendaylight.controller.containermanager.IContainerManager;
25 import org.opendaylight.controller.northbound.commons.RestMessages;
26 import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;
27 import org.opendaylight.controller.northbound.commons.exception.ResourceConflictException;
28 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
29 import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
30 import org.opendaylight.controller.sal.core.Node;
31 import org.opendaylight.controller.sal.reader.FlowOnNode;
32 import org.opendaylight.controller.sal.reader.NodeConnectorStatistics;
33 import org.opendaylight.controller.sal.utils.GlobalConstants;
34 import org.opendaylight.controller.sal.utils.ServiceHelper;
35 import org.opendaylight.controller.statisticsmanager.IStatisticsManager;
36 import org.opendaylight.controller.switchmanager.ISwitchManager;
39 * Northbound APIs that returns various Statistics exposed by the Southbound plugins such as Openflow.
42 * Authentication scheme : <b>HTTP Basic</b><br>
43 * Authentication realm : <b>opendaylight</b><br>
44 * Transport : <b>HTTP and HTTPS</b><br>
46 * HTTPS Authentication is disabled by default. Administrator can enable it in tomcat-server.xml after adding
47 * a proper keystore / SSL certificate from a trusted authority.<br>
48 * More info : http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
52 public class StatisticsNorthbound {
54 private IStatisticsManager getStatisticsService(String containerName) {
55 IContainerManager containerManager = (IContainerManager) ServiceHelper
56 .getGlobalInstance(IContainerManager.class, this);
57 if (containerManager == null) {
58 throw new ServiceUnavailableException("Container "
59 + RestMessages.SERVICEUNAVAILABLE.toString());
62 boolean found = false;
63 List<String> containerNames = containerManager.getContainerNames();
64 for (String cName : containerNames) {
65 if (cName.trim().equalsIgnoreCase(containerName.trim())) {
71 throw new ResourceNotFoundException(containerName + " "
72 + RestMessages.NOCONTAINER.toString());
75 IStatisticsManager statsManager = (IStatisticsManager) ServiceHelper
76 .getInstance(IStatisticsManager.class, containerName, this);
78 if (statsManager == null) {
79 throw new ServiceUnavailableException("Statistics "
80 + RestMessages.SERVICEUNAVAILABLE.toString());
87 * Returns a list of all Flow Statistics from all the Nodes.
89 * @param containerName Name of the Container. The Container name for the base controller is "default".
90 * @return List of FlowStatistics from all the Nodes
93 @Path("/{containerName}/flowstats")
95 @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
96 @TypeHint(AllFlowStatistics.class)
98 @ResponseCode(code = 200, condition = "Operation successful"),
99 @ResponseCode(code = 404, condition = "The containerName is not found"),
100 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
101 public AllFlowStatistics getFlowStatistics(
102 @PathParam("containerName") String containerName) {
103 IStatisticsManager statisticsManager = getStatisticsService(containerName);
104 if (statisticsManager == null) {
105 throw new ServiceUnavailableException("Statistics "
106 + RestMessages.SERVICEUNAVAILABLE.toString());
109 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
110 .getInstance(ISwitchManager.class, containerName, this);
111 if (switchManager == null) {
112 throw new ServiceUnavailableException("Switch manager "
113 + RestMessages.SERVICEUNAVAILABLE.toString());
116 List<FlowStatistics> statistics = new ArrayList<FlowStatistics>();
117 for (Node node : switchManager.getNodes()) {
118 List<FlowOnNode> flowStats = new ArrayList<FlowOnNode>();
120 List<FlowOnNode> flows = statisticsManager.getFlows(node);
121 for (FlowOnNode flowOnSwitch : flows) {
122 flowStats.add(flowOnSwitch);
124 FlowStatistics stat = new FlowStatistics(node,
126 statistics.add(stat);
128 return new AllFlowStatistics(statistics);
132 * Returns a list of Flow Statistics for a given Node.
134 * @param containerName Name of the Container. The Container name
135 * for the base controller is "default".
136 * @param nodeType Node Type as specifid by Node class
137 * @param nodeId Node Identifier
138 * @return List of Flow Statistics for a given Node.
140 @Path("/{containerName}/flowstats/{nodeType}/{nodeId}")
142 @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
143 @TypeHint(FlowStatistics.class)
145 @ResponseCode(code = 200, condition = "Operation successful"),
146 @ResponseCode(code = 404, condition = "The containerName is not found"),
147 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
148 public FlowStatistics getFlowStatistics(
149 @PathParam("containerName") String containerName,
150 @PathParam("nodeType") String nodeType,
151 @PathParam("nodeId") String nodeId) {
153 handleDefaultDisabled(containerName);
155 IStatisticsManager statisticsManager = getStatisticsService(containerName);
156 if (statisticsManager == null) {
157 throw new ServiceUnavailableException("Statistics "
158 + RestMessages.SERVICEUNAVAILABLE.toString());
161 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
162 .getInstance(ISwitchManager.class, containerName, this);
163 if (switchManager == null) {
164 throw new ServiceUnavailableException("Switch manager "
165 + RestMessages.SERVICEUNAVAILABLE.toString());
168 Node node = handleNodeAvailability(containerName, nodeType, nodeId);
169 return new FlowStatistics(node, statisticsManager.getFlows(node));
173 * Returns a list of all the Port Statistics across all the NodeConnectors on all the Nodes.
175 * @param containerName Name of the Container. The Container name for the base controller is "default".
176 * @return List of all the Port Statistics across all the NodeConnectors on all the Nodes.
179 @Path("/{containerName}/portstats")
181 @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
182 @TypeHint(AllPortStatistics.class)
184 @ResponseCode(code = 200, condition = "Operation successful"),
185 @ResponseCode(code = 404, condition = "The containerName is not found"),
186 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
187 public AllPortStatistics getPortStatistics(
188 @PathParam("containerName") String containerName) {
190 IStatisticsManager statisticsManager = getStatisticsService(containerName);
191 if (statisticsManager == null) {
192 throw new ServiceUnavailableException("Statistics "
193 + RestMessages.SERVICEUNAVAILABLE.toString());
196 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
197 .getInstance(ISwitchManager.class, containerName, this);
198 if (switchManager == null) {
199 throw new ServiceUnavailableException("Switch manager "
200 + RestMessages.SERVICEUNAVAILABLE.toString());
203 List<PortStatistics> statistics = new ArrayList<PortStatistics>();
204 for (Node node : switchManager.getNodes()) {
205 List<NodeConnectorStatistics> stat = statisticsManager
206 .getNodeConnectorStatistics(node);
207 PortStatistics portStat = new PortStatistics(node, stat);
208 statistics.add(portStat);
210 return new AllPortStatistics(statistics);
214 * Returns a list of all the Port Statistics across all the NodeConnectors in a given Node.
216 * @param containerName Name of the Container. The Container name
217 * for the base controller is "default".
218 * @param nodeType Node Type as specifid by Node class
219 * @param Node Identifier
220 * @return Returns a list of all the Port Statistics across all the NodeConnectors in a given Node.
222 @Path("/{containerName}/portstats/{nodeType}/{nodeId}")
224 @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
225 @TypeHint(PortStatistics.class)
227 @ResponseCode(code = 200, condition = "Operation successful"),
228 @ResponseCode(code = 404, condition = "The containerName is not found"),
229 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
230 public PortStatistics getPortStatistics(
231 @PathParam("containerName") String containerName,
232 @PathParam("nodeType") String nodeType,
233 @PathParam("nodeId") String nodeId) {
235 handleDefaultDisabled(containerName);
237 IStatisticsManager statisticsManager = getStatisticsService(containerName);
238 if (statisticsManager == null) {
239 throw new ServiceUnavailableException("Statistics "
240 + RestMessages.SERVICEUNAVAILABLE.toString());
243 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
244 .getInstance(ISwitchManager.class, containerName, this);
245 if (switchManager == null) {
246 throw new ServiceUnavailableException("Switch manager "
247 + RestMessages.SERVICEUNAVAILABLE.toString());
250 Node node = handleNodeAvailability(containerName,
252 return new PortStatistics(node, statisticsManager
253 .getNodeConnectorStatistics(node));
256 private void handleDefaultDisabled(String containerName) {
257 IContainerManager containerManager = (IContainerManager) ServiceHelper
258 .getGlobalInstance(IContainerManager.class, this);
259 if (containerManager == null) {
260 throw new InternalServerErrorException(RestMessages.INTERNALERROR
263 if (containerName.equals(GlobalConstants.DEFAULT.toString())
264 && containerManager.hasNonDefaultContainer()) {
265 throw new ResourceConflictException(RestMessages.DEFAULTDISABLED
270 private Node handleNodeAvailability(String containerName, String nodeType,
273 Node node = Node.fromString(nodeType, nodeId);
275 throw new ResourceNotFoundException(nodeId + " : "
276 + RestMessages.NONODE.toString());
279 ISwitchManager sm = (ISwitchManager) ServiceHelper.getInstance(
280 ISwitchManager.class, containerName, this);
283 throw new ServiceUnavailableException("Switch Manager "
284 + RestMessages.SERVICEUNAVAILABLE.toString());
287 if (!sm.getNodes().contains(node)) {
288 throw new ResourceNotFoundException(node.toString() + " : "
289 + RestMessages.NONODE.toString());