blob: 8a85941b7e5b8b91703560b59e22b2771619eb1f [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
18import com.fasterxml.jackson.databind.JsonNode;
19import com.fasterxml.jackson.databind.node.ObjectNode;
20import com.google.common.collect.Lists;
21import org.apache.commons.lang.exception.ExceptionUtils;
22import org.onosproject.rest.AbstractWebResource;
23import org.onosproject.xran.XranStore;
24import org.onosproject.xran.annotations.Patch;
slowr67d05e42017-08-11 20:37:22 -070025import org.onosproject.xran.controller.XranController;
slowr89c2ac12017-08-15 16:20:06 -070026import org.onosproject.xran.entities.RnibCell;
slowr13fa5b02017-08-08 16:32:31 -070027import org.onosproject.xran.entities.RnibLink;
slowr89c2ac12017-08-15 16:20:06 -070028import org.onosproject.xran.entities.RnibUe;
slowr67d05e42017-08-11 20:37:22 -070029import org.openmuc.jasn1.ber.types.BerInteger;
slowr13fa5b02017-08-08 16:32:31 -070030import org.slf4j.Logger;
31import org.slf4j.LoggerFactory;
32
slowr89c2ac12017-08-15 16:20:06 -070033import javax.ws.rs.*;
slowr13fa5b02017-08-08 16:32:31 -070034import javax.ws.rs.core.MediaType;
35import javax.ws.rs.core.Response;
36import java.io.IOException;
37import java.io.InputStream;
38import java.util.List;
slowr67d05e42017-08-11 20:37:22 -070039import java.util.Optional;
40import java.util.concurrent.SynchronousQueue;
slowr8ddc2b12017-08-14 14:13:38 -070041import java.util.concurrent.TimeUnit;
slowr13fa5b02017-08-08 16:32:31 -070042
43/**
44 * Link web resource.
45 */
46@Path("links")
47public class LinkWebResource extends AbstractWebResource {
48
49 private static final Logger log =
50 LoggerFactory.getLogger(LinkWebResource.class);
51
52 /**
53 * test.
54 *
55 * @param eciHex test
56 * @param ue test
57 * @return test
58 */
59 @GET
60 @Produces(MediaType.APPLICATION_JSON)
61 public Response getLinksBetween(@DefaultValue("") @QueryParam("cell") String eciHex,
slowr8ddc2b12017-08-14 14:13:38 -070062 @DefaultValue("-1") @QueryParam("ue") long ue) {
slowr13fa5b02017-08-08 16:32:31 -070063 List<RnibLink> list = Lists.newArrayList();
64 if (!eciHex.isEmpty() && ue != -1) {
65 RnibLink link = get(XranStore.class).getLinkBetweenCellIdUeId(eciHex, ue);
66 if (link != null) {
67 list.add(link);
68 }
69 } else if (!eciHex.isEmpty()) {
70 list.addAll(get(XranStore.class).getLinksByCellId(eciHex));
71 } else if (ue != -1) {
72 list.addAll(get(XranStore.class).getLinksByUeId(ue));
73 } else {
74 list.addAll(get(XranStore.class).getLinks());
75 }
76
slowr13fa5b02017-08-08 16:32:31 -070077 try {
slowr8ddc2b12017-08-14 14:13:38 -070078 ObjectNode rootNode = mapper().createObjectNode();
slowr13fa5b02017-08-08 16:32:31 -070079 JsonNode jsonNode = mapper().readTree(list.toString());
80 rootNode.put("links", jsonNode);
slowr8ddc2b12017-08-14 14:13:38 -070081 return Response.ok(rootNode.toString()).build();
slowr13fa5b02017-08-08 16:32:31 -070082 } catch (IOException e) {
83 log.error(ExceptionUtils.getFullStackTrace(e));
84 e.printStackTrace();
slowr8ddc2b12017-08-14 14:13:38 -070085 return Response.serverError()
86 .entity(ExceptionUtils.getFullStackTrace(e))
87 .build();
slowr13fa5b02017-08-08 16:32:31 -070088 }
slowr13fa5b02017-08-08 16:32:31 -070089 }
90
91 /**
92 * test.
93 *
94 * @param src test
95 * @param dst test
96 * @param stream test
97 * @return test
98 */
99 @Patch
100 @Path("{src},{dst}")
101 @Consumes(MediaType.APPLICATION_JSON)
102 public Response patchLinks(@PathParam("src") String src, @PathParam("dst") long dst, InputStream stream) {
slowr8ddc2b12017-08-14 14:13:38 -0700103 RnibLink link = get(XranStore.class).getLinkBetweenCellIdUeId(src, dst);
104 if (link != null) {
105 try {
slowr67d05e42017-08-11 20:37:22 -0700106 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
slowr13fa5b02017-08-08 16:32:31 -0700107
slowr89c2ac12017-08-15 16:20:06 -0700108 JsonNode type = jsonTree.path("type");
109 if (!type.isMissingNode()) {
110 RnibLink.Type anEnum = RnibLink.Type.getEnum(type.asText());
111 return handleTypeChange(link, anEnum);
slowr67d05e42017-08-11 20:37:22 -0700112 }
slowr13fa5b02017-08-08 16:32:31 -0700113
slowr89c2ac12017-08-15 16:20:06 -0700114 JsonNode trafficpercent = jsonTree.path("trafficpercent");
115 if (!trafficpercent.isMissingNode()) {
116 return handleTrafficChange(link, trafficpercent);
slowr67d05e42017-08-11 20:37:22 -0700117 }
slowr13fa5b02017-08-08 16:32:31 -0700118
slowr89c2ac12017-08-15 16:20:06 -0700119 JsonNode rrmConf = jsonTree.path("RRMConf");
120 if (!rrmConf.isMissingNode()) {
121 return handleRRMChange(link, rrmConf);
slowr8ddc2b12017-08-14 14:13:38 -0700122 }
123
124 } catch (Exception e) {
125 log.error(ExceptionUtils.getFullStackTrace(e));
126 e.printStackTrace();
127 return Response.serverError().entity(ExceptionUtils.getFullStackTrace(e)).build();
128 }
129 }
slowr89c2ac12017-08-15 16:20:06 -0700130 return Response.serverError().entity("link not found use POST request").build();
slowr13fa5b02017-08-08 16:32:31 -0700131 }
132
133 /**
134 * test.
135 *
136 * @param src test
137 * @param dst test
138 * @param stream test
139 * @return test
140 */
141 @POST
142 @Path("{src},{dst}")
143 @Consumes(MediaType.APPLICATION_JSON)
144 public Response postLinks(@PathParam("src") String src, @PathParam("dst") long dst, InputStream stream) {
slowr89c2ac12017-08-15 16:20:06 -0700145 RnibCell cell = get(XranStore.class).getCell(src);
146 RnibUe ue = get(XranStore.class).getUe(dst);
147
148 if (cell == null) {
149 return Response.serverError()
150 .entity("cell not found")
151 .build();
152 }
153
154 if (ue == null) {
155 return Response.serverError()
156 .entity("ue not found")
157 .build();
158 }
159
160 if (get(XranStore.class).getLink(cell.getEcgi(), ue.getMmeS1apId()) != null) {
161 return Response.serverError()
162 .entity("link exists use PATCH request")
163 .build();
164 }
165
slowr13fa5b02017-08-08 16:32:31 -0700166 try {
167 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
168
slowr89c2ac12017-08-15 16:20:06 -0700169 JsonNode type = jsonTree.path("type");
slowr13fa5b02017-08-08 16:32:31 -0700170
slowr077957a2017-08-16 11:54:22 -0700171 RnibLink link = new RnibLink(cell, ue);
172 // store it as non-serving when creating link
173 get(XranStore.class).storeLink(link);
slowr89c2ac12017-08-15 16:20:06 -0700174 if (!type.isMissingNode()) {
slowr077957a2017-08-16 11:54:22 -0700175 return handleTypeChange(link, RnibLink.Type.getEnum(type.asText()));
slowr13fa5b02017-08-08 16:32:31 -0700176 }
slowr077957a2017-08-16 11:54:22 -0700177
178 JsonNode trafficpercent = jsonTree.path("trafficpercent");
179 if (!trafficpercent.isMissingNode()) {
180 return handleTrafficChange(link, trafficpercent);
181 }
182
183 JsonNode rrmConf = jsonTree.path("RRMConf");
184 if (!rrmConf.isMissingNode()) {
185 return handleRRMChange(link, rrmConf);
186 }
187
slowr13fa5b02017-08-08 16:32:31 -0700188 } catch (Exception e) {
189 log.error(ExceptionUtils.getFullStackTrace(e));
190 e.printStackTrace();
slowr8ddc2b12017-08-14 14:13:38 -0700191 return Response.serverError()
192 .entity(ExceptionUtils.getFullStackTrace(e))
193 .build();
slowr13fa5b02017-08-08 16:32:31 -0700194 }
195
slowr89c2ac12017-08-15 16:20:06 -0700196 return Response.serverError()
197 .entity("unreachable code")
198 .build();
slowr13fa5b02017-08-08 16:32:31 -0700199 }
200
slowr89c2ac12017-08-15 16:20:06 -0700201 private Response handleTypeChange(RnibLink link, RnibLink.Type newType) throws InterruptedException {
202 final SynchronousQueue<String>[] queue = new SynchronousQueue[1];
203
204 if (newType.equals(RnibLink.Type.SERVING_PRIMARY)) {
slowr077957a2017-08-16 11:54:22 -0700205 switch (link.getType()) {
206 case SERVING_PRIMARY: {
slowr89c2ac12017-08-15 16:20:06 -0700207 return Response.serverError()
slowr077957a2017-08-16 11:54:22 -0700208 .entity("link already a primary")
slowr89c2ac12017-08-15 16:20:06 -0700209 .build();
210 }
slowr077957a2017-08-16 11:54:22 -0700211 case SERVING_SECONDARY_CA:
212 case SERVING_SECONDARY_DC:
213 case NON_SERVING: {
214 List<RnibLink> linksByUeId = get(XranStore.class).getLinksByUeId(link.getLinkId().getMmeues1apid().longValue());
215
216 Optional<RnibLink> primary = linksByUeId.stream()
217 .filter(l -> l.getType().equals(RnibLink.Type.SERVING_PRIMARY))
218 .findFirst();
219 if (primary.isPresent()) {
220 queue[0] = get(XranController.class).sendHORequest(link, primary.get());
221 String poll = queue[0].poll(5, TimeUnit.SECONDS);
222
223 if (poll != null) {
224 return Response.ok()
225 .entity(poll)
226 .build();
227 } else {
228 return Response.serverError()
229 .entity("did not receive response in time")
230 .build();
231 }
232 } else {
233 link.setType(RnibLink.Type.SERVING_PRIMARY);
234 return Response.ok()
235 .entity("there was not another primary link")
236 .build();
237 }
238 }
slowr89c2ac12017-08-15 16:20:06 -0700239 }
240 } else if (newType.equals(RnibLink.Type.NON_SERVING)) {
241 switch (link.getType()) {
242 case NON_SERVING:
243 return Response.ok()
244 .entity("It's already a non serving link!" + link)
245 .build();
246 case SERVING_PRIMARY:
247 return Response.serverError()
248 .entity("Cannot change a Primary link.")
249 .build();
250 case SERVING_SECONDARY_CA:
251 case SERVING_SECONDARY_DC:
252 if (get(XranController.class).sendScellDelete(link)) {
253 return Response.ok()
254 .entity("Successfully changed link type to " + link.getType())
255 .build();
256 } else {
257 return Response.serverError()
258 .entity("Could not change link type.")
259 .build();
260 }
261 }
262 } else if (newType.equals(RnibLink.Type.SERVING_SECONDARY_CA)) {
263 switch (link.getType()) {
264 case SERVING_PRIMARY:
265 return Response.serverError()
266 .entity("Cannot change a Primary link.")
267 .build();
268 case SERVING_SECONDARY_DC:
269 case NON_SERVING:
270 queue[0] = get(XranController.class).sendScellAdd(link);
271 String poll = queue[0].poll(5, TimeUnit.SECONDS);
272 if (poll != null) {
273 return Response.ok()
274 .entity("Successfully changed link type to " + link.getType())
275 .build();
276 } else {
277 return Response.serverError()
278 .entity("did not receive response in time")
279 .build();
280 }
281 case SERVING_SECONDARY_CA:
282 return Response.ok()
283 .entity("It's already a service secondary ca link!")
284 .build();
285 }
286 }
287
288 return Response.serverError()
289 .entity("Unknown type")
290 .build();
291 }
292
293 private Response handleTrafficChange(RnibLink link, JsonNode trafficpercent) {
294 JsonNode jsonNode = trafficpercent.path("traffic-percent-dl");
295 if (!jsonNode.isMissingNode()) {
296 link.getTrafficPercent().setTrafficPercentDl(new BerInteger(jsonNode.asInt()));
297 }
298
299 jsonNode = trafficpercent.path("traffic-percent-ul");
300 if (!jsonNode.isMissingNode()) {
301 link.getTrafficPercent().setTrafficPercentUl(new BerInteger(jsonNode.asInt()));
302 }
303
304 return Response.ok("trafficpercent changed successfully").build();
305 }
306
307 private Response handleRRMChange(RnibLink link, JsonNode rrmConf) throws InterruptedException {
308 final SynchronousQueue<String>[] queue = new SynchronousQueue[1];
309 get(XranStore.class).modifyLinkRrmConf(link, rrmConf);
310 queue[0] = get(XranController.class).sendModifiedRRMConf(link.getRrmParameters(),
311 link.getLinkId().getCell().getVersion().equals("3"));
312 String poll = queue[0].poll(5, TimeUnit.SECONDS);
313
314 if (poll != null) {
315 return Response.ok()
316 .entity(poll)
317 .build();
318 } else {
319 return Response.serverError()
320 .entity("did not receive response in time")
321 .build();
322 }
323 }
slowr13fa5b02017-08-08 16:32:31 -0700324}