2 * ========================LICENSE_START=================================
5 * Copyright (C) 2019 AT&T Intellectual Property and Nokia
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ========================LICENSE_END===================================
20 package org.oransc.ric.portal.dashboard.controller;
22 import java.lang.invoke.MethodHandles;
23 import java.util.ArrayList;
24 import java.util.List;
26 import javax.servlet.http.HttpServletResponse;
28 import org.oransc.ric.e2mgr.client.api.HealthCheckApi;
29 import org.oransc.ric.e2mgr.client.api.NodebApi;
30 import org.oransc.ric.e2mgr.client.model.GetNodebResponse;
31 import org.oransc.ric.e2mgr.client.model.NodebIdentity;
32 import org.oransc.ric.e2mgr.client.model.NodebIdentityGlobalNbId;
33 import org.oransc.ric.e2mgr.client.model.SetupRequest;
34 import org.oransc.ric.portal.dashboard.DashboardApplication;
35 import org.oransc.ric.portal.dashboard.DashboardConstants;
36 import org.oransc.ric.portal.dashboard.model.ErrorTransport;
37 import org.oransc.ric.portal.dashboard.model.RanDetailsTransport;
38 import org.oransc.ric.portal.dashboard.model.SuccessTransport;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41 import org.springframework.beans.factory.annotation.Autowired;
42 import org.springframework.beans.factory.annotation.Value;
43 import org.springframework.context.annotation.Configuration;
44 import org.springframework.http.HttpStatus;
45 import org.springframework.http.MediaType;
46 import org.springframework.http.ResponseEntity;
47 import org.springframework.util.Assert;
48 import org.springframework.web.bind.annotation.PathVariable;
49 import org.springframework.web.bind.annotation.RequestBody;
50 import org.springframework.web.bind.annotation.RequestMapping;
51 import org.springframework.web.bind.annotation.RequestMethod;
52 import org.springframework.web.bind.annotation.RestController;
53 import org.springframework.web.client.HttpStatusCodeException;
55 import io.swagger.annotations.ApiOperation;
58 * Proxies calls from the front end to the E2 Manager API. All methods answer
59 * 502 on failure and wrap the remote details: <blockquote>HTTP server received
60 * an invalid response from a server it consulted when acting as a proxy or
61 * gateway.</blockquote>
63 * In R1 the E2 interface does not yet implement the get-ID-list method, so this
64 * class mocks up some functionality.
68 @RequestMapping(value = DashboardConstants.ENDPOINT_PREFIX + "/e2mgr", produces = MediaType.APPLICATION_JSON_VALUE)
69 public class E2ManagerController {
71 private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
73 private final List<NodebIdentity> mockNodebIdList;
76 private static final String PP_RANNAME = "ranName";
78 // Populated by the autowired constructor
79 private final HealthCheckApi e2HealthCheckApi;
80 private final NodebApi e2NodebApi;
83 public E2ManagerController(final HealthCheckApi e2HealthCheckApi, final NodebApi e2NodebApi,
84 @Value("${e2mgr.mock.rannames:#{null}}") final String mockRanNames) {
85 Assert.notNull(e2HealthCheckApi, "API must not be null");
86 Assert.notNull(e2NodebApi, "API must not be null");
87 this.e2HealthCheckApi = e2HealthCheckApi;
88 this.e2NodebApi = e2NodebApi;
89 mockNodebIdList = new ArrayList<>();
90 if (mockRanNames != null) {
91 logger.debug("ctor: Mocking RAN names: {}", mockRanNames);
92 for (String id : mockRanNames.split(",")) {
93 NodebIdentityGlobalNbId globalNbId = new NodebIdentityGlobalNbId().nbId("mockNbId").plmnId("mockPlmId");
94 mockNodebIdList.add(new NodebIdentity().globalNbId(globalNbId).inventoryName(id.trim()));
99 @ApiOperation(value = "Gets the E2 manager client library MANIFEST.MF property Implementation-Version.", response = SuccessTransport.class)
100 @RequestMapping(value = DashboardConstants.VERSION_PATH, method = RequestMethod.GET)
101 public SuccessTransport getE2ManagerClientVersion() {
102 return new SuccessTransport(200, DashboardApplication.getImplementationVersion(HealthCheckApi.class));
105 @ApiOperation(value = "Gets the health from the E2 manager, expressed as the response code.")
106 @RequestMapping(value = "/health", method = RequestMethod.GET)
107 public Object healthGet(HttpServletResponse response) {
108 logger.debug("healthGet");
110 e2HealthCheckApi.healthGet();
111 response.setStatus(e2HealthCheckApi.getApiClient().getStatusCode().value());
113 } catch (HttpStatusCodeException ex) {
114 logger.warn("healthGet failed: {}", ex.toString());
115 return new ResponseEntity<ErrorTransport>(new ErrorTransport(ex.getRawStatusCode(), ex.toString()),
116 HttpStatus.BAD_GATEWAY);
120 // This calls other methods to simplify the task of the front-end.
121 @ApiOperation(value = "Gets all RAN identities and statuses from the E2 manager.", response = RanDetailsTransport.class, responseContainer = "List")
122 @RequestMapping(value = "/ran", method = RequestMethod.GET)
123 public Object getRanDetails() {
124 logger.debug("getRanDetails");
125 List<NodebIdentity> nodebIdList = null;
127 // TODO: remove mock when e2mgr delivers the getNodebIdList() method
128 nodebIdList = mockNodebIdList.isEmpty() ? e2NodebApi.getNodebIdList() : mockNodebIdList;
129 } catch (HttpStatusCodeException ex) {
130 logger.warn("getRanDetails: getNodebIdList failed: {}", ex.toString());
131 return new ResponseEntity<ErrorTransport>(new ErrorTransport(ex.getRawStatusCode(), ex.toString()),
132 HttpStatus.BAD_GATEWAY);
134 List<RanDetailsTransport> details = new ArrayList<>();
135 for (NodebIdentity nbid : nodebIdList) {
136 GetNodebResponse nbResp = null;
138 // Keep looping despite failures
139 nbResp = e2NodebApi.getNb(nbid.getInventoryName());
140 } catch (HttpStatusCodeException ex) {
141 logger.warn("getRanDetails failed for name {}: {}", nbid.getInventoryName(), ex.toString());
142 nbResp = new GetNodebResponse().connectionStatus("UNKNOWN").ip("UNKNOWN").port(-1)
143 .ranName(nbid.getInventoryName());
145 details.add(new RanDetailsTransport(nbid, nbResp));
150 @ApiOperation(value = "Get RAN identities list.", response = NodebIdentity.class, responseContainer = "List")
151 @RequestMapping(value = "/nodeb-ids", method = RequestMethod.GET)
152 public Object getNodebIdList() {
153 logger.debug("getNodebIdList");
155 return e2NodebApi.getNodebIdList();
156 } catch (HttpStatusCodeException ex) {
157 logger.warn("getNodebIdList failed: {}", ex.toString());
158 return new ResponseEntity<ErrorTransport>(new ErrorTransport(ex.getRawStatusCode(), ex.toString()),
159 HttpStatus.BAD_GATEWAY);
163 @ApiOperation(value = "Get RAN by name.", response = GetNodebResponse.class)
164 @RequestMapping(value = "/nodeb/{" + PP_RANNAME + "}", method = RequestMethod.GET)
165 public Object getNb(@PathVariable(PP_RANNAME) String ranName) {
166 logger.debug("getNb {}", ranName);
168 return e2NodebApi.getNb(ranName);
169 } catch (HttpStatusCodeException ex) {
170 logger.warn("getNb failed: {}", ex.toString());
171 return new ResponseEntity<ErrorTransport>(new ErrorTransport(ex.getRawStatusCode(), ex.toString()),
172 HttpStatus.BAD_GATEWAY);
176 @ApiOperation(value = "Close all connections to the RANs and delete the data from the nodeb-rnib DB.")
177 @RequestMapping(value = "/nodeb", method = RequestMethod.DELETE)
178 public Object nodebDelete(HttpServletResponse response) {
179 logger.debug("nodebDelete");
181 e2NodebApi.nodebDelete();
182 response.setStatus(e2NodebApi.getApiClient().getStatusCode().value());
184 } catch (HttpStatusCodeException ex) {
185 logger.warn("nodebDelete failed: {}", ex.toString());
186 return new ResponseEntity<ErrorTransport>(new ErrorTransport(ex.getRawStatusCode(), ex.toString()),
187 HttpStatus.BAD_GATEWAY);
191 @ApiOperation(value = "Sets up an EN-DC RAN connection via the E2 manager.")
192 @RequestMapping(value = "/endcSetup", method = RequestMethod.POST)
193 public Object endcSetup(@RequestBody SetupRequest setupRequest, HttpServletResponse response) {
194 logger.debug("endcSetup {}", setupRequest);
196 e2NodebApi.endcSetup(setupRequest);
197 response.setStatus(e2NodebApi.getApiClient().getStatusCode().value());
199 } catch (HttpStatusCodeException ex) {
200 logger.warn("endcSetup failed: {}", ex.toString());
201 return new ResponseEntity<ErrorTransport>(new ErrorTransport(ex.getRawStatusCode(), ex.toString()),
202 HttpStatus.BAD_GATEWAY);
206 @ApiOperation(value = "Sets up an X2 RAN connection via the E2 manager.")
207 @RequestMapping(value = "/x2Setup", method = RequestMethod.POST)
208 public Object x2Setup(@RequestBody SetupRequest setupRequest, HttpServletResponse response) {
209 logger.debug("x2Setup {}", setupRequest);
211 e2NodebApi.x2Setup(setupRequest);
212 response.setStatus(e2NodebApi.getApiClient().getStatusCode().value());
214 } catch (HttpStatusCodeException ex) {
215 logger.warn("x2Setup failed: {}", ex.toString());
216 return new ResponseEntity<ErrorTransport>(new ErrorTransport(ex.getRawStatusCode(), ex.toString()),
217 HttpStatus.BAD_GATEWAY);