From fae0114184010519a175ef4b529c84e735c2e41f Mon Sep 17 00:00:00 2001 From: Yevgeny Khodorkovsky Date: Mon, 26 Aug 2013 15:48:15 -0700 Subject: [PATCH] Cleaup Statistics northbound and add exmaples - Clean up stats northbound to align with common REST conventions, add more descriptive javadoc with examples Change-Id: I9508e72b9f62dc576ab4a569f699b75e7bfb29a9 Signed-off-by: Yevgeny Khodorkovsky --- .../containermanager/IContainerManager.java | 10 +- .../integrationtest/NorthboundIT.java | 18 +- .../northbound/AllFlowStatistics.java | 7 +- .../northbound/AllPortStatistics.java | 7 +- .../northbound/AllTableStatistics.java | 6 +- .../statistics/northbound/FlowStatistics.java | 15 +- .../statistics/northbound/PortStatistics.java | 12 +- .../northbound/StatisticsNorthbound.java | 652 +++++++++++++++++- .../northbound/TableStatistics.java | 14 +- .../controller/sal/core/NodeTable.java | 3 +- 10 files changed, 676 insertions(+), 68 deletions(-) diff --git a/opendaylight/containermanager/api/src/main/java/org/opendaylight/controller/containermanager/IContainerManager.java b/opendaylight/containermanager/api/src/main/java/org/opendaylight/controller/containermanager/IContainerManager.java index 89c0c0b217..9300921be9 100644 --- a/opendaylight/containermanager/api/src/main/java/org/opendaylight/controller/containermanager/IContainerManager.java +++ b/opendaylight/containermanager/api/src/main/java/org/opendaylight/controller/containermanager/IContainerManager.java @@ -14,8 +14,7 @@ import java.util.List; import org.opendaylight.controller.sal.utils.Status; /** - * Container Manager interface - * + * Container Manager Interface - provides methods to get information on existing OSGI containers * */ public interface IContainerManager { @@ -23,14 +22,14 @@ public interface IContainerManager { /** * Returns true if there are any non-default Containers present. * - * @return true, if any non-default container is present, else false + * @return true if any non-default container is present false otherwise. */ public boolean hasNonDefaultContainer(); /** - * Returns a list of Containers that currently exist. + * Returns a list of the existing containers. * - * @return array of String Container names + * @return List of Container name strings. */ public List getContainerNames(); @@ -41,5 +40,6 @@ public interface IContainerManager { * * @return status code */ + @Deprecated public Status saveContainerConfig(); } diff --git a/opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIT.java b/opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIT.java index b4c3e1e028..b672f5e9c2 100644 --- a/opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIT.java +++ b/opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIT.java @@ -558,7 +558,7 @@ public class NorthboundIT { String baseURL = "http://127.0.0.1:8080/controller/nb/v2/statistics/default/"; - String result = getJsonResult(baseURL + "flowstats"); + String result = getJsonResult(baseURL + "flow"); JSONTokener jt = new JSONTokener(result); JSONObject json = new JSONObject(jt); JSONObject flowStatistics = getJsonInstance(json, "flowStatistics", 0xCAFE); @@ -568,7 +568,7 @@ public class NorthboundIT { Assert.assertEquals(node.getString("@type"), "STUB"); // test that flow statistics results are correct - JSONArray flowStats = flowStatistics.getJSONArray("flowStat"); + JSONArray flowStats = flowStatistics.getJSONArray("flowStatistic"); for (int i = 0; i < flowStats.length(); i++) { JSONObject flowStat = flowStats.getJSONObject(i); @@ -576,8 +576,8 @@ public class NorthboundIT { } - // for /controller/nb/v2/statistics/default/portstats - result = getJsonResult(baseURL + "portstats"); + // for /controller/nb/v2/statistics/default/port + result = getJsonResult(baseURL + "port"); jt = new JSONTokener(result); json = new JSONObject(jt); JSONObject portStatistics = getJsonInstance(json, "portStatistics", 0xCAFE); @@ -587,7 +587,7 @@ public class NorthboundIT { Assert.assertEquals(node2.getString("@type"), "STUB"); // test that port statistic results are correct - JSONObject portStat = portStatistics.getJSONObject("portStat"); + JSONObject portStat = portStatistics.getJSONObject("portStatistic"); Assert.assertTrue(portStat.getInt("receivePackets") == 250); Assert.assertTrue(portStat.getInt("transmitPackets") == 500); Assert.assertTrue(portStat.getInt("receiveBytes") == 1000); @@ -602,7 +602,7 @@ public class NorthboundIT { Assert.assertTrue(portStat.getInt("collisionCount") == 4); // test for getting one specific node's stats - result = getJsonResult(baseURL + "flowstats/STUB/51966"); + result = getJsonResult(baseURL + "flow/node/STUB/51966"); jt = new JSONTokener(result); json = new JSONObject(jt); node = json.getJSONObject("node"); @@ -611,13 +611,13 @@ public class NorthboundIT { Assert.assertEquals(node.getString("@type"), "STUB"); // test that flow statistics results are correct - flowStats = json.getJSONArray("flowStat"); + flowStats = json.getJSONArray("flowStatistic"); for (int i = 0; i < flowStats.length(); i++) { JSONObject flowStat = flowStats.getJSONObject(i); testFlowStat(flowStat, actionTypes[i], i); } - result = getJsonResult(baseURL + "portstats/STUB/51966"); + result = getJsonResult(baseURL + "port/node/STUB/51966"); jt = new JSONTokener(result); json = new JSONObject(jt); node2 = json.getJSONObject("node"); @@ -626,7 +626,7 @@ public class NorthboundIT { Assert.assertEquals(node2.getString("@type"), "STUB"); // test that port statistic results are correct - portStat = json.getJSONObject("portStat"); + portStat = json.getJSONObject("portStatistic"); Assert.assertTrue(portStat.getInt("receivePackets") == 250); Assert.assertTrue(portStat.getInt("transmitPackets") == 500); Assert.assertTrue(portStat.getInt("receiveBytes") == 1000); diff --git a/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/AllFlowStatistics.java b/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/AllFlowStatistics.java index 7f37afec21..18627285ea 100644 --- a/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/AllFlowStatistics.java +++ b/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/AllFlowStatistics.java @@ -15,15 +15,14 @@ import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; -@XmlRootElement +@XmlRootElement(name = "list") @XmlAccessorType(XmlAccessType.NONE) - public class AllFlowStatistics { @XmlElement List flowStatistics; //To satisfy JAXB - private AllFlowStatistics() { - } + @SuppressWarnings("unused") + private AllFlowStatistics() {} public AllFlowStatistics(List flowStatistics) { this.flowStatistics = flowStatistics; diff --git a/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/AllPortStatistics.java b/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/AllPortStatistics.java index e377de2b88..2117690d97 100644 --- a/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/AllPortStatistics.java +++ b/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/AllPortStatistics.java @@ -15,15 +15,14 @@ import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; -@XmlRootElement +@XmlRootElement(name = "list") @XmlAccessorType(XmlAccessType.NONE) - public class AllPortStatistics { @XmlElement List portStatistics; //To satisfy JAXB - private AllPortStatistics() { - } + @SuppressWarnings("unused") + private AllPortStatistics() {} public AllPortStatistics(List portStatistics) { this.portStatistics = portStatistics; diff --git a/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/AllTableStatistics.java b/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/AllTableStatistics.java index 5b998ee21a..4a10eb4fa2 100644 --- a/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/AllTableStatistics.java +++ b/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/AllTableStatistics.java @@ -14,14 +14,14 @@ import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; -@XmlRootElement +@XmlRootElement(name = "list") @XmlAccessorType(XmlAccessType.NONE) public class AllTableStatistics { @XmlElement List tableStatistics; //To satisfy JAXB - private AllTableStatistics() { - } + @SuppressWarnings("unused") + private AllTableStatistics() {} public AllTableStatistics(List tableStatistics) { this.tableStatistics = tableStatistics; diff --git a/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/FlowStatistics.java b/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/FlowStatistics.java index 25b671c1a8..9b31b913fe 100644 --- a/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/FlowStatistics.java +++ b/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/FlowStatistics.java @@ -14,26 +14,27 @@ import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; + import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.reader.FlowOnNode; -@XmlRootElement +@XmlRootElement(name = "nodeFlowStatistics") @XmlAccessorType(XmlAccessType.NONE) public class FlowStatistics { @XmlElement private Node node; - @XmlElement(name="flowStat") - private List flowStat; + @XmlElement + private List flowStatistic; // To satisfy JAXB @SuppressWarnings("unused") - private FlowStatistics() { + private FlowStatistics() { } public FlowStatistics(Node node, List flowStat) { super(); this.node = node; - this.flowStat = flowStat; + this.flowStatistic = flowStat; } public Node getNode() { @@ -45,10 +46,10 @@ public class FlowStatistics { } public List getFlowStats() { - return flowStat; + return flowStatistic; } public void setFlowStats(List flowStats) { - this.flowStat = flowStats; + this.flowStatistic = flowStats; } } diff --git a/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/PortStatistics.java b/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/PortStatistics.java index 876bb7f7b0..e519472d40 100644 --- a/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/PortStatistics.java +++ b/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/PortStatistics.java @@ -18,13 +18,13 @@ import javax.xml.bind.annotation.XmlRootElement; import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.reader.NodeConnectorStatistics; -@XmlRootElement +@XmlRootElement(name = "nodePortStatistics") @XmlAccessorType(XmlAccessType.NONE) public class PortStatistics { @XmlElement private Node node; - @XmlElement(name="portStat") - private List portStats; + @XmlElement + private List portStatistic; // To satisfy JAXB @SuppressWarnings("unused") @@ -34,7 +34,7 @@ public class PortStatistics { public PortStatistics(Node node, List portStats) { super(); this.node = node; - this.portStats = portStats; + this.portStatistic = portStats; } public Node getNode() { @@ -46,11 +46,11 @@ public class PortStatistics { } public List getPortStats() { - return portStats; + return portStatistic; } public void setFlowStats(List portStats) { - this.portStats = portStats; + this.portStatistic = portStats; } } 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 197ebabf91..1c3fd1cf2e 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 @@ -23,9 +23,12 @@ 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.*; +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; @@ -39,7 +42,7 @@ import org.opendaylight.controller.switchmanager.ISwitchManager; /** * Northbound APIs that returns various Statistics exposed by the Southbound - * plugins such as Openflow. + * protocol plugins such as Openflow. * *
*
@@ -107,9 +110,114 @@ public class StatisticsNorthbound { * Name of the Container. The Container name for the base * controller is "default". * @return List of FlowStatistics from all the Nodes + * + *
+     * Example:
+     * Request URL: localhost:8080/controller/nb/v2/statistics/default/flow
+     *
+     * Response in JSON:
+     * {
+     *     "flowStatistics": [
+     *         {
+     *             "node": {
+     *                 "@type": "OF",
+     *                 "@id": "00:00:00:00:00:00:00:02"
+     *             },
+     *             "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": {
+     *                                 "@type": "OF",
+     *                                 "@id": "3",
+     *                                 "node": {
+     *                                     "@type": "OF",
+     *                                     "@id": "00:00:00:00:00:00:00:02"
+     *                                 }
+     *                             }
+     *                         },
+     *                         "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 type="OF" id="00:00:00:00:00:00:00:02"/>
+     *         <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 type="OF" id="3">
+     *                         <node type="OF" id="00:00:00:00:00:00:00:02"/>
+     *                     </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 }) @TypeHint(AllFlowStatistics.class) @@ -159,12 +267,138 @@ public class StatisticsNorthbound { * Name of the Container. The Container name for the base * controller is "default". * @param nodeType - * Node Type as specifid by Node class + * 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. + * @return List of Flow Statistics for a given Node. * + * + *
+     * Example:
+     * Request URL:
+     * http://host:8080/controller/nb/v2/statistics/default/flow/node/OF/00:00:00:00:00:00:00:01
+     *
+     * Response in JSON:
+     * {
+     *     "node": {
+     *         "@type": "OF",
+     *         "@id": "00:00:00:00:00:00:00:01"
+     *     },
+     *     "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": {
+     *                             "@type": "OF",
+     *                             "@id": "5",
+     *                             "node": {
+     *                                 "@type": "OF",
+     *                                 "@id": "00:00:00:00:00:00:00:01"
+     *                             }
+     *                         }
+     *                     }
+     *                 ],
+     *                 "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 type="OF" id="00:00:00:00:00:00:00:02"/>
+     *         <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 type="OF" id="3">
+     *                         <node type="OF" id="00:00:00:00:00:00:00:02"/>
+     *                     </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 type="OF" id="3">
+     *                         <node type="OF" id="00:00:00:00:00:00:00:02"/>
+     *                     </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 }) @TypeHint(FlowStatistics.class) @@ -210,9 +444,128 @@ public class StatisticsNorthbound { * controller is "default". * @return List of all the Port Statistics across all the NodeConnectors on * all the Nodes. + * + *
+     * Example:
+     *
+     * Requset URL: http://host:8080/controller/nb/v2/statistics/default/port
+     *
+     * Response in JSON:
+     * {
+     *     "portStatistics": [
+     *         {
+     *             "node": {
+     *                 "@type": "OF",
+     *                 "@id": "00:00:00:00:00:00:00:02"
+     *             },
+     *             "portStatistic": [
+     *                 {
+     *                     "nodeConnector": {
+     *                         "@type": "OF",
+     *                         "@id": "3",
+     *                         "node": {
+     *                             "@type": "OF",
+     *                             "@id": "00:00:00:00:00:00:00:02"
+     *                         }
+     *                     },
+     *                     "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": {
+     *                         "@type": "OF",
+     *                         "@id": "2",
+     *                         "node": {
+     *                             "@type": "OF",
+     *                             "@id": "00:00:00:00:00:00:00:02"
+     *                         }
+     *                     },
+     *                     "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": {
+     *                 "@type": "OF",
+     *                 "@id": "00:00:00:00:00:00:00:03"
+     *             },
+     *             "portStatistic": [
+     *                  ..................
+     *                  .......................
+     *                  ..........................
+     *             ]
+     *         }
+     *     ]
+     * }
+     *
+     * Response in XML:
+     * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+     * <list>
+     *     <portStatistics>
+     *         <node type="OF" id="00:00:00:00:00:00:00:02"/>
+     *         <portStatistic>
+     *             <nodeConnector type="OF" id="3">
+     *                 <node type="OF" id="00:00:00:00:00:00:00:02"/>
+     *             </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 type="OF" id="2">
+     *                 <node type="OF" id="00:00:00:00:00:00:00:02"/>
+     *             </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 }) @TypeHint(AllPortStatistics.class) @@ -260,13 +613,114 @@ public class StatisticsNorthbound { * Name of the Container. The Container name for the base * controller is "default". * @param nodeType - * Node Type as specifid by Node class + * Node Type as specifid in {@link org.opendaylight.controller.sal.core.Node} class * @param Node - * Identifier + * Identifier (e.g. MAC address) * @return Returns a list of all the Port Statistics across all the * NodeConnectors in a given Node. + * + *
+     * Example:
+     *
+     * Request URL:
+     * http://host:8080/controller/nb/v2/statistics/default/port/node/OF/00:00:00:00:00:00:00:01
+     *
+     * Response in JSON:
+     * {
+     *     "node": {
+     *         "@type": "OF",
+     *         "@id": "00:00:00:00:00:00:00:01"
+     *     },
+     *     "portStatistic": [
+     *         {
+     *             "nodeConnector": {
+     *                 "@type": "OF",
+     *                 "@id": "3",
+     *                 "node": {
+     *                     "@type": "OF",
+     *                     "@id": "00:00:00:00:00:00:00:01"
+     *                 }
+     *             },
+     *             "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": {
+     *                 "@type": "OF",
+     *                 "@id": "2",
+     *                 "node": {
+     *                     "@type": "OF",
+     *                     "@id": "00:00:00:00:00:00:00:01"
+     *                 }
+     *             },
+     *             "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 type="OF" id="00:00:00:00:00:00:00:01"/>
+     *     <portStatistic>
+     *         <nodeConnector type="OF" id="2">
+     *             <node type="OF" id="00:00:00:00:00:00:00:01"/>
+     *         </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 type="OF" id="5">
+     *             <node type="OF" id="00:00:00:00:00:00:00:01"/>
+     *         </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 }) @TypeHint(PortStatistics.class) @@ -313,11 +767,91 @@ public class StatisticsNorthbound { * controller is "default". * * @return Returns a list of all the Table Statistics in a given Node. + * + *
+     *
+     *  Example:
+     *
+     *  Request URL:
+     *  http://host:8080/controller/nb/v2/statistics/default/table
+     *
+     *  Response in JSON:
+     *
+     * {
+     *     "tableStatistics": [
+     *         {
+     *             "node": {
+     *                 "@type": "OF",
+     *                 "@id": "00:00:00:00:00:00:00:02"
+     *             },
+     *             "tableStatistic": [
+     *                 {
+     *                     "nodeTable": {
+     *                         "@id": "0",
+     *                         "node": {
+     *                             "@type": "OF",
+     *                             "@id": "00:00:00:00:00:00:00:02"
+     *                         }
+     *                     },
+     *                     "activeCount": "11",
+     *                     "lookupCount": "816",
+     *                     "matchedCount": "220"
+     *                 },
+     *                 {
+     *                     ...another table
+     *                     .....
+     *                     ........
+     *                 }
+     *
+     *             ]
+     *         }
+     *     ]
+     * }
+     *
+     *
+     *  Response in XML:
+     *  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+     *  <list>
+     *  <tableStatistics>
+     *      <node type="OF" id="00:00:00:00:00:00:00:01"/>
+     *      <tableStatistic>
+     *          <nodeTable id="0">
+     *              <node type="OF" id="00:00:00:00:00:00:00:01"/>
+     *          </nodeTable>
+     *          <activeCount>12</activeCount>
+     *          <lookupCount>10935</lookupCount>
+     *          <matchedCount>10084</matchedCount>
+     *      </tableStatistic>
+     *      <tableStatistic>
+     *          <nodeTable id="1">
+     *              <node type="OF" id="00:00:00:00:00:00:00:01"/>
+     *          </nodeTable>
+     *          <activeCount>0</activeCount>
+     *          <lookupCount>0</lookupCount>
+     *          <matchedCount>0</matchedCount>
+     *      </tableStatistic>
+     *      <tableStatistic>
+     *          <nodeTable id="2">
+     *              <node type="OF" id="00:00:00:00:00:00:00:01"/>
+     *          </nodeTable>
+     *          <activeCount>0</activeCount>
+     *          <lookupCount>0</lookupCount>
+     *          <matchedCount>0</matchedCount>
+     *      </tableStatistic>
+     *  </tableStatistics>
+     *  <tableStatistics>
+     *  ...
+     *  ......
+     *  ........
+     *  </tableStatistics>
+     *  </list>
+     *
+     * 
*/ - @Path("/{containerName}/tablestats") + @Path("/{containerName}/table") @GET @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) - @TypeHint(TableStatistics.class) + @TypeHint(AllTableStatistics.class) @StatusCodes({ @ResponseCode(code = 200, condition = "Operation successful"), @ResponseCode(code = 404, condition = "The containerName is not found"), @@ -325,17 +859,15 @@ public class StatisticsNorthbound { 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); + 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 " + throw new ServiceUnavailableException("Statistics manager" + RestMessages.SERVICEUNAVAILABLE.toString()); } @@ -357,18 +889,92 @@ public class StatisticsNorthbound { } /** - * Returns a list of all the Table Statistics on all Nodes. + * Returns a list of all the Table Statistics on a specific 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 + * Node Type as specified in {@link org.opendaylight.controller.sal.core.Node} class (e.g. OF for Openflow) * @param Node - * Identifier + * Identifier (e.g. MAC address) * @return Returns a list of all the Table Statistics in a given Node. + * + *
+     *
+     * Example:
+     *
+     * Request URL:
+     * http://host:8080/controller/nb/v2/statistics/default/table/node/OF/00:00:00:00:00:00:00:01
+     *
+     * Response in JSON:
+     * {
+     *     "node": {
+     *         "@type": "OF",
+     *         "@id": "00:00:00:00:00:00:00:01"
+     *     },
+     *     "tableStatistic": [
+     *         {
+     *             "nodeTable": {
+     *                 "@id": "0",
+     *                 "node": {
+     *                     "@type": "OF",
+     *                     "@id": "00:00:00:00:00:00:00:01"
+     *                 }
+     *             },
+     *             "activeCount": "12",
+     *             "lookupCount": "11382",
+     *             "matchedCount": "10524"
+     *         },
+     *         {
+     *             "nodeTable": {
+     *                 "@id": "1",
+     *                 "node": {
+     *                     "@type": "OF",
+     *                     "@id": "00:00:00:00:00:00:00:01"
+     *                 }
+     *             },
+     *             "activeCount": "0",
+     *             "lookupCount": "0",
+     *             "matchedCount": "0"
+     *         }
+     *    ]
+     * }
+     *
+     * Response in XML:
+     * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+     * <nodeTableStatistics>
+     *     <node type="OF" id="00:00:00:00:00:00:00:01"/>
+     *     <tableStatistic>
+     *         <nodeTable id="0">
+     *             <node type="OF" id="00:00:00:00:00:00:00:01"/>
+     *         </nodeTable>
+     *         <activeCount>12</activeCount>
+     *         <lookupCount>10935</lookupCount>
+     *         <matchedCount>10084</matchedCount>
+     *     </tableStatistic>
+     *     <tableStatistic>
+     *         <nodeTable id="1">
+     *             <node type="OF" id="00:00:00:00:00:00:00:01"/>
+     *         </nodeTable>
+     *         <activeCount>0</activeCount>
+     *         <lookupCount>0</lookupCount>
+     *         <matchedCount>0</matchedCount>
+     *     </tableStatistic>
+     *     <tableStatistic>
+     *         <nodeTable id="2">
+     *             <node type="OF" id="00:00:00:00:00:00:00:01"/>
+     *         </nodeTable>
+     *         <activeCount>0</activeCount>
+     *         <lookupCount>0</lookupCount>
+     *         <matchedCount>0</matchedCount>
+     *     </tableStatistic>
+     * </nodeTableStatistics>
+     *
+     *
+     * 
*/ - @Path("/{containerName}/tablestats/{nodeType}/{nodeId}") + @Path("/{containerName}/table/node/{nodeType}/{nodeId}") @GET @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @TypeHint(TableStatistics.class) diff --git a/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/TableStatistics.java b/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/TableStatistics.java index a1c20190e6..552e707dae 100644 --- a/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/TableStatistics.java +++ b/opendaylight/northbound/statistics/src/main/java/org/opendaylight/controller/statistics/northbound/TableStatistics.java @@ -5,7 +5,9 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ + package org.opendaylight.controller.statistics.northbound; + import java.util.List; import javax.xml.bind.annotation.XmlAccessType; @@ -16,13 +18,13 @@ import javax.xml.bind.annotation.XmlRootElement; import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.reader.NodeTableStatistics; -@XmlRootElement +@XmlRootElement(name = "nodeTableStatistics") @XmlAccessorType(XmlAccessType.NONE) public class TableStatistics { @XmlElement private Node node; - @XmlElement(name="tableStat") - private List tableStats; + @XmlElement + private List tableStatistic; // To satisfy JAXB @SuppressWarnings("unused") @@ -32,7 +34,7 @@ public class TableStatistics { public TableStatistics(Node node, List tableStats) { super(); this.node = node; - this.tableStats = tableStats; + this.tableStatistic = tableStats; } public Node getNode() { @@ -44,11 +46,11 @@ public class TableStatistics { } public List getTableStats() { - return tableStats; + return tableStatistic; } public void setTableStats(List tableStats) { - this.tableStats = tableStats; + this.tableStatistic = tableStats; } } diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/NodeTable.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/NodeTable.java index 22c379614d..68ff9b4f38 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/NodeTable.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/NodeTable.java @@ -118,6 +118,7 @@ public class NodeTable implements Serializable { /** * Private constructor used for JAXB mapping */ + @SuppressWarnings("unused") private NodeTable() { this.nodeTableIDString = null; this.nodeTableID = null; @@ -207,7 +208,7 @@ public class NodeTable implements Serializable { */ @XmlAttribute(name = "id") public String getNodeTableIDString() { - return this.nodeTableIDString.toString(); + return this.nodeTableIDString != null? this.nodeTableIDString : nodeTableID.toString(); } /** -- 2.36.6