diff --git a/core/common/src/main/java/org/onosproject/codec/impl/CodecManager.java b/core/common/src/main/java/org/onosproject/codec/impl/CodecManager.java index 3433b3b7d5..c7af4e5b22 100644 --- a/core/common/src/main/java/org/onosproject/codec/impl/CodecManager.java +++ b/core/common/src/main/java/org/onosproject/codec/impl/CodecManager.java @@ -38,6 +38,7 @@ import org.onosproject.net.driver.Driver; import org.onosproject.net.flow.FlowEntry; import org.onosproject.net.flow.FlowRule; import org.onosproject.net.flow.TableStatisticsEntry; +import org.onosproject.net.device.PortStatistics; import org.onosproject.net.flow.TrafficSelector; import org.onosproject.net.flow.TrafficTreatment; import org.onosproject.net.flow.criteria.Criterion; @@ -102,6 +103,7 @@ public class CodecManager implements CodecService { registerCodec(GroupBucket.class, new GroupBucketCodec()); registerCodec(Load.class, new LoadCodec()); registerCodec(TableStatisticsEntry.class, new TableStatisticsEntryCodec()); + registerCodec(PortStatistics.class, new PortStatisticsCodec()); log.info("Started"); } diff --git a/core/common/src/main/java/org/onosproject/codec/impl/FlowEntryCodec.java b/core/common/src/main/java/org/onosproject/codec/impl/FlowEntryCodec.java index 923bdf2bfa..3f581bedc1 100644 --- a/core/common/src/main/java/org/onosproject/codec/impl/FlowEntryCodec.java +++ b/core/common/src/main/java/org/onosproject/codec/impl/FlowEntryCodec.java @@ -39,6 +39,7 @@ public final class FlowEntryCodec extends JsonCodec { final ObjectNode result = context.mapper().createObjectNode() .put("id", Long.toString(flowEntry.id().value())) + .put("tableId", flowEntry.tableId()) .put("appId", service.getAppId(flowEntry.appId()).name()) .put("groupId", flowEntry.groupId().id()) .put("priority", flowEntry.priority()) diff --git a/core/common/src/main/java/org/onosproject/codec/impl/PortStatisticsCodec.java b/core/common/src/main/java/org/onosproject/codec/impl/PortStatisticsCodec.java new file mode 100644 index 0000000000..e8b3c4c664 --- /dev/null +++ b/core/common/src/main/java/org/onosproject/codec/impl/PortStatisticsCodec.java @@ -0,0 +1,51 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.codec.impl; + +import org.onosproject.codec.CodecContext; +import org.onosproject.codec.JsonCodec; +import org.onosproject.net.device.PortStatistics; + +import com.fasterxml.jackson.databind.node.ObjectNode; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Port statistics entry JSON codec. + */ +public final class PortStatisticsCodec extends JsonCodec { + + @Override + public ObjectNode encode(PortStatistics entry, CodecContext context) { + checkNotNull(entry, "Port Statistics cannot be null"); + + final ObjectNode result = context.mapper().createObjectNode() + .put("port", entry.port()) + .put("packetsReceived", entry.packetsReceived()) + .put("packetsSent", entry.packetsSent()) + .put("bytesReceived", entry.bytesReceived()) + .put("bytesSent", entry.bytesSent()) + .put("packetsRxDropped", entry.packetsRxDropped()) + .put("packetsTxDropped", entry.packetsTxDropped()) + .put("packetsRxErrors", entry.packetsRxErrors()) + .put("packetsTxErrors", entry.packetsTxErrors()) + .put("durationSec", entry.durationSec()); + + return result; + } + +} + diff --git a/web/api/src/main/java/org/onosproject/rest/resources/StatisticsWebResource.java b/web/api/src/main/java/org/onosproject/rest/resources/StatisticsWebResource.java index 7a452044ad..284d377570 100644 --- a/web/api/src/main/java/org/onosproject/rest/resources/StatisticsWebResource.java +++ b/web/api/src/main/java/org/onosproject/rest/resources/StatisticsWebResource.java @@ -36,6 +36,7 @@ import org.onosproject.net.Device; import org.onosproject.net.DeviceId; import org.onosproject.net.Link; import org.onosproject.net.device.DeviceService; +import org.onosproject.net.device.PortStatistics; import org.onosproject.net.flow.FlowRuleService; import org.onosproject.net.flow.TableStatisticsEntry; import org.onosproject.net.link.LinkService; @@ -153,4 +154,62 @@ public class StatisticsWebResource extends AbstractWebResource { rootArrayNode.add(deviceStatsNode); return ok(root).build(); } + + /** + * Get port statistics of all devices. + * @rsModel StatisticsPorts + * @return JSON encoded array of port statistics + */ + @GET + @Path("ports") + @Produces(MediaType.APPLICATION_JSON) + public Response getPortStatistics() { + final DeviceService service = get(DeviceService.class); + final Iterable devices = service.getDevices(); + final ObjectNode root = mapper().createObjectNode(); + final ArrayNode rootArrayNode = root.putArray("statistics"); + for (final Device device : devices) { + final ObjectNode deviceStatsNode = mapper().createObjectNode(); + deviceStatsNode.put("device", device.id().toString()); + final ArrayNode statisticsNode = deviceStatsNode.putArray("ports"); + final Iterable portStatsEntries = service.getPortStatistics(device.id()); + if (portStatsEntries != null) { + for (final PortStatistics entry : portStatsEntries) { + statisticsNode.add(codec(PortStatistics.class).encode(entry, this)); + } + } + rootArrayNode.add(deviceStatsNode); + } + + return ok(root).build(); + } + + /** + * Get port statistics of a specified devices. + * @rsModel StatisticsPorts + * @param deviceId device ID + * @return JSON encoded array of port statistics + */ + @GET + @Path("ports/{deviceId}") + @Produces(MediaType.APPLICATION_JSON) + public Response getPortStatisticsByDeviceId(@PathParam("deviceId") String deviceId) { + final DeviceService service = get(DeviceService.class); + final Iterable portStatsEntries = + service.getPortStatistics(DeviceId.deviceId(deviceId)); + final ObjectNode root = mapper().createObjectNode(); + final ArrayNode rootArrayNode = root.putArray("statistics"); + final ObjectNode deviceStatsNode = mapper().createObjectNode(); + deviceStatsNode.put("device", deviceId); + final ArrayNode statisticsNode = deviceStatsNode.putArray("ports"); + if (portStatsEntries != null) { + for (final PortStatistics entry : portStatsEntries) { + statisticsNode.add(codec(PortStatistics.class).encode(entry, this)); + } + } + rootArrayNode.add(deviceStatsNode); + + return ok(root).build(); + } + } diff --git a/web/api/src/main/resources/definitions/Flows.json b/web/api/src/main/resources/definitions/Flows.json index 8879629a47..ed0767c90f 100644 --- a/web/api/src/main/resources/definitions/Flows.json +++ b/web/api/src/main/resources/definitions/Flows.json @@ -16,6 +16,7 @@ "title": "flow", "required": [ "id", + "tableId", "appId", "groupId", "priority", @@ -33,6 +34,11 @@ "type": "string", "example": "12103425214920339" }, + "tableId": { + "type": "integer", + "format": "int64", + "example": 3 + }, "appId": { "type": "string", "example": "org.onosproject.core" diff --git a/web/api/src/main/resources/definitions/StatisticsPorts.json b/web/api/src/main/resources/definitions/StatisticsPorts.json new file mode 100644 index 0000000000..e3ed71f168 --- /dev/null +++ b/web/api/src/main/resources/definitions/StatisticsPorts.json @@ -0,0 +1,107 @@ +{ + "type": "object", + "title": "all-port-statistics", + "required": [ + "statistics" + ], + "properties": { + "statistics": { + "type": "array", + "required": [ + "statistics" + ], + "xml": { + "name": "statistics", + "wrapped": true + }, + "items": { + "type": "object", + "title": "statistics", + "required": [ + "ports" + ], + "properties": { + "deviceId": { + "type": "string", + "example": "of:0000000000000001" + }, + "ports": { + "type": "array", + "xml": { + "name": "ports", + "wrapped": true + }, + "items": { + "type": "object", + "title": "ports", + "required": [ + "port", + "packetsReceived", + "packetsSent", + "bytesReceived", + "bytesSent", + "packetsRxDropped", + "packetsTxDropped", + "packetsRxErrors", + "packetsTxErrors", + "durationSec" + ], + "properties": { + "port": { + "type": "integer", + "format": "int64", + "example": 1 + }, + "packetsReceived": { + "type": "integer", + "format": "int64", + "example": 98 + }, + "packetsSent": { + "type": "integer", + "format": "int64", + "example": 98 + }, + "bytesReceived": { + "type": "integer", + "format": "int64", + "example": 9162 + }, + "bytesSent": { + "type": "integer", + "format": "int64", + "example": 9162 + }, + "packetsRxDropped": { + "type": "integer", + "format": "int64", + "example": 0 + }, + "packetsTxDropped": { + "type": "integer", + "format": "int64", + "example": 0 + }, + "packetsRxErrors": { + "type": "integer", + "format": "int64", + "example": 0 + }, + "packetsTxErrors": { + "type": "integer", + "format": "int64", + "example": 0 + }, + "durationSec": { + "type": "integer", + "format": "int64", + "example": 90 + } + } + } + } + } + } + } + } +} \ No newline at end of file