blob: 1c91bac158d4e49c42524197995ecf36113d2886 [file] [log] [blame]
slowr13fa5b02017-08-08 16:32:31 -07001/*
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -08002 * Copyright 2017-present Open Networking Foundation
slowr13fa5b02017-08-08 16:32:31 -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 */
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -080016package org.onosproject.xran.impl.rest;
slowr13fa5b02017-08-08 16:32:31 -070017
18import com.fasterxml.jackson.databind.JsonNode;
19import com.fasterxml.jackson.databind.node.ObjectNode;
20import com.google.common.collect.Lists;
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -080021import io.swagger.annotations.ApiResponse;
22import io.swagger.annotations.ApiResponses;
slowr13fa5b02017-08-08 16:32:31 -070023import org.apache.commons.lang.exception.ExceptionUtils;
24import org.onosproject.rest.AbstractWebResource;
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -080025import org.onosproject.xran.XranService;
slowr13fa5b02017-08-08 16:32:31 -070026import org.onosproject.xran.XranStore;
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -080027import org.onosproject.xran.asn1lib.ber.types.BerInteger;
28import org.onosproject.xran.impl.entities.RnibCell;
29import org.onosproject.xran.impl.entities.RnibLink;
30import org.onosproject.xran.impl.entities.RnibUe;
slowr13fa5b02017-08-08 16:32:31 -070031import org.slf4j.Logger;
32import org.slf4j.LoggerFactory;
33
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -080034import javax.ws.rs.Consumes;
slowr60d4d102017-08-16 18:33:58 -070035import javax.ws.rs.DefaultValue;
36import javax.ws.rs.GET;
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -080037import javax.ws.rs.PATCH;
slowr577f3222017-08-28 10:49:08 -070038import javax.ws.rs.POST;
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -080039import javax.ws.rs.Path;
slowr577f3222017-08-28 10:49:08 -070040import javax.ws.rs.PathParam;
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -080041import 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;
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -080046import java.net.HttpURLConnection;
slowr13fa5b02017-08-08 16:32:31 -070047import java.util.List;
slowr67d05e42017-08-11 20:37:22 -070048import java.util.Optional;
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
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -080060 private XranStore xranStore;
61 private XranService xranService;
slowr60d4d102017-08-16 18:33:58 -070062
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -080063 public LinkWebResource() {
64 xranStore = get(XranStore.class);
65 xranService = get(XranService.class);
slowr60d4d102017-08-16 18:33:58 -070066 }
67
slowr13fa5b02017-08-08 16:32:31 -070068 /**
slowr577f3222017-08-28 10:49:08 -070069 * List all the links originating or terminating at cell/UE OR list the link connecting between cell and UE.
slowr13fa5b02017-08-08 16:32:31 -070070 *
slowr577f3222017-08-28 10:49:08 -070071 * @param eciHex EutranCellIdentifier in binary
72 * @param ue UE ID
73 * @return Response
slowr13fa5b02017-08-08 16:32:31 -070074 */
75 @GET
76 @Produces(MediaType.APPLICATION_JSON)
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -080077 @ApiResponses(value = {
78 @ApiResponse(code = 200, message = "HTTP_OK"),
79 @ApiResponse(code = 500, message = "HTTP_INTERNAL_ERROR"),
80 @ApiResponse(code = 404, message = "HTTP_NOT_FOUND")
81 })
slowr13fa5b02017-08-08 16:32:31 -070082 public Response getLinksBetween(@DefaultValue("") @QueryParam("cell") String eciHex,
slowr8ddc2b12017-08-14 14:13:38 -070083 @DefaultValue("-1") @QueryParam("ue") long ue) {
slowr13fa5b02017-08-08 16:32:31 -070084 List<RnibLink> list = Lists.newArrayList();
85 if (!eciHex.isEmpty() && ue != -1) {
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -080086 xranStore.getLink(eciHex, ue).ifPresent(list::add);
slowr13fa5b02017-08-08 16:32:31 -070087 } else if (!eciHex.isEmpty()) {
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -080088 list.addAll(xranStore.getLinks(eciHex));
slowr13fa5b02017-08-08 16:32:31 -070089 } else if (ue != -1) {
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -080090 list.addAll(xranStore.getLinks(ue));
slowr13fa5b02017-08-08 16:32:31 -070091 } else {
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -080092 list.addAll(xranStore.getLinks());
slowr13fa5b02017-08-08 16:32:31 -070093 }
94
slowr60d4d102017-08-16 18:33:58 -070095 if (list.size() > 0) {
96 try {
97 JsonNode jsonNode = mapper().valueToTree(list);
98
99 return ResponseHelper.getResponse(
100 mapper(),
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800101 HttpURLConnection.HTTP_OK,
slowr60d4d102017-08-16 18:33:58 -0700102 jsonNode
103 );
104 } catch (Exception e) {
105 String fullStackTrace = ExceptionUtils.getFullStackTrace(e);
106 log.error(fullStackTrace);
107 e.printStackTrace();
108
109 return ResponseHelper.getResponse(
110 mapper(),
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800111 HttpURLConnection.HTTP_INTERNAL_ERROR,
slowr60d4d102017-08-16 18:33:58 -0700112 "Exception",
113 fullStackTrace
114 );
115 }
slowr13fa5b02017-08-08 16:32:31 -0700116 }
slowr60d4d102017-08-16 18:33:58 -0700117
118 return ResponseHelper.getResponse(
119 mapper(),
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800120 HttpURLConnection.HTTP_NOT_FOUND,
slowr60d4d102017-08-16 18:33:58 -0700121 "Not Found",
122 "Specified links not found"
123 );
slowr13fa5b02017-08-08 16:32:31 -0700124 }
125
126 /**
slowr577f3222017-08-28 10:49:08 -0700127 * Modify the link.
slowr13fa5b02017-08-08 16:32:31 -0700128 *
slowr577f3222017-08-28 10:49:08 -0700129 * @param src CELL ECI in binary
130 * @param dst UE ID
131 * @param stream Parameter on basis of which link is to be modified
132 * @return Response
slowr13fa5b02017-08-08 16:32:31 -0700133 */
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800134 @PATCH
slowr13fa5b02017-08-08 16:32:31 -0700135 @Path("{src},{dst}")
136 @Consumes(MediaType.APPLICATION_JSON)
slowr60d4d102017-08-16 18:33:58 -0700137 @Produces(MediaType.APPLICATION_JSON)
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800138 @ApiResponses(value = {
139 @ApiResponse(code = 200, message = "HTTP_OK"),
140 @ApiResponse(code = 501, message = "HTTP_NOT_IMPLEMENTED"),
141 @ApiResponse(code = 500, message = "HTTP_INTERNAL_ERROR"),
142 @ApiResponse(code = 404, message = "HTTP_NOT_FOUND"),
143 @ApiResponse(code = 400, message = "HTTP_BAD_REQUEST"),
144 @ApiResponse(code = 408, message = "HTTP_CLIENT_TIMEOUT")
145 })
slowr13fa5b02017-08-08 16:32:31 -0700146 public Response patchLinks(@PathParam("src") String src, @PathParam("dst") long dst, InputStream stream) {
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800147 return xranStore.getLink(src, dst).map(link -> {
slowr8ddc2b12017-08-14 14:13:38 -0700148 try {
slowr67d05e42017-08-11 20:37:22 -0700149 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
slowr13fa5b02017-08-08 16:32:31 -0700150
slowr577f3222017-08-28 10:49:08 -0700151 // Modify link based on Type
slowr89c2ac12017-08-15 16:20:06 -0700152 JsonNode type = jsonTree.path("type");
153 if (!type.isMissingNode()) {
154 RnibLink.Type anEnum = RnibLink.Type.getEnum(type.asText());
155 return handleTypeChange(link, anEnum);
slowr67d05e42017-08-11 20:37:22 -0700156 }
slowr13fa5b02017-08-08 16:32:31 -0700157
slowr577f3222017-08-28 10:49:08 -0700158 // Modify link based on traffic percent
slowr89c2ac12017-08-15 16:20:06 -0700159 JsonNode trafficpercent = jsonTree.path("trafficpercent");
160 if (!trafficpercent.isMissingNode()) {
161 return handleTrafficChange(link, trafficpercent);
slowr67d05e42017-08-11 20:37:22 -0700162 }
slowr13fa5b02017-08-08 16:32:31 -0700163
slowr577f3222017-08-28 10:49:08 -0700164 // Modify link based on RRMConf
slowr89c2ac12017-08-15 16:20:06 -0700165 JsonNode rrmConf = jsonTree.path("RRMConf");
166 if (!rrmConf.isMissingNode()) {
slowr577f3222017-08-28 10:49:08 -0700167 return handleRrmChange(link, rrmConf);
slowr8ddc2b12017-08-14 14:13:38 -0700168 }
169
slowrd19a83b2017-08-17 08:57:46 -0700170 return ResponseHelper.getResponse(
171 mapper(),
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800172 HttpURLConnection.HTTP_NOT_IMPLEMENTED,
slowrd19a83b2017-08-17 08:57:46 -0700173 "Not Implemented",
174 "The command you specified is not implemented or doesn't exist. We support " +
175 "type/RRMConf/traficpercent commands."
176 );
177
slowr8ddc2b12017-08-14 14:13:38 -0700178 } catch (Exception e) {
slowr60d4d102017-08-16 18:33:58 -0700179 String fullStackTrace = ExceptionUtils.getFullStackTrace(e);
180 log.error(fullStackTrace);
slowr8ddc2b12017-08-14 14:13:38 -0700181 e.printStackTrace();
slowr60d4d102017-08-16 18:33:58 -0700182
183 return ResponseHelper.getResponse(
184 mapper(),
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800185 HttpURLConnection.HTTP_INTERNAL_ERROR,
slowr60d4d102017-08-16 18:33:58 -0700186 "Exception",
187 fullStackTrace
188 );
slowr8ddc2b12017-08-14 14:13:38 -0700189 }
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800190 }).orElse(ResponseHelper.getResponse(
slowr60d4d102017-08-16 18:33:58 -0700191 mapper(),
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800192 HttpURLConnection.HTTP_NOT_FOUND,
slowr60d4d102017-08-16 18:33:58 -0700193 "Not Found",
194 "Link not found use POST request"
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800195 ));
slowr13fa5b02017-08-08 16:32:31 -0700196 }
197
198 /**
slowr577f3222017-08-28 10:49:08 -0700199 * Create link based on Type of the link.
slowr13fa5b02017-08-08 16:32:31 -0700200 *
slowr577f3222017-08-28 10:49:08 -0700201 * @param src CELL ECI in binary
202 * @param dst UE ID
203 * @param stream LinkType
204 * @return Response
slowr13fa5b02017-08-08 16:32:31 -0700205 */
206 @POST
207 @Path("{src},{dst}")
208 @Consumes(MediaType.APPLICATION_JSON)
slowr60d4d102017-08-16 18:33:58 -0700209 @Produces(MediaType.APPLICATION_JSON)
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800210 @ApiResponses(value = {
211 @ApiResponse(code = 200, message = "HTTP_OK"),
212 @ApiResponse(code = 501, message = "HTTP_NOT_IMPLEMENTED"),
213 @ApiResponse(code = 500, message = "HTTP_INTERNAL_ERROR"),
214 @ApiResponse(code = 404, message = "HTTP_NOT_FOUND"),
215 @ApiResponse(code = 400, message = "HTTP_BAD_REQUEST"),
216 @ApiResponse(code = 408, message = "HTTP_CLIENT_TIMEOUT"),
217 })
slowr13fa5b02017-08-08 16:32:31 -0700218 public Response postLinks(@PathParam("src") String src, @PathParam("dst") long dst, InputStream stream) {
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800219 Optional<RnibCell> cellOptional = xranStore.getCell(src);
220 Optional<RnibUe> ueOptional = xranStore.getUe(dst);
slowr89c2ac12017-08-15 16:20:06 -0700221
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800222 if (!cellOptional.isPresent()) {
slowr60d4d102017-08-16 18:33:58 -0700223 return ResponseHelper.getResponse(
224 mapper(),
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800225 HttpURLConnection.HTTP_NOT_FOUND,
slowr60d4d102017-08-16 18:33:58 -0700226 "Not Found",
227 "Cell " + src + " was not found"
228 );
slowr89c2ac12017-08-15 16:20:06 -0700229 }
230
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800231 if (!ueOptional.isPresent()) {
slowr60d4d102017-08-16 18:33:58 -0700232 return ResponseHelper.getResponse(
233 mapper(),
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800234 HttpURLConnection.HTTP_NOT_FOUND,
slowr60d4d102017-08-16 18:33:58 -0700235 "Not Found",
236 "Ue with " + dst + " was not found"
237 );
slowr89c2ac12017-08-15 16:20:06 -0700238 }
239
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800240 if (xranStore.getLink(cellOptional.get().getEcgi(), ueOptional.get().getId()) != null) {
slowr60d4d102017-08-16 18:33:58 -0700241 return ResponseHelper.getResponse(
242 mapper(),
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800243 HttpURLConnection.HTTP_BAD_REQUEST,
slowr60d4d102017-08-16 18:33:58 -0700244 "Bad Request",
245 "Link already exists use PATCH to modify"
246 );
slowr89c2ac12017-08-15 16:20:06 -0700247 }
248
slowr13fa5b02017-08-08 16:32:31 -0700249 try {
250 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
251
slowr89c2ac12017-08-15 16:20:06 -0700252 JsonNode type = jsonTree.path("type");
slowr13fa5b02017-08-08 16:32:31 -0700253
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800254 RnibLink link = new RnibLink(cellOptional.get(), ueOptional.get());
slowr077957a2017-08-16 11:54:22 -0700255 // store it as non-serving when creating link
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800256 xranStore.storeLink(link);
slowr89c2ac12017-08-15 16:20:06 -0700257 if (!type.isMissingNode()) {
slowr077957a2017-08-16 11:54:22 -0700258 return handleTypeChange(link, RnibLink.Type.getEnum(type.asText()));
slowr13fa5b02017-08-08 16:32:31 -0700259 }
slowr077957a2017-08-16 11:54:22 -0700260
261 JsonNode trafficpercent = jsonTree.path("trafficpercent");
262 if (!trafficpercent.isMissingNode()) {
263 return handleTrafficChange(link, trafficpercent);
264 }
265
266 JsonNode rrmConf = jsonTree.path("RRMConf");
267 if (!rrmConf.isMissingNode()) {
slowr577f3222017-08-28 10:49:08 -0700268 return handleRrmChange(link, rrmConf);
slowr077957a2017-08-16 11:54:22 -0700269 }
270
slowr13fa5b02017-08-08 16:32:31 -0700271 } catch (Exception e) {
slowr60d4d102017-08-16 18:33:58 -0700272 String fullStackTrace = ExceptionUtils.getFullStackTrace(e);
273 log.error(fullStackTrace);
slowr13fa5b02017-08-08 16:32:31 -0700274 e.printStackTrace();
slowr60d4d102017-08-16 18:33:58 -0700275
276 return ResponseHelper.getResponse(
277 mapper(),
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800278 HttpURLConnection.HTTP_INTERNAL_ERROR,
slowr60d4d102017-08-16 18:33:58 -0700279 "Exception",
280 fullStackTrace
281 );
slowr13fa5b02017-08-08 16:32:31 -0700282 }
283
slowr60d4d102017-08-16 18:33:58 -0700284 return ResponseHelper.getResponse(
285 mapper(),
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800286 HttpURLConnection.HTTP_BAD_REQUEST,
slowr73b4eae2017-08-17 16:09:09 -0700287 "Bad Request",
slowr577f3222017-08-28 10:49:08 -0700288 "The command you specified is not implemented " +
289 "or doesn't exist. We support " +
slowrd19a83b2017-08-17 08:57:46 -0700290 "type/RRMConf/traficpercent commands."
slowr60d4d102017-08-16 18:33:58 -0700291 );
slowr13fa5b02017-08-08 16:32:31 -0700292 }
293
slowr577f3222017-08-28 10:49:08 -0700294
295 /**
296 * Change link based on type of the link.
297 *
298 * @param link Link
299 * @param newType LinkType
300 * @return Response
301 * @throws InterruptedException Interrupted queue
302 */
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800303
slowr577f3222017-08-28 10:49:08 -0700304 private Response handleTypeChange(RnibLink link, RnibLink.Type newType)
305 throws InterruptedException {
slowr89c2ac12017-08-15 16:20:06 -0700306 if (newType.equals(RnibLink.Type.SERVING_PRIMARY)) {
slowr077957a2017-08-16 11:54:22 -0700307 switch (link.getType()) {
308 case SERVING_PRIMARY: {
slowr60d4d102017-08-16 18:33:58 -0700309 return ResponseHelper.getResponse(
310 mapper(),
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800311 HttpURLConnection.HTTP_BAD_REQUEST,
slowr60d4d102017-08-16 18:33:58 -0700312 "Bad Request",
313 "Link is already a primary link"
314 );
slowr89c2ac12017-08-15 16:20:06 -0700315 }
slowr077957a2017-08-16 11:54:22 -0700316 case SERVING_SECONDARY_CA:
317 case SERVING_SECONDARY_DC:
318 case NON_SERVING: {
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800319 List<RnibLink> linksByUeId = xranStore
320 .getLinks(link.getLinkId().getUeId());
slowr077957a2017-08-16 11:54:22 -0700321
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800322 return linksByUeId.stream()
slowr077957a2017-08-16 11:54:22 -0700323 .filter(l -> l.getType().equals(RnibLink.Type.SERVING_PRIMARY))
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800324 .findFirst().map(primaryLink -> xranService.sendHoRequest(link, primaryLink)
325 .flatMap(q -> {
326 try {
327 return Optional.ofNullable(q.poll(xranService
328 .getNorthboundTimeout(), TimeUnit.MILLISECONDS));
329 } catch (InterruptedException e) {
330 log.error(ExceptionUtils.getFullStackTrace(e));
331 return Optional.empty();
332 }
333 }).map(poll ->
334 ResponseHelper.getResponse(
335 mapper(),
336 HttpURLConnection.HTTP_OK,
337 "Handoff Response",
338 poll
339 )
340 ).orElse(
341 ResponseHelper.getResponse(
342 mapper(),
343 HttpURLConnection.HTTP_CLIENT_TIMEOUT,
344 "Handoff Timeout",
345 "eNodeB did not send a HOComplete/HOFailure on time"
346 )
347 )
348 )
349 .orElseGet(
350 () -> {
351 link.setType(RnibLink.Type.SERVING_PRIMARY);
352 return ResponseHelper.getResponse(
353 mapper(),
354 HttpURLConnection.HTTP_OK,
355 "OK",
356 "Link set to primary"
357 );
358 }
slowr60d4d102017-08-16 18:33:58 -0700359 );
slowr077957a2017-08-16 11:54:22 -0700360 }
slowr577f3222017-08-28 10:49:08 -0700361 default:
slowr89c2ac12017-08-15 16:20:06 -0700362 }
363 } else if (newType.equals(RnibLink.Type.NON_SERVING)) {
364 switch (link.getType()) {
slowr577f3222017-08-28 10:49:08 -0700365 case NON_SERVING: {
slowr60d4d102017-08-16 18:33:58 -0700366 return ResponseHelper.getResponse(
367 mapper(),
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800368 HttpURLConnection.HTTP_BAD_REQUEST,
slowr60d4d102017-08-16 18:33:58 -0700369 "Bad Request",
370 "Link is already a primary link"
371 );
slowr577f3222017-08-28 10:49:08 -0700372 }
373 case SERVING_PRIMARY: {
slowr60d4d102017-08-16 18:33:58 -0700374 return ResponseHelper.getResponse(
375 mapper(),
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800376 HttpURLConnection.HTTP_BAD_REQUEST,
slowr60d4d102017-08-16 18:33:58 -0700377 "Bad Request",
378 "Cannot modify a primary link"
379 );
slowr577f3222017-08-28 10:49:08 -0700380 }
slowr89c2ac12017-08-15 16:20:06 -0700381 case SERVING_SECONDARY_CA:
slowr577f3222017-08-28 10:49:08 -0700382 case SERVING_SECONDARY_DC: {
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800383 if (xranService.sendScellDelete(link)) {
slowr60d4d102017-08-16 18:33:58 -0700384 return ResponseHelper.getResponse(
385 mapper(),
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800386 HttpURLConnection.HTTP_OK,
slowr60d4d102017-08-16 18:33:58 -0700387 "OK",
388 "Link set to non-serving"
389 );
slowr89c2ac12017-08-15 16:20:06 -0700390 } else {
slowr60d4d102017-08-16 18:33:58 -0700391 return ResponseHelper.getResponse(
392 mapper(),
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800393 HttpURLConnection.HTTP_NOT_FOUND,
slowr60d4d102017-08-16 18:33:58 -0700394 "Not Found",
395 "Could not find cell config report to construct Scell Delete"
396 );
slowr89c2ac12017-08-15 16:20:06 -0700397 }
slowr577f3222017-08-28 10:49:08 -0700398 }
399 default:
slowr89c2ac12017-08-15 16:20:06 -0700400 }
401 } else if (newType.equals(RnibLink.Type.SERVING_SECONDARY_CA)) {
402 switch (link.getType()) {
slowr577f3222017-08-28 10:49:08 -0700403 case SERVING_PRIMARY: {
slowr60d4d102017-08-16 18:33:58 -0700404 return ResponseHelper.getResponse(
405 mapper(),
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800406 HttpURLConnection.HTTP_BAD_REQUEST,
slowr60d4d102017-08-16 18:33:58 -0700407 "Bad Request",
408 "Cannot modify a primary link"
409 );
slowr577f3222017-08-28 10:49:08 -0700410 }
slowr89c2ac12017-08-15 16:20:06 -0700411 case SERVING_SECONDARY_DC:
slowr577f3222017-08-28 10:49:08 -0700412 case NON_SERVING: {
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800413 return xranService.sendScellAdd(link).flatMap(queue -> {
414 try {
415 return Optional.ofNullable(queue.poll(xranService
416 .getNorthboundTimeout(), TimeUnit.MILLISECONDS));
417 } catch (InterruptedException e) {
418 log.error(ExceptionUtils.getFullStackTrace(e));
419 return Optional.empty();
420 }
421 }).map(poll ->
422 ResponseHelper.getResponse(
423 mapper(),
424 HttpURLConnection.HTTP_OK,
425 "ScellAdd Response",
426 poll
427 )
428 ).orElse(
429 ResponseHelper.getResponse(
430 mapper(),
431 HttpURLConnection.HTTP_CLIENT_TIMEOUT,
432 "ScellAdd Timeout",
433 "eNodeB did not send a ScellAddStatus on time"
434 )
435 );
slowr577f3222017-08-28 10:49:08 -0700436 }
437 case SERVING_SECONDARY_CA: {
slowr60d4d102017-08-16 18:33:58 -0700438 return ResponseHelper.getResponse(
439 mapper(),
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800440 HttpURLConnection.HTTP_BAD_REQUEST,
slowr60d4d102017-08-16 18:33:58 -0700441 "Bad Request",
442 "Link is already a secondary CA link"
443 );
slowr577f3222017-08-28 10:49:08 -0700444 }
445 default:
slowr89c2ac12017-08-15 16:20:06 -0700446 }
447 }
448
slowr60d4d102017-08-16 18:33:58 -0700449 return ResponseHelper.getResponse(
450 mapper(),
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800451 HttpURLConnection.HTTP_BAD_REQUEST,
slowr73b4eae2017-08-17 16:09:09 -0700452 "Bad Request",
453 "The command you specified is not implemented or doesn't exist."
slowr60d4d102017-08-16 18:33:58 -0700454 );
slowr89c2ac12017-08-15 16:20:06 -0700455 }
456
slowr577f3222017-08-28 10:49:08 -0700457 /**
458 * Modify link based on the traffic percent.
459 *
460 * @param link Link
461 * @param trafficpercent Traffic Percent of the link to be modified
462 * @return Response
463 */
slowr89c2ac12017-08-15 16:20:06 -0700464 private Response handleTrafficChange(RnibLink link, JsonNode trafficpercent) {
465 JsonNode jsonNode = trafficpercent.path("traffic-percent-dl");
466 if (!jsonNode.isMissingNode()) {
467 link.getTrafficPercent().setTrafficPercentDl(new BerInteger(jsonNode.asInt()));
468 }
469
470 jsonNode = trafficpercent.path("traffic-percent-ul");
471 if (!jsonNode.isMissingNode()) {
472 link.getTrafficPercent().setTrafficPercentUl(new BerInteger(jsonNode.asInt()));
473 }
474
slowr60d4d102017-08-16 18:33:58 -0700475 return ResponseHelper.getResponse(
476 mapper(),
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800477 HttpURLConnection.HTTP_OK,
slowr60d4d102017-08-16 18:33:58 -0700478 "OK",
479 "Traffic Percent changed"
480 );
slowr89c2ac12017-08-15 16:20:06 -0700481 }
482
slowr577f3222017-08-28 10:49:08 -0700483 /**
484 * Modify link based on RRMConf parameters.
485 *
486 * @param link Link
487 * @param rrmConf RRMConfig of the Link to be modified
488 * @return Response
489 * @throws InterruptedException Interrupted queue
490 */
491 private Response handleRrmChange(RnibLink link, JsonNode rrmConf) throws InterruptedException {
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800492 xranStore.modifyLinkRrmConf(link, rrmConf);
slowr89c2ac12017-08-15 16:20:06 -0700493
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800494 return xranService.sendModifiedRrm(link.getRrmParameters()).flatMap(queue -> {
495 try {
496 return Optional.ofNullable(queue.poll(xranService
497 .getNorthboundTimeout(), TimeUnit.MILLISECONDS));
498 } catch (InterruptedException e) {
499 log.error(ExceptionUtils.getFullStackTrace(e));
500 return Optional.empty();
501 }
502 }).map(poll ->
503 ResponseHelper.getResponse(
slowr73b4eae2017-08-17 16:09:09 -0700504 mapper(),
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800505 HttpURLConnection.HTTP_OK,
slowr73b4eae2017-08-17 16:09:09 -0700506 "RRMConfig Response",
507 poll
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800508 )
509 ).orElse(
510 ResponseHelper.getResponse(
slowr73b4eae2017-08-17 16:09:09 -0700511 mapper(),
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800512 HttpURLConnection.HTTP_CLIENT_TIMEOUT,
slowr73b4eae2017-08-17 16:09:09 -0700513 "RRMConfig Timeout",
514 "eNodeB did not send a RRMConfingStatus on time"
Dimitrios Mavrommatis96b255a2017-12-06 13:09:25 -0800515 )
516 );
517
slowr89c2ac12017-08-15 16:20:06 -0700518 }
slowr13fa5b02017-08-08 16:32:31 -0700519}