blob: 097cab9dcc15bd2e40cfc2d1f2bec309d9d029da [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;
slowr89c2ac12017-08-15 16:20:06 -070027import org.onosproject.xran.entities.RnibCell;
slowr13fa5b02017-08-08 16:32:31 -070028import org.onosproject.xran.entities.RnibLink;
slowr89c2ac12017-08-15 16:20:06 -070029import org.onosproject.xran.entities.RnibUe;
slowr60d4d102017-08-16 18:33:58 -070030import org.onosproject.xran.codecs.ber.types.BerInteger;
slowr13fa5b02017-08-08 16:32:31 -070031import org.slf4j.Logger;
32import org.slf4j.LoggerFactory;
33
slowr60d4d102017-08-16 18:33:58 -070034import javax.ws.rs.Consumes;
35import javax.ws.rs.DefaultValue;
36import javax.ws.rs.GET;
37import javax.ws.rs.POST;
38import javax.ws.rs.Path;
39import javax.ws.rs.PathParam;
40import javax.ws.rs.Produces;
41import javax.ws.rs.QueryParam;
slowr13fa5b02017-08-08 16:32:31 -070042import javax.ws.rs.core.MediaType;
43import javax.ws.rs.core.Response;
slowr13fa5b02017-08-08 16:32:31 -070044import java.io.InputStream;
45import java.util.List;
slowr67d05e42017-08-11 20:37:22 -070046import java.util.Optional;
47import java.util.concurrent.SynchronousQueue;
slowr8ddc2b12017-08-14 14:13:38 -070048import java.util.concurrent.TimeUnit;
slowr13fa5b02017-08-08 16:32:31 -070049
50/**
51 * Link web resource.
52 */
53@Path("links")
54public class LinkWebResource extends AbstractWebResource {
55
56 private static final Logger log =
57 LoggerFactory.getLogger(LinkWebResource.class);
58
slowr60d4d102017-08-16 18:33:58 -070059 public LinkWebResource() {
60
61 }
62
slowr13fa5b02017-08-08 16:32:31 -070063 /**
64 * test.
65 *
66 * @param eciHex test
67 * @param ue test
68 * @return test
69 */
70 @GET
71 @Produces(MediaType.APPLICATION_JSON)
72 public Response getLinksBetween(@DefaultValue("") @QueryParam("cell") String eciHex,
slowr8ddc2b12017-08-14 14:13:38 -070073 @DefaultValue("-1") @QueryParam("ue") long ue) {
slowr13fa5b02017-08-08 16:32:31 -070074 List<RnibLink> list = Lists.newArrayList();
75 if (!eciHex.isEmpty() && ue != -1) {
76 RnibLink link = get(XranStore.class).getLinkBetweenCellIdUeId(eciHex, ue);
77 if (link != null) {
78 list.add(link);
79 }
80 } else if (!eciHex.isEmpty()) {
81 list.addAll(get(XranStore.class).getLinksByCellId(eciHex));
82 } else if (ue != -1) {
83 list.addAll(get(XranStore.class).getLinksByUeId(ue));
84 } else {
85 list.addAll(get(XranStore.class).getLinks());
86 }
87
slowr60d4d102017-08-16 18:33:58 -070088 if (list.size() > 0) {
89 try {
90 JsonNode jsonNode = mapper().valueToTree(list);
91
92 return ResponseHelper.getResponse(
93 mapper(),
94 ResponseHelper.statusCode.OK,
95 jsonNode
96 );
97 } catch (Exception e) {
98 String fullStackTrace = ExceptionUtils.getFullStackTrace(e);
99 log.error(fullStackTrace);
100 e.printStackTrace();
101
102 return ResponseHelper.getResponse(
103 mapper(),
104 ResponseHelper.statusCode.INTERNAL_SERVER_ERROR,
105 "Exception",
106 fullStackTrace
107 );
108 }
slowr13fa5b02017-08-08 16:32:31 -0700109 }
slowr60d4d102017-08-16 18:33:58 -0700110
111 return ResponseHelper.getResponse(
112 mapper(),
113 ResponseHelper.statusCode.NOT_FOUND,
114 "Not Found",
115 "Specified links not found"
116 );
slowr13fa5b02017-08-08 16:32:31 -0700117 }
118
119 /**
120 * test.
121 *
122 * @param src test
123 * @param dst test
124 * @param stream test
125 * @return test
126 */
127 @Patch
128 @Path("{src},{dst}")
129 @Consumes(MediaType.APPLICATION_JSON)
slowr60d4d102017-08-16 18:33:58 -0700130 @Produces(MediaType.APPLICATION_JSON)
slowr13fa5b02017-08-08 16:32:31 -0700131 public Response patchLinks(@PathParam("src") String src, @PathParam("dst") long dst, InputStream stream) {
slowr8ddc2b12017-08-14 14:13:38 -0700132 RnibLink link = get(XranStore.class).getLinkBetweenCellIdUeId(src, dst);
133 if (link != null) {
134 try {
slowr67d05e42017-08-11 20:37:22 -0700135 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
slowr13fa5b02017-08-08 16:32:31 -0700136
slowr89c2ac12017-08-15 16:20:06 -0700137 JsonNode type = jsonTree.path("type");
138 if (!type.isMissingNode()) {
139 RnibLink.Type anEnum = RnibLink.Type.getEnum(type.asText());
140 return handleTypeChange(link, anEnum);
slowr67d05e42017-08-11 20:37:22 -0700141 }
slowr13fa5b02017-08-08 16:32:31 -0700142
slowr89c2ac12017-08-15 16:20:06 -0700143 JsonNode trafficpercent = jsonTree.path("trafficpercent");
144 if (!trafficpercent.isMissingNode()) {
145 return handleTrafficChange(link, trafficpercent);
slowr67d05e42017-08-11 20:37:22 -0700146 }
slowr13fa5b02017-08-08 16:32:31 -0700147
slowr89c2ac12017-08-15 16:20:06 -0700148 JsonNode rrmConf = jsonTree.path("RRMConf");
149 if (!rrmConf.isMissingNode()) {
150 return handleRRMChange(link, rrmConf);
slowr8ddc2b12017-08-14 14:13:38 -0700151 }
152
slowrd19a83b2017-08-17 08:57:46 -0700153 return ResponseHelper.getResponse(
154 mapper(),
155 ResponseHelper.statusCode.NOT_IMPLEMENTED,
156 "Not Implemented",
157 "The command you specified is not implemented or doesn't exist. We support " +
158 "type/RRMConf/traficpercent commands."
159 );
160
slowr8ddc2b12017-08-14 14:13:38 -0700161 } catch (Exception e) {
slowr60d4d102017-08-16 18:33:58 -0700162 String fullStackTrace = ExceptionUtils.getFullStackTrace(e);
163 log.error(fullStackTrace);
slowr8ddc2b12017-08-14 14:13:38 -0700164 e.printStackTrace();
slowr60d4d102017-08-16 18:33:58 -0700165
166 return ResponseHelper.getResponse(
167 mapper(),
168 ResponseHelper.statusCode.INTERNAL_SERVER_ERROR,
169 "Exception",
170 fullStackTrace
171 );
slowr8ddc2b12017-08-14 14:13:38 -0700172 }
173 }
slowr60d4d102017-08-16 18:33:58 -0700174
175 return ResponseHelper.getResponse(
176 mapper(),
177 ResponseHelper.statusCode.NOT_FOUND,
178 "Not Found",
179 "Link not found use POST request"
180 );
slowr13fa5b02017-08-08 16:32:31 -0700181 }
182
183 /**
184 * test.
185 *
186 * @param src test
187 * @param dst test
188 * @param stream test
189 * @return test
190 */
191 @POST
192 @Path("{src},{dst}")
193 @Consumes(MediaType.APPLICATION_JSON)
slowr60d4d102017-08-16 18:33:58 -0700194 @Produces(MediaType.APPLICATION_JSON)
slowr13fa5b02017-08-08 16:32:31 -0700195 public Response postLinks(@PathParam("src") String src, @PathParam("dst") long dst, InputStream stream) {
slowr89c2ac12017-08-15 16:20:06 -0700196 RnibCell cell = get(XranStore.class).getCell(src);
197 RnibUe ue = get(XranStore.class).getUe(dst);
198
199 if (cell == null) {
slowr60d4d102017-08-16 18:33:58 -0700200 return ResponseHelper.getResponse(
201 mapper(),
202 ResponseHelper.statusCode.NOT_FOUND,
203 "Not Found",
204 "Cell " + src + " was not found"
205 );
slowr89c2ac12017-08-15 16:20:06 -0700206 }
207
208 if (ue == null) {
slowr60d4d102017-08-16 18:33:58 -0700209 return ResponseHelper.getResponse(
210 mapper(),
211 ResponseHelper.statusCode.NOT_FOUND,
212 "Not Found",
213 "Ue with " + dst + " was not found"
214 );
slowr89c2ac12017-08-15 16:20:06 -0700215 }
216
217 if (get(XranStore.class).getLink(cell.getEcgi(), ue.getMmeS1apId()) != null) {
slowr60d4d102017-08-16 18:33:58 -0700218 return ResponseHelper.getResponse(
219 mapper(),
220 ResponseHelper.statusCode.BAD_REQUEST,
221 "Bad Request",
222 "Link already exists use PATCH to modify"
223 );
slowr89c2ac12017-08-15 16:20:06 -0700224 }
225
slowr13fa5b02017-08-08 16:32:31 -0700226 try {
227 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
228
slowr89c2ac12017-08-15 16:20:06 -0700229 JsonNode type = jsonTree.path("type");
slowr13fa5b02017-08-08 16:32:31 -0700230
slowr077957a2017-08-16 11:54:22 -0700231 RnibLink link = new RnibLink(cell, ue);
232 // store it as non-serving when creating link
233 get(XranStore.class).storeLink(link);
slowr89c2ac12017-08-15 16:20:06 -0700234 if (!type.isMissingNode()) {
slowr077957a2017-08-16 11:54:22 -0700235 return handleTypeChange(link, RnibLink.Type.getEnum(type.asText()));
slowr13fa5b02017-08-08 16:32:31 -0700236 }
slowr077957a2017-08-16 11:54:22 -0700237
238 JsonNode trafficpercent = jsonTree.path("trafficpercent");
239 if (!trafficpercent.isMissingNode()) {
240 return handleTrafficChange(link, trafficpercent);
241 }
242
243 JsonNode rrmConf = jsonTree.path("RRMConf");
244 if (!rrmConf.isMissingNode()) {
245 return handleRRMChange(link, rrmConf);
246 }
247
slowr13fa5b02017-08-08 16:32:31 -0700248 } catch (Exception e) {
slowr60d4d102017-08-16 18:33:58 -0700249 String fullStackTrace = ExceptionUtils.getFullStackTrace(e);
250 log.error(fullStackTrace);
slowr13fa5b02017-08-08 16:32:31 -0700251 e.printStackTrace();
slowr60d4d102017-08-16 18:33:58 -0700252
253 return ResponseHelper.getResponse(
254 mapper(),
255 ResponseHelper.statusCode.INTERNAL_SERVER_ERROR,
256 "Exception",
257 fullStackTrace
258 );
slowr13fa5b02017-08-08 16:32:31 -0700259 }
260
slowr60d4d102017-08-16 18:33:58 -0700261 return ResponseHelper.getResponse(
262 mapper(),
slowr73b4eae2017-08-17 16:09:09 -0700263 ResponseHelper.statusCode.BAD_REQUEST,
264 "Bad Request",
slowrd19a83b2017-08-17 08:57:46 -0700265 "The command you specified is not implemented or doesn't exist. We support " +
266 "type/RRMConf/traficpercent commands."
slowr60d4d102017-08-16 18:33:58 -0700267 );
slowr13fa5b02017-08-08 16:32:31 -0700268 }
269
slowr89c2ac12017-08-15 16:20:06 -0700270 private Response handleTypeChange(RnibLink link, RnibLink.Type newType) throws InterruptedException {
271 final SynchronousQueue<String>[] queue = new SynchronousQueue[1];
272
273 if (newType.equals(RnibLink.Type.SERVING_PRIMARY)) {
slowr077957a2017-08-16 11:54:22 -0700274 switch (link.getType()) {
275 case SERVING_PRIMARY: {
slowr60d4d102017-08-16 18:33:58 -0700276 return ResponseHelper.getResponse(
277 mapper(),
278 ResponseHelper.statusCode.BAD_REQUEST,
279 "Bad Request",
280 "Link is already a primary link"
281 );
slowr89c2ac12017-08-15 16:20:06 -0700282 }
slowr077957a2017-08-16 11:54:22 -0700283 case SERVING_SECONDARY_CA:
284 case SERVING_SECONDARY_DC:
285 case NON_SERVING: {
286 List<RnibLink> linksByUeId = get(XranStore.class).getLinksByUeId(link.getLinkId().getMmeues1apid().longValue());
287
288 Optional<RnibLink> primary = linksByUeId.stream()
289 .filter(l -> l.getType().equals(RnibLink.Type.SERVING_PRIMARY))
290 .findFirst();
291 if (primary.isPresent()) {
292 queue[0] = get(XranController.class).sendHORequest(link, primary.get());
293 String poll = queue[0].poll(5, TimeUnit.SECONDS);
294
295 if (poll != null) {
slowr60d4d102017-08-16 18:33:58 -0700296 return ResponseHelper.getResponse(
297 mapper(),
298 ResponseHelper.statusCode.OK,
299 "Handoff Response",
300 poll
301 );
slowr077957a2017-08-16 11:54:22 -0700302 } else {
slowr60d4d102017-08-16 18:33:58 -0700303 return ResponseHelper.getResponse(
304 mapper(),
305 ResponseHelper.statusCode.REQUEST_TIMEOUT,
306 "Handoff Timeout",
307 "eNodeB did not send a HOComplete/HOFailure on time"
308 );
slowr077957a2017-08-16 11:54:22 -0700309 }
310 } else {
311 link.setType(RnibLink.Type.SERVING_PRIMARY);
slowr60d4d102017-08-16 18:33:58 -0700312 return ResponseHelper.getResponse(
313 mapper(),
314 ResponseHelper.statusCode.OK,
315 "OK",
316 "Link set to primary"
317 );
slowr077957a2017-08-16 11:54:22 -0700318 }
319 }
slowr89c2ac12017-08-15 16:20:06 -0700320 }
321 } else if (newType.equals(RnibLink.Type.NON_SERVING)) {
322 switch (link.getType()) {
323 case NON_SERVING:
slowr60d4d102017-08-16 18:33:58 -0700324 return ResponseHelper.getResponse(
325 mapper(),
326 ResponseHelper.statusCode.BAD_REQUEST,
327 "Bad Request",
328 "Link is already a primary link"
329 );
slowr89c2ac12017-08-15 16:20:06 -0700330 case SERVING_PRIMARY:
slowr60d4d102017-08-16 18:33:58 -0700331 return ResponseHelper.getResponse(
332 mapper(),
333 ResponseHelper.statusCode.BAD_REQUEST,
334 "Bad Request",
335 "Cannot modify a primary link"
336 );
slowr89c2ac12017-08-15 16:20:06 -0700337 case SERVING_SECONDARY_CA:
338 case SERVING_SECONDARY_DC:
339 if (get(XranController.class).sendScellDelete(link)) {
slowr60d4d102017-08-16 18:33:58 -0700340 return ResponseHelper.getResponse(
341 mapper(),
342 ResponseHelper.statusCode.OK,
343 "OK",
344 "Link set to non-serving"
345 );
slowr89c2ac12017-08-15 16:20:06 -0700346 } else {
slowr60d4d102017-08-16 18:33:58 -0700347 return ResponseHelper.getResponse(
348 mapper(),
349 ResponseHelper.statusCode.NOT_FOUND,
350 "Not Found",
351 "Could not find cell config report to construct Scell Delete"
352 );
slowr89c2ac12017-08-15 16:20:06 -0700353 }
354 }
355 } else if (newType.equals(RnibLink.Type.SERVING_SECONDARY_CA)) {
356 switch (link.getType()) {
357 case SERVING_PRIMARY:
slowr60d4d102017-08-16 18:33:58 -0700358 return ResponseHelper.getResponse(
359 mapper(),
360 ResponseHelper.statusCode.BAD_REQUEST,
361 "Bad Request",
362 "Cannot modify a primary link"
363 );
slowr89c2ac12017-08-15 16:20:06 -0700364 case SERVING_SECONDARY_DC:
365 case NON_SERVING:
366 queue[0] = get(XranController.class).sendScellAdd(link);
367 String poll = queue[0].poll(5, TimeUnit.SECONDS);
368 if (poll != null) {
slowr60d4d102017-08-16 18:33:58 -0700369 return ResponseHelper.getResponse(
370 mapper(),
371 ResponseHelper.statusCode.OK,
372 "ScellAdd Response",
373 poll
374 );
slowr89c2ac12017-08-15 16:20:06 -0700375 } else {
slowr60d4d102017-08-16 18:33:58 -0700376 return ResponseHelper.getResponse(
377 mapper(),
378 ResponseHelper.statusCode.REQUEST_TIMEOUT,
379 "ScellAdd Timeout",
380 "eNodeB did not send a ScellAddStatus on time"
381 );
slowr89c2ac12017-08-15 16:20:06 -0700382 }
383 case SERVING_SECONDARY_CA:
slowr60d4d102017-08-16 18:33:58 -0700384 return ResponseHelper.getResponse(
385 mapper(),
386 ResponseHelper.statusCode.BAD_REQUEST,
387 "Bad Request",
388 "Link is already a secondary CA link"
389 );
slowr89c2ac12017-08-15 16:20:06 -0700390 }
391 }
392
slowr60d4d102017-08-16 18:33:58 -0700393 return ResponseHelper.getResponse(
394 mapper(),
slowr73b4eae2017-08-17 16:09:09 -0700395 ResponseHelper.statusCode.BAD_REQUEST,
396 "Bad Request",
397 "The command you specified is not implemented or doesn't exist."
slowr60d4d102017-08-16 18:33:58 -0700398 );
slowr89c2ac12017-08-15 16:20:06 -0700399 }
400
401 private Response handleTrafficChange(RnibLink link, JsonNode trafficpercent) {
402 JsonNode jsonNode = trafficpercent.path("traffic-percent-dl");
403 if (!jsonNode.isMissingNode()) {
404 link.getTrafficPercent().setTrafficPercentDl(new BerInteger(jsonNode.asInt()));
405 }
406
407 jsonNode = trafficpercent.path("traffic-percent-ul");
408 if (!jsonNode.isMissingNode()) {
409 link.getTrafficPercent().setTrafficPercentUl(new BerInteger(jsonNode.asInt()));
410 }
411
slowr60d4d102017-08-16 18:33:58 -0700412 return ResponseHelper.getResponse(
413 mapper(),
414 ResponseHelper.statusCode.OK,
415 "OK",
416 "Traffic Percent changed"
417 );
slowr89c2ac12017-08-15 16:20:06 -0700418 }
419
420 private Response handleRRMChange(RnibLink link, JsonNode rrmConf) throws InterruptedException {
421 final SynchronousQueue<String>[] queue = new SynchronousQueue[1];
422 get(XranStore.class).modifyLinkRrmConf(link, rrmConf);
slowr73b4eae2017-08-17 16:09:09 -0700423 boolean isxICIC = link.getLinkId().getCell().getVersion() <= 3;
slowr89c2ac12017-08-15 16:20:06 -0700424
slowr73b4eae2017-08-17 16:09:09 -0700425 queue[0] = get(XranController.class).sendModifiedRRMConf(link.getRrmParameters(),
426 isxICIC);
427
428 if (isxICIC) {
slowr60d4d102017-08-16 18:33:58 -0700429 return ResponseHelper.getResponse(
430 mapper(),
431 ResponseHelper.statusCode.OK,
slowr73b4eae2017-08-17 16:09:09 -0700432 "OK",
433 "xICIC was sent successfully"
slowr60d4d102017-08-16 18:33:58 -0700434 );
slowr89c2ac12017-08-15 16:20:06 -0700435 } else {
slowr73b4eae2017-08-17 16:09:09 -0700436 String poll = queue[0].poll(5, TimeUnit.SECONDS);
437
438 if (poll != null) {
439 return ResponseHelper.getResponse(
440 mapper(),
441 ResponseHelper.statusCode.OK,
442 "RRMConfig Response",
443 poll
444 );
445 } else {
446 return ResponseHelper.getResponse(
447 mapper(),
448 ResponseHelper.statusCode.REQUEST_TIMEOUT,
449 "RRMConfig Timeout",
450 "eNodeB did not send a RRMConfingStatus on time"
451 );
452 }
slowr89c2ac12017-08-15 16:20:06 -0700453 }
454 }
slowr13fa5b02017-08-08 16:32:31 -0700455}