* ========================LICENSE_START=================================
* O-RAN-SC
* %%
- * Copyright (C) 2019 AT&T Intellectual Property and Nokia
+ * Copyright (C) 2019 AT&T Intellectual Property
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
-import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.annotation.Secured;
import org.springframework.util.Assert;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.client.HttpStatusCodeException;
import io.swagger.annotations.ApiOperation;
/**
- * Proxies calls from the front end to the App Manager API. All methods answer
- * 502 on failure: <blockquote>HTTP server received an invalid response from a
- * server it consulted when acting as a proxy or gateway.</blockquote>
+ * Proxies calls from the front end to the App Manager API.
+ *
+ * If a method throws RestClientResponseException, it is handled by
+ * {@link CustomResponseEntityExceptionHandler#handleProxyMethodException(Exception, org.springframework.web.context.request.WebRequest)}
+ * which returns status 502. All other exceptions are handled by Spring which
+ * returns status 500.
*/
@Configuration
@RestController
-@RequestMapping(value = DashboardConstants.ENDPOINT_PREFIX + "/appmgr", produces = MediaType.APPLICATION_JSON_VALUE)
+@RequestMapping(value = AppManagerController.CONTROLLER_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
public class AppManagerController {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+ // Publish paths in constants so tests are easy to write
+ public static final String CONTROLLER_PATH = DashboardConstants.ENDPOINT_PREFIX + "/appmgr";
+ // Endpoints
+ public static final String HEALTH_ALIVE_METHOD = "/health/alive";
+ public static final String HEALTH_READY_METHOD = "/health/ready";
+ public static final String CONFIG_METHOD = "/config";
+ public static final String XAPPS_METHOD = "/xapps";
+ public static final String XAPPS_LIST_METHOD = XAPPS_METHOD + "/list";
+ public static final String VERSION_METHOD = DashboardConstants.VERSION_METHOD;
+ // Path parameters
+ public static final String PP_XAPP_NAME = "xAppName";
+
// Populated by the autowired constructor
private final HealthApi healthApi;
private final XappApi xappApi;
}
@ApiOperation(value = "Gets the XApp manager client library MANIFEST.MF property Implementation-Version.", response = SuccessTransport.class)
- @RequestMapping(value = DashboardConstants.VERSION_PATH, method = RequestMethod.GET)
- public SuccessTransport getXappManagerClientVersion() {
+ @GetMapping(VERSION_METHOD)
+ // No role required
+ public SuccessTransport getClientVersion() {
return new SuccessTransport(200, DashboardApplication.getImplementationVersion(HealthApi.class));
}
@ApiOperation(value = "Health check of xApp Manager - Liveness probe.")
- @RequestMapping(value = "/health/alive", method = RequestMethod.GET)
- public Object getHealth(HttpServletResponse response) {
+ @GetMapping(HEALTH_ALIVE_METHOD)
+ // No role required
+ public void getHealth(HttpServletResponse response) {
logger.debug("getHealthAlive");
- try {
- healthApi.getHealthAlive();
- response.setStatus(healthApi.getApiClient().getStatusCode().value());
- return null;
- } catch (HttpStatusCodeException ex) {
- logger.error("getHealthAlive failed: {}", ex.toString());
- return ResponseEntity.status(HttpServletResponse.SC_BAD_GATEWAY).body(ex.getResponseBodyAsString());
- }
+ healthApi.getHealthAlive();
+ response.setStatus(healthApi.getApiClient().getStatusCode().value());
}
@ApiOperation(value = "Readiness check of xApp Manager - Readiness probe.")
- @RequestMapping(value = "/health/ready", method = RequestMethod.GET)
- public Object getHealthReady(HttpServletResponse response) {
+ @GetMapping(HEALTH_READY_METHOD)
+ // No role required
+ public void getHealthReady(HttpServletResponse response) {
logger.debug("getHealthReady");
- try {
- healthApi.getHealthReady();
- response.setStatus(healthApi.getApiClient().getStatusCode().value());
- return null;
- } catch (HttpStatusCodeException ex) {
- logger.error("getHealthReady failed: {}", ex.toString());
- return ResponseEntity.status(HttpServletResponse.SC_BAD_GATEWAY).body(ex.getResponseBodyAsString());
- }
+ healthApi.getHealthReady();
+ response.setStatus(healthApi.getApiClient().getStatusCode().value());
}
@ApiOperation(value = "Returns the configuration of all xapps.", response = AllXappConfig.class)
- @RequestMapping(value = "/config", method = RequestMethod.GET)
- public Object getAllXappConfig() {
+ @GetMapping(CONFIG_METHOD)
+ @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD })
+ public AllXappConfig getAllXappConfig() {
logger.debug("getAllXappConfig");
- try {
- return xappApi.getAllXappConfig();
- } catch (HttpStatusCodeException ex) {
- logger.error("getAllXappConfig failed: {}", ex.toString());
- return ResponseEntity.status(HttpServletResponse.SC_BAD_GATEWAY).body(ex.getResponseBodyAsString());
- }
+ return xappApi.getAllXappConfig();
}
- @ApiOperation(value = "Create xApp config.")
- @RequestMapping(value = "/config", method = RequestMethod.POST)
- public Object createXappConfig(@RequestBody XAppConfig xAppConfig) {
+ @ApiOperation(value = "Create xApp config.", response = XAppConfig.class)
+ @PostMapping(CONFIG_METHOD)
+ @Secured({ DashboardConstants.ROLE_ADMIN })
+ public XAppConfig createXappConfig(@RequestBody XAppConfig xAppConfig) {
logger.debug("createXappConfig {}", xAppConfig);
- try {
- return xappApi.createXappConfig(xAppConfig);
- } catch (HttpStatusCodeException ex) {
- logger.error("undeployXapp failed: {}", ex.toString());
- return ResponseEntity.status(HttpServletResponse.SC_BAD_GATEWAY).body(ex.getResponseBodyAsString());
- }
+ return xappApi.createXappConfig(xAppConfig);
}
- @ApiOperation(value = "Modify xApp config.")
- @RequestMapping(value = "/config", method = RequestMethod.PUT)
- public Object modifyXappConfig(@RequestBody XAppConfig xAppConfig) {
+ @ApiOperation(value = "Modify xApp config.", response = XAppConfig.class)
+ @PutMapping(CONFIG_METHOD)
+ @Secured({ DashboardConstants.ROLE_ADMIN })
+ public XAppConfig modifyXappConfig(@RequestBody XAppConfig xAppConfig) {
logger.debug("modifyXappConfig {}", xAppConfig);
- try {
- return xappApi.modifyXappConfig(xAppConfig);
- } catch (HttpStatusCodeException ex) {
- logger.error("modifyXappConfig failed: {}", ex.toString());
- return ResponseEntity.status(HttpServletResponse.SC_BAD_GATEWAY).body(ex.getResponseBodyAsString());
- }
+ return xappApi.modifyXappConfig(xAppConfig);
}
@ApiOperation(value = "Delete xApp configuration.")
- @RequestMapping(value = "/config/{xAppName}", method = RequestMethod.DELETE)
- public Object deleteXappConfig(@RequestBody ConfigMetadata configMetadata, HttpServletResponse response) {
+ @DeleteMapping(CONFIG_METHOD + "/{" + PP_XAPP_NAME + "}")
+ @Secured({ DashboardConstants.ROLE_ADMIN })
+ public void deleteXappConfig(@RequestBody ConfigMetadata configMetadata, HttpServletResponse response) {
logger.debug("deleteXappConfig {}", configMetadata);
- try {
- xappApi.deleteXappConfig(configMetadata);
- response.setStatus(healthApi.getApiClient().getStatusCode().value());
- return null;
- } catch (HttpStatusCodeException ex) {
- logger.error("deleteXappConfig failed: {}", ex.toString());
- return ResponseEntity.status(HttpServletResponse.SC_BAD_GATEWAY).body(ex.getResponseBodyAsString());
- }
+ xappApi.deleteXappConfig(configMetadata);
+ response.setStatus(healthApi.getApiClient().getStatusCode().value());
}
@ApiOperation(value = "Returns a list of deployable xapps.", response = DashboardDeployableXapps.class)
- @RequestMapping(value = "/xapps/list", method = RequestMethod.GET)
- public Object getAvailableXapps() {
+ @GetMapping(XAPPS_LIST_METHOD)
+ @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD })
+ public DashboardDeployableXapps getAvailableXapps() {
logger.debug("getAvailableXapps");
- try {
- AllDeployableXapps appNames = xappApi.listAllXapps();
- // Answer a collection of structure instead of string
- DashboardDeployableXapps apps = new DashboardDeployableXapps();
- for (String n : appNames)
- apps.add(new AppTransport(n));
- return apps;
- } catch (HttpStatusCodeException ex) {
- logger.error("getAvailableXapps failed: {}", ex.toString());
- return ResponseEntity.status(HttpServletResponse.SC_BAD_GATEWAY).body(ex.getResponseBodyAsString());
- }
+ AllDeployableXapps appNames = xappApi.listAllDeployableXapps();
+ // Answer a collection of structure instead of string
+ // because I expect the AppMgr to be extended with
+ // additional properties for each one.
+ DashboardDeployableXapps apps = new DashboardDeployableXapps();
+ for (String n : appNames)
+ apps.add(new AppTransport(n));
+ return apps;
}
@ApiOperation(value = "Returns the status of all deployed xapps.", response = AllDeployedXapps.class)
- @RequestMapping(value = "/xapps", method = RequestMethod.GET)
- public Object getDeployedXapps() {
+ @GetMapping(XAPPS_METHOD)
+ @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD })
+ public AllDeployedXapps getDeployedXapps() {
logger.debug("getDeployedXapps");
- try {
- return xappApi.getAllXapps();
- } catch (HttpStatusCodeException ex) {
- logger.error("getDeployedXapps failed: {}", ex.toString());
- return ResponseEntity.status(HttpServletResponse.SC_BAD_GATEWAY).body(ex.getResponseBodyAsString());
- }
+ return xappApi.getAllXapps();
}
@ApiOperation(value = "Returns the status of a given xapp.", response = Xapp.class)
- @RequestMapping(value = "/xapps/{xAppName}", method = RequestMethod.GET)
- public Object getXapp(@PathVariable("xAppName") String xAppName) {
+ @GetMapping(XAPPS_METHOD + "/{" + PP_XAPP_NAME + "}")
+ @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD })
+ public Xapp getXapp(@PathVariable("xAppName") String xAppName) {
logger.debug("getXapp {}", xAppName);
- try {
- return xappApi.getXappByName(xAppName);
- } catch (HttpStatusCodeException ex) {
- logger.error("getXapp failed: {}", ex.toString());
- return ResponseEntity.status(HttpServletResponse.SC_BAD_GATEWAY).body(ex.getResponseBodyAsString());
- }
+ return xappApi.getXappByName(xAppName);
}
@ApiOperation(value = "Deploy a xapp.", response = Xapp.class)
- @RequestMapping(value = "/xapps", method = RequestMethod.POST)
- public Object deployXapp(@RequestBody XAppInfo xAppInfo) {
+ @PostMapping(XAPPS_METHOD)
+ @Secured({ DashboardConstants.ROLE_ADMIN })
+ public Xapp deployXapp(@RequestBody XAppInfo xAppInfo) {
logger.debug("deployXapp {}", xAppInfo);
- try {
- return xappApi.deployXapp(xAppInfo);
- } catch (HttpStatusCodeException ex) {
- logger.error("deployXapp failed: {}", ex.toString());
- return ResponseEntity.status(HttpServletResponse.SC_BAD_GATEWAY).body(ex.getResponseBodyAsString());
- }
+ return xappApi.deployXapp(xAppInfo);
}
@ApiOperation(value = "Undeploy an existing xapp.")
- @RequestMapping(value = "/xapps/{xAppName}", method = RequestMethod.DELETE)
- public Object undeployXapp(@PathVariable("xAppName") String xAppName, HttpServletResponse response) {
+ @DeleteMapping(XAPPS_METHOD + "/{" + PP_XAPP_NAME + "}")
+ @Secured({ DashboardConstants.ROLE_ADMIN })
+ public void undeployXapp(@PathVariable("xAppName") String xAppName, HttpServletResponse response) {
logger.debug("undeployXapp {}", xAppName);
- try {
- xappApi.undeployXapp(xAppName);
- response.setStatus(healthApi.getApiClient().getStatusCode().value());
- return null;
- } catch (HttpStatusCodeException ex) {
- logger.error("undeployXapp failed: {}", ex.toString());
- return ResponseEntity.status(HttpServletResponse.SC_BAD_GATEWAY).body(ex.getResponseBodyAsString());
- }
+ xappApi.undeployXapp(xAppName);
+ response.setStatus(xappApi.getApiClient().getStatusCode().value());
}
}