blob: c38d5f8aadea20389497c8b80fcedb9183d0a385 [file] [log] [blame]
Ray Milkeyb9af9462015-07-17 11:12:09 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Ray Milkeyb9af9462015-07-17 11:12:09 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.rest.resources;
17
18import java.util.Spliterator;
19import java.util.Spliterators;
20import java.util.stream.StreamSupport;
21
22import javax.ws.rs.GET;
23import javax.ws.rs.Path;
Srikanth Vavilapalli95810f52015-09-14 15:49:56 -070024import javax.ws.rs.PathParam;
Ray Milkeyb9af9462015-07-17 11:12:09 -070025import javax.ws.rs.Produces;
26import javax.ws.rs.QueryParam;
27import javax.ws.rs.core.Context;
28import javax.ws.rs.core.MediaType;
29import javax.ws.rs.core.Response;
30import javax.ws.rs.core.UriBuilder;
31import javax.ws.rs.core.UriInfo;
32
33import org.onosproject.codec.JsonCodec;
34import org.onosproject.net.ConnectPoint;
Srikanth Vavilapalli95810f52015-09-14 15:49:56 -070035import org.onosproject.net.Device;
36import org.onosproject.net.DeviceId;
Ray Milkeyb9af9462015-07-17 11:12:09 -070037import org.onosproject.net.Link;
Viswanath KSP8ffb7752016-08-23 22:19:06 +053038import org.onosproject.net.PortNumber;
Srikanth Vavilapalli95810f52015-09-14 15:49:56 -070039import org.onosproject.net.device.DeviceService;
Srikanth Vavilapallid120f5c2015-11-24 14:15:01 -080040import org.onosproject.net.device.PortStatistics;
Jordan Haltermanb81fdc12019-03-04 18:12:20 -080041import org.onosproject.net.flow.FlowEntry;
Srikanth Vavilapalli95810f52015-09-14 15:49:56 -070042import org.onosproject.net.flow.FlowRuleService;
43import org.onosproject.net.flow.TableStatisticsEntry;
Ray Milkeyb9af9462015-07-17 11:12:09 -070044import org.onosproject.net.link.LinkService;
45import org.onosproject.net.statistic.Load;
46import org.onosproject.net.statistic.StatisticService;
47import org.onosproject.rest.AbstractWebResource;
48
49import com.fasterxml.jackson.databind.node.ArrayNode;
50import com.fasterxml.jackson.databind.node.ObjectNode;
51
52import static org.onosproject.net.DeviceId.deviceId;
53import static org.onosproject.net.PortNumber.portNumber;
54
55/**
Laszlo Pappb2a91f22018-01-10 16:41:22 +000056 * Query statistics.
Ray Milkeyb9af9462015-07-17 11:12:09 -070057 */
58@Path("statistics")
59public class StatisticsWebResource extends AbstractWebResource {
60 @Context
Jian Licc730a62016-05-10 16:36:16 -070061 private UriInfo uriInfo;
Ray Milkeyb9af9462015-07-17 11:12:09 -070062
63 /**
Jian Licc730a62016-05-10 16:36:16 -070064 * Gets load statistics for all links or for a specific link.
65 *
Andrea Campanella10c4adc2015-12-03 15:27:54 -080066 * @onos.rsModel StatisticsFlowsLink
Ray Milkeyb9af9462015-07-17 11:12:09 -070067 * @param deviceId (optional) device ID for a specific link
68 * @param port (optional) port number for a specified link
Jian Licc730a62016-05-10 16:36:16 -070069 * @return 200 OK with JSON encoded array of Load objects
Ray Milkeyb9af9462015-07-17 11:12:09 -070070 */
71 @GET
72 @Path("flows/link")
73 @Produces(MediaType.APPLICATION_JSON)
74 public Response getLoads(@QueryParam("device") String deviceId,
75 @QueryParam("port") String port) {
76 Iterable<Link> links;
77
78 if (deviceId == null || port == null) {
79 links = get(LinkService.class).getLinks();
80 } else {
81 ConnectPoint connectPoint = new ConnectPoint(deviceId(deviceId),
82 portNumber(port));
83 links = get(LinkService.class).getLinks(connectPoint);
84 }
85 ObjectNode result = mapper().createObjectNode();
86 ArrayNode loads = mapper().createArrayNode();
87 JsonCodec<Load> loadCodec = codec(Load.class);
88 StatisticService statsService = getService(StatisticService.class);
89
Ray Milkeyb9af9462015-07-17 11:12:09 -070090 StreamSupport.stream(Spliterators.spliteratorUnknownSize(
91 links.iterator(), Spliterator.ORDERED), false)
92 .forEach(link -> {
93 ObjectNode loadNode = loadCodec.encode(statsService.load(link), this);
94
95 UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
96 .path("links")
97 .queryParam("device", link.src().deviceId().toString())
98 .queryParam("port", link.src().port().toString());
99 loadNode.put("link", locationBuilder.build().toString());
100 loads.add(loadNode);
101 });
102 result.set("loads", loads);
103 return ok(result).build();
104 }
Srikanth Vavilapalli95810f52015-09-14 15:49:56 -0700105
106 /**
Jian Licc730a62016-05-10 16:36:16 -0700107 * Gets table statistics for all tables of all devices.
108 *
Andrea Campanella10c4adc2015-12-03 15:27:54 -0800109 * @onos.rsModel StatisticsFlowsTables
Jian Licc730a62016-05-10 16:36:16 -0700110 * @return 200 OK with JSON encoded array of table statistics
Srikanth Vavilapalli95810f52015-09-14 15:49:56 -0700111 */
112 @GET
113 @Path("flows/tables")
114 @Produces(MediaType.APPLICATION_JSON)
115 public Response getTableStatistics() {
116 final FlowRuleService service = get(FlowRuleService.class);
117 final Iterable<Device> devices = get(DeviceService.class).getDevices();
118 final ObjectNode root = mapper().createObjectNode();
andrea1ce2bc82015-11-18 16:58:10 -0800119 final ArrayNode rootArrayNode = root.putArray("statistics");
Srikanth Vavilapalli95810f52015-09-14 15:49:56 -0700120 for (final Device device : devices) {
121 final ObjectNode deviceStatsNode = mapper().createObjectNode();
122 deviceStatsNode.put("device", device.id().toString());
andrea1ce2bc82015-11-18 16:58:10 -0800123 final ArrayNode statisticsNode = deviceStatsNode.putArray("table");
Srikanth Vavilapalli95810f52015-09-14 15:49:56 -0700124 final Iterable<TableStatisticsEntry> tableStatsEntries = service.getFlowTableStatistics(device.id());
125 if (tableStatsEntries != null) {
126 for (final TableStatisticsEntry entry : tableStatsEntries) {
127 statisticsNode.add(codec(TableStatisticsEntry.class).encode(entry, this));
128 }
129 }
130 rootArrayNode.add(deviceStatsNode);
131 }
132
133 return ok(root).build();
134 }
135
136 /**
Jian Licc730a62016-05-10 16:36:16 -0700137 * Gets table statistics for all tables of a specified device.
138 *
Andrea Campanella10c4adc2015-12-03 15:27:54 -0800139 * @onos.rsModel StatisticsFlowsTables
Srikanth Vavilapalli95810f52015-09-14 15:49:56 -0700140 * @param deviceId device ID
Jian Licc730a62016-05-10 16:36:16 -0700141 * @return 200 OK with JSON encoded array of table statistics
Srikanth Vavilapalli95810f52015-09-14 15:49:56 -0700142 */
143 @GET
144 @Path("flows/tables/{deviceId}")
145 @Produces(MediaType.APPLICATION_JSON)
146 public Response getTableStatisticsByDeviceId(@PathParam("deviceId") String deviceId) {
147 final FlowRuleService service = get(FlowRuleService.class);
148 final Iterable<TableStatisticsEntry> tableStatisticsEntries =
149 service.getFlowTableStatistics(DeviceId.deviceId(deviceId));
150 final ObjectNode root = mapper().createObjectNode();
andrea1ce2bc82015-11-18 16:58:10 -0800151 final ArrayNode rootArrayNode = root.putArray("statistics");
Srikanth Vavilapalli95810f52015-09-14 15:49:56 -0700152
153 final ObjectNode deviceStatsNode = mapper().createObjectNode();
154 deviceStatsNode.put("device", deviceId);
andrea1ce2bc82015-11-18 16:58:10 -0800155 final ArrayNode statisticsNode = deviceStatsNode.putArray("table");
Srikanth Vavilapalli95810f52015-09-14 15:49:56 -0700156 for (final TableStatisticsEntry entry : tableStatisticsEntries) {
157 statisticsNode.add(codec(TableStatisticsEntry.class).encode(entry, this));
158 }
159 rootArrayNode.add(deviceStatsNode);
160 return ok(root).build();
161 }
Srikanth Vavilapallid120f5c2015-11-24 14:15:01 -0800162
163 /**
Jian Licc730a62016-05-10 16:36:16 -0700164 * Gets port statistics of all devices.
Andrea Campanella10c4adc2015-12-03 15:27:54 -0800165 * @onos.rsModel StatisticsPorts
Jian Licc730a62016-05-10 16:36:16 -0700166 * @return 200 OK with JSON encoded array of port statistics
Srikanth Vavilapallid120f5c2015-11-24 14:15:01 -0800167 */
168 @GET
169 @Path("ports")
170 @Produces(MediaType.APPLICATION_JSON)
171 public Response getPortStatistics() {
172 final DeviceService service = get(DeviceService.class);
173 final Iterable<Device> devices = service.getDevices();
174 final ObjectNode root = mapper().createObjectNode();
175 final ArrayNode rootArrayNode = root.putArray("statistics");
176 for (final Device device : devices) {
177 final ObjectNode deviceStatsNode = mapper().createObjectNode();
178 deviceStatsNode.put("device", device.id().toString());
179 final ArrayNode statisticsNode = deviceStatsNode.putArray("ports");
180 final Iterable<PortStatistics> portStatsEntries = service.getPortStatistics(device.id());
181 if (portStatsEntries != null) {
182 for (final PortStatistics entry : portStatsEntries) {
183 statisticsNode.add(codec(PortStatistics.class).encode(entry, this));
184 }
185 }
186 rootArrayNode.add(deviceStatsNode);
187 }
188
189 return ok(root).build();
190 }
191
192 /**
Jian Licc730a62016-05-10 16:36:16 -0700193 * Gets port statistics of a specified devices.
Andrea Campanella10c4adc2015-12-03 15:27:54 -0800194 * @onos.rsModel StatisticsPorts
Srikanth Vavilapallid120f5c2015-11-24 14:15:01 -0800195 * @param deviceId device ID
Jian Licc730a62016-05-10 16:36:16 -0700196 * @return 200 OK with JSON encoded array of port statistics
Srikanth Vavilapallid120f5c2015-11-24 14:15:01 -0800197 */
198 @GET
199 @Path("ports/{deviceId}")
200 @Produces(MediaType.APPLICATION_JSON)
201 public Response getPortStatisticsByDeviceId(@PathParam("deviceId") String deviceId) {
202 final DeviceService service = get(DeviceService.class);
203 final Iterable<PortStatistics> portStatsEntries =
204 service.getPortStatistics(DeviceId.deviceId(deviceId));
205 final ObjectNode root = mapper().createObjectNode();
206 final ArrayNode rootArrayNode = root.putArray("statistics");
207 final ObjectNode deviceStatsNode = mapper().createObjectNode();
208 deviceStatsNode.put("device", deviceId);
209 final ArrayNode statisticsNode = deviceStatsNode.putArray("ports");
210 if (portStatsEntries != null) {
211 for (final PortStatistics entry : portStatsEntries) {
212 statisticsNode.add(codec(PortStatistics.class).encode(entry, this));
213 }
214 }
215 rootArrayNode.add(deviceStatsNode);
216
217 return ok(root).build();
218 }
219
Viswanath KSP8ffb7752016-08-23 22:19:06 +0530220 /**
221 * Gets port statistics of a specified device and port.
222 * @onos.rsModel StatisticsPorts
223 * @param deviceId device ID
224 * @param port port
225 * @return 200 OK with JSON encoded array of port statistics for the specified port
226 */
227 @GET
228 @Path("ports/{deviceId}/{port}")
229 @Produces(MediaType.APPLICATION_JSON)
230 public Response getPortStatisticsByDeviceIdAndPort(@PathParam("deviceId") String deviceId,
231 @PathParam("port") String port) {
232 final DeviceService service = get(DeviceService.class);
233 final PortNumber portNumber = portNumber(port);
234 final PortStatistics portStatsEntry =
235 service.getStatisticsForPort(DeviceId.deviceId(deviceId), portNumber);
236 final ObjectNode root = mapper().createObjectNode();
237 final ArrayNode rootArrayNode = root.putArray("statistics");
238 final ObjectNode deviceStatsNode = mapper().createObjectNode();
239 deviceStatsNode.put("device", deviceId);
240 final ArrayNode statisticsNode = deviceStatsNode.putArray("ports");
241 if (portStatsEntry != null) {
242 statisticsNode.add(codec(PortStatistics.class).encode(portStatsEntry, this));
243 }
244 rootArrayNode.add(deviceStatsNode);
245
246 return ok(root).build();
247 }
248
Viswanath KSP13e5b512016-08-25 12:33:16 +0530249 /**
250 * Gets port delta statistics of all devices.
251 * @onos.rsModel StatisticsPorts
252 * @return 200 OK with JSON encoded array of port delta statistics
253 */
254 @GET
255 @Path("delta/ports")
256 @Produces(MediaType.APPLICATION_JSON)
257 public Response getPortDeltaStatistics() {
258 final DeviceService service = get(DeviceService.class);
259 final Iterable<Device> devices = service.getDevices();
260 final ObjectNode root = mapper().createObjectNode();
261 final ArrayNode rootArrayNode = root.putArray("statistics");
262 for (final Device device : devices) {
263 final ObjectNode deviceStatsNode = mapper().createObjectNode();
264 deviceStatsNode.put("device", device.id().toString());
265 final ArrayNode statisticsNode = deviceStatsNode.putArray("ports");
266 final Iterable<PortStatistics> portStatsEntries = service.getPortDeltaStatistics(device.id());
267 if (portStatsEntries != null) {
268 for (final PortStatistics entry : portStatsEntries) {
269 statisticsNode.add(codec(PortStatistics.class).encode(entry, this));
270 }
271 }
272 rootArrayNode.add(deviceStatsNode);
273 }
274
275 return ok(root).build();
276 }
277
278 /**
279 * Gets port delta statistics of a specified devices.
280 * @onos.rsModel StatisticsPorts
281 * @param deviceId device ID
282 * @return 200 OK with JSON encoded array of port delta statistics
283 */
284 @GET
285 @Path("delta/ports/{deviceId}")
286 @Produces(MediaType.APPLICATION_JSON)
287 public Response getPortDeltaStatisticsByDeviceId(@PathParam("deviceId") String deviceId) {
288 final DeviceService service = get(DeviceService.class);
289 final Iterable<PortStatistics> portStatsEntries =
290 service.getPortDeltaStatistics(DeviceId.deviceId(deviceId));
291 final ObjectNode root = mapper().createObjectNode();
292 final ArrayNode rootArrayNode = root.putArray("statistics");
293 final ObjectNode deviceStatsNode = mapper().createObjectNode();
294 deviceStatsNode.put("device", deviceId);
295 final ArrayNode statisticsNode = deviceStatsNode.putArray("ports");
296 if (portStatsEntries != null) {
297 for (final PortStatistics entry : portStatsEntries) {
298 statisticsNode.add(codec(PortStatistics.class).encode(entry, this));
299 }
300 }
301 rootArrayNode.add(deviceStatsNode);
302
303 return ok(root).build();
304 }
305
306 /**
307 * Gets port delta statistics of a specified device and port.
308 * @onos.rsModel StatisticsPorts
309 * @param deviceId device ID
310 * @param port port
311 * @return 200 OK with JSON encoded array of port delta statistics for the specified port
312 */
313 @GET
314 @Path("delta/ports/{deviceId}/{port}")
315 @Produces(MediaType.APPLICATION_JSON)
316 public Response getPortDeltaStatisticsByDeviceIdAndPort(@PathParam("deviceId") String deviceId,
317 @PathParam("port") String port) {
318 final DeviceService service = get(DeviceService.class);
319 final PortNumber portNumber = portNumber(port);
320 final PortStatistics portStatsEntry =
321 service.getDeltaStatisticsForPort(DeviceId.deviceId(deviceId), portNumber);
322 final ObjectNode root = mapper().createObjectNode();
323 final ArrayNode rootArrayNode = root.putArray("statistics");
324 final ObjectNode deviceStatsNode = mapper().createObjectNode();
325 deviceStatsNode.put("device", deviceId);
326 final ArrayNode statisticsNode = deviceStatsNode.putArray("ports");
327 if (portStatsEntry != null) {
328 statisticsNode.add(codec(PortStatistics.class).encode(portStatsEntry, this));
329 }
330 rootArrayNode.add(deviceStatsNode);
331
332 return ok(root).build();
333 }
334
Patryk Konopka7e40c012017-06-06 13:38:06 +0200335 /**
336 * Gets sum of active entries in all tables for all devices.
337 *
338 * @onos.rsModel StatisticsFlowsActiveEntries
339 * @return 200 OK with JSON encoded array of active entry count per device
340 */
341 @GET
342 @Path("flows/activeentries")
343 @Produces(MediaType.APPLICATION_JSON)
344 public Response getActiveEntriesCountPerDevice() {
345 final FlowRuleService service = get(FlowRuleService.class);
346 final Iterable<Device> devices = get(DeviceService.class).getDevices();
347 final ObjectNode root = mapper().createObjectNode();
348 final ArrayNode rootArrayNode = root.putArray("statistics");
349 for (final Device device : devices) {
Jordan Haltermanb81fdc12019-03-04 18:12:20 -0800350 int activeEntries = service.getFlowRuleCount(device.id(), FlowEntry.FlowEntryState.ADDED);
Patryk Konopka7e40c012017-06-06 13:38:06 +0200351 final ObjectNode entry = mapper().createObjectNode();
352 entry.put("device", device.id().toString());
353 entry.put("activeEntries", activeEntries);
354 rootArrayNode.add(entry);
355 }
356
357 return ok(root).build();
358 }
Ray Milkeyb9af9462015-07-17 11:12:09 -0700359}