blob: 6b01b13153b796d48b201784d842e16a87f673fe [file] [log] [blame]
Sangsik Yoonf0b3ad82016-08-19 18:47:59 +09001/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
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 *
79 * @return 200 OK with a dpi statistics
80 * @onos.rsModel DpiStatistics
81 */
82 @GET
83 @Produces(MediaType.APPLICATION_JSON)
84 public Response getDpisLatest(@QueryParam("topn") int topn) {
85 log.debug("getDpisLatest request with topn={}", topn);
86
87 DpiStatistics ds = service.getDpiStatisticsLatest();
88 DpiStatistics retDs;
89
90 if (ds == null) {
91 retDs = new DpiStatistics("", new DpiStatInfo());
92 } else if (topn <= 0) {
93 retDs = ds;
94 } else {
95 if (topn > MAX_TOPN) {
96 topn = MAX_TOPN;
97 }
98 retDs = new DpiStatistics(ds.receivedTime(),
99 new DpiStatInfo(ds.dpiStatInfo().trafficStatistics()));
100 List<ProtocolStatInfo> psiList = ds.dpiStatInfo().detectedProtos();
101 if (psiList != null) {
102 // sorts protocol list with descending order based on bytes within topn
103 List<ProtocolStatInfo> psiListSorted =
104 psiList.stream().sorted(PROTOCOL_STAT_INFO_COMPARATOR).
105 limit(topn).collect(Collectors.toList());
106 retDs.dpiStatInfo().setDetectedProtos(psiListSorted);
107 }
108 List<FlowStatInfo> fsiList = ds.dpiStatInfo().knownFlows();
109 if (fsiList != null) {
110 // sorts known flow list with descending order based on bytes within topn
111 List<FlowStatInfo> fsiListSorted =
112 fsiList.stream().sorted(FLOW_STAT_INFO_COMPARATOR).
113 limit(topn).collect(Collectors.toList());
114 retDs.dpiStatInfo().setKnownFlows(fsiListSorted);
115 }
116 fsiList = ds.dpiStatInfo().unknownFlows();
117 if (fsiList != null) {
118 // sorts unknown flow list with descending order based on bytes within topn
119 List<FlowStatInfo> fsiListSorted =
120 fsiList.stream().sorted(FLOW_STAT_INFO_COMPARATOR).
121 limit(topn).collect(Collectors.toList());
122 retDs.dpiStatInfo().setUnknownFlows(fsiListSorted);
123 }
124 }
125
126 ObjectNode result = codec(DpiStatistics.class).encode(retDs, this);
127 return ok(result).build();
128
129 }
130
131 /**
132 * Gets the latest traffic statistics only.
133 *
134 * @return 200 OK with a traffic statistics
135 * @onos.rsModel TrafficStatistics
136 */
137 @GET
138 @Produces(MediaType.APPLICATION_JSON)
139 @Path("traffic")
140 public Response getTrafficStatistics() {
141 log.debug("getTrafficStatistics request");
142
143 DpiStatistics ds = service.getDpiStatisticsLatest();
144 if (ds == null) {
145 ds = new DpiStatistics("", new DpiStatInfo());
146 }
147
148 DpiStatInfo dsi = new DpiStatInfo();
149 dsi.setTrafficStatistics(ds.dpiStatInfo().trafficStatistics());
150 DpiStatistics dsTraffic = new DpiStatistics(ds.receivedTime(), dsi);
151
152 ObjectNode result = codec(DpiStatistics.class).encode(dsTraffic, this);
153 return ok(result).build();
154 }
155
156 /**
157 * Gets the latest detected protocol statistics only.
158 *
159 * @return 200 OK with a protocol statistics
160 * @onos.rsModel ProtocolStatistics
161 */
162 @GET
163 @Produces(MediaType.APPLICATION_JSON)
164 @Path("protocols")
165 public Response getDetectedProtocols(@QueryParam("topn") int topn) {
166 log.debug("getDetectedProtocols request with topn={}", topn);
167
168 DpiStatistics ds = service.getDpiStatisticsLatest();
169 DpiStatistics dsProtocol;
170
171 if (ds == null) {
172 dsProtocol = new DpiStatistics("", new DpiStatInfo());
173 } else if (topn <= 0) {
174 DpiStatInfo dsi = new DpiStatInfo();
175 dsi.setDetectedProtos(ds.dpiStatInfo().detectedProtos());
176 dsProtocol = new DpiStatistics(ds.receivedTime(), dsi);
177 } else {
178 if (topn > MAX_TOPN) {
179 topn = MAX_TOPN;
180 }
181 dsProtocol = new DpiStatistics(ds.receivedTime(), new DpiStatInfo());
182 List<ProtocolStatInfo> psiList = ds.dpiStatInfo().detectedProtos();
183 if (psiList != null) {
184 // sorts protocol list with descending order based on bytes within topn
185 List<ProtocolStatInfo> psiListSorted =
186 psiList.stream().sorted(PROTOCOL_STAT_INFO_COMPARATOR).
187 limit(topn).collect(Collectors.toList());
188 dsProtocol.dpiStatInfo().setDetectedProtos(psiListSorted);
189 }
190 }
191
192 ObjectNode result = codec(DpiStatistics.class).encode(dsProtocol, this);
193 return ok(result).build();
194 }
195
196 /**
197 * Gets the latest known flows statistics only.
198 *
199 * @return 200 OK with a known flow statistics
200 * @onos.rsModel KnownFlowStatistics
201 */
202 @GET
203 @Produces(MediaType.APPLICATION_JSON)
204 @Path("knownFlows")
205 public Response getKnownFlows(@QueryParam("topn") int topn) {
206 log.debug("getKnownFlows request with topn={}", topn);
207
208 DpiStatistics ds = service.getDpiStatisticsLatest();
209 DpiStatistics dsKnownFlows;
210
211 if (ds == null) {
212 dsKnownFlows = new DpiStatistics("", new DpiStatInfo());
213 } else if (topn <= 0) {
214 DpiStatInfo dsi = new DpiStatInfo();
215 dsi.setKnownFlows(ds.dpiStatInfo().knownFlows());
216 dsKnownFlows = new DpiStatistics(ds.receivedTime(), dsi);
217 } else {
218 if (topn > MAX_TOPN) {
219 topn = MAX_TOPN;
220 }
221 dsKnownFlows = new DpiStatistics(ds.receivedTime(), new DpiStatInfo());
222 List<FlowStatInfo> fsiList = ds.dpiStatInfo().knownFlows();
223 if (fsiList != null) {
224 // sorts known flow list with descending order based on bytes within topn
225 List<FlowStatInfo> fsiListSorted =
226 fsiList.stream().sorted(FLOW_STAT_INFO_COMPARATOR).
227 limit(topn).collect(Collectors.toList());
228 dsKnownFlows.dpiStatInfo().setKnownFlows(fsiListSorted);
229 }
230 }
231
232 ObjectNode result = codec(DpiStatistics.class).encode(dsKnownFlows, this);
233 return ok(result).build();
234 }
235
236 /**
237 * Gets the latest unknown flows statistics only.
238 *
239 * @return 200 OK with an unknown flow statistics
240 * @onos.rsModel UnknownFlowStatistics
241 */
242 @GET
243 @Produces(MediaType.APPLICATION_JSON)
244 @Path("unknownFlows")
245 public Response getUnknownFlows(@QueryParam("topn") int topn) {
246 log.debug("getUnknownFlows request with topn={}", topn);
247
248 DpiStatistics ds = service.getDpiStatisticsLatest();
249 DpiStatistics dsUnknownFlows;
250
251 if (ds == null) {
252 dsUnknownFlows = new DpiStatistics("", new DpiStatInfo());
253 } else if (topn <= 0) {
254 DpiStatInfo dsi = new DpiStatInfo();
255 dsi.setUnknownFlows(ds.dpiStatInfo().unknownFlows());
256 dsUnknownFlows = new DpiStatistics(ds.receivedTime(), dsi);
257 } else {
258 if (topn > 100) {
259 topn = 100;
260 }
261 dsUnknownFlows = new DpiStatistics(ds.receivedTime(), new DpiStatInfo());
262 List<FlowStatInfo> fsiList = ds.dpiStatInfo().unknownFlows();
263 if (fsiList != null) {
264 // sorts unknown flow list with descending order based on bytes within topn
265 List<FlowStatInfo> fsiListSorted =
266 fsiList.stream().sorted(FLOW_STAT_INFO_COMPARATOR).
267 limit(topn).collect(Collectors.toList());
268 dsUnknownFlows.dpiStatInfo().setUnknownFlows(fsiListSorted);
269 }
270 }
271
272 ObjectNode result = codec(DpiStatistics.class).encode(dsUnknownFlows, this);
273 return ok(result).build();
274 }
275
276 /**
277 * Add new dpi statistics entry at the end of list.
278 *
279 * @param stream dpi statistics JSON
280 * @return status of the request - CREATED if the JSON is correct,
281 * BAD_REQUEST if the JSON is invalid
282 * @onos.rsModel DpiStatisticsPost
283 */
284 @POST
285 @Consumes(MediaType.APPLICATION_JSON)
286 @Produces(MediaType.APPLICATION_JSON)
287 public Response addDpiStatistics(InputStream stream) {
288 ObjectNode result;
289
290 try {
291 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
292 log.debug("jsonTree={}", jsonTree);
293
294 DpiStatistics ds = codec(DpiStatistics.class).decode(jsonTree, this);
295 if (ds == null) {
296 log.error("Wrong DpiStatistics json format error");
297 }
298
299 // TODO: check the validity of dpi statistics values, specially receivedTime format
300 DpiStatistics added = service.addDpiStatistics(ds);
301
302 result = codec(DpiStatistics.class).encode(added, this);
303 } catch (IOException ex) {
304 throw new IllegalArgumentException(ex);
305 }
306 return ok(result).build();
307 }
308}