blob: 4d8dc112a407d24679b6580e10bd61ba9e2f84fb [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
153 } catch (Exception e) {
slowr60d4d102017-08-16 18:33:58 -0700154 String fullStackTrace = ExceptionUtils.getFullStackTrace(e);
155 log.error(fullStackTrace);
slowr8ddc2b12017-08-14 14:13:38 -0700156 e.printStackTrace();
slowr60d4d102017-08-16 18:33:58 -0700157
158 return ResponseHelper.getResponse(
159 mapper(),
160 ResponseHelper.statusCode.INTERNAL_SERVER_ERROR,
161 "Exception",
162 fullStackTrace
163 );
slowr8ddc2b12017-08-14 14:13:38 -0700164 }
165 }
slowr60d4d102017-08-16 18:33:58 -0700166
167 return ResponseHelper.getResponse(
168 mapper(),
169 ResponseHelper.statusCode.NOT_FOUND,
170 "Not Found",
171 "Link not found use POST request"
172 );
slowr13fa5b02017-08-08 16:32:31 -0700173 }
174
175 /**
176 * test.
177 *
178 * @param src test
179 * @param dst test
180 * @param stream test
181 * @return test
182 */
183 @POST
184 @Path("{src},{dst}")
185 @Consumes(MediaType.APPLICATION_JSON)
slowr60d4d102017-08-16 18:33:58 -0700186 @Produces(MediaType.APPLICATION_JSON)
slowr13fa5b02017-08-08 16:32:31 -0700187 public Response postLinks(@PathParam("src") String src, @PathParam("dst") long dst, InputStream stream) {
slowr89c2ac12017-08-15 16:20:06 -0700188 RnibCell cell = get(XranStore.class).getCell(src);
189 RnibUe ue = get(XranStore.class).getUe(dst);
190
191 if (cell == null) {
slowr60d4d102017-08-16 18:33:58 -0700192 return ResponseHelper.getResponse(
193 mapper(),
194 ResponseHelper.statusCode.NOT_FOUND,
195 "Not Found",
196 "Cell " + src + " was not found"
197 );
slowr89c2ac12017-08-15 16:20:06 -0700198 }
199
200 if (ue == null) {
slowr60d4d102017-08-16 18:33:58 -0700201 return ResponseHelper.getResponse(
202 mapper(),
203 ResponseHelper.statusCode.NOT_FOUND,
204 "Not Found",
205 "Ue with " + dst + " was not found"
206 );
slowr89c2ac12017-08-15 16:20:06 -0700207 }
208
209 if (get(XranStore.class).getLink(cell.getEcgi(), ue.getMmeS1apId()) != null) {
slowr60d4d102017-08-16 18:33:58 -0700210 return ResponseHelper.getResponse(
211 mapper(),
212 ResponseHelper.statusCode.BAD_REQUEST,
213 "Bad Request",
214 "Link already exists use PATCH to modify"
215 );
slowr89c2ac12017-08-15 16:20:06 -0700216 }
217
slowr13fa5b02017-08-08 16:32:31 -0700218 try {
219 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
220
slowr89c2ac12017-08-15 16:20:06 -0700221 JsonNode type = jsonTree.path("type");
slowr13fa5b02017-08-08 16:32:31 -0700222
slowr077957a2017-08-16 11:54:22 -0700223 RnibLink link = new RnibLink(cell, ue);
224 // store it as non-serving when creating link
225 get(XranStore.class).storeLink(link);
slowr89c2ac12017-08-15 16:20:06 -0700226 if (!type.isMissingNode()) {
slowr077957a2017-08-16 11:54:22 -0700227 return handleTypeChange(link, RnibLink.Type.getEnum(type.asText()));
slowr13fa5b02017-08-08 16:32:31 -0700228 }
slowr077957a2017-08-16 11:54:22 -0700229
230 JsonNode trafficpercent = jsonTree.path("trafficpercent");
231 if (!trafficpercent.isMissingNode()) {
232 return handleTrafficChange(link, trafficpercent);
233 }
234
235 JsonNode rrmConf = jsonTree.path("RRMConf");
236 if (!rrmConf.isMissingNode()) {
237 return handleRRMChange(link, rrmConf);
238 }
239
slowr13fa5b02017-08-08 16:32:31 -0700240 } catch (Exception e) {
slowr60d4d102017-08-16 18:33:58 -0700241 String fullStackTrace = ExceptionUtils.getFullStackTrace(e);
242 log.error(fullStackTrace);
slowr13fa5b02017-08-08 16:32:31 -0700243 e.printStackTrace();
slowr60d4d102017-08-16 18:33:58 -0700244
245 return ResponseHelper.getResponse(
246 mapper(),
247 ResponseHelper.statusCode.INTERNAL_SERVER_ERROR,
248 "Exception",
249 fullStackTrace
250 );
slowr13fa5b02017-08-08 16:32:31 -0700251 }
252
slowr60d4d102017-08-16 18:33:58 -0700253 return ResponseHelper.getResponse(
254 mapper(),
255 ResponseHelper.statusCode.NOT_IMPLEMENTED,
256 "Not Implemented",
257 "This request is not implemented"
258 );
slowr13fa5b02017-08-08 16:32:31 -0700259 }
260
slowr89c2ac12017-08-15 16:20:06 -0700261 private Response handleTypeChange(RnibLink link, RnibLink.Type newType) throws InterruptedException {
262 final SynchronousQueue<String>[] queue = new SynchronousQueue[1];
263
264 if (newType.equals(RnibLink.Type.SERVING_PRIMARY)) {
slowr077957a2017-08-16 11:54:22 -0700265 switch (link.getType()) {
266 case SERVING_PRIMARY: {
slowr60d4d102017-08-16 18:33:58 -0700267 return ResponseHelper.getResponse(
268 mapper(),
269 ResponseHelper.statusCode.BAD_REQUEST,
270 "Bad Request",
271 "Link is already a primary link"
272 );
slowr89c2ac12017-08-15 16:20:06 -0700273 }
slowr077957a2017-08-16 11:54:22 -0700274 case SERVING_SECONDARY_CA:
275 case SERVING_SECONDARY_DC:
276 case NON_SERVING: {
277 List<RnibLink> linksByUeId = get(XranStore.class).getLinksByUeId(link.getLinkId().getMmeues1apid().longValue());
278
279 Optional<RnibLink> primary = linksByUeId.stream()
280 .filter(l -> l.getType().equals(RnibLink.Type.SERVING_PRIMARY))
281 .findFirst();
282 if (primary.isPresent()) {
283 queue[0] = get(XranController.class).sendHORequest(link, primary.get());
284 String poll = queue[0].poll(5, TimeUnit.SECONDS);
285
286 if (poll != null) {
slowr60d4d102017-08-16 18:33:58 -0700287 return ResponseHelper.getResponse(
288 mapper(),
289 ResponseHelper.statusCode.OK,
290 "Handoff Response",
291 poll
292 );
slowr077957a2017-08-16 11:54:22 -0700293 } else {
slowr60d4d102017-08-16 18:33:58 -0700294 return ResponseHelper.getResponse(
295 mapper(),
296 ResponseHelper.statusCode.REQUEST_TIMEOUT,
297 "Handoff Timeout",
298 "eNodeB did not send a HOComplete/HOFailure on time"
299 );
slowr077957a2017-08-16 11:54:22 -0700300 }
301 } else {
302 link.setType(RnibLink.Type.SERVING_PRIMARY);
slowr60d4d102017-08-16 18:33:58 -0700303 return ResponseHelper.getResponse(
304 mapper(),
305 ResponseHelper.statusCode.OK,
306 "OK",
307 "Link set to primary"
308 );
slowr077957a2017-08-16 11:54:22 -0700309 }
310 }
slowr89c2ac12017-08-15 16:20:06 -0700311 }
312 } else if (newType.equals(RnibLink.Type.NON_SERVING)) {
313 switch (link.getType()) {
314 case NON_SERVING:
slowr60d4d102017-08-16 18:33:58 -0700315 return ResponseHelper.getResponse(
316 mapper(),
317 ResponseHelper.statusCode.BAD_REQUEST,
318 "Bad Request",
319 "Link is already a primary link"
320 );
slowr89c2ac12017-08-15 16:20:06 -0700321 case SERVING_PRIMARY:
slowr60d4d102017-08-16 18:33:58 -0700322 return ResponseHelper.getResponse(
323 mapper(),
324 ResponseHelper.statusCode.BAD_REQUEST,
325 "Bad Request",
326 "Cannot modify a primary link"
327 );
slowr89c2ac12017-08-15 16:20:06 -0700328 case SERVING_SECONDARY_CA:
329 case SERVING_SECONDARY_DC:
330 if (get(XranController.class).sendScellDelete(link)) {
slowr60d4d102017-08-16 18:33:58 -0700331 return ResponseHelper.getResponse(
332 mapper(),
333 ResponseHelper.statusCode.OK,
334 "OK",
335 "Link set to non-serving"
336 );
slowr89c2ac12017-08-15 16:20:06 -0700337 } else {
slowr60d4d102017-08-16 18:33:58 -0700338 return ResponseHelper.getResponse(
339 mapper(),
340 ResponseHelper.statusCode.NOT_FOUND,
341 "Not Found",
342 "Could not find cell config report to construct Scell Delete"
343 );
slowr89c2ac12017-08-15 16:20:06 -0700344 }
345 }
346 } else if (newType.equals(RnibLink.Type.SERVING_SECONDARY_CA)) {
347 switch (link.getType()) {
348 case SERVING_PRIMARY:
slowr60d4d102017-08-16 18:33:58 -0700349 return ResponseHelper.getResponse(
350 mapper(),
351 ResponseHelper.statusCode.BAD_REQUEST,
352 "Bad Request",
353 "Cannot modify a primary link"
354 );
slowr89c2ac12017-08-15 16:20:06 -0700355 case SERVING_SECONDARY_DC:
356 case NON_SERVING:
357 queue[0] = get(XranController.class).sendScellAdd(link);
358 String poll = queue[0].poll(5, TimeUnit.SECONDS);
359 if (poll != null) {
slowr60d4d102017-08-16 18:33:58 -0700360 return ResponseHelper.getResponse(
361 mapper(),
362 ResponseHelper.statusCode.OK,
363 "ScellAdd Response",
364 poll
365 );
slowr89c2ac12017-08-15 16:20:06 -0700366 } else {
slowr60d4d102017-08-16 18:33:58 -0700367 return ResponseHelper.getResponse(
368 mapper(),
369 ResponseHelper.statusCode.REQUEST_TIMEOUT,
370 "ScellAdd Timeout",
371 "eNodeB did not send a ScellAddStatus on time"
372 );
slowr89c2ac12017-08-15 16:20:06 -0700373 }
374 case SERVING_SECONDARY_CA:
slowr60d4d102017-08-16 18:33:58 -0700375 return ResponseHelper.getResponse(
376 mapper(),
377 ResponseHelper.statusCode.BAD_REQUEST,
378 "Bad Request",
379 "Link is already a secondary CA link"
380 );
slowr89c2ac12017-08-15 16:20:06 -0700381 }
382 }
383
slowr60d4d102017-08-16 18:33:58 -0700384 return ResponseHelper.getResponse(
385 mapper(),
386 ResponseHelper.statusCode.NOT_IMPLEMENTED,
387 "Not Implemented",
388 "This request is not implemented"
389 );
slowr89c2ac12017-08-15 16:20:06 -0700390 }
391
392 private Response handleTrafficChange(RnibLink link, JsonNode trafficpercent) {
393 JsonNode jsonNode = trafficpercent.path("traffic-percent-dl");
394 if (!jsonNode.isMissingNode()) {
395 link.getTrafficPercent().setTrafficPercentDl(new BerInteger(jsonNode.asInt()));
396 }
397
398 jsonNode = trafficpercent.path("traffic-percent-ul");
399 if (!jsonNode.isMissingNode()) {
400 link.getTrafficPercent().setTrafficPercentUl(new BerInteger(jsonNode.asInt()));
401 }
402
slowr60d4d102017-08-16 18:33:58 -0700403 return ResponseHelper.getResponse(
404 mapper(),
405 ResponseHelper.statusCode.OK,
406 "OK",
407 "Traffic Percent changed"
408 );
slowr89c2ac12017-08-15 16:20:06 -0700409 }
410
411 private Response handleRRMChange(RnibLink link, JsonNode rrmConf) throws InterruptedException {
412 final SynchronousQueue<String>[] queue = new SynchronousQueue[1];
413 get(XranStore.class).modifyLinkRrmConf(link, rrmConf);
414 queue[0] = get(XranController.class).sendModifiedRRMConf(link.getRrmParameters(),
415 link.getLinkId().getCell().getVersion().equals("3"));
416 String poll = queue[0].poll(5, TimeUnit.SECONDS);
417
418 if (poll != null) {
slowr60d4d102017-08-16 18:33:58 -0700419 return ResponseHelper.getResponse(
420 mapper(),
421 ResponseHelper.statusCode.OK,
422 "RRMConfig Response",
423 poll
424 );
slowr89c2ac12017-08-15 16:20:06 -0700425 } else {
slowr60d4d102017-08-16 18:33:58 -0700426 return ResponseHelper.getResponse(
427 mapper(),
428 ResponseHelper.statusCode.REQUEST_TIMEOUT,
429 "RRMConfig Timeout",
430 "eNodeB did not send a RRMConfingStatus on time"
431 );
slowr89c2ac12017-08-15 16:20:06 -0700432 }
433 }
slowr13fa5b02017-08-08 16:32:31 -0700434}