blob: 0213bebef32f0062fddb13f72b2a7a08974b3718 [file] [log] [blame]
slowr13fa5b02017-08-08 16:32:31 -07001/*
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 */
16package org.onosproject.xran.rest;
17
slowr60d4d102017-08-16 18:33:58 -070018import com.fasterxml.jackson.annotation.JsonInclude;
slowr13fa5b02017-08-08 16:32:31 -070019import com.fasterxml.jackson.databind.JsonNode;
20import com.fasterxml.jackson.databind.node.ObjectNode;
21import com.google.common.collect.Lists;
22import org.apache.commons.lang.exception.ExceptionUtils;
23import org.onosproject.rest.AbstractWebResource;
24import org.onosproject.xran.XranStore;
25import org.onosproject.xran.annotations.Patch;
slowr67d05e42017-08-11 20:37:22 -070026import org.onosproject.xran.controller.XranController;
slowrd337c932017-08-18 13:54:02 -070027import org.onosproject.xran.controller.XranControllerImpl;
slowr89c2ac12017-08-15 16:20:06 -070028import org.onosproject.xran.entities.RnibCell;
slowr13fa5b02017-08-08 16:32:31 -070029import org.onosproject.xran.entities.RnibLink;
slowr89c2ac12017-08-15 16:20:06 -070030import org.onosproject.xran.entities.RnibUe;
slowr60d4d102017-08-16 18:33:58 -070031import org.onosproject.xran.codecs.ber.types.BerInteger;
slowr13fa5b02017-08-08 16:32:31 -070032import org.slf4j.Logger;
33import org.slf4j.LoggerFactory;
34
slowr60d4d102017-08-16 18:33:58 -070035import javax.ws.rs.Consumes;
36import javax.ws.rs.DefaultValue;
37import javax.ws.rs.GET;
38import javax.ws.rs.POST;
39import javax.ws.rs.Path;
40import javax.ws.rs.PathParam;
41import javax.ws.rs.Produces;
42import javax.ws.rs.QueryParam;
slowr13fa5b02017-08-08 16:32:31 -070043import javax.ws.rs.core.MediaType;
44import javax.ws.rs.core.Response;
slowr13fa5b02017-08-08 16:32:31 -070045import java.io.InputStream;
46import java.util.List;
slowr67d05e42017-08-11 20:37:22 -070047import java.util.Optional;
48import java.util.concurrent.SynchronousQueue;
slowr8ddc2b12017-08-14 14:13:38 -070049import java.util.concurrent.TimeUnit;
slowr13fa5b02017-08-08 16:32:31 -070050
51/**
52 * Link web resource.
53 */
54@Path("links")
55public class LinkWebResource extends AbstractWebResource {
56
57 private static final Logger log =
58 LoggerFactory.getLogger(LinkWebResource.class);
59
slowr60d4d102017-08-16 18:33:58 -070060 public LinkWebResource() {
61
62 }
63
slowr13fa5b02017-08-08 16:32:31 -070064 /**
65 * test.
66 *
67 * @param eciHex test
68 * @param ue test
69 * @return test
70 */
71 @GET
72 @Produces(MediaType.APPLICATION_JSON)
73 public Response getLinksBetween(@DefaultValue("") @QueryParam("cell") String eciHex,
slowr8ddc2b12017-08-14 14:13:38 -070074 @DefaultValue("-1") @QueryParam("ue") long ue) {
slowr13fa5b02017-08-08 16:32:31 -070075 List<RnibLink> list = Lists.newArrayList();
76 if (!eciHex.isEmpty() && ue != -1) {
77 RnibLink link = get(XranStore.class).getLinkBetweenCellIdUeId(eciHex, ue);
78 if (link != null) {
79 list.add(link);
80 }
81 } else if (!eciHex.isEmpty()) {
82 list.addAll(get(XranStore.class).getLinksByCellId(eciHex));
83 } else if (ue != -1) {
84 list.addAll(get(XranStore.class).getLinksByUeId(ue));
85 } else {
86 list.addAll(get(XranStore.class).getLinks());
87 }
88
slowr60d4d102017-08-16 18:33:58 -070089 if (list.size() > 0) {
90 try {
91 JsonNode jsonNode = mapper().valueToTree(list);
92
93 return ResponseHelper.getResponse(
94 mapper(),
95 ResponseHelper.statusCode.OK,
96 jsonNode
97 );
98 } catch (Exception e) {
99 String fullStackTrace = ExceptionUtils.getFullStackTrace(e);
100 log.error(fullStackTrace);
101 e.printStackTrace();
102
103 return ResponseHelper.getResponse(
104 mapper(),
105 ResponseHelper.statusCode.INTERNAL_SERVER_ERROR,
106 "Exception",
107 fullStackTrace
108 );
109 }
slowr13fa5b02017-08-08 16:32:31 -0700110 }
slowr60d4d102017-08-16 18:33:58 -0700111
112 return ResponseHelper.getResponse(
113 mapper(),
114 ResponseHelper.statusCode.NOT_FOUND,
115 "Not Found",
116 "Specified links not found"
117 );
slowr13fa5b02017-08-08 16:32:31 -0700118 }
119
120 /**
121 * test.
122 *
123 * @param src test
124 * @param dst test
125 * @param stream test
126 * @return test
127 */
128 @Patch
129 @Path("{src},{dst}")
130 @Consumes(MediaType.APPLICATION_JSON)
slowr60d4d102017-08-16 18:33:58 -0700131 @Produces(MediaType.APPLICATION_JSON)
slowr13fa5b02017-08-08 16:32:31 -0700132 public Response patchLinks(@PathParam("src") String src, @PathParam("dst") long dst, InputStream stream) {
slowr8ddc2b12017-08-14 14:13:38 -0700133 RnibLink link = get(XranStore.class).getLinkBetweenCellIdUeId(src, dst);
134 if (link != null) {
135 try {
slowr67d05e42017-08-11 20:37:22 -0700136 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
slowr13fa5b02017-08-08 16:32:31 -0700137
slowr89c2ac12017-08-15 16:20:06 -0700138 JsonNode type = jsonTree.path("type");
139 if (!type.isMissingNode()) {
140 RnibLink.Type anEnum = RnibLink.Type.getEnum(type.asText());
141 return handleTypeChange(link, anEnum);
slowr67d05e42017-08-11 20:37:22 -0700142 }
slowr13fa5b02017-08-08 16:32:31 -0700143
slowr89c2ac12017-08-15 16:20:06 -0700144 JsonNode trafficpercent = jsonTree.path("trafficpercent");
145 if (!trafficpercent.isMissingNode()) {
146 return handleTrafficChange(link, trafficpercent);
slowr67d05e42017-08-11 20:37:22 -0700147 }
slowr13fa5b02017-08-08 16:32:31 -0700148
slowr89c2ac12017-08-15 16:20:06 -0700149 JsonNode rrmConf = jsonTree.path("RRMConf");
150 if (!rrmConf.isMissingNode()) {
151 return handleRRMChange(link, rrmConf);
slowr8ddc2b12017-08-14 14:13:38 -0700152 }
153
slowrd19a83b2017-08-17 08:57:46 -0700154 return ResponseHelper.getResponse(
155 mapper(),
156 ResponseHelper.statusCode.NOT_IMPLEMENTED,
157 "Not Implemented",
158 "The command you specified is not implemented or doesn't exist. We support " +
159 "type/RRMConf/traficpercent commands."
160 );
161
slowr8ddc2b12017-08-14 14:13:38 -0700162 } catch (Exception e) {
slowr60d4d102017-08-16 18:33:58 -0700163 String fullStackTrace = ExceptionUtils.getFullStackTrace(e);
164 log.error(fullStackTrace);
slowr8ddc2b12017-08-14 14:13:38 -0700165 e.printStackTrace();
slowr60d4d102017-08-16 18:33:58 -0700166
167 return ResponseHelper.getResponse(
168 mapper(),
169 ResponseHelper.statusCode.INTERNAL_SERVER_ERROR,
170 "Exception",
171 fullStackTrace
172 );
slowr8ddc2b12017-08-14 14:13:38 -0700173 }
174 }
slowr60d4d102017-08-16 18:33:58 -0700175
176 return ResponseHelper.getResponse(
177 mapper(),
178 ResponseHelper.statusCode.NOT_FOUND,
179 "Not Found",
180 "Link not found use POST request"
181 );
slowr13fa5b02017-08-08 16:32:31 -0700182 }
183
184 /**
185 * test.
186 *
187 * @param src test
188 * @param dst test
189 * @param stream test
190 * @return test
191 */
192 @POST
193 @Path("{src},{dst}")
194 @Consumes(MediaType.APPLICATION_JSON)
slowr60d4d102017-08-16 18:33:58 -0700195 @Produces(MediaType.APPLICATION_JSON)
slowr13fa5b02017-08-08 16:32:31 -0700196 public Response postLinks(@PathParam("src") String src, @PathParam("dst") long dst, InputStream stream) {
slowr89c2ac12017-08-15 16:20:06 -0700197 RnibCell cell = get(XranStore.class).getCell(src);
198 RnibUe ue = get(XranStore.class).getUe(dst);
199
200 if (cell == null) {
slowr60d4d102017-08-16 18:33:58 -0700201 return ResponseHelper.getResponse(
202 mapper(),
203 ResponseHelper.statusCode.NOT_FOUND,
204 "Not Found",
205 "Cell " + src + " was not found"
206 );
slowr89c2ac12017-08-15 16:20:06 -0700207 }
208
209 if (ue == null) {
slowr60d4d102017-08-16 18:33:58 -0700210 return ResponseHelper.getResponse(
211 mapper(),
212 ResponseHelper.statusCode.NOT_FOUND,
213 "Not Found",
214 "Ue with " + dst + " was not found"
215 );
slowr89c2ac12017-08-15 16:20:06 -0700216 }
217
218 if (get(XranStore.class).getLink(cell.getEcgi(), ue.getMmeS1apId()) != null) {
slowr60d4d102017-08-16 18:33:58 -0700219 return ResponseHelper.getResponse(
220 mapper(),
221 ResponseHelper.statusCode.BAD_REQUEST,
222 "Bad Request",
223 "Link already exists use PATCH to modify"
224 );
slowr89c2ac12017-08-15 16:20:06 -0700225 }
226
slowr13fa5b02017-08-08 16:32:31 -0700227 try {
228 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
229
slowr89c2ac12017-08-15 16:20:06 -0700230 JsonNode type = jsonTree.path("type");
slowr13fa5b02017-08-08 16:32:31 -0700231
slowr077957a2017-08-16 11:54:22 -0700232 RnibLink link = new RnibLink(cell, ue);
233 // store it as non-serving when creating link
234 get(XranStore.class).storeLink(link);
slowr89c2ac12017-08-15 16:20:06 -0700235 if (!type.isMissingNode()) {
slowr077957a2017-08-16 11:54:22 -0700236 return handleTypeChange(link, RnibLink.Type.getEnum(type.asText()));
slowr13fa5b02017-08-08 16:32:31 -0700237 }
slowr077957a2017-08-16 11:54:22 -0700238
239 JsonNode trafficpercent = jsonTree.path("trafficpercent");
240 if (!trafficpercent.isMissingNode()) {
241 return handleTrafficChange(link, trafficpercent);
242 }
243
244 JsonNode rrmConf = jsonTree.path("RRMConf");
245 if (!rrmConf.isMissingNode()) {
246 return handleRRMChange(link, rrmConf);
247 }
248
slowr13fa5b02017-08-08 16:32:31 -0700249 } catch (Exception e) {
slowr60d4d102017-08-16 18:33:58 -0700250 String fullStackTrace = ExceptionUtils.getFullStackTrace(e);
251 log.error(fullStackTrace);
slowr13fa5b02017-08-08 16:32:31 -0700252 e.printStackTrace();
slowr60d4d102017-08-16 18:33:58 -0700253
254 return ResponseHelper.getResponse(
255 mapper(),
256 ResponseHelper.statusCode.INTERNAL_SERVER_ERROR,
257 "Exception",
258 fullStackTrace
259 );
slowr13fa5b02017-08-08 16:32:31 -0700260 }
261
slowr60d4d102017-08-16 18:33:58 -0700262 return ResponseHelper.getResponse(
263 mapper(),
slowr73b4eae2017-08-17 16:09:09 -0700264 ResponseHelper.statusCode.BAD_REQUEST,
265 "Bad Request",
slowrd19a83b2017-08-17 08:57:46 -0700266 "The command you specified is not implemented or doesn't exist. We support " +
267 "type/RRMConf/traficpercent commands."
slowr60d4d102017-08-16 18:33:58 -0700268 );
slowr13fa5b02017-08-08 16:32:31 -0700269 }
270
slowr89c2ac12017-08-15 16:20:06 -0700271 private Response handleTypeChange(RnibLink link, RnibLink.Type newType) throws InterruptedException {
272 final SynchronousQueue<String>[] queue = new SynchronousQueue[1];
273
274 if (newType.equals(RnibLink.Type.SERVING_PRIMARY)) {
slowr077957a2017-08-16 11:54:22 -0700275 switch (link.getType()) {
276 case SERVING_PRIMARY: {
slowr60d4d102017-08-16 18:33:58 -0700277 return ResponseHelper.getResponse(
278 mapper(),
279 ResponseHelper.statusCode.BAD_REQUEST,
280 "Bad Request",
281 "Link is already a primary link"
282 );
slowr89c2ac12017-08-15 16:20:06 -0700283 }
slowr077957a2017-08-16 11:54:22 -0700284 case SERVING_SECONDARY_CA:
285 case SERVING_SECONDARY_DC:
286 case NON_SERVING: {
287 List<RnibLink> linksByUeId = get(XranStore.class).getLinksByUeId(link.getLinkId().getMmeues1apid().longValue());
288
289 Optional<RnibLink> primary = linksByUeId.stream()
290 .filter(l -> l.getType().equals(RnibLink.Type.SERVING_PRIMARY))
291 .findFirst();
292 if (primary.isPresent()) {
293 queue[0] = get(XranController.class).sendHORequest(link, primary.get());
slowrd337c932017-08-18 13:54:02 -0700294 String poll = queue[0].poll(get(XranControllerImpl.class).northbound_timeout, TimeUnit.MILLISECONDS);
slowr077957a2017-08-16 11:54:22 -0700295
296 if (poll != null) {
slowr60d4d102017-08-16 18:33:58 -0700297 return ResponseHelper.getResponse(
298 mapper(),
299 ResponseHelper.statusCode.OK,
300 "Handoff Response",
301 poll
302 );
slowr077957a2017-08-16 11:54:22 -0700303 } else {
slowr60d4d102017-08-16 18:33:58 -0700304 return ResponseHelper.getResponse(
305 mapper(),
306 ResponseHelper.statusCode.REQUEST_TIMEOUT,
307 "Handoff Timeout",
308 "eNodeB did not send a HOComplete/HOFailure on time"
309 );
slowr077957a2017-08-16 11:54:22 -0700310 }
311 } else {
312 link.setType(RnibLink.Type.SERVING_PRIMARY);
slowr60d4d102017-08-16 18:33:58 -0700313 return ResponseHelper.getResponse(
314 mapper(),
315 ResponseHelper.statusCode.OK,
316 "OK",
317 "Link set to primary"
318 );
slowr077957a2017-08-16 11:54:22 -0700319 }
320 }
slowr89c2ac12017-08-15 16:20:06 -0700321 }
322 } else if (newType.equals(RnibLink.Type.NON_SERVING)) {
323 switch (link.getType()) {
324 case NON_SERVING:
slowr60d4d102017-08-16 18:33:58 -0700325 return ResponseHelper.getResponse(
326 mapper(),
327 ResponseHelper.statusCode.BAD_REQUEST,
328 "Bad Request",
329 "Link is already a primary link"
330 );
slowr89c2ac12017-08-15 16:20:06 -0700331 case SERVING_PRIMARY:
slowr60d4d102017-08-16 18:33:58 -0700332 return ResponseHelper.getResponse(
333 mapper(),
334 ResponseHelper.statusCode.BAD_REQUEST,
335 "Bad Request",
336 "Cannot modify a primary link"
337 );
slowr89c2ac12017-08-15 16:20:06 -0700338 case SERVING_SECONDARY_CA:
339 case SERVING_SECONDARY_DC:
340 if (get(XranController.class).sendScellDelete(link)) {
slowr60d4d102017-08-16 18:33:58 -0700341 return ResponseHelper.getResponse(
342 mapper(),
343 ResponseHelper.statusCode.OK,
344 "OK",
345 "Link set to non-serving"
346 );
slowr89c2ac12017-08-15 16:20:06 -0700347 } else {
slowr60d4d102017-08-16 18:33:58 -0700348 return ResponseHelper.getResponse(
349 mapper(),
350 ResponseHelper.statusCode.NOT_FOUND,
351 "Not Found",
352 "Could not find cell config report to construct Scell Delete"
353 );
slowr89c2ac12017-08-15 16:20:06 -0700354 }
355 }
356 } else if (newType.equals(RnibLink.Type.SERVING_SECONDARY_CA)) {
357 switch (link.getType()) {
358 case SERVING_PRIMARY:
slowr60d4d102017-08-16 18:33:58 -0700359 return ResponseHelper.getResponse(
360 mapper(),
361 ResponseHelper.statusCode.BAD_REQUEST,
362 "Bad Request",
363 "Cannot modify a primary link"
364 );
slowr89c2ac12017-08-15 16:20:06 -0700365 case SERVING_SECONDARY_DC:
366 case NON_SERVING:
367 queue[0] = get(XranController.class).sendScellAdd(link);
slowrd337c932017-08-18 13:54:02 -0700368 String poll = queue[0].poll(get(XranControllerImpl.class).northbound_timeout, TimeUnit.MILLISECONDS);
slowr89c2ac12017-08-15 16:20:06 -0700369 if (poll != null) {
slowr60d4d102017-08-16 18:33:58 -0700370 return ResponseHelper.getResponse(
371 mapper(),
372 ResponseHelper.statusCode.OK,
373 "ScellAdd Response",
374 poll
375 );
slowr89c2ac12017-08-15 16:20:06 -0700376 } else {
slowr60d4d102017-08-16 18:33:58 -0700377 return ResponseHelper.getResponse(
378 mapper(),
379 ResponseHelper.statusCode.REQUEST_TIMEOUT,
380 "ScellAdd Timeout",
381 "eNodeB did not send a ScellAddStatus on time"
382 );
slowr89c2ac12017-08-15 16:20:06 -0700383 }
384 case SERVING_SECONDARY_CA:
slowr60d4d102017-08-16 18:33:58 -0700385 return ResponseHelper.getResponse(
386 mapper(),
387 ResponseHelper.statusCode.BAD_REQUEST,
388 "Bad Request",
389 "Link is already a secondary CA link"
390 );
slowr89c2ac12017-08-15 16:20:06 -0700391 }
392 }
393
slowr60d4d102017-08-16 18:33:58 -0700394 return ResponseHelper.getResponse(
395 mapper(),
slowr73b4eae2017-08-17 16:09:09 -0700396 ResponseHelper.statusCode.BAD_REQUEST,
397 "Bad Request",
398 "The command you specified is not implemented or doesn't exist."
slowr60d4d102017-08-16 18:33:58 -0700399 );
slowr89c2ac12017-08-15 16:20:06 -0700400 }
401
402 private Response handleTrafficChange(RnibLink link, JsonNode trafficpercent) {
403 JsonNode jsonNode = trafficpercent.path("traffic-percent-dl");
404 if (!jsonNode.isMissingNode()) {
405 link.getTrafficPercent().setTrafficPercentDl(new BerInteger(jsonNode.asInt()));
406 }
407
408 jsonNode = trafficpercent.path("traffic-percent-ul");
409 if (!jsonNode.isMissingNode()) {
410 link.getTrafficPercent().setTrafficPercentUl(new BerInteger(jsonNode.asInt()));
411 }
412
slowr60d4d102017-08-16 18:33:58 -0700413 return ResponseHelper.getResponse(
414 mapper(),
415 ResponseHelper.statusCode.OK,
416 "OK",
417 "Traffic Percent changed"
418 );
slowr89c2ac12017-08-15 16:20:06 -0700419 }
420
421 private Response handleRRMChange(RnibLink link, JsonNode rrmConf) throws InterruptedException {
422 final SynchronousQueue<String>[] queue = new SynchronousQueue[1];
423 get(XranStore.class).modifyLinkRrmConf(link, rrmConf);
slowr73b4eae2017-08-17 16:09:09 -0700424 boolean isxICIC = link.getLinkId().getCell().getVersion() <= 3;
slowr89c2ac12017-08-15 16:20:06 -0700425
slowr73b4eae2017-08-17 16:09:09 -0700426 queue[0] = get(XranController.class).sendModifiedRRMConf(link.getRrmParameters(),
427 isxICIC);
428
429 if (isxICIC) {
slowr60d4d102017-08-16 18:33:58 -0700430 return ResponseHelper.getResponse(
431 mapper(),
432 ResponseHelper.statusCode.OK,
slowr73b4eae2017-08-17 16:09:09 -0700433 "OK",
434 "xICIC was sent successfully"
slowr60d4d102017-08-16 18:33:58 -0700435 );
slowr89c2ac12017-08-15 16:20:06 -0700436 } else {
slowrd337c932017-08-18 13:54:02 -0700437 String poll = queue[0].poll(get(XranControllerImpl.class).northbound_timeout, TimeUnit.MILLISECONDS);
slowr73b4eae2017-08-17 16:09:09 -0700438
439 if (poll != null) {
440 return ResponseHelper.getResponse(
441 mapper(),
442 ResponseHelper.statusCode.OK,
443 "RRMConfig Response",
444 poll
445 );
446 } else {
447 return ResponseHelper.getResponse(
448 mapper(),
449 ResponseHelper.statusCode.REQUEST_TIMEOUT,
450 "RRMConfig Timeout",
451 "eNodeB did not send a RRMConfingStatus on time"
452 );
453 }
slowr89c2ac12017-08-15 16:20:06 -0700454 }
455 }
slowr13fa5b02017-08-08 16:32:31 -0700456}