blob: e3b2035c7e2284f4f7ac4f0f677bdb90c953183f [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
slowr89c2ac12017-08-15 16:20:06 -0700171 if (!type.isMissingNode()) {
172 RnibLink link = new RnibLink(cell, ue);
173 link.setType(RnibLink.Type.getEnum(type.asText()));
174 get(XranStore.class).storeLink(link);
175
176 // TODO: trigger the scell add
slowr13fa5b02017-08-08 16:32:31 -0700177 }
178 } catch (Exception e) {
179 log.error(ExceptionUtils.getFullStackTrace(e));
180 e.printStackTrace();
slowr8ddc2b12017-08-14 14:13:38 -0700181 return Response.serverError()
182 .entity(ExceptionUtils.getFullStackTrace(e))
183 .build();
slowr13fa5b02017-08-08 16:32:31 -0700184 }
185
slowr89c2ac12017-08-15 16:20:06 -0700186 return Response.serverError()
187 .entity("unreachable code")
188 .build();
slowr13fa5b02017-08-08 16:32:31 -0700189 }
190
slowr89c2ac12017-08-15 16:20:06 -0700191 private Response handleTypeChange(RnibLink link, RnibLink.Type newType) throws InterruptedException {
192 final SynchronousQueue<String>[] queue = new SynchronousQueue[1];
193
194 if (newType.equals(RnibLink.Type.SERVING_PRIMARY)) {
195 List<RnibLink> linksByUeId = get(XranStore.class).getLinksByUeId(link.getLinkId().getMmeues1apid().longValue());
196
197 Optional<RnibLink> primary = linksByUeId.stream()
198 .filter(l -> l.getType().equals(RnibLink.Type.SERVING_PRIMARY))
199 .findFirst();
200 if (primary.isPresent()) {
201 queue[0] = get(XranController.class).sendHORequest(link, primary.get());
202 String poll = queue[0].poll(5, TimeUnit.SECONDS);
203
204 if (poll != null) {
205 return Response.ok()
206 .entity(poll)
207 .build();
208 } else {
209 return Response.serverError()
210 .entity("did not receive response in time")
211 .build();
212 }
213 } else {
214 link.setType(RnibLink.Type.SERVING_PRIMARY);
215 return Response.ok()
216 .entity("there was not another primary link")
217 .build();
218 }
219 } else if (newType.equals(RnibLink.Type.NON_SERVING)) {
220 switch (link.getType()) {
221 case NON_SERVING:
222 return Response.ok()
223 .entity("It's already a non serving link!" + link)
224 .build();
225 case SERVING_PRIMARY:
226 return Response.serverError()
227 .entity("Cannot change a Primary link.")
228 .build();
229 case SERVING_SECONDARY_CA:
230 case SERVING_SECONDARY_DC:
231 if (get(XranController.class).sendScellDelete(link)) {
232 return Response.ok()
233 .entity("Successfully changed link type to " + link.getType())
234 .build();
235 } else {
236 return Response.serverError()
237 .entity("Could not change link type.")
238 .build();
239 }
240 }
241 } else if (newType.equals(RnibLink.Type.SERVING_SECONDARY_CA)) {
242 switch (link.getType()) {
243 case SERVING_PRIMARY:
244 return Response.serverError()
245 .entity("Cannot change a Primary link.")
246 .build();
247 case SERVING_SECONDARY_DC:
248 case NON_SERVING:
249 queue[0] = get(XranController.class).sendScellAdd(link);
250 String poll = queue[0].poll(5, TimeUnit.SECONDS);
251 if (poll != null) {
252 return Response.ok()
253 .entity("Successfully changed link type to " + link.getType())
254 .build();
255 } else {
256 return Response.serverError()
257 .entity("did not receive response in time")
258 .build();
259 }
260 case SERVING_SECONDARY_CA:
261 return Response.ok()
262 .entity("It's already a service secondary ca link!")
263 .build();
264 }
265 }
266
267 return Response.serverError()
268 .entity("Unknown type")
269 .build();
270 }
271
272 private Response handleTrafficChange(RnibLink link, JsonNode trafficpercent) {
273 JsonNode jsonNode = trafficpercent.path("traffic-percent-dl");
274 if (!jsonNode.isMissingNode()) {
275 link.getTrafficPercent().setTrafficPercentDl(new BerInteger(jsonNode.asInt()));
276 }
277
278 jsonNode = trafficpercent.path("traffic-percent-ul");
279 if (!jsonNode.isMissingNode()) {
280 link.getTrafficPercent().setTrafficPercentUl(new BerInteger(jsonNode.asInt()));
281 }
282
283 return Response.ok("trafficpercent changed successfully").build();
284 }
285
286 private Response handleRRMChange(RnibLink link, JsonNode rrmConf) throws InterruptedException {
287 final SynchronousQueue<String>[] queue = new SynchronousQueue[1];
288 get(XranStore.class).modifyLinkRrmConf(link, rrmConf);
289 queue[0] = get(XranController.class).sendModifiedRRMConf(link.getRrmParameters(),
290 link.getLinkId().getCell().getVersion().equals("3"));
291 String poll = queue[0].poll(5, TimeUnit.SECONDS);
292
293 if (poll != null) {
294 return Response.ok()
295 .entity(poll)
296 .build();
297 } else {
298 return Response.serverError()
299 .entity("did not receive response in time")
300 .build();
301 }
302 }
slowr13fa5b02017-08-08 16:32:31 -0700303}