X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=opendaylight%2Fnorthbound%2Fstatistics%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fstatistics%2Fnorthbound%2FStatisticsNorthbound.java;h=a07f6435fe0e92e96d53eea61dd5abdffab921a3;hb=04187bee472c35e1f200bff6ef0daeb5163d36fa;hp=651cb2dad3e10ede85d55fd2882e33898cc75848;hpb=29f7cfb54b580928c7feac63abce028a7014b0d5;p=controller.git
diff --git a/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/StatisticsNorthbound.java b/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/StatisticsNorthbound.java
index 651cb2dad3..a07f6435fe 100644
--- a/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/StatisticsNorthbound.java
+++ b/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/StatisticsNorthbound.java
@@ -15,42 +15,62 @@ import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.SecurityContext;
import org.codehaus.enunciate.jaxrs.ResponseCode;
import org.codehaus.enunciate.jaxrs.StatusCodes;
import org.codehaus.enunciate.jaxrs.TypeHint;
import org.opendaylight.controller.containermanager.IContainerManager;
-
import org.opendaylight.controller.northbound.commons.RestMessages;
import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;
import org.opendaylight.controller.northbound.commons.exception.ResourceConflictException;
import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException;
+import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
+import org.opendaylight.controller.sal.authorization.Privilege;
import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.reader.FlowOnNode;
import org.opendaylight.controller.sal.reader.NodeConnectorStatistics;
+import org.opendaylight.controller.sal.reader.NodeTableStatistics;
import org.opendaylight.controller.sal.utils.GlobalConstants;
import org.opendaylight.controller.sal.utils.ServiceHelper;
import org.opendaylight.controller.statisticsmanager.IStatisticsManager;
import org.opendaylight.controller.switchmanager.ISwitchManager;
/**
- * Northbound APIs that returns various Statistics exposed by the Southbound plugins such as Openflow.
- *
- *
+ * Northbound APIs that returns various Statistics exposed by the Southbound
+ * protocol plugins such as Openflow.
+ *
+ *
+ *
* Authentication scheme : HTTP Basic
* Authentication realm : opendaylight
* Transport : HTTP and HTTPS
*
- * HTTPS Authentication is disabled by default. Administrator can enable it in tomcat-server.xml after adding
- * a proper keystore / SSL certificate from a trusted authority.
- * More info : http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
*
*/
@Path("/")
public class StatisticsNorthbound {
+ private String username;
+
+ @Context
+ public void setSecurityContext(SecurityContext context) {
+ if (context != null && context.getUserPrincipal() != null) username = context.getUserPrincipal().getName();
+ }
+
+ protected String getUserName() {
+ return username;
+ }
+
private IStatisticsManager getStatisticsService(String containerName) {
IContainerManager containerManager = (IContainerManager) ServiceHelper
.getGlobalInstance(IContainerManager.class, this);
@@ -86,20 +106,145 @@ public class StatisticsNorthbound {
/**
* Returns a list of all Flow Statistics from all the Nodes.
*
- * @param containerName Name of the Container. The Container name for the base controller is "default".
+ * @param containerName
+ * Name of the Container. The Container name for the base
+ * controller is "default".
* @return List of FlowStatistics from all the Nodes
+ *
+ *
+ * + * Example: + * + * Request URL: + * http://localhost:8080/controller/nb/v2/statistics/default/flow + * + * Response in JSON: + * { + * "flowStatistics": [ + * { + * "node": { + * "id":"00:00:00:00:00:00:00:02", + * "type":"OF" + * }, + * "flowStatistic": [ + * { + * "flow": { + * "match": { + * "matchField": [ + * { + * "type": "DL_TYPE", + * "value": "2048" + * }, + * { + * "mask": "255.255.255.255", + * "type": "NW_DST", + * "value": "1.1.1.1" + * } + * ] + * }, + * "actions": { + * "@type": "output", + * "port": { + * "node":{ + * "id":"00:00:00:00:00:00:00:02", + * "type":"OF" + * }, + * "id":"3", + * "type":"OF" + * } + * }, + * "priority": "1", + * "idleTimeout": "0", + * "hardTimeout": "0", + * "id": "0" + * }, + * "tableId": "0", + * "durationSeconds": "1828", + * "durationNanoseconds": "397000000", + * "packetCount": "0", + * "byteCount": "0" + * } + * ] + * }, + * { flow statistics of another node + * ............ + * ................ + * ...................... + * } + * + * ] + * } + * + * Response in XML: + * <?xml version="1.0" encoding="UTF-8" standalone="yes"?> + * <list> + * <flowStatistics> + * <node> + * <id>00:00:00:00:00:00:00:02</id> + * <type>OF</type> + * </node> + * <flowStatistic> + * <flow> + * <match> + * <matchField> + * <type>DL_TYPE</type> + * <value>2048</value> + * </matchField> + * <matchField> + * <mask>255.255.255.255</mask> + * <type>NW_DST</type> + * <value>1.1.1.2</value> + * </matchField> + * </match> + * <actions + * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="output"> + * <port> + * <node> + * <id>00:00:00:00:00:00:00:02</id> + * <type>OF</type> + * </node> + * <id>3</id> + * <type>OF</type> + * </port> + * </actions> + * <priority>1</priority> + * <idleTimeout>0</idleTimeout> + * <hardTimeout>0</hardTimeout> + * <id>0</id> + * </flow> + * <tableId>0</tableId> + * <durationSeconds>337</durationSeconds> + * <durationNanoseconds>149000000</durationNanoseconds> + * <packetCount>0</packetCount> + * <byteCount>0</byteCount> + * </flowStatistic> + * </flowStatistics> + * <flowStatistics> + * flow statistics for another node + * .......... + * ................ + * ..................... + * </flowStatistics> + * </list> + **/ - @Path("/{containerName}/flowstats") + @Path("/{containerName}/flow") @GET - @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @TypeHint(AllFlowStatistics.class) - @StatusCodes( { - @ResponseCode(code = 200, condition = "Operation successful"), - @ResponseCode(code = 404, condition = "The containerName is not found"), - @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") }) + @StatusCodes({ + @ResponseCode(code = 200, condition = "Operation successful"), + @ResponseCode(code = 404, condition = "The containerName is not found"), + @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") }) public AllFlowStatistics getFlowStatistics( @PathParam("containerName") String containerName) { + if (!NorthboundUtils.isAuthorized( + getUserName(), containerName, Privilege.READ, this)) { + throw new UnauthorizedException( + "User is not authorized to perform this operation on container " + + containerName); + } IStatisticsManager statisticsManager = getStatisticsService(containerName); if (statisticsManager == null) { throw new ServiceUnavailableException("Statistics " @@ -121,8 +266,7 @@ public class StatisticsNorthbound { for (FlowOnNode flowOnSwitch : flows) { flowStats.add(flowOnSwitch); } - FlowStatistics stat = new FlowStatistics(node, - flowStats); + FlowStatistics stat = new FlowStatistics(node, flowStats); statistics.add(stat); } return new AllFlowStatistics(statistics); @@ -131,25 +275,173 @@ public class StatisticsNorthbound { /** * Returns a list of Flow Statistics for a given Node. * - * @param containerName Name of the Container. The Container name - * for the base controller is "default". - * @param nodeType Node Type as specifid by Node class - * @param nodeId Node Identifier - * @return List of Flow Statistics for a given Node. + * @param containerName + * Name of the Container. The Container name for the base + * controller is "default". + * @param nodeType + * Node Type as specifid in {@link org.opendaylight.controller.sal.core.Node} class + * @param nodeId + * Node Identifier + * @return List of Flow Statistics for a given Node. * + * + *
+ * + * Example: + * + * Request URL: + * http://localhost:8080/controller/nb/v2/statistics/default/flow/node/OF/00:00:00:00:00:00:00:01 + * + * Response in JSON: + * { + * "node": { + * "id":"00:00:00:00:00:00:00:01", + * "type":"OF" + * }, + * "flowStatistic": [ + * { + * "flow": { + * "match": { + * "matchField": [ + * { + * "type": "DL_TYPE", + * "value": "2048" + * }, + * { + * "mask": "255.255.255.255", + * "type": "NW_DST", + * "value": "1.1.1.2" + * } + * ] + * }, + * "actions": [ + * { + * "@type": "setDlDst", + * "address": "52d28b0f76ec" + * }, + * { + * "@type": "output", + * "port":{ + * "node":{ + * "id":"00:00:00:00:00:00:00:01", + * "type":"OF" + * }, + * "id":"5", + * "type":"OF" + * } + * } + * ], + * "priority": "1", + * "idleTimeout": "0", + * "hardTimeout": "0", + * "id": "0" + * }, + * "tableId": "0", + * "durationSeconds": "2089", + * "durationNanoseconds": "538000000", + * "packetCount": "0", + * "byteCount": "0" + * } + * ] + * } + * + * Response in XML: + * <?xml version="1.0" encoding="UTF-8" standalone="yes"?> + * <nodeFlowStatistics> + * <node> + * <id>00:00:00:00:00:00:00:02</id> + * <type>OF</type> + * </node> + * <flowStatistic> + * <flow> + * <match> + * <matchField> + * <type>DL_TYPE</type> + * <value>2048</value> + * </matchField> + * <matchField> + * <mask>255.255.255.255</mask> + * <type>NW_DST</type> + * <value>1.1.1.2</value> + * </matchField> + * </match> + * <actions + * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="output"> + * <port> + * <node> + * <id>00:00:00:00:00:00:00:02</id> + * <type>OF</type> + * </node> + * <id>3</id> + * <type>OF</type> + * </port> + * </actions> + * <priority>1</priority> + * <idleTimeout>0</idleTimeout> + * <hardTimeout>0</hardTimeout> + * <id>0</id> + * </flow> + * <tableId>0</tableId> + * <durationSeconds>337</durationSeconds> + * <durationNanoseconds>149000000</durationNanoseconds> + * <packetCount>0</packetCount> + * <byteCount>0</byteCount> + * </flowStatistic> + * <flowStatistic> + * <flow> + * <match> + * <matchField> + * <type>DL_TYPE</type> + * <value>2048</value> + * </matchField> + * <matchField> + * <mask>255.255.255.255</mask> + * <type>NW_DST</type> + * <value>1.1.1.1</value> + * </matchField> + * </match> + * <actions + * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="output"> + * <port> + * <node> + * <id>00:00:00:00:00:00:00:02</id> + * <type>OF</type> + * </node> + * <id>3</id> + * <type>OF</type> + * </port> + * </actions> + * <priority>1</priority> + * <idleTimeout>0</idleTimeout> + * <hardTimeout>0</hardTimeout> + * <id>0</id> + * </flow> + * <tableId>0</tableId> + * <durationSeconds>337</durationSeconds> + * <durationNanoseconds>208000000</durationNanoseconds> + * <packetCount>0</packetCount> + * <byteCount>0</byteCount> + * </flowStatistic> + * </nodeFlowStatistics> + **/ - @Path("/{containerName}/flowstats/{nodeType}/{nodeId}") + @Path("/{containerName}/flow/node/{nodeType}/{nodeId}") @GET - @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @TypeHint(FlowStatistics.class) - @StatusCodes( { - @ResponseCode(code = 200, condition = "Operation successful"), - @ResponseCode(code = 404, condition = "The containerName is not found"), - @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") }) + @StatusCodes({ + @ResponseCode(code = 200, condition = "Operation successful"), + @ResponseCode(code = 404, condition = "The containerName is not found"), + @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") }) public FlowStatistics getFlowStatistics( @PathParam("containerName") String containerName, @PathParam("nodeType") String nodeType, @PathParam("nodeId") String nodeId) { - + if (!NorthboundUtils.isAuthorized( + getUserName(), containerName, Privilege.READ, this)) { + throw new UnauthorizedException( + "User is not authorized to perform this operation on container " + + containerName); + } handleDefaultDisabled(containerName); IStatisticsManager statisticsManager = getStatisticsService(containerName); @@ -170,23 +462,166 @@ public class StatisticsNorthbound { } /** - * Returns a list of all the Port Statistics across all the NodeConnectors on all the Nodes. + * Returns a list of all the Port Statistics across all the NodeConnectors + * on all the Nodes. + * + * @param containerName + * Name of the Container. The Container name for the base + * controller is "default". + * @return List of all the Port Statistics across all the NodeConnectors on + * all the Nodes. + * + *
+ * + * Example: * - * @param containerName Name of the Container. The Container name for the base controller is "default". - * @return List of all the Port Statistics across all the NodeConnectors on all the Nodes. + * Request URL: + * http://localhost:8080/controller/nb/v2/statistics/default/port + * + * Response in JSON: + * { + * "portStatistics": [ + * { + * "node": { + * "id":"00:00:00:00:00:00:00:02", + * "type":"OF" + * }, + * "portStatistic": [ + * { + * "nodeConnector":{ + * "node":{ + * "id":"00:00:00:00:00:00:00:02", + * "type":"OF" + * }, + * "id":"3", + * "type":"OF" + * }, + * "receivePackets": "182", + * "transmitPackets": "173", + * "receiveBytes": "12740", + * "transmitBytes": "12110", + * "receiveDrops": "0", + * "transmitDrops": "0", + * "receiveErrors": "0", + * "transmitErrors": "0", + * "receiveFrameError": "0", + * "receiveOverRunError": "0", + * "receiveCrcError": "0", + * "collisionCount": "0" + * }, + * { + * "nodeConnector": { + * "node":{ + * "id":"00:00:00:00:00:00:00:02", + * "type":"OF" + * }, + * "id":"2", + * "type":"OF" + * }, + * "receivePackets": "174", + * "transmitPackets": "181", + * "receiveBytes": "12180", + * "transmitBytes": "12670", + * "receiveDrops": "0", + * "transmitDrops": "0", + * "receiveErrors": "0", + * "transmitErrors": "0", + * "receiveFrameError": "0", + * "receiveOverRunError": "0", + * "receiveCrcError": "0", + * "collisionCount": "0" + * }, + * + * ] + * }, + * { + * "node": { + * "id":"00:00:00:00:00:00:00:03", + * "type":"OF" + * }, + * "portStatistic": [ + * .................. + * ....................... + * .......................... + * ] + * } + * ] + * } + * + * Response in XML: + * <?xml version="1.0" encoding="UTF-8" standalone="yes"?> + * <list> + * <portStatistics> + * <node> + * <id>00:00:00:00:00:00:00:02</id> + * <type>OF</type> + * </node> + * <portStatistic> + * <nodeConnector> + * <node> + * <id>00:00:00:00:00:00:00:02</id> + * <type>OF</type> + * </node> + * <id>3</id> + * <type>OF</type> + * </nodeConnector> + * <receivePackets>181</receivePackets> + * <transmitPackets>172</transmitPackets> + * <receiveBytes>12670</receiveBytes> + * <transmitBytes>12040</transmitBytes> + * <receiveDrops>0</receiveDrops> + * <transmitDrops>0</transmitDrops> + * <receiveErrors>0</receiveErrors> + * <transmitErrors>0</transmitErrors> + * <receiveFrameError>0</receiveFrameError> + * <receiveOverRunError>0</receiveOverRunError> + * <receiveCrcError>0</receiveCrcError> + * <collisionCount>0</collisionCount> + * </portStatistic> + * <portStatistic> + * <nodeConnector> + * <node> + * <id>00:00:00:00:00:00:00:02</id> + * <type>OF</type> + * </node> + * <id>2</id> + * <type>OF</type> + * </nodeConnector> + * <receivePackets>173</receivePackets> + * <transmitPackets>180</transmitPackets> + * <receiveBytes>12110</receiveBytes> + * <transmitBytes>12600</transmitBytes> + * <receiveDrops>0</receiveDrops> + * <transmitDrops>0</transmitDrops> + * <receiveErrors>0</receiveErrors> + * <transmitErrors>0</transmitErrors> + * <receiveFrameError>0</receiveFrameError> + * <receiveOverRunError>0</receiveOverRunError> + * <receiveCrcError>0</receiveCrcError> + * <collisionCount>0</collisionCount> + * </portStatistic> + * </portStatistics> + * </list> + **/ - @Path("/{containerName}/portstats") + @Path("/{containerName}/port") @GET - @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @TypeHint(AllPortStatistics.class) - @StatusCodes( { - @ResponseCode(code = 200, condition = "Operation successful"), - @ResponseCode(code = 404, condition = "The containerName is not found"), - @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") }) + @StatusCodes({ + @ResponseCode(code = 200, condition = "Operation successful"), + @ResponseCode(code = 404, condition = "The containerName is not found"), + @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") }) public AllPortStatistics getPortStatistics( @PathParam("containerName") String containerName) { + if (!NorthboundUtils.isAuthorized( + getUserName(), containerName, Privilege.READ, this)) { + throw new UnauthorizedException( + "User is not authorized to perform this operation on container " + + containerName); + } IStatisticsManager statisticsManager = getStatisticsService(containerName); if (statisticsManager == null) { throw new ServiceUnavailableException("Statistics " @@ -211,27 +646,153 @@ public class StatisticsNorthbound { } /** - * Returns a list of all the Port Statistics across all the NodeConnectors in a given Node. + * Returns a list of all the Port Statistics across all the NodeConnectors + * in a given Node. + * + * @param containerName + * Name of the Container. The Container name for the base + * controller is "default". + * @param nodeType + * Node Type as specifid in {@link org.opendaylight.controller.sal.core.Node} class + * @param Node + * Identifier (e.g. MAC address) + * @return Returns a list of all the Port Statistics across all the + * NodeConnectors in a given Node. + * + *
+ * + * Example: * - * @param containerName Name of the Container. The Container name - * for the base controller is "default". - * @param nodeType Node Type as specifid by Node class - * @param Node Identifier - * @return Returns a list of all the Port Statistics across all the NodeConnectors in a given Node. + * Request URL: + * http://localhost:8080/controller/nb/v2/statistics/default/port/node/OF/00:00:00:00:00:00:00:01 + * + * Response in JSON: + * { + * "node": { + * "id":"00:00:00:00:00:00:00:01", + * "type":"OF" + * }, + * "portStatistic": [ + * { + * "nodeConnector": { + * "node":{ + * "id":"00:00:00:00:00:00:00:01", + * "type":"OF" + * }, + * "id":"3", + * "type":"OF" + * }, + * "receivePackets": "171", + * "transmitPackets": "2451", + * "receiveBytes": "11970", + * "transmitBytes": "235186", + * "receiveDrops": "0", + * "transmitDrops": "0", + * "receiveErrors": "0", + * "transmitErrors": "0", + * "receiveFrameError": "0", + * "receiveOverRunError": "0", + * "receiveCrcError": "0", + * "collisionCount": "0" + * }, + * { + * "nodeConnector": { + * "node":{ + * "id":"00:00:00:00:00:00:00:01", + * "type":"OF" + * }, + * "id":"2", + * "type":"OF" + * }, + * "receivePackets": "179", + * "transmitPackets": "2443", + * "receiveBytes": "12530", + * "transmitBytes": "234626", + * "receiveDrops": "0", + * "transmitDrops": "0", + * "receiveErrors": "0", + * "transmitErrors": "0", + * "receiveFrameError": "0", + * "receiveOverRunError": "0", + * "receiveCrcError": "0", + * "collisionCount": "0" + * } + * ] + * } + * + * Response in XML: + * <?xml version="1.0" encoding="UTF-8" standalone="yes"?> + * <nodePortStatistics> + * <node> + * <id>00:00:00:00:00:00:00:01</id> + * <type>OF</type> + * </node> + * <portStatistic> + * <nodeConnector> + * <node> + * <id>00:00:00:00:00:00:00:01</id> + * <type>OF</type> + * </node> + * <id>2</id> + * <type>OF</type> + * </nodeConnector> + * <receivePackets>180</receivePackets> + * <transmitPackets>2594</transmitPackets> + * <receiveBytes>12600</receiveBytes> + * <transmitBytes>249396</transmitBytes> + * <receiveDrops>0</receiveDrops> + * <transmitDrops>0</transmitDrops> + * <receiveErrors>0</receiveErrors> + * <transmitErrors>0</transmitErrors> + * <receiveFrameError>0</receiveFrameError> + * <receiveOverRunError>0</receiveOverRunError> + * <receiveCrcError>0</receiveCrcError> + * <collisionCount>0</collisionCount> + * </portStatistic> + * <portStatistic> + * <nodeConnector> + * <node> + * <id>00:00:00:00:00:00:00:01</id> + * <type>OF</type> + * </node> + * <id>5</id> + * <type>OF</type> + * </nodeConnector> + * <receivePackets>2542</receivePackets> + * <transmitPackets>2719</transmitPackets> + * <receiveBytes>243012</receiveBytes> + * <transmitBytes>255374</transmitBytes> + * <receiveDrops>0</receiveDrops> + * <transmitDrops>0</transmitDrops> + * <receiveErrors>0</receiveErrors> + * <transmitErrors>0</transmitErrors> + * <receiveFrameError>0</receiveFrameError> + * <receiveOverRunError>0</receiveOverRunError> + * <receiveCrcError>0</receiveCrcError> + * <collisionCount>0</collisionCount> + * </portStatistic> + * </nodePortStatistics> + **/ - @Path("/{containerName}/portstats/{nodeType}/{nodeId}") + @Path("/{containerName}/port/node/{nodeType}/{nodeId}") @GET - @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @TypeHint(PortStatistics.class) - @StatusCodes( { - @ResponseCode(code = 200, condition = "Operation successful"), - @ResponseCode(code = 404, condition = "The containerName is not found"), - @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") }) + @StatusCodes({ + @ResponseCode(code = 200, condition = "Operation successful"), + @ResponseCode(code = 404, condition = "The containerName is not found"), + @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") }) public PortStatistics getPortStatistics( @PathParam("containerName") String containerName, @PathParam("nodeType") String nodeType, @PathParam("nodeId") String nodeId) { + if (!NorthboundUtils.isAuthorized( + getUserName(), containerName, Privilege.READ, this)) { + throw new UnauthorizedException( + "User is not authorized to perform this operation on container " + + containerName); + } handleDefaultDisabled(containerName); IStatisticsManager statisticsManager = getStatisticsService(containerName); @@ -247,28 +808,308 @@ public class StatisticsNorthbound { + RestMessages.SERVICEUNAVAILABLE.toString()); } - Node node = handleNodeAvailability(containerName, - nodeType, nodeId); - return new PortStatistics(node, statisticsManager - .getNodeConnectorStatistics(node)); + Node node = handleNodeAvailability(containerName, nodeType, nodeId); + return new PortStatistics(node, + statisticsManager.getNodeConnectorStatistics(node)); + } + + /** + * Returns a list of all the Table Statistics on all Nodes. + * + * @param containerName + * Name of the Container. The Container name for the base + * controller is "default". + * + * @return Returns a list of all the Table Statistics in a given Node. + * + *
+ * + * Example: + * + * Request URL: + * http://localhost:8080/controller/nb/v2/statistics/default/table + * + * Response in JSON: + * { + * "tableStatistics": [ + * { + * "node": { + * "id":"00:00:00:00:00:00:00:02", + * "type":"OF" + * }, + * "tableStatistic": [ + * { + * "nodeTable": { + * "node":{ + * "id":"00:00:00:00:00:00:00:02", + * "type":"OF" + * }, + * "id":"0" + * }, + * "activeCount": "11", + * "lookupCount": "816", + * "matchedCount": "220" + * }, + * { + * ...another table + * ..... + * ........ + * } + * + * ] + * } + * ] + * } + * + * Response in XML: + * <?xml version="1.0" encoding="UTF-8" standalone="yes"?> + * <list> + * <tableStatistics> + * <node> + * <id>00:00:00:00:00:00:00:01</id> + * <type>OF</type> + * </node> + * <tableStatistic> + * <nodeTable> + * <node> + * <id>00:00:00:00:00:00:00:01</id> + * <type>OF</type> + * </node> + * <id>0</id> + * </nodeTable> + * <activeCount>12</activeCount> + * <lookupCount>10935</lookupCount> + * <matchedCount>10084</matchedCount> + * </tableStatistic> + * <tableStatistic> + * <nodeTable> + * <node> + * <id>00:00:00:00:00:00:00:01</id> + * <type>OF</type> + * </node> + * <id>1</id> + * </nodeTable> + * <activeCount>0</activeCount> + * <lookupCount>0</lookupCount> + * <matchedCount>0</matchedCount> + * </tableStatistic> + * <tableStatistic> + * <nodeTable> + * <node> + * <id>00:00:00:00:00:00:00:01</id> + * <type>OF</type> + * </node> + * <id>2</id> + * </nodeTable> + * <activeCount>0</activeCount> + * <lookupCount>0</lookupCount> + * <matchedCount>0</matchedCount> + * </tableStatistic> + * </tableStatistics> + * <tableStatistics> + * ... + * ...... + * ........ + * </tableStatistics> + * </list> + * + *+ */ + @Path("/{containerName}/table") + @GET + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @TypeHint(AllTableStatistics.class) + @StatusCodes({ + @ResponseCode(code = 200, condition = "Operation successful"), + @ResponseCode(code = 404, condition = "The containerName is not found"), + @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") }) + public AllTableStatistics getTableStatistics( + @PathParam("containerName") String containerName) { + + if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) { + throw new UnauthorizedException("User is not authorized to perform this operation on container " + + containerName); + } + handleDefaultDisabled(containerName); + + IStatisticsManager statisticsManager = getStatisticsService(containerName); + if (statisticsManager == null) { + throw new ServiceUnavailableException("Statistics manager" + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + + ISwitchManager switchManager = (ISwitchManager) ServiceHelper + .getInstance(ISwitchManager.class, containerName, this); + if (switchManager == null) { + throw new ServiceUnavailableException("Switch manager " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + + List
+ * + * Example: + * + * Request URL: + * http://localhost:8080/controller/nb/v2/statistics/default/table/node/OF/00:00:00:00:00:00:00:01 + * + * Response in JSON: + * { + * "node": { + * "id":"00:00:00:00:00:00:00:01", + * "type":"OF" + * }, + * "tableStatistic": [ + * { + * "nodeTable": { + * "node":{ + * "id":"00:00:00:00:00:00:00:01", + * "type":"OF" + * }, + * "id":"0" + * }, + * "activeCount": "12", + * "lookupCount": "11382", + * "matchedCount": "10524" + * }, + * { + * "nodeTable": { + * "node":{ + * "id":"00:00:00:00:00:00:00:01", + * "type":"OF" + * }, + * "id":"1" + * }, + * "activeCount": "0", + * "lookupCount": "0", + * "matchedCount": "0" + * } + * ] + * } + * + * Response in XML: + * <?xml version="1.0" encoding="UTF-8" standalone="yes"?> + * <nodeTableStatistics> + * <node> + * <id>00:00:00:00:00:00:00:01</id> + * <type>OF</type> + * </node> + * <tableStatistic> + * <nodeTable> + * <node> + * <id>00:00:00:00:00:00:00:01</id> + * <type>OF</type> + * </node> + * <id>0</id> + * </nodeTable> + * <activeCount>12</activeCount> + * <lookupCount>10935</lookupCount> + * <matchedCount>10084</matchedCount> + * </tableStatistic> + * <tableStatistic> + * <nodeTable> + * <node> + * <id>00:00:00:00:00:00:00:01</id> + * <type>OF</type> + * </node> + * <id>1</id> + * </nodeTable> + * <activeCount>0</activeCount> + * <lookupCount>0</lookupCount> + * <matchedCount>0</matchedCount> + * </tableStatistic> + * <tableStatistic> + * <nodeTable> + * <node> + * <id>00:00:00:00:00:00:00:01</id> + * <type>OF</type> + * </node> + * <id>2</id> + * </nodeTable> + * <activeCount>0</activeCount> + * <lookupCount>0</lookupCount> + * <matchedCount>0</matchedCount> + * </tableStatistic> + * </nodeTableStatistics> + * + *+ */ + @Path("/{containerName}/table/node/{nodeType}/{nodeId}") + @GET + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @TypeHint(TableStatistics.class) + @StatusCodes({ + @ResponseCode(code = 200, condition = "Operation successful"), + @ResponseCode(code = 404, condition = "The containerName is not found"), + @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") }) + public TableStatistics getTableStatistics( + @PathParam("containerName") String containerName, + @PathParam("nodeType") String nodeType, + @PathParam("nodeId") String nodeId) { + + if (!NorthboundUtils.isAuthorized( + getUserName(), containerName, Privilege.READ, this)) { + throw new UnauthorizedException( + "User is not authorized to perform this operation on container " + + containerName); + } + handleDefaultDisabled(containerName); + + IStatisticsManager statisticsManager = getStatisticsService(containerName); + if (statisticsManager == null) { + throw new ServiceUnavailableException("Statistics " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + + ISwitchManager switchManager = (ISwitchManager) ServiceHelper + .getInstance(ISwitchManager.class, containerName, this); + if (switchManager == null) { + throw new ServiceUnavailableException("Switch manager " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + + Node node = handleNodeAvailability(containerName, nodeType, nodeId); + return new TableStatistics(node, + statisticsManager.getNodeTableStatistics(node)); } private void handleDefaultDisabled(String containerName) { IContainerManager containerManager = (IContainerManager) ServiceHelper .getGlobalInstance(IContainerManager.class, this); if (containerManager == null) { - throw new InternalServerErrorException(RestMessages.INTERNALERROR - .toString()); + throw new InternalServerErrorException( + RestMessages.INTERNALERROR.toString()); } if (containerName.equals(GlobalConstants.DEFAULT.toString()) && containerManager.hasNonDefaultContainer()) { - throw new ResourceConflictException(RestMessages.DEFAULTDISABLED - .toString()); + throw new ResourceConflictException( + RestMessages.DEFAULTDISABLED.toString()); } } private Node handleNodeAvailability(String containerName, String nodeType, - String nodeId) { + String nodeId) { Node node = Node.fromString(nodeType, nodeId); if (node == null) {