blob: d3ff8860e1d56b05454cfd8960d95fb2036a2715 [file] [log] [blame]
Sangsik Yoonf0b3ad82016-08-19 18:47:59 +09001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Sangsik Yoonf0b3ad82016-08-19 18:47:59 +09003 *
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 */
16
17package org.onosproject.rest.resources;
18
19import com.fasterxml.jackson.databind.node.ObjectNode;
20import org.onosproject.incubator.net.dpi.DpiStatInfo;
21import org.onosproject.incubator.net.dpi.DpiStatistics;
22import org.onosproject.incubator.net.dpi.DpiStatisticsManagerService;
23import org.onosproject.incubator.net.dpi.FlowStatInfo;
24import org.onosproject.incubator.net.dpi.ProtocolStatInfo;
25import org.onosproject.rest.AbstractWebResource;
26import org.slf4j.Logger;
27
28import javax.ws.rs.Consumes;
29import javax.ws.rs.GET;
30import javax.ws.rs.POST;
31import javax.ws.rs.Path;
32import javax.ws.rs.Produces;
33import javax.ws.rs.QueryParam;
34import javax.ws.rs.core.MediaType;
35import javax.ws.rs.core.Response;
36
37import java.io.IOException;
38import java.io.InputStream;
39import java.util.Comparator;
40import java.util.List;
41import java.util.stream.Collectors;
42
43import static org.slf4j.LoggerFactory.getLogger;
44
45/**
46 * Query the latest DPI statistics info.
47 */
48
49@Path("dpis")
50public class DpisWebResource extends AbstractWebResource {
51
52 private final Logger log = getLogger(getClass());
53
54 private static final int MAX_TOPN = 100;
55
56 private final DpiStatisticsManagerService service = get(DpiStatisticsManagerService.class);
57
58 public static final Comparator<ProtocolStatInfo> PROTOCOL_STAT_INFO_COMPARATOR =
59 new Comparator<ProtocolStatInfo>() {
60 @Override
61 public int compare(ProtocolStatInfo psi1, ProtocolStatInfo psi2) {
62 long delta = psi1.bytes() - psi2.bytes();
63 return delta == 0 ? 0 : (delta > 0 ? -1 : +1);
64 }
65 };
66
67 public static final Comparator<FlowStatInfo> FLOW_STAT_INFO_COMPARATOR =
68 new Comparator<FlowStatInfo>() {
69 @Override
70 public int compare(FlowStatInfo fsi1, FlowStatInfo fsi2) {
71 long delta = fsi1.bytes() - fsi2.bytes();
72 return delta == 0 ? 0 : (delta > 0 ? -1 : +1);
73 }
74 };
75
76 /**
77 * Gets the latest dpi statistics.
78 *
Ray Milkeyef794342016-11-09 16:20:29 -080079 * @param topn max size
Sangsik Yoonf0b3ad82016-08-19 18:47:59 +090080 * @return 200 OK with a dpi statistics
81 * @onos.rsModel DpiStatistics
82 */
83 @GET
84 @Produces(MediaType.APPLICATION_JSON)
85 public Response getDpisLatest(@QueryParam("topn") int topn) {
86 log.debug("getDpisLatest request with topn={}", topn);
87
88 DpiStatistics ds = service.getDpiStatisticsLatest();
89 DpiStatistics retDs;
90
91 if (ds == null) {
92 retDs = new DpiStatistics("", new DpiStatInfo());
93 } else if (topn <= 0) {
94 retDs = ds;
95 } else {
96 if (topn > MAX_TOPN) {
97 topn = MAX_TOPN;
98 }
99 retDs = new DpiStatistics(ds.receivedTime(),
100 new DpiStatInfo(ds.dpiStatInfo().trafficStatistics()));
101 List<ProtocolStatInfo> psiList = ds.dpiStatInfo().detectedProtos();
102 if (psiList != null) {
103 // sorts protocol list with descending order based on bytes within topn
104 List<ProtocolStatInfo> psiListSorted =
105 psiList.stream().sorted(PROTOCOL_STAT_INFO_COMPARATOR).
106 limit(topn).collect(Collectors.toList());
107 retDs.dpiStatInfo().setDetectedProtos(psiListSorted);
108 }
109 List<FlowStatInfo> fsiList = ds.dpiStatInfo().knownFlows();
110 if (fsiList != null) {
111 // sorts known flow list with descending order based on bytes within topn
112 List<FlowStatInfo> fsiListSorted =
113 fsiList.stream().sorted(FLOW_STAT_INFO_COMPARATOR).
114 limit(topn).collect(Collectors.toList());
115 retDs.dpiStatInfo().setKnownFlows(fsiListSorted);
116 }
117 fsiList = ds.dpiStatInfo().unknownFlows();
118 if (fsiList != null) {
119 // sorts unknown flow list with descending order based on bytes within topn
120 List<FlowStatInfo> fsiListSorted =
121 fsiList.stream().sorted(FLOW_STAT_INFO_COMPARATOR).
122 limit(topn).collect(Collectors.toList());
123 retDs.dpiStatInfo().setUnknownFlows(fsiListSorted);
124 }
125 }
126
127 ObjectNode result = codec(DpiStatistics.class).encode(retDs, this);
128 return ok(result).build();
129
130 }
131
132 /**
133 * Gets the latest traffic statistics only.
134 *
135 * @return 200 OK with a traffic statistics
136 * @onos.rsModel TrafficStatistics
137 */
138 @GET
139 @Produces(MediaType.APPLICATION_JSON)
140 @Path("traffic")
141 public Response getTrafficStatistics() {
142 log.debug("getTrafficStatistics request");
143
144 DpiStatistics ds = service.getDpiStatisticsLatest();
145 if (ds == null) {
146 ds = new DpiStatistics("", new DpiStatInfo());
147 }
148
149 DpiStatInfo dsi = new DpiStatInfo();
150 dsi.setTrafficStatistics(ds.dpiStatInfo().trafficStatistics());
151 DpiStatistics dsTraffic = new DpiStatistics(ds.receivedTime(), dsi);
152
153 ObjectNode result = codec(DpiStatistics.class).encode(dsTraffic, this);
154 return ok(result).build();
155 }
156
157 /**
158 * Gets the latest detected protocol statistics only.
159 *
Ray Milkeyef794342016-11-09 16:20:29 -0800160 * @param topn max size
Sangsik Yoonf0b3ad82016-08-19 18:47:59 +0900161 * @return 200 OK with a protocol statistics
162 * @onos.rsModel ProtocolStatistics
163 */
164 @GET
165 @Produces(MediaType.APPLICATION_JSON)
166 @Path("protocols")
167 public Response getDetectedProtocols(@QueryParam("topn") int topn) {
168 log.debug("getDetectedProtocols request with topn={}", topn);
169
170 DpiStatistics ds = service.getDpiStatisticsLatest();
171 DpiStatistics dsProtocol;
172
173 if (ds == null) {
174 dsProtocol = new DpiStatistics("", new DpiStatInfo());
175 } else if (topn <= 0) {
176 DpiStatInfo dsi = new DpiStatInfo();
177 dsi.setDetectedProtos(ds.dpiStatInfo().detectedProtos());
178 dsProtocol = new DpiStatistics(ds.receivedTime(), dsi);
179 } else {
180 if (topn > MAX_TOPN) {
181 topn = MAX_TOPN;
182 }
183 dsProtocol = new DpiStatistics(ds.receivedTime(), new DpiStatInfo());
184 List<ProtocolStatInfo> psiList = ds.dpiStatInfo().detectedProtos();
185 if (psiList != null) {
186 // sorts protocol list with descending order based on bytes within topn
187 List<ProtocolStatInfo> psiListSorted =
188 psiList.stream().sorted(PROTOCOL_STAT_INFO_COMPARATOR).
189 limit(topn).collect(Collectors.toList());
190 dsProtocol.dpiStatInfo().setDetectedProtos(psiListSorted);
191 }
192 }
193
194 ObjectNode result = codec(DpiStatistics.class).encode(dsProtocol, this);
195 return ok(result).build();
196 }
197
198 /**
199 * Gets the latest known flows statistics only.
200 *
Ray Milkeyef794342016-11-09 16:20:29 -0800201 * @param topn max size
Sangsik Yoonf0b3ad82016-08-19 18:47:59 +0900202 * @return 200 OK with a known flow statistics
203 * @onos.rsModel KnownFlowStatistics
204 */
205 @GET
206 @Produces(MediaType.APPLICATION_JSON)
207 @Path("knownFlows")
208 public Response getKnownFlows(@QueryParam("topn") int topn) {
209 log.debug("getKnownFlows request with topn={}", topn);
210
211 DpiStatistics ds = service.getDpiStatisticsLatest();
212 DpiStatistics dsKnownFlows;
213
214 if (ds == null) {
215 dsKnownFlows = new DpiStatistics("", new DpiStatInfo());
216 } else if (topn <= 0) {
217 DpiStatInfo dsi = new DpiStatInfo();
218 dsi.setKnownFlows(ds.dpiStatInfo().knownFlows());
219 dsKnownFlows = new DpiStatistics(ds.receivedTime(), dsi);
220 } else {
221 if (topn > MAX_TOPN) {
222 topn = MAX_TOPN;
223 }
224 dsKnownFlows = new DpiStatistics(ds.receivedTime(), new DpiStatInfo());
225 List<FlowStatInfo> fsiList = ds.dpiStatInfo().knownFlows();
226 if (fsiList != null) {
227 // sorts known flow list with descending order based on bytes within topn
228 List<FlowStatInfo> fsiListSorted =
229 fsiList.stream().sorted(FLOW_STAT_INFO_COMPARATOR).
230 limit(topn).collect(Collectors.toList());
231 dsKnownFlows.dpiStatInfo().setKnownFlows(fsiListSorted);
232 }
233 }
234
235 ObjectNode result = codec(DpiStatistics.class).encode(dsKnownFlows, this);
236 return ok(result).build();
237 }
238
239 /**
240 * Gets the latest unknown flows statistics only.
241 *
Ray Milkeyef794342016-11-09 16:20:29 -0800242 * @param topn max size
Sangsik Yoonf0b3ad82016-08-19 18:47:59 +0900243 * @return 200 OK with an unknown flow statistics
244 * @onos.rsModel UnknownFlowStatistics
245 */
246 @GET
247 @Produces(MediaType.APPLICATION_JSON)
248 @Path("unknownFlows")
249 public Response getUnknownFlows(@QueryParam("topn") int topn) {
250 log.debug("getUnknownFlows request with topn={}", topn);
251
252 DpiStatistics ds = service.getDpiStatisticsLatest();
253 DpiStatistics dsUnknownFlows;
254
255 if (ds == null) {
256 dsUnknownFlows = new DpiStatistics("", new DpiStatInfo());
257 } else if (topn <= 0) {
258 DpiStatInfo dsi = new DpiStatInfo();
259 dsi.setUnknownFlows(ds.dpiStatInfo().unknownFlows());
260 dsUnknownFlows = new DpiStatistics(ds.receivedTime(), dsi);
261 } else {
262 if (topn > 100) {
263 topn = 100;
264 }
265 dsUnknownFlows = new DpiStatistics(ds.receivedTime(), new DpiStatInfo());
266 List<FlowStatInfo> fsiList = ds.dpiStatInfo().unknownFlows();
267 if (fsiList != null) {
268 // sorts unknown flow list with descending order based on bytes within topn
269 List<FlowStatInfo> fsiListSorted =
270 fsiList.stream().sorted(FLOW_STAT_INFO_COMPARATOR).
271 limit(topn).collect(Collectors.toList());
272 dsUnknownFlows.dpiStatInfo().setUnknownFlows(fsiListSorted);
273 }
274 }
275
276 ObjectNode result = codec(DpiStatistics.class).encode(dsUnknownFlows, this);
277 return ok(result).build();
278 }
279
280 /**
281 * Add new dpi statistics entry at the end of list.
282 *
283 * @param stream dpi statistics JSON
284 * @return status of the request - CREATED if the JSON is correct,
285 * BAD_REQUEST if the JSON is invalid
286 * @onos.rsModel DpiStatisticsPost
287 */
288 @POST
289 @Consumes(MediaType.APPLICATION_JSON)
290 @Produces(MediaType.APPLICATION_JSON)
291 public Response addDpiStatistics(InputStream stream) {
292 ObjectNode result;
293
294 try {
295 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
296 log.debug("jsonTree={}", jsonTree);
297
298 DpiStatistics ds = codec(DpiStatistics.class).decode(jsonTree, this);
299 if (ds == null) {
300 log.error("Wrong DpiStatistics json format error");
301 }
302
303 // TODO: check the validity of dpi statistics values, specially receivedTime format
304 DpiStatistics added = service.addDpiStatistics(ds);
305
306 result = codec(DpiStatistics.class).encode(added, this);
307 } catch (IOException ex) {
308 throw new IllegalArgumentException(ex);
309 }
310 return ok(result).build();
311 }
312}