From: Lott, Christopher (cl778h) Date: Thu, 12 Dec 2019 18:36:30 +0000 (-0500) Subject: Require RIC instance key in controller methods X-Git-Tag: 2.0.0~12 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=53f1fcf033e3a166d7203e0a1c5e0971f9c6bc16;p=portal%2Fric-dashboard.git Require RIC instance key in controller methods Change-Id: Ibd0d1499a7391744904fabcce5f202eaa4e282d8 Signed-off-by: Lott, Christopher (cl778h) --- diff --git a/docs/developer-guide.rst b/docs/developer-guide.rst index b0c71a7f..e7812943 100644 --- a/docs/developer-guide.rst +++ b/docs/developer-guide.rst @@ -58,7 +58,7 @@ files. These steps are required to launch: 1. Install all project jar files locally 2. Set an environment variable via JVM argument: ``-Dorg.oransc.ric.portal.dashboard=mock`` -3. Run the JUnit test case ``DashboardServerTest`` which is not exactly a "test" because it never finishes. +3. Run the JUnit test case ``DashboardTestServer`` which is not exactly a "test" because it never finishes. These steps can be done with these commands:: diff --git a/docs/release-notes.rst b/docs/release-notes.rst index 8ef088ea..ddcd11ac 100644 --- a/docs/release-notes.rst +++ b/docs/release-notes.rst @@ -11,6 +11,8 @@ Version 2.0.0, 22 Dec 2019 * Add mock list of RIC instances to application properties * Add admin controller method to fetch list of RIC instances * Drop AUX cluster container list fetched via CAAS Ingress +* Revise controller methods to require RIC instance key +* Upgrade to Spring-Boot 2.1.11.RELEASE Version 1.3.0, 26 Nov 2019 -------------------------- diff --git a/pom.xml b/pom.xml index 8bee35b8..97178839 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ limitations under the License. org.springframework.boot spring-boot-starter-parent - 2.1.9.RELEASE + 2.1.11.RELEASE org.o-ran-sc.portal.ric-dashboard diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/DashboardApplication.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/DashboardApplication.java index 8cb774f8..3a6d6a2b 100644 --- a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/DashboardApplication.java +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/DashboardApplication.java @@ -21,9 +21,10 @@ package org.oransc.ric.portal.dashboard; import java.lang.invoke.MethodHandles; +import java.util.List; -import org.oransc.ric.portal.dashboard.config.RICInstanceConfiguration; -import org.oransc.ric.portal.dashboard.model.InstanceTransport; +import org.oransc.ric.portal.dashboard.model.RicInstance; +import org.oransc.ric.portal.dashboard.model.RicInstanceList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -31,6 +32,7 @@ import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ComponentScan; +import org.springframework.util.Assert; @SpringBootApplication // Limit scan to dashboard classes; exclude generated API classes @@ -40,7 +42,7 @@ public class DashboardApplication implements CommandLineRunner { private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); @Autowired - private RICInstanceConfiguration instanceConfig; + private RicInstanceList instanceConfig; public static void main(String[] args) { SpringApplication.run(DashboardApplication.class, args); @@ -50,8 +52,17 @@ public class DashboardApplication implements CommandLineRunner { public void run(String... args) throws Exception { // Ensure output appears on the console by using level WARN logger.warn("run: version '{}'", getImplementationVersion(MethodHandles.lookup().lookupClass())); - for (InstanceTransport it : instanceConfig.getInstances()) + // Validate configuration + List instances = instanceConfig.getInstances(); + Assert.notEmpty(instances, "Instance list empty"); + for (RicInstance it : instances) { logger.warn("run: RIC instance {}", it); + Assert.hasText(it.getKey(), "Instance key missing"); + Assert.hasText(it.getName(), "Name missing for instance " + it.getKey()); + Assert.hasText(it.getAppUrlPrefix(), "App URL prefix missing for instance " + it.getKey()); + Assert.hasText(it.getCaasUrlPrefix(), "Caas URL prefix missing for instance " + it.getKey()); + Assert.hasText(it.getPltUrlPrefix(), "Plt URL prefix missing for instance " + it.getKey()); + } } /** diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/DashboardConstants.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/DashboardConstants.java index 4225e886..6f02a223 100644 --- a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/DashboardConstants.java +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/DashboardConstants.java @@ -26,8 +26,11 @@ public abstract class DashboardConstants { } public static final String ENDPOINT_PREFIX = "/api"; + // Spring path parameters + public static final String RIC_INSTANCE_KEY = "ric"; // Factor out method names used in multiple controllers public static final String VERSION_METHOD = "version"; + // Apps with metric panels public static final String APP_NAME_AC = "AC"; public static final String APP_NAME_MC = "MC"; // The role names are defined by ONAP Portal. diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/A1MediatorApiBuilder.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/A1MediatorApiBuilder.java new file mode 100644 index 00000000..0fbbcb35 --- /dev/null +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/A1MediatorApiBuilder.java @@ -0,0 +1,65 @@ +/*- + * ========================LICENSE_START================================= + * O-RAN-SC + * %% + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================LICENSE_END=================================== + */ +package org.oransc.ric.portal.dashboard.config; + +import java.lang.invoke.MethodHandles; + +import org.oransc.ric.a1med.client.api.A1MediatorApi; +import org.oransc.ric.a1med.client.invoker.ApiClient; +import org.oransc.ric.portal.dashboard.model.RicInstanceList; +import org.oransc.ric.portal.dashboard.model.RicInstance; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.DefaultUriBuilderFactory; + +/** + * The OpenAPI generated API client code using Spring RestTemplate is not thread + * safe according to https://github.com/swagger-api/swagger-codegen/issues/9222 + * + * As a workaround this builder creates a new client at every request. If this + * proves to be too slow then clients could be cached for each thread. + */ +public class A1MediatorApiBuilder { + + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + private final String urlSuffix; + private final RicInstanceList instanceConfig; + + public A1MediatorApiBuilder(final RicInstanceList instanceConfig, final String urlSuffix) { + logger.debug("ctor: suffix {}", urlSuffix); + this.instanceConfig = instanceConfig; + this.urlSuffix = urlSuffix; + } + + private ApiClient apiClient(String instanceKey) { + RicInstance instance = instanceConfig.getInstance(instanceKey); + String url = new DefaultUriBuilderFactory(instance.getPltUrlPrefix().trim()).builder() + .path(this.urlSuffix.trim()).build().normalize().toString(); + logger.debug("apiClient URL {}", url); + return new ApiClient(new RestTemplate()).setBasePath(url); + } + + public A1MediatorApi getA1MediatorApi(String instanceKey) { + return new A1MediatorApi(apiClient(instanceKey)); + } + +} diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/A1MediatorConfiguration.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/A1MediatorConfiguration.java index fd1bcbc9..68538060 100644 --- a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/A1MediatorConfiguration.java +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/A1MediatorConfiguration.java @@ -21,8 +21,7 @@ package org.oransc.ric.portal.dashboard.config; import java.lang.invoke.MethodHandles; -import org.oransc.ric.a1med.client.api.A1MediatorApi; -import org.oransc.ric.a1med.client.invoker.ApiClient; +import org.oransc.ric.portal.dashboard.model.RicInstanceList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -30,11 +29,9 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; -import org.springframework.web.client.RestTemplate; -import org.springframework.web.util.DefaultUriBuilderFactory; /** - * Creates an A1 mediator client as a bean to be managed by the Spring + * Creates an A1 mediator client builder as a bean to be managed by the Spring * container. */ @Configuration @@ -44,27 +41,21 @@ public class A1MediatorConfiguration { private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); // Populated by the autowired constructor - private final String a1medUrl; + private final String urlSuffix; + private final RicInstanceList instanceConfig; @Autowired - public A1MediatorConfiguration(@Value("${a1med.url.prefix}") final String urlPrefix, // - @Value("${a1med.url.suffix}") final String urlSuffix) { - logger.debug("ctor prefix '{}' suffix '{}'", urlPrefix, urlSuffix); - a1medUrl = new DefaultUriBuilderFactory(urlPrefix.trim()).builder().path(urlSuffix.trim()).build().normalize() - .toString(); - logger.info("Configuring A1 Mediator at URL {}", a1medUrl); - } - - private ApiClient apiClient() { - ApiClient apiClient = new ApiClient(new RestTemplate()); - apiClient.setBasePath(a1medUrl); - return apiClient; + public A1MediatorConfiguration(@Value("${a1med.url.suffix}") final String urlSuffix, + final RicInstanceList instanceConfig) { + logger.info("ctor: URL suffix {}", urlSuffix); + this.urlSuffix = urlSuffix; + this.instanceConfig = instanceConfig; } @Bean // The bean (method) name must be globally unique - public A1MediatorApi a1MediatorApi() { - return new A1MediatorApi(apiClient()); + public A1MediatorApiBuilder a1MediatorApiBuilder() { + return new A1MediatorApiBuilder(instanceConfig, urlSuffix); } } diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/AppManagerApiBuilder.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/AppManagerApiBuilder.java new file mode 100644 index 00000000..aeb75590 --- /dev/null +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/AppManagerApiBuilder.java @@ -0,0 +1,70 @@ +/*- + * ========================LICENSE_START================================= + * O-RAN-SC + * %% + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================LICENSE_END=================================== + */ +package org.oransc.ric.portal.dashboard.config; + +import java.lang.invoke.MethodHandles; + +import org.oransc.ric.plt.appmgr.client.api.HealthApi; +import org.oransc.ric.plt.appmgr.client.api.XappApi; +import org.oransc.ric.plt.appmgr.client.invoker.ApiClient; +import org.oransc.ric.portal.dashboard.model.RicInstanceList; +import org.oransc.ric.portal.dashboard.model.RicInstance; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.DefaultUriBuilderFactory; + +/** + * The OpenAPI generated API client code using Spring RestTemplate is not thread + * safe according to https://github.com/swagger-api/swagger-codegen/issues/9222 + * + * As a workaround this builder creates a new client at every request. If this + * proves to be too slow then clients could be cached for each thread. + */ +public class AppManagerApiBuilder { + + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + private final String urlSuffix; + private final RicInstanceList instanceConfig; + + public AppManagerApiBuilder(final RicInstanceList instanceConfig, final String urlSuffix) { + logger.debug("ctor: suffix {}", urlSuffix); + this.instanceConfig = instanceConfig; + this.urlSuffix = urlSuffix; + } + + private ApiClient apiClient(String instanceKey) { + RicInstance instance = instanceConfig.getInstance(instanceKey); + String url = new DefaultUriBuilderFactory(instance.getPltUrlPrefix().trim()).builder() + .path(this.urlSuffix.trim()).build().normalize().toString(); + logger.debug("apiClient URL {}", url); + return new ApiClient(new RestTemplate()).setBasePath(url); + } + + public HealthApi getHealthApi(String instanceKey) { + return new HealthApi(apiClient(instanceKey)); + } + + public XappApi getXappApi(String instanceKey) { + return new XappApi(apiClient(instanceKey)); + } + +} diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/AppManagerConfiguration.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/AppManagerConfiguration.java index 94ba3575..ffb5db64 100644 --- a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/AppManagerConfiguration.java +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/AppManagerConfiguration.java @@ -21,9 +21,7 @@ package org.oransc.ric.portal.dashboard.config; import java.lang.invoke.MethodHandles; -import org.oransc.ric.plt.appmgr.client.api.HealthApi; -import org.oransc.ric.plt.appmgr.client.api.XappApi; -import org.oransc.ric.plt.appmgr.client.invoker.ApiClient; +import org.oransc.ric.portal.dashboard.model.RicInstanceList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -31,11 +29,9 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; -import org.springframework.web.client.RestTemplate; -import org.springframework.web.util.DefaultUriBuilderFactory; /** - * Creates an xApp manager client as a bean to be managed by the Spring + * Creates an App manager client builder as a bean to be managed by the Spring * container. */ @Configuration @@ -45,38 +41,21 @@ public class AppManagerConfiguration { private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); // Populated by the autowired constructor - private final String xappMgrUrl; + private final String urlSuffix; + private final RicInstanceList instanceConfig; @Autowired - public AppManagerConfiguration(@Value("${appmgr.url.prefix}") final String urlPrefix, - @Value("${appmgr.url.suffix}") final String urlSuffix) { - logger.debug("ctor prefix '{}' suffix '{}'", urlPrefix, urlSuffix); - xappMgrUrl = new DefaultUriBuilderFactory(urlPrefix.trim()).builder().path(urlSuffix.trim()).build().normalize() - .toString(); - logger.info("Configuring App Manager at URL {}", xappMgrUrl); + public AppManagerConfiguration(@Value("${appmgr.url.suffix}") final String urlSuffix, + final RicInstanceList instanceConfig) { + logger.info("ctor: URL suffix {}", urlSuffix); + this.urlSuffix = urlSuffix; + this.instanceConfig = instanceConfig; } - private ApiClient apiClient() { - ApiClient apiClient = new ApiClient(new RestTemplate()); - apiClient.setBasePath(xappMgrUrl); - return apiClient; - } - - /** - * @return A HealthApi with an ApiClient configured from properties - */ @Bean // The bean (method) name must be globally unique - public HealthApi xappMgrHealthApi() { - return new HealthApi(apiClient()); + public AppManagerApiBuilder appManagerApiBuilder() { + return new AppManagerApiBuilder(instanceConfig, urlSuffix); } - /** - * @return An XappApi with an ApiClient configured from properties - */ - @Bean - // The bean (method) name must be globally unique - public XappApi xappMgrXappApi() { - return new XappApi(apiClient()); - } } diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/CaasIngressConfiguration.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/CaasIngressConfiguration.java index dd9449dc..7bb31493 100644 --- a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/CaasIngressConfiguration.java +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/CaasIngressConfiguration.java @@ -23,7 +23,7 @@ import java.lang.invoke.MethodHandles; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; -import org.oransc.ric.portal.dashboard.k8sapi.SimpleKubernetesClient; +import org.oransc.ric.portal.dashboard.model.RicInstanceList; import org.oransc.ric.portal.dashboard.util.HttpsURLConnectionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,7 +32,6 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; -import org.springframework.web.util.DefaultUriBuilderFactory; /** * Creates instances of CAAS-Ingres clients. @@ -44,19 +43,18 @@ public class CaasIngressConfiguration { private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); // Populated by the autowired constructor - private final String caasIngressPltUrl; + private final String urlSuffix; + private final RicInstanceList instanceConfig; @Autowired public CaasIngressConfiguration( // - @Value("${caasingress.plt.url.prefix}") final String pltUrlPrefix, - @Value("${caasingress.plt.url.suffix}") final String pltUrlSuffix, - @Value("${caasingress.insecure}") final Boolean insecureFlag) // - throws KeyManagementException, NoSuchAlgorithmException { - logger.debug("ctor caasingress plt prefix '{}' suffix '{}'", pltUrlPrefix, pltUrlSuffix); - logger.debug("ctor caasingress insecure flag {}", insecureFlag); - caasIngressPltUrl = new DefaultUriBuilderFactory(pltUrlPrefix.trim()).builder().path(pltUrlSuffix.trim()) - .build().normalize().toString(); - logger.info("Configuring CAAS-Ingress URL: plt {}", caasIngressPltUrl); + @Value("${caasingress.plt.url.suffix}") final String pltUrlSuffix, // + @Value("${caasingress.insecure}") final Boolean insecureFlag, // + final RicInstanceList instanceConfig) throws KeyManagementException, NoSuchAlgorithmException { + logger.debug("ctor: suffix {} insecure flag {}", pltUrlSuffix, insecureFlag); + this.urlSuffix = pltUrlSuffix; + this.instanceConfig = instanceConfig; + // This is a brutal hack: if (insecureFlag != null && insecureFlag) { logger.warn("ctor: insecure flag set, disabling SSL checks"); HttpsURLConnectionUtils.turnOffSslChecking(); @@ -65,8 +63,8 @@ public class CaasIngressConfiguration { @Bean // The bean (method) name must be globally unique - public SimpleKubernetesClient ciPltApi() { - return new SimpleKubernetesClient(caasIngressPltUrl); + public SimpleKubernetesClientBuilder simpleKubernetesClientBuilder() { + return new SimpleKubernetesClientBuilder(instanceConfig, urlSuffix); } } diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/E2ManagerApiBuilder.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/E2ManagerApiBuilder.java new file mode 100644 index 00000000..6e64a548 --- /dev/null +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/E2ManagerApiBuilder.java @@ -0,0 +1,70 @@ +/*- + * ========================LICENSE_START================================= + * O-RAN-SC + * %% + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================LICENSE_END=================================== + */ +package org.oransc.ric.portal.dashboard.config; + +import java.lang.invoke.MethodHandles; + +import org.oransc.ric.e2mgr.client.api.HealthCheckApi; +import org.oransc.ric.e2mgr.client.api.NodebApi; +import org.oransc.ric.e2mgr.client.invoker.ApiClient; +import org.oransc.ric.portal.dashboard.model.RicInstanceList; +import org.oransc.ric.portal.dashboard.model.RicInstance; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.DefaultUriBuilderFactory; + +/** + * The OpenAPI generated API client code using Spring RestTemplate is not thread + * safe according to https://github.com/swagger-api/swagger-codegen/issues/9222 + * + * As a workaround this builder creates a new client at every request. If this + * proves to be too slow then clients could be cached for each thread. + */ +public class E2ManagerApiBuilder { + + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + private final String urlSuffix; + private final RicInstanceList instanceConfig; + + public E2ManagerApiBuilder(final RicInstanceList instanceConfig, final String urlSuffix) { + logger.debug("ctor: suffix {}", urlSuffix); + this.instanceConfig = instanceConfig; + this.urlSuffix = urlSuffix; + } + + private ApiClient apiClient(String instanceKey) { + RicInstance instance = instanceConfig.getInstance(instanceKey); + String url = new DefaultUriBuilderFactory(instance.getPltUrlPrefix().trim()).builder() + .path(this.urlSuffix.trim()).build().normalize().toString(); + logger.debug("apiClient URL {}", url); + return new ApiClient(new RestTemplate()).setBasePath(url); + } + + public HealthCheckApi getHealthCheckApi(String instanceKey) { + return new HealthCheckApi(apiClient(instanceKey)); + } + + public NodebApi getNodebApi(String instanceKey) { + return new NodebApi(apiClient(instanceKey)); + } + +} diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/E2ManagerConfiguration.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/E2ManagerConfiguration.java index 21ca8637..4b25622a 100644 --- a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/E2ManagerConfiguration.java +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/E2ManagerConfiguration.java @@ -21,9 +21,7 @@ package org.oransc.ric.portal.dashboard.config; import java.lang.invoke.MethodHandles; -import org.oransc.ric.e2mgr.client.api.HealthCheckApi; -import org.oransc.ric.e2mgr.client.api.NodebApi; -import org.oransc.ric.e2mgr.client.invoker.ApiClient; +import org.oransc.ric.portal.dashboard.model.RicInstanceList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -31,11 +29,10 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; -import org.springframework.web.client.RestTemplate; -import org.springframework.web.util.DefaultUriBuilderFactory; /** - * Creates an E2 manager client as a bean to be managed by the Spring container. + * Creates an E2 manager client builder as a bean to be managed by the Spring + * container. */ @Configuration @Profile("!test") @@ -44,33 +41,21 @@ public class E2ManagerConfiguration { private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); // Populated by the autowired constructor - private final String e2mgrUrl; + private final String urlSuffix; + private final RicInstanceList instanceConfig; @Autowired - public E2ManagerConfiguration(@Value("${e2mgr.url.prefix}") final String urlPrefix, - @Value("${e2mgr.url.suffix}") final String urlSuffix) { - logger.debug("ctor prefix '{}' suffix '{}'", urlPrefix, urlSuffix); - e2mgrUrl = new DefaultUriBuilderFactory(urlPrefix.trim()).builder().path(urlSuffix.trim()).build().normalize() - .toString(); - logger.info("Configuring E2 Manager at URL {}", e2mgrUrl); - } - - private ApiClient apiClient() { - ApiClient apiClient = new ApiClient(new RestTemplate()); - apiClient.setBasePath(e2mgrUrl); - return apiClient; - } - - @Bean - // The bean (method) name must be globally unique - public HealthCheckApi e2MgrHealthCheckApi() { - return new HealthCheckApi(apiClient()); + public E2ManagerConfiguration(@Value("${e2mgr.url.suffix}") final String urlSuffix, + final RicInstanceList instanceConfig) { + logger.info("ctor: URL suffix {}", urlSuffix); + this.urlSuffix = urlSuffix; + this.instanceConfig = instanceConfig; } @Bean // The bean (method) name must be globally unique - public NodebApi e2MgrNodebApi() { - return new NodebApi(apiClient()); + public E2ManagerApiBuilder e2ManagerApiBuilder() { + return new E2ManagerApiBuilder(instanceConfig, urlSuffix); } } diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/RICInstanceConfiguration.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/RICInstanceConfiguration.java index f39f2001..290331fc 100644 --- a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/RICInstanceConfiguration.java +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/RICInstanceConfiguration.java @@ -23,14 +23,16 @@ package org.oransc.ric.portal.dashboard.config; import java.util.ArrayList; import java.util.List; -import org.oransc.ric.portal.dashboard.model.InstanceTransport; +import org.oransc.ric.portal.dashboard.model.RicInstance; +import org.oransc.ric.portal.dashboard.model.RicInstanceList; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; /** - * Holds the list of RIC instances read from configuration data. This asserts no - * Spring profile such as ("!test"). No mock version of this class is required. - * Populated from a YAML list in the application properties like this: + * Publishes a list of RIC instances from configuration, written as a YAML list + * in application properties like this: * *
  * ric-instance-list:
@@ -38,21 +40,28 @@ import org.springframework.context.annotation.Configuration;
         -
           key: key1
           name: Friendly Name One
+          urlPrefix: http://foo.bar.one/
         -
           key: key2
           name: Friendly Name Two
+          urlPrefix: http://foo.bar.two/
  * 
*/ @Configuration @ConfigurationProperties(prefix = "ric-instance-list") +@Profile("!test") public class RICInstanceConfiguration { - private List instances = new ArrayList<>(); - public List getInstances() { - return instances; - } + private List instances = new ArrayList<>(); - public void setInstances(List instances) { + // Called by spring with config data + public void setInstances(List instances) { this.instances = instances; } + + @Bean + public RicInstanceList ricInstanceList() { + return new RicInstanceList(instances); + } + } diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/SimpleKubernetesClientBuilder.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/SimpleKubernetesClientBuilder.java new file mode 100644 index 00000000..50af74f8 --- /dev/null +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/SimpleKubernetesClientBuilder.java @@ -0,0 +1,63 @@ +/*- + * ========================LICENSE_START================================= + * O-RAN-SC + * %% + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================LICENSE_END=================================== + */ +package org.oransc.ric.portal.dashboard.config; + +import java.lang.invoke.MethodHandles; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.oransc.ric.portal.dashboard.k8sapi.SimpleKubernetesClient; +import org.oransc.ric.portal.dashboard.model.RicInstance; +import org.oransc.ric.portal.dashboard.model.RicInstanceList; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.util.DefaultUriBuilderFactory; + +/** + * Creates, caches and serves out instances of SimpleKubernetesClient for a + * given instance. That class seems to be thread safe. + */ +public class SimpleKubernetesClientBuilder { + + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + private Map cache = new ConcurrentHashMap<>(); + + private final String urlSuffix; + private final RicInstanceList instanceConfig; + + public SimpleKubernetesClientBuilder(final RicInstanceList instanceConfig, final String urlSuffix) { + logger.debug("ctor: suffix {}", urlSuffix); + this.instanceConfig = instanceConfig; + this.urlSuffix = urlSuffix; + } + + public SimpleKubernetesClient getSimpleKubernetesClient(String instanceKey) { + logger.debug("getSimpleKubernetesClient instance {}", instanceKey); + if (cache.containsKey(instanceKey)) + return cache.get(instanceKey); + RicInstance instance = instanceConfig.getInstance(instanceKey); + String url = new DefaultUriBuilderFactory(instance.getCaasUrlPrefix().trim()).builder() + .path(this.urlSuffix.trim()).build().normalize().toString(); + SimpleKubernetesClient client = new SimpleKubernetesClient(url); + cache.put(instanceKey, client); + return client; + } + +} diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/WebSecurityConfiguration.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/WebSecurityConfiguration.java index f4819d30..941dc465 100644 --- a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/WebSecurityConfiguration.java +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/WebSecurityConfiguration.java @@ -23,6 +23,7 @@ import java.lang.invoke.MethodHandles; import java.lang.reflect.InvocationTargetException; import org.onap.portalsdk.core.onboarding.util.PortalApiConstants; +import org.oransc.ric.portal.dashboard.DashboardConstants; import org.oransc.ric.portal.dashboard.DashboardUserManager; import org.oransc.ric.portal.dashboard.controller.A1MediatorController; import org.oransc.ric.portal.dashboard.controller.AdminController; @@ -83,7 +84,7 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { } /** - * Resource paths that do not require authentication, especially including + * Resource paths that do not require authentication, including * Swagger-generated documentation. */ protected static final String[] OPEN_PATHS = { // @@ -92,14 +93,17 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { "/swagger-ui.html", // "/webjars/**", // PortalApiConstants.API_PREFIX + "/**", // - A1MediatorController.CONTROLLER_PATH + "/" + A1MediatorController.VERSION_METHOD, // + A1MediatorController.CONTROLLER_PATH + "/" + DashboardConstants.VERSION_METHOD, // AdminController.CONTROLLER_PATH + "/" + AdminController.HEALTH_METHOD, // AdminController.CONTROLLER_PATH + "/" + AdminController.VERSION_METHOD, // - AppManagerController.CONTROLLER_PATH + "/" + AppManagerController.HEALTH_ALIVE_METHOD, // - AppManagerController.CONTROLLER_PATH + "/" + AppManagerController.HEALTH_READY_METHOD, // - AppManagerController.CONTROLLER_PATH + "/" + AppManagerController.VERSION_METHOD, // - E2ManagerController.CONTROLLER_PATH + "/" + E2ManagerController.HEALTH_METHOD, // - E2ManagerController.CONTROLLER_PATH + "/" + E2ManagerController.VERSION_METHOD, // + AppManagerController.CONTROLLER_PATH + "/" + DashboardConstants.RIC_INSTANCE_KEY + "/*/" + + AppManagerController.HEALTH_ALIVE_METHOD, // + AppManagerController.CONTROLLER_PATH + "/" + DashboardConstants.RIC_INSTANCE_KEY + "/*/" + + AppManagerController.HEALTH_READY_METHOD, // + AppManagerController.CONTROLLER_PATH + "/" + DashboardConstants.VERSION_METHOD, // + E2ManagerController.CONTROLLER_PATH + "/" + DashboardConstants.RIC_INSTANCE_KEY + "/*/" + + E2ManagerController.HEALTH_METHOD, // + E2ManagerController.CONTROLLER_PATH + "/" + DashboardConstants.VERSION_METHOD, // SimpleErrorController.ERROR_PATH }; @Override diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/A1MediatorController.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/A1MediatorController.java index 6fc80691..98a48558 100644 --- a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/A1MediatorController.java +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/A1MediatorController.java @@ -26,6 +26,7 @@ import javax.servlet.http.HttpServletResponse; import org.oransc.ric.a1med.client.api.A1MediatorApi; import org.oransc.ric.portal.dashboard.DashboardApplication; import org.oransc.ric.portal.dashboard.DashboardConstants; +import org.oransc.ric.portal.dashboard.config.A1MediatorApiBuilder; import org.oransc.ric.portal.dashboard.model.SuccessTransport; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,7 +46,7 @@ import io.swagger.annotations.ApiParam; /** * Proxies calls from the front end to the A1 Mediator API to get and put - * policies. The first application managed via this path is Admission Control. + * policies. All methods are deliberately kept ignorant of the data format. * * If a method throws RestClientResponseException, it is handled by * {@link CustomResponseEntityExceptionHandler#handleProxyMethodException(Exception, org.springframework.web.context.request.WebRequest)} @@ -58,54 +59,51 @@ public class A1MediatorController { private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - // Publish paths in constants so tests are easy to write + /** This path lacks the RIC instance pattern */ public static final String CONTROLLER_PATH = DashboardConstants.ENDPOINT_PREFIX + "/a1-p"; - // Endpoints - public static final String VERSION_METHOD = DashboardConstants.VERSION_METHOD; // Path parameters public static final String PP_POLICIES = "policies"; + // The get and put methods use the same path + private static final String POLICY_METHOD_PATH = /* controller path + */ DashboardConstants.RIC_INSTANCE_KEY + "/{" + + DashboardConstants.RIC_INSTANCE_KEY + "}/" + PP_POLICIES + "/{" + PP_POLICIES + "}"; // Populated by the autowired constructor - private final A1MediatorApi a1MediatorApi; + private final A1MediatorApiBuilder a1MediatorClientBuilder; @Autowired - public A1MediatorController(final A1MediatorApi a1MediatorApi) { - Assert.notNull(a1MediatorApi, "API must not be null"); - this.a1MediatorApi = a1MediatorApi; + public A1MediatorController(final A1MediatorApiBuilder a1MediatorApiBuilder) { + Assert.notNull(a1MediatorApiBuilder, "builder must not be null"); + this.a1MediatorClientBuilder = a1MediatorApiBuilder; if (logger.isDebugEnabled()) - logger.debug("ctor: configured with client type {}", a1MediatorApi.getClass().getName()); + logger.debug("ctor: configured with builder type {}", a1MediatorApiBuilder.getClass().getName()); } @ApiOperation(value = "Gets the A1 client library MANIFEST.MF property Implementation-Version.", response = SuccessTransport.class) - @GetMapping(VERSION_METHOD) + @GetMapping(DashboardConstants.VERSION_METHOD) // No role required public SuccessTransport getA1MediatorClientVersion() { return new SuccessTransport(200, DashboardApplication.getImplementationVersion(A1MediatorApi.class)); } - /* - * This method is deliberately kept ignorant of the data passing thru. - */ @ApiOperation(value = "Gets the specified policy from the A1 Mediator") - @GetMapping(PP_POLICIES + "/{" + PP_POLICIES + "}") + @GetMapping(POLICY_METHOD_PATH) @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD }) - public Object getPolicy(@PathVariable(PP_POLICIES) String policyName) { - logger.debug("getPolicy {}", policyName); - return a1MediatorApi.a1ControllerGetHandler(policyName); + public Object getPolicy(@PathVariable(DashboardConstants.RIC_INSTANCE_KEY) String instanceKey, + @PathVariable(PP_POLICIES) String policyName) { + logger.debug("getPolicy instance {} policy {}", instanceKey, policyName); + return a1MediatorClientBuilder.getA1MediatorApi(instanceKey).a1ControllerGetHandler(policyName); } - /* - * This method is deliberately kept ignorant of the data passing thru. - */ @ApiOperation(value = "Puts the specified policy to the A1 Mediator") - @PutMapping(PP_POLICIES + "/{" + PP_POLICIES + "}") + @PutMapping(POLICY_METHOD_PATH) @Secured({ DashboardConstants.ROLE_ADMIN }) - public void putPolicy(@PathVariable(PP_POLICIES) String policyName, - @ApiParam(value = "Policy body") @RequestBody String policy, // + public void putPolicy(@PathVariable(DashboardConstants.RIC_INSTANCE_KEY) String instanceKey, + @PathVariable(PP_POLICIES) String policyName, @ApiParam(value = "Policy body") @RequestBody String policy, // HttpServletResponse response) { - logger.debug("putPolicy name {} value {}", policyName, policy); - a1MediatorApi.a1ControllerPutHandler(policyName, policy); - response.setStatus(a1MediatorApi.getApiClient().getStatusCode().value()); + logger.debug("putPolicy instance {} name {} value {}", instanceKey, policyName, policy); + A1MediatorApi api = a1MediatorClientBuilder.getA1MediatorApi(instanceKey); + api.a1ControllerPutHandler(policyName, policy); + response.setStatus(api.getApiClient().getStatusCode().value()); } } diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/AdminController.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/AdminController.java index 39488bd1..17d98439 100644 --- a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/AdminController.java +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/AdminController.java @@ -28,10 +28,10 @@ import org.onap.portalsdk.core.restful.domain.EcompUser; import org.oransc.ric.portal.dashboard.DashboardApplication; import org.oransc.ric.portal.dashboard.DashboardConstants; import org.oransc.ric.portal.dashboard.DashboardUserManager; -import org.oransc.ric.portal.dashboard.config.RICInstanceConfiguration; import org.oransc.ric.portal.dashboard.model.ErrorTransport; import org.oransc.ric.portal.dashboard.model.IDashboardResponse; -import org.oransc.ric.portal.dashboard.model.InstanceTransport; +import org.oransc.ric.portal.dashboard.model.RicInstanceList; +import org.oransc.ric.portal.dashboard.model.RicInstanceKeyName; import org.oransc.ric.portal.dashboard.model.SuccessTransport; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -73,7 +73,7 @@ public class AdminController { private DashboardUserManager dashboardUserManager; @Autowired - private RICInstanceConfiguration instanceConfig; + private RicInstanceList instanceConfig; @ApiOperation(value = "Gets the Dashboard MANIFEST.MF property Implementation-Version.", response = SuccessTransport.class) @GetMapping(VERSION_METHOD) @@ -102,12 +102,12 @@ public class AdminController { return dashboardUserManager.getUsers(); } - @ApiOperation(value = "Gets the list of RIC instances.", response = InstanceTransport.class, responseContainer = "List") + @ApiOperation(value = "Gets the list of RIC instances.", response = RicInstanceKeyName.class, responseContainer = "List") @GetMapping(INSTANCE_METHOD) @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD }) - public List getInstances() { + public List getInstances() { logger.debug("getInstances"); - return instanceConfig.getInstances(); + return instanceConfig.getKeyNameList(); } @ApiOperation(value = "Gets the kibana metrics URL for the specified app.", response = SuccessTransport.class) diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/AppManagerController.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/AppManagerController.java index cf267da0..2dcc7d50 100644 --- a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/AppManagerController.java +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/AppManagerController.java @@ -34,6 +34,7 @@ import org.oransc.ric.plt.appmgr.client.model.XAppInfo; import org.oransc.ric.plt.appmgr.client.model.Xapp; import org.oransc.ric.portal.dashboard.DashboardApplication; import org.oransc.ric.portal.dashboard.DashboardConstants; +import org.oransc.ric.portal.dashboard.config.AppManagerApiBuilder; import org.oransc.ric.portal.dashboard.model.AppTransport; import org.oransc.ric.portal.dashboard.model.DashboardDeployableXapps; import org.oransc.ric.portal.dashboard.model.SuccessTransport; @@ -72,95 +73,106 @@ public class AppManagerController { // 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 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"; + // minimize repeats + private static final String CONFIG_METHOD_PATH = DashboardConstants.RIC_INSTANCE_KEY + "/{" + + DashboardConstants.RIC_INSTANCE_KEY + "}/" + CONFIG_METHOD; + private static final String XAPPS_METHOD_PATH = DashboardConstants.RIC_INSTANCE_KEY + "/{" + + DashboardConstants.RIC_INSTANCE_KEY + "}/" + XAPPS_METHOD; // Populated by the autowired constructor - private final HealthApi healthApi; - private final XappApi xappApi; + private final AppManagerApiBuilder appManagerApiBuilder; @Autowired - public AppManagerController(final HealthApi healthApi, final XappApi xappApi) { - Assert.notNull(healthApi, "health API must not be null"); - Assert.notNull(xappApi, "xapp API must not be null"); - this.healthApi = healthApi; - this.xappApi = xappApi; + public AppManagerController(final AppManagerApiBuilder appManagerApiBuilder) { + Assert.notNull(appManagerApiBuilder, "builder must not be null"); + this.appManagerApiBuilder = appManagerApiBuilder; if (logger.isDebugEnabled()) - logger.debug("ctor: configured with client types {} and {}", healthApi.getClass().getName(), - xappApi.getClass().getName()); + logger.debug("ctor: configured with builder type {}", appManagerApiBuilder.getClass().getName()); } - @ApiOperation(value = "Gets the XApp manager client library MANIFEST.MF property Implementation-Version.", response = SuccessTransport.class) - @GetMapping(VERSION_METHOD) + @ApiOperation(value = "Gets the App manager client library MANIFEST.MF property Implementation-Version.", response = SuccessTransport.class) + @GetMapping(DashboardConstants.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.") - @GetMapping(HEALTH_ALIVE_METHOD) + @ApiOperation(value = "Health check of App Manager - Liveness probe.") + @GetMapping(DashboardConstants.RIC_INSTANCE_KEY + "/{" + DashboardConstants.RIC_INSTANCE_KEY + "}/" + + HEALTH_ALIVE_METHOD) // No role required - public void getHealth(HttpServletResponse response) { - logger.debug("getHealthAlive"); - healthApi.getHealthAlive(); - response.setStatus(healthApi.getApiClient().getStatusCode().value()); + public void getHealth(@PathVariable(DashboardConstants.RIC_INSTANCE_KEY) String instanceKey, + HttpServletResponse response) { + logger.debug("getHealthAlive instance {}", instanceKey); + HealthApi api = appManagerApiBuilder.getHealthApi(instanceKey); + api.getHealthAlive(); + response.setStatus(api.getApiClient().getStatusCode().value()); } - @ApiOperation(value = "Readiness check of xApp Manager - Readiness probe.") - @GetMapping(HEALTH_READY_METHOD) + @ApiOperation(value = "Readiness check of App Manager - Readiness probe.") + @GetMapping(DashboardConstants.RIC_INSTANCE_KEY + "/{" + DashboardConstants.RIC_INSTANCE_KEY + "}/" + + HEALTH_READY_METHOD) // No role required - public void getHealthReady(HttpServletResponse response) { - logger.debug("getHealthReady"); - healthApi.getHealthReady(); - response.setStatus(healthApi.getApiClient().getStatusCode().value()); + public void getHealthReady(@PathVariable(DashboardConstants.RIC_INSTANCE_KEY) String instanceKey, + HttpServletResponse response) { + logger.debug("getHealthReady instance {}", instanceKey); + HealthApi api = appManagerApiBuilder.getHealthApi(instanceKey); + api.getHealthReady(); + response.setStatus(api.getApiClient().getStatusCode().value()); } - @ApiOperation(value = "Returns the configuration of all xapps.", response = AllXappConfig.class) - @GetMapping(CONFIG_METHOD) + @ApiOperation(value = "Returns the configuration of all Xapps.", response = AllXappConfig.class) + @GetMapping(CONFIG_METHOD_PATH) @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD }) - public AllXappConfig getAllXappConfig() { - logger.debug("getAllXappConfig"); - return xappApi.getAllXappConfig(); + public AllXappConfig getAllXappConfig(@PathVariable(DashboardConstants.RIC_INSTANCE_KEY) String instanceKey) { + logger.debug("getAllXappConfig instance {}", instanceKey); + return appManagerApiBuilder.getXappApi(instanceKey).getAllXappConfig(); } - @ApiOperation(value = "Create xApp config.", response = XAppConfig.class) - @PostMapping(CONFIG_METHOD) + @ApiOperation(value = "Create XApp config.", response = XAppConfig.class) + @PostMapping(CONFIG_METHOD_PATH) @Secured({ DashboardConstants.ROLE_ADMIN }) - public XAppConfig createXappConfig(@RequestBody XAppConfig xAppConfig) { - logger.debug("createXappConfig {}", xAppConfig); - return xappApi.createXappConfig(xAppConfig); + public XAppConfig createXappConfig(@PathVariable(DashboardConstants.RIC_INSTANCE_KEY) String instanceKey, + @RequestBody XAppConfig xAppConfig) { + logger.debug("createXappConfig instance {} config {}", instanceKey, xAppConfig); + return appManagerApiBuilder.getXappApi(instanceKey).createXappConfig(xAppConfig); } - @ApiOperation(value = "Modify xApp config.", response = XAppConfig.class) - @PutMapping(CONFIG_METHOD) + @ApiOperation(value = "Modify XApp config.", response = XAppConfig.class) + @PutMapping(CONFIG_METHOD_PATH) @Secured({ DashboardConstants.ROLE_ADMIN }) - public XAppConfig modifyXappConfig(@RequestBody XAppConfig xAppConfig) { - logger.debug("modifyXappConfig {}", xAppConfig); - return xappApi.modifyXappConfig(xAppConfig); + public XAppConfig modifyXappConfig(@PathVariable(DashboardConstants.RIC_INSTANCE_KEY) String instanceKey, + @RequestBody XAppConfig xAppConfig) { + logger.debug("modifyXappConfig instance {} config {}", instanceKey, xAppConfig); + return appManagerApiBuilder.getXappApi(instanceKey).modifyXappConfig(xAppConfig); } - @ApiOperation(value = "Delete xApp configuration.") - @DeleteMapping(CONFIG_METHOD + "/{" + PP_XAPP_NAME + "}") + @ApiOperation(value = "Delete XApp configuration.") + @DeleteMapping(CONFIG_METHOD_PATH + "/{" + PP_XAPP_NAME + "}") @Secured({ DashboardConstants.ROLE_ADMIN }) - public void deleteXappConfig(@RequestBody ConfigMetadata configMetadata, HttpServletResponse response) { - logger.debug("deleteXappConfig {}", configMetadata); - xappApi.deleteXappConfig(configMetadata); - response.setStatus(healthApi.getApiClient().getStatusCode().value()); + public void deleteXappConfig(@PathVariable(DashboardConstants.RIC_INSTANCE_KEY) String instanceKey, + @RequestBody ConfigMetadata configMetadata, HttpServletResponse response) { + logger.debug("deleteXappConfig instance {} config {}", instanceKey, configMetadata); + XappApi api = appManagerApiBuilder.getXappApi(instanceKey); + api.deleteXappConfig(configMetadata); + response.setStatus(api.getApiClient().getStatusCode().value()); } @ApiOperation(value = "Returns a list of deployable xapps.", response = DashboardDeployableXapps.class) - @GetMapping(XAPPS_LIST_METHOD) + @GetMapping(DashboardConstants.RIC_INSTANCE_KEY + "/{" + DashboardConstants.RIC_INSTANCE_KEY + "}/" + + XAPPS_LIST_METHOD) @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD }) - public DashboardDeployableXapps getAvailableXapps() { - logger.debug("getAvailableXapps"); - AllDeployableXapps appNames = xappApi.listAllDeployableXapps(); + public DashboardDeployableXapps getAvailableXapps( + @PathVariable(DashboardConstants.RIC_INSTANCE_KEY) String instanceKey) { + logger.debug("getAvailableXapps instance {}", instanceKey); + AllDeployableXapps appNames = appManagerApiBuilder.getXappApi(instanceKey).listAllDeployableXapps(); // Answer a collection of structure instead of string // because I expect the AppMgr to be extended with // additional properties for each one. @@ -171,36 +183,40 @@ public class AppManagerController { } @ApiOperation(value = "Returns the status of all deployed xapps.", response = AllDeployedXapps.class) - @GetMapping(XAPPS_METHOD) + @GetMapping(XAPPS_METHOD_PATH) @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD }) - public AllDeployedXapps getDeployedXapps() { - logger.debug("getDeployedXapps"); - return xappApi.getAllXapps(); + public AllDeployedXapps getDeployedXapps(@PathVariable(DashboardConstants.RIC_INSTANCE_KEY) String instanceKey) { + logger.debug("getDeployedXapps instance {}", instanceKey); + return appManagerApiBuilder.getXappApi(instanceKey).getAllXapps(); } @ApiOperation(value = "Returns the status of a given xapp.", response = Xapp.class) - @GetMapping(XAPPS_METHOD + "/{" + PP_XAPP_NAME + "}") + @GetMapping(XAPPS_METHOD_PATH + "/{" + PP_XAPP_NAME + "}") @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD }) - public Xapp getXapp(@PathVariable("xAppName") String xAppName) { - logger.debug("getXapp {}", xAppName); - return xappApi.getXappByName(xAppName); + public Xapp getXapp(@PathVariable(DashboardConstants.RIC_INSTANCE_KEY) String instanceKey, + @PathVariable(PP_XAPP_NAME) String appName) { + logger.debug("getXapp instance {} name {}", instanceKey, appName); + return appManagerApiBuilder.getXappApi(instanceKey).getXappByName(appName); } @ApiOperation(value = "Deploy a xapp.", response = Xapp.class) - @PostMapping(XAPPS_METHOD) + @PostMapping(XAPPS_METHOD_PATH) @Secured({ DashboardConstants.ROLE_ADMIN }) - public Xapp deployXapp(@RequestBody XAppInfo xAppInfo) { - logger.debug("deployXapp {}", xAppInfo); - return xappApi.deployXapp(xAppInfo); + public Xapp deployXapp(@PathVariable(DashboardConstants.RIC_INSTANCE_KEY) String instanceKey, + @RequestBody XAppInfo appInfo) { + logger.debug("deployXapp instance {} info {}", instanceKey, appInfo); + return appManagerApiBuilder.getXappApi(instanceKey).deployXapp(appInfo); } @ApiOperation(value = "Undeploy an existing xapp.") - @DeleteMapping(XAPPS_METHOD + "/{" + PP_XAPP_NAME + "}") + @DeleteMapping(XAPPS_METHOD_PATH + "/{" + PP_XAPP_NAME + "}") @Secured({ DashboardConstants.ROLE_ADMIN }) - public void undeployXapp(@PathVariable("xAppName") String xAppName, HttpServletResponse response) { - logger.debug("undeployXapp {}", xAppName); - xappApi.undeployXapp(xAppName); - response.setStatus(xappApi.getApiClient().getStatusCode().value()); + public void undeployXapp(@PathVariable(DashboardConstants.RIC_INSTANCE_KEY) String instanceKey, + @PathVariable(PP_XAPP_NAME) String appName, HttpServletResponse response) { + logger.debug("undeployXapp instance {} name {}", instanceKey, appName); + XappApi api = appManagerApiBuilder.getXappApi(instanceKey); + api.undeployXapp(appName); + response.setStatus(api.getApiClient().getStatusCode().value()); } } diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/CaasIngressController.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/CaasIngressController.java index f8272b3f..7d91f17b 100644 --- a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/CaasIngressController.java +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/CaasIngressController.java @@ -24,6 +24,7 @@ import java.lang.invoke.MethodHandles; import javax.servlet.http.HttpServletResponse; import org.oransc.ric.portal.dashboard.DashboardConstants; +import org.oransc.ric.portal.dashboard.config.SimpleKubernetesClientBuilder; import org.oransc.ric.portal.dashboard.k8sapi.SimpleKubernetesClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -59,7 +60,7 @@ public class CaasIngressController { // Publish constants so tests are easy to write public static final String CONTROLLER_PATH = DashboardConstants.ENDPOINT_PREFIX + "/caas-ingress"; // Endpoints - public static final String PODS_METHOD = "/pods"; + public static final String PODS_METHOD = "pods"; // Path parameters public static final String PP_CLUSTER = "cluster"; public static final String PP_NAMESPACE = "namespace"; @@ -67,28 +68,31 @@ public class CaasIngressController { public static final String CLUSTER_PLT = "plt"; public static final String CLUSTER_RIC = "ric"; // alternate for PLT - private final SimpleKubernetesClient ciPltClient; + // Populated by the autowired constructor + private final SimpleKubernetesClientBuilder simpleKubernetesClientBuilder; @Autowired - public CaasIngressController(final SimpleKubernetesClient ciPltApi) { - Assert.notNull(ciPltApi, "pltApi must not be null"); - this.ciPltClient = ciPltApi; + public CaasIngressController(final SimpleKubernetesClientBuilder simpleKubernetesClientBuilder) { + Assert.notNull(simpleKubernetesClientBuilder, "builder must not be null"); + this.simpleKubernetesClientBuilder = simpleKubernetesClientBuilder; if (logger.isDebugEnabled()) - logger.debug("ctor: configured with plt api {}", ciPltClient.getClass().getName()); + logger.debug("ctor: configured with builder type {}", simpleKubernetesClientBuilder.getClass().getName()); } /* * No need to parse the V1PodList, just pass thru as a string. */ @ApiOperation(value = "Gets list of pods in the specified cluster for the specified namespace", response = String.class) - @GetMapping(PODS_METHOD + "/" + PP_CLUSTER + "/{" + PP_CLUSTER + "}" + "/" + PP_NAMESPACE + "/{" + PP_NAMESPACE - + "}") + @GetMapping(DashboardConstants.RIC_INSTANCE_KEY + "/{" + DashboardConstants.RIC_INSTANCE_KEY + "}/" + PODS_METHOD + + "/" + PP_CLUSTER + "/{" + PP_CLUSTER + "}" + "/" + PP_NAMESPACE + "/{" + PP_NAMESPACE + "}") @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD }) - public String listPods(@PathVariable(PP_CLUSTER) String cluster, @PathVariable(PP_NAMESPACE) String namespace, - HttpServletResponse response) { - logger.debug("listPods: cluster {}, namespace {}", cluster, namespace); + public String listPods(@PathVariable(DashboardConstants.RIC_INSTANCE_KEY) String instanceKey, // + @PathVariable(PP_CLUSTER) String cluster, // + @PathVariable(PP_NAMESPACE) String namespace, HttpServletResponse response) { + logger.debug("listPods: instance {} cluster {} namespace {}", instanceKey, cluster, namespace); + SimpleKubernetesClient client = simpleKubernetesClientBuilder.getSimpleKubernetesClient(instanceKey); if (CLUSTER_PLT.equalsIgnoreCase(cluster) || CLUSTER_RIC.equalsIgnoreCase(cluster)) { - return ciPltClient.listPods(namespace); + return client.listPods(namespace); } else { logger.warn("listPods: unknown cluster {}", cluster); response.setStatus(HttpStatus.BAD_REQUEST.value()); diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/CustomResponseEntityExceptionHandler.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/CustomResponseEntityExceptionHandler.java index f5ecd104..a8816162 100644 --- a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/CustomResponseEntityExceptionHandler.java +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/CustomResponseEntityExceptionHandler.java @@ -21,6 +21,7 @@ package org.oransc.ric.portal.dashboard.controller; import java.lang.invoke.MethodHandles; +import org.oransc.ric.portal.dashboard.exception.UnknownInstanceException; import org.oransc.ric.portal.dashboard.model.ErrorTransport; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -79,4 +80,20 @@ public class CustomResponseEntityExceptionHandler extends ResponseEntityExceptio } } + /** + * Logs a warning if an invalid RIC instance key is used. + * + * @param ex + * The exception + * @param request + * The original request + * @return A response entity with status code 400 + */ + @ExceptionHandler({ UnknownInstanceException.class }) + public final ResponseEntity handleUnknownInstanceException(Exception ex, WebRequest request) { + log.warn("handleUnknownInstanceException: request {}, exception {}", request.getDescription(false), + ex.toString()); + return new ResponseEntity<>(new ErrorTransport(400, ex), HttpStatus.BAD_REQUEST); + } + } diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/E2ManagerController.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/E2ManagerController.java index 17e68fdc..749ecaeb 100644 --- a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/E2ManagerController.java +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/E2ManagerController.java @@ -33,6 +33,7 @@ import org.oransc.ric.e2mgr.client.model.ResetRequest; import org.oransc.ric.e2mgr.client.model.SetupRequest; import org.oransc.ric.portal.dashboard.DashboardApplication; import org.oransc.ric.portal.dashboard.DashboardConstants; +import org.oransc.ric.portal.dashboard.config.E2ManagerApiBuilder; import org.oransc.ric.portal.dashboard.model.RanDetailsTransport; import org.oransc.ric.portal.dashboard.model.SuccessTransport; import org.slf4j.Logger; @@ -68,65 +69,67 @@ public class E2ManagerController { private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - // Publish paths in constants so tests are easy to write + // Publish paths in constants for tests public static final String CONTROLLER_PATH = DashboardConstants.ENDPOINT_PREFIX + "/e2mgr"; // Dashboard only public static final String HEALTH_METHOD = "health"; - public static final String VERSION_METHOD = DashboardConstants.VERSION_METHOD; // Keep these consistent with the E2M implementation - /* package */ static final String NODEB_PREFIX = "/nodeb"; + /* package */ static final String NODEB_PREFIX = "nodeb"; public static final String RAN_METHOD = NODEB_PREFIX + "/ran"; public static final String NODEB_SHUTDOWN_METHOD = NODEB_PREFIX + "/shutdown"; public static final String NODEB_LIST_METHOD = NODEB_PREFIX + "/ids"; public static final String ENDC_SETUP_METHOD = NODEB_PREFIX + "/endc-setup"; public static final String X2_SETUP_METHOD = NODEB_PREFIX + "/x2-setup"; // Reset uses prefix, adds a path parameter below - public static final String RESET_METHOD = "/reset"; + public static final String RESET_METHOD = "reset"; // Path parameters private static final String PP_RANNAME = "ranName"; // Populated by the autowired constructor - private final HealthCheckApi e2HealthCheckApi; - private final NodebApi e2NodebApi; + private final E2ManagerApiBuilder e2ManagerApiBuilder; @Autowired - public E2ManagerController(final HealthCheckApi e2HealthCheckApi, final NodebApi e2NodebApi) { - Assert.notNull(e2HealthCheckApi, "API must not be null"); - Assert.notNull(e2NodebApi, "API must not be null"); - this.e2HealthCheckApi = e2HealthCheckApi; - this.e2NodebApi = e2NodebApi; + public E2ManagerController(final E2ManagerApiBuilder e2ManagerApiBuilder) { + Assert.notNull(e2ManagerApiBuilder, "builder must not be null"); + this.e2ManagerApiBuilder = e2ManagerApiBuilder; + if (logger.isDebugEnabled()) + logger.debug("ctor: configured with builder type {}", e2ManagerApiBuilder.getClass().getName()); } @ApiOperation(value = "Gets the E2 manager client library MANIFEST.MF property Implementation-Version.", response = SuccessTransport.class) - @GetMapping(VERSION_METHOD) + @GetMapping(DashboardConstants.VERSION_METHOD) // No role required public SuccessTransport getClientVersion() { return new SuccessTransport(200, DashboardApplication.getImplementationVersion(HealthCheckApi.class)); } @ApiOperation(value = "Gets the health from the E2 manager, expressed as the response code.") - @GetMapping(HEALTH_METHOD) + @GetMapping(DashboardConstants.RIC_INSTANCE_KEY + "/{" + DashboardConstants.RIC_INSTANCE_KEY + "}/" + HEALTH_METHOD) // No role required - public void healthGet(HttpServletResponse response) { - logger.debug("healthGet"); - e2HealthCheckApi.healthGet(); - response.setStatus(e2HealthCheckApi.getApiClient().getStatusCode().value()); + public void healthGet(@PathVariable(DashboardConstants.RIC_INSTANCE_KEY) String instanceKey, + HttpServletResponse response) { + logger.debug("healthGet instance {}", instanceKey); + HealthCheckApi api = e2ManagerApiBuilder.getHealthCheckApi(instanceKey); + api.healthGet(); + response.setStatus(api.getApiClient().getStatusCode().value()); } // This calls other methods to simplify the task of the front-end. @ApiOperation(value = "Gets all RAN identities and statuses from the E2 manager.", response = RanDetailsTransport.class, responseContainer = "List") - @GetMapping(RAN_METHOD) + @GetMapping(DashboardConstants.RIC_INSTANCE_KEY + "/{" + DashboardConstants.RIC_INSTANCE_KEY + "}/" + RAN_METHOD) @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD }) - public List getRanDetails() { - logger.debug("getRanDetails"); - List nodebIdList = e2NodebApi.getNodebIdList(); + public List getRanDetails( + @PathVariable(DashboardConstants.RIC_INSTANCE_KEY) String instanceKey) { + logger.debug("getRanDetails instance {}", instanceKey); + NodebApi api = e2ManagerApiBuilder.getNodebApi(instanceKey); + List nodebIdList = api.getNodebIdList(); logger.debug("getRanDetails: nodebIdList {}", nodebIdList); List details = new ArrayList<>(); for (NodebIdentity nbid : nodebIdList) { GetNodebResponse nbResp = null; try { // Catch exceptions to keep looping despite failures - nbResp = e2NodebApi.getNb(nbid.getInventoryName()); + nbResp = api.getNb(nbid.getInventoryName()); } catch (HttpStatusCodeException ex) { logger.warn("E2 getNb failed for name {}: {}", nbid.getInventoryName(), ex.toString()); nbResp = new GetNodebResponse().connectionStatus("UNKNOWN").ip("UNKNOWN").port(-1) @@ -138,56 +141,71 @@ public class E2ManagerController { } @ApiOperation(value = "Get RAN identities list.", response = NodebIdentity.class, responseContainer = "List") - @GetMapping(NODEB_LIST_METHOD) + @GetMapping(DashboardConstants.RIC_INSTANCE_KEY + "/{" + DashboardConstants.RIC_INSTANCE_KEY + "}/" + + NODEB_LIST_METHOD) @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD }) - public List getNodebIdList() { - logger.debug("getNodebIdList"); - return e2NodebApi.getNodebIdList(); + public List getNodebIdList(@PathVariable(DashboardConstants.RIC_INSTANCE_KEY) String instanceKey) { + logger.debug("getNodebIdList instance {}", instanceKey); + return e2ManagerApiBuilder.getNodebApi(instanceKey).getNodebIdList(); } @ApiOperation(value = "Get RAN by name.", response = GetNodebResponse.class) - @GetMapping(NODEB_SHUTDOWN_METHOD + "/{" + PP_RANNAME + "}") + @GetMapping(DashboardConstants.RIC_INSTANCE_KEY + "/{" + DashboardConstants.RIC_INSTANCE_KEY + "}/" + NODEB_PREFIX + + "/{" + PP_RANNAME + "}") @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD }) - public GetNodebResponse getNb(@PathVariable(PP_RANNAME) String ranName) { - logger.debug("getNb {}", ranName); - return e2NodebApi.getNb(ranName); + public GetNodebResponse getNb(@PathVariable(DashboardConstants.RIC_INSTANCE_KEY) String instanceKey, + @PathVariable(PP_RANNAME) String ranName) { + logger.debug("getNb instance {} name {}", instanceKey, ranName); + return e2ManagerApiBuilder.getNodebApi(instanceKey).getNb(ranName); } @ApiOperation(value = "Sets up an EN-DC RAN connection via the E2 manager.") - @PostMapping(ENDC_SETUP_METHOD) + @PostMapping(DashboardConstants.RIC_INSTANCE_KEY + "/{" + DashboardConstants.RIC_INSTANCE_KEY + "}/" + + ENDC_SETUP_METHOD) @Secured({ DashboardConstants.ROLE_ADMIN }) - public void endcSetup(@RequestBody SetupRequest setupRequest, HttpServletResponse response) { - logger.debug("endcSetup {}", setupRequest); - e2NodebApi.endcSetup(setupRequest); - response.setStatus(e2NodebApi.getApiClient().getStatusCode().value()); + public void endcSetup(@PathVariable(DashboardConstants.RIC_INSTANCE_KEY) String instanceKey, + @RequestBody SetupRequest setupRequest, HttpServletResponse response) { + logger.debug("endcSetup instance {} request {}", instanceKey, setupRequest); + NodebApi api = e2ManagerApiBuilder.getNodebApi(instanceKey); + api.endcSetup(setupRequest); + response.setStatus(api.getApiClient().getStatusCode().value()); } @ApiOperation(value = "Sets up an X2 RAN connection via the E2 manager.") - @PostMapping(X2_SETUP_METHOD) + @PostMapping(DashboardConstants.RIC_INSTANCE_KEY + "/{" + DashboardConstants.RIC_INSTANCE_KEY + "}/" + + X2_SETUP_METHOD) @Secured({ DashboardConstants.ROLE_ADMIN }) - public void x2Setup(@RequestBody SetupRequest setupRequest, HttpServletResponse response) { - logger.debug("x2Setup {}", setupRequest); - e2NodebApi.x2Setup(setupRequest); - response.setStatus(e2NodebApi.getApiClient().getStatusCode().value()); + public void x2Setup(@PathVariable(DashboardConstants.RIC_INSTANCE_KEY) String instanceKey, + @RequestBody SetupRequest setupRequest, HttpServletResponse response) { + logger.debug("x2Setup instance {} request {}", instanceKey, setupRequest); + NodebApi api = e2ManagerApiBuilder.getNodebApi(instanceKey); + api.x2Setup(setupRequest); + response.setStatus(api.getApiClient().getStatusCode().value()); } @ApiOperation(value = "Close all connections to the RANs and delete the data from the nodeb-rnib DB.") - @PutMapping(NODEB_SHUTDOWN_METHOD) + @PutMapping(DashboardConstants.RIC_INSTANCE_KEY + "/{" + DashboardConstants.RIC_INSTANCE_KEY + "}/" + + NODEB_SHUTDOWN_METHOD) @Secured({ DashboardConstants.ROLE_ADMIN }) - public void nodebShutdownPut(HttpServletResponse response) { - logger.debug("nodebShutdownPut"); - e2NodebApi.nodebShutdownPut(); - response.setStatus(e2NodebApi.getApiClient().getStatusCode().value()); + public void nodebShutdownPut(@PathVariable(DashboardConstants.RIC_INSTANCE_KEY) String instanceKey, + HttpServletResponse response) { + logger.debug("nodebShutdownPut instance {}", instanceKey); + NodebApi api = e2ManagerApiBuilder.getNodebApi(instanceKey); + api.nodebShutdownPut(); + response.setStatus(api.getApiClient().getStatusCode().value()); } @ApiOperation(value = "Abort any other ongoing procedures over X2 between the RIC and the RAN.") - @PutMapping(NODEB_PREFIX + "/{" + PP_RANNAME + "}" + RESET_METHOD) + @PutMapping(DashboardConstants.RIC_INSTANCE_KEY + "/{" + DashboardConstants.RIC_INSTANCE_KEY + "}/" + NODEB_PREFIX + + "/{" + PP_RANNAME + "}/" + RESET_METHOD) @Secured({ DashboardConstants.ROLE_ADMIN }) - public void reset(@PathVariable(PP_RANNAME) String ranName, @RequestBody ResetRequest resetRequest, + public void reset(@PathVariable(DashboardConstants.RIC_INSTANCE_KEY) String instanceKey, + @PathVariable(PP_RANNAME) String ranName, @RequestBody ResetRequest resetRequest, HttpServletResponse response) { - logger.debug("reset"); - e2NodebApi.reset(ranName, resetRequest); - response.setStatus(e2NodebApi.getApiClient().getStatusCode().value()); + logger.debug("reset instance {} name {}", instanceKey, ranName); + NodebApi api = e2ManagerApiBuilder.getNodebApi(instanceKey); + api.reset(ranName, resetRequest); + response.setStatus(api.getApiClient().getStatusCode().value()); } } diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/exception/UnknownInstanceException.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/exception/UnknownInstanceException.java new file mode 100644 index 00000000..f0fb074a --- /dev/null +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/exception/UnknownInstanceException.java @@ -0,0 +1,33 @@ +/*- + * ========================LICENSE_START================================= + * O-RAN-SC + * %% + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================LICENSE_END=================================== + */ +package org.oransc.ric.portal.dashboard.exception; + +public class UnknownInstanceException extends IllegalArgumentException { + + private static final long serialVersionUID = -3887065423512216019L; + + public UnknownInstanceException() { + super(); + } + + public UnknownInstanceException(String s) { + super(s); + } +} diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/RicInstance.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/RicInstance.java new file mode 100644 index 00000000..ad3b3f2e --- /dev/null +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/RicInstance.java @@ -0,0 +1,111 @@ +/*- + * ========================LICENSE_START================================= + * O-RAN-SC + * %% + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================LICENSE_END=================================== + */ + +package org.oransc.ric.portal.dashboard.model; + +/** + * POJO for RIC instance details. + */ +public class RicInstance extends RicInstanceKeyName { + + /* Application entry point */ + private String appUrlPrefix; + /* Platform entry point */ + private String pltUrlPrefix; + /* CAAS-Ingress */ + private String caasUrlPrefix; + + /** + * Builds an empty object. + */ + public RicInstance() { + super(); + } + + public RicInstance key(String key) { + super.key(key); + return this; + } + + public RicInstance name(String name) { + super.name(name); + return this; + } + + public RicInstanceKeyName toKeyName() { + return new RicInstanceKeyName(getKey(), getName()); + } + + public String getAppUrlPrefix() { + return appUrlPrefix; + } + + public void setAppUrlPrefix(String urlPrefix) { + this.appUrlPrefix = urlPrefix; + } + + public RicInstance appUrlPrefix(String prefix) { + this.appUrlPrefix = prefix; + return this; + } + + public String getPltUrlPrefix() { + return pltUrlPrefix; + } + + public void setPltUrlPrefix(String pltUrlPrefix) { + this.pltUrlPrefix = pltUrlPrefix; + } + + public RicInstance pltUrlPrefix(String prefix) { + this.pltUrlPrefix = prefix; + return this; + } + + public String getCaasUrlPrefix() { + return caasUrlPrefix; + } + + public void setCaasUrlPrefix(String caasUrlPrefix) { + this.caasUrlPrefix = caasUrlPrefix; + } + + public RicInstance caasUrlPrefix(String prefix) { + this.caasUrlPrefix = prefix; + return this; + } + + @Override + public String toString() { + return this.getClass().getName() + "[key=" + getKey() + ", name=" + getName() + ", appUrlPrefix=" + appUrlPrefix + + ", pltUrlPrefix=" + pltUrlPrefix + ", caasUrlPrefix=" + caasUrlPrefix + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((appUrlPrefix == null) ? 0 : appUrlPrefix.hashCode()); + result = prime * result + ((caasUrlPrefix == null) ? 0 : caasUrlPrefix.hashCode()); + result = prime * result + ((pltUrlPrefix == null) ? 0 : pltUrlPrefix.hashCode()); + return result; + } + +} diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/InstanceTransport.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/RicInstanceKeyName.java similarity index 62% rename from webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/InstanceTransport.java rename to webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/RicInstanceKeyName.java index df364387..97f08fff 100644 --- a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/InstanceTransport.java +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/RicInstanceKeyName.java @@ -20,10 +20,12 @@ package org.oransc.ric.portal.dashboard.model; +import java.util.Objects; + /** - * Trivial model to transport key-name pairs that represent RIC instances. + * Transport model for RIC instance key-name pairs. */ -public class InstanceTransport implements IDashboardResponse { +public class RicInstanceKeyName implements IDashboardResponse { private String key; private String name; @@ -31,7 +33,7 @@ public class InstanceTransport implements IDashboardResponse { /** * Builds an empty object. */ - public InstanceTransport() { + public RicInstanceKeyName() { // no-arg constructor } @@ -43,7 +45,7 @@ public class InstanceTransport implements IDashboardResponse { * @param name * Name */ - public InstanceTransport(String key, String name) { + public RicInstanceKeyName(String key, String name) { this.key = key; this.name = name; } @@ -56,6 +58,11 @@ public class InstanceTransport implements IDashboardResponse { this.key = key; } + public RicInstanceKeyName key(String key) { + this.key = key; + return this; + } + public String getName() { return name; } @@ -64,9 +71,35 @@ public class InstanceTransport implements IDashboardResponse { this.name = s; } + public RicInstanceKeyName name(String name) { + this.name = name; + return this; + } + @Override public String toString() { return this.getClass().getName() + "[key=" + getKey() + ", name=" + getName() + "]"; } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((key == null) ? 0 : key.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + RicInstanceKeyName other = (RicInstanceKeyName) obj; + return Objects.equals(key, other.key); + } + } diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/RicInstanceList.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/RicInstanceList.java new file mode 100644 index 00000000..4f8d34e5 --- /dev/null +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/RicInstanceList.java @@ -0,0 +1,71 @@ +/*- + * ========================LICENSE_START================================= + * O-RAN-SC + * %% + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================LICENSE_END=================================== + */ + +package org.oransc.ric.portal.dashboard.model; + +import java.util.ArrayList; +import java.util.List; + +import org.oransc.ric.portal.dashboard.exception.UnknownInstanceException; + +public class RicInstanceList { + + private final List instances; + + public RicInstanceList() { + this.instances = new ArrayList<>(); + } + + public RicInstanceList(List list) { + this.instances = list; + } + + public List getInstances() { + return instances; + } + + /** + * Gets a list of key-name pairs. + * + * @return List of RicInstanceKeyName objects. + */ + public List getKeyNameList() { + List list = new ArrayList<>(); + for (RicInstance i : instances) + list.add(i.toKeyName()); + return list; + } + + /** + * Gets the instance with the specified key + * + * @param instanceKey + * Key to fetch + * @return Instance + * @throws UnknownInstanceException + * If the key is not known + */ + public RicInstance getInstance(String instanceKey) { + for (RicInstance i : instances) + if (i.getKey().equals(instanceKey)) + return i; + throw new UnknownInstanceException(instanceKey); + } +} diff --git a/webapp-backend/src/main/resources/application.yaml b/webapp-backend/src/main/resources/application.yaml index ab7ff6f0..9b8f5d05 100644 --- a/webapp-backend/src/main/resources/application.yaml +++ b/webapp-backend/src/main/resources/application.yaml @@ -45,24 +45,21 @@ portalapi: username: password: -# endpoint URLs must be supplied at deployment time +# Instance-specific URL prefixes must be supplied at deployment time # A1 Mediator a1med: url: - prefix: http://jar-app-props-default-A1-URL-prefix suffix: # App Manager appmgr: url: - prefix: http://jar-app-props-default-Xapp-Mgr-URL suffix: /ric/v1 # E2 Manager e2mgr: url: - prefix: http://jar-app-props-default-E2-URL suffix: /v1 # Kubernetes API via https://github.com/nokia/caas-ingress @@ -71,7 +68,6 @@ caasingress: insecure: true plt: url: - prefix: https://jar-app-props-default-caas-ingress-plt-URL suffix: /api # Mimic slow endpoints by defining sleep period, in milliseconds @@ -91,6 +87,12 @@ ric-instance-list: - key: i1 name: Primary RIC Instance + appUrlPrefix: App prefix 1 + caasUrlPrefix: Caas prefix 1 + pltUrlPrefix: Plt prefix 1 - key: i2 name: RIC Instance Nr Two + appUrlPrefix: App prefix 2 + caasUrlPrefix: Caas prefix 2 + pltUrlPrefix: Plt prefix 2 diff --git a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/A1MediatorMockConfiguration.java b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/A1MediatorMockConfiguration.java index 877f0976..d3ac7a7d 100644 --- a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/A1MediatorMockConfiguration.java +++ b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/A1MediatorMockConfiguration.java @@ -42,7 +42,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; /** - * Creates a mock implementation of the A1 mediator client API. + * Creates a mock implementation of the A1 mediator client builder. */ @Configuration @Profile("test") @@ -54,13 +54,14 @@ public class A1MediatorMockConfiguration { public static final String AC_CONTROL_NAME = "admission_control_policy"; // Simulate remote method delay for UI testing - @Value("${mock.config.delay:0}") - private int delayMs; + private final int delayMs; + // Mock values private final Map appPolicyMap; - public A1MediatorMockConfiguration() { - logger.info("Configuring mock A1 Mediator"); + public A1MediatorMockConfiguration(@Value("${mock.config.delay:0}") int delayMs) { + logger.info("ctor: mock A1 Mediator configured with delay {}", delayMs); + this.delayMs = delayMs; appPolicyMap = new HashMap<>(); // Define a mock AC policy ObjectMapper mapper = new ObjectMapper(); @@ -80,9 +81,7 @@ public class A1MediatorMockConfiguration { return mockClient; } - @Bean - // Use the same name as regular configuration - public A1MediatorApi a1MediatorApi() { + private A1MediatorApi a1MediatorApi() { ApiClient apiClient = apiClient(); A1MediatorApi mockApi = mock(A1MediatorApi.class); when(mockApi.getApiClient()).thenReturn(apiClient); @@ -107,4 +106,13 @@ public class A1MediatorMockConfiguration { return mockApi; } + @Bean + // Must use the same name as the non-mock configuration + public A1MediatorApiBuilder a1MediatorApiBuilder() { + final A1MediatorApi mockApi = a1MediatorApi(); + final A1MediatorApiBuilder mockBuilder = mock(A1MediatorApiBuilder.class); + when(mockBuilder.getA1MediatorApi(any(String.class))).thenReturn(mockApi); + return mockBuilder; + } + } diff --git a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/AppManagerMockConfiguration.java b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/AppManagerMockConfiguration.java index ba84fd4f..6b0517e8 100644 --- a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/AppManagerMockConfiguration.java +++ b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/AppManagerMockConfiguration.java @@ -88,9 +88,7 @@ public class AppManagerMockConfiguration { subRes = new SubscriptionResponse().eventType(SubscriptionResponse.EventTypeEnum.ALL).id("subid").version(1); } - @Bean - // Use the same name as regular configuration - public HealthApi xappMgrHealthApi() { + private HealthApi healthApi() { ApiClient mockClient = mock(ApiClient.class); when(mockClient.getStatusCode()).thenReturn(HttpStatus.OK); HealthApi mockApi = mock(HealthApi.class); @@ -100,9 +98,7 @@ public class AppManagerMockConfiguration { return mockApi; } - @Bean - // Use the same name as regular configuration - public XappApi xappMgrXappApi() { + private XappApi xappApi() { ApiClient mockClient = mock(ApiClient.class); when(mockClient.getStatusCode()).thenReturn(HttpStatus.OK); XappApi mockApi = mock(XappApi.class); @@ -187,4 +183,15 @@ public class AppManagerMockConfiguration { return mockApi; } + @Bean + // Must use the same name as the non-mock configuration + public AppManagerApiBuilder appManagerApiBuilder() { + final AppManagerApiBuilder mockBuilder = mock(AppManagerApiBuilder.class); + final HealthApi mockHealthApi = healthApi(); + when(mockBuilder.getHealthApi(any(String.class))).thenReturn(mockHealthApi); + final XappApi mockXappApi = xappApi(); + when(mockBuilder.getXappApi(any(String.class))).thenReturn(mockXappApi); + return mockBuilder; + } + } diff --git a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/CaasIngressMockConfiguration.java b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/CaasIngressMockConfiguration.java index 56a01ab2..1420086f 100644 --- a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/CaasIngressMockConfiguration.java +++ b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/CaasIngressMockConfiguration.java @@ -22,6 +22,7 @@ package org.oransc.ric.portal.dashboard.config; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import java.io.IOException; import java.io.InputStream; @@ -76,9 +77,7 @@ public class CaasIngressMockConfiguration { return sb.toString(); } - @Bean - // Use the same name as regular configuration - public SimpleKubernetesClient ciPltApi() throws IOException { + private SimpleKubernetesClient simpleKubernetesClient() { SimpleKubernetesClient mockClient = mock(SimpleKubernetesClient.class); doAnswer(inv -> { String ns = inv.getArgument(0); @@ -86,9 +85,18 @@ public class CaasIngressMockConfiguration { if ("ricplt".equals(ns)) return pltPods; else - throw new Exception("Fake server failure"); + throw new IllegalArgumentException("Fake server failure"); }).when(mockClient).listPods(any(String.class)); return mockClient; } + @Bean + // The bean (method) name must be globally unique + public SimpleKubernetesClientBuilder simpleKubernetesClientBuilder() { + final SimpleKubernetesClientBuilder mockBuilder = mock(SimpleKubernetesClientBuilder.class); + SimpleKubernetesClient client = simpleKubernetesClient(); + when(mockBuilder.getSimpleKubernetesClient(any(String.class))).thenReturn(client); + return mockBuilder; + } + } diff --git a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/E2ManagerMockConfiguration.java b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/E2ManagerMockConfiguration.java index b3b4c9c1..3f33f40b 100644 --- a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/E2ManagerMockConfiguration.java +++ b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/E2ManagerMockConfiguration.java @@ -59,8 +59,8 @@ public class E2ManagerMockConfiguration { @Value("${mock.config.delay:0}") private int delayMs; - public static final String RAN_NAME_1 = "Connected RAN"; - public static final String RAN_NAME_2 = "Unknown RAN"; + public static final String RAN_NAME_1 = "Connected-RAN"; + public static final String RAN_NAME_2 = "Unknown-RAN"; private final List nodebIdList; private final Map nodebResponseMap; @@ -91,9 +91,7 @@ public class E2ManagerMockConfiguration { return mockClient; } - @Bean - // Use the same name as regular configuration - public HealthCheckApi e2MgrHealthCheckApi() { + private HealthCheckApi healthCheckApi() { ApiClient apiClient = apiClient(); HealthCheckApi mockApi = mock(HealthCheckApi.class); when(mockApi.getApiClient()).thenReturn(apiClient); @@ -101,9 +99,7 @@ public class E2ManagerMockConfiguration { return mockApi; } - @Bean - // Use the same name as regular configuration - public NodebApi e2MgrNodebApi() { + private NodebApi nodebApi() { ApiClient apiClient = apiClient(); NodebApi mockApi = mock(NodebApi.class); when(mockApi.getApiClient()).thenReturn(apiClient); @@ -164,4 +160,15 @@ public class E2ManagerMockConfiguration { return mockApi; } + @Bean + // Must use the same name as the non-mock configuration + public E2ManagerApiBuilder e2ManagerApiBuilder() { + final E2ManagerApiBuilder mockBuilder = mock(E2ManagerApiBuilder.class); + final HealthCheckApi mockHealthCheckApi = healthCheckApi(); + when(mockBuilder.getHealthCheckApi(any(String.class))).thenReturn(mockHealthCheckApi); + final NodebApi mockNodebApi = nodebApi(); + when(mockBuilder.getNodebApi(any(String.class))).thenReturn(mockNodebApi); + return mockBuilder; + } + } diff --git a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/RICInstanceMockConfiguration.java b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/RICInstanceMockConfiguration.java new file mode 100644 index 00000000..2f9e82cf --- /dev/null +++ b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/RICInstanceMockConfiguration.java @@ -0,0 +1,57 @@ +/*- + * ========================LICENSE_START================================= + * O-RAN-SC + * %% + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================LICENSE_END=================================== + */ + +package org.oransc.ric.portal.dashboard.config; + +import java.util.ArrayList; +import java.util.List; + +import org.oransc.ric.portal.dashboard.model.RicInstance; +import org.oransc.ric.portal.dashboard.model.RicInstanceList; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Component; + +/** + * Publishes a mock list of RIC instances. + */ +@Component +@Profile("test") +public class RICInstanceMockConfiguration { + + // Publish constants for use in tests + public static final String INSTANCE_KEY_1 = "i1"; + public static final String INSTANCE_KEY_2 = "i2"; + + @Bean + public RicInstanceList ricInstanceList() { + List instances = new ArrayList<>(); + RicInstance i1 = new RicInstance().key(INSTANCE_KEY_1).name("Friendly Name One") + .appUrlPrefix("http://foo.bar/app").pltUrlPrefix("http://foo.bar/plt") + .caasUrlPrefix("http://foo.bar/caas"); + instances.add(i1); + RicInstance i2 = new RicInstance().key(INSTANCE_KEY_2).name("Friendly Name Two") + .appUrlPrefix("http://foo.bar/2/app").pltUrlPrefix("http://foo.bar/2/plt") + .caasUrlPrefix("http://foo.bar/2/caas"); + instances.add(i2); + return new RicInstanceList(instances); + } + +} diff --git a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/A1MediatorControllerTest.java b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/A1MediatorControllerTest.java index 77e23b8a..325d869c 100644 --- a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/A1MediatorControllerTest.java +++ b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/A1MediatorControllerTest.java @@ -26,7 +26,9 @@ import java.net.URI; import org.junit.Assert; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.oransc.ric.portal.dashboard.DashboardConstants; import org.oransc.ric.portal.dashboard.config.A1MediatorMockConfiguration; +import org.oransc.ric.portal.dashboard.config.RICInstanceMockConfiguration; import org.oransc.ric.portal.dashboard.model.SuccessTransport; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,7 +45,7 @@ public class A1MediatorControllerTest extends AbstractControllerTest { @Test public void versionTest() { - URI uri = buildUri(null, A1MediatorController.CONTROLLER_PATH, A1MediatorController.VERSION_METHOD); + URI uri = buildUri(null, A1MediatorController.CONTROLLER_PATH, DashboardConstants.VERSION_METHOD); logger.info("Invoking {}", uri); SuccessTransport st = restTemplate.getForObject(uri, SuccessTransport.class); Assertions.assertFalse(st.getData().toString().isEmpty()); @@ -51,7 +53,8 @@ public class A1MediatorControllerTest extends AbstractControllerTest { @Test public void getTest() throws IOException { - URI uri = buildUri(null, A1MediatorController.CONTROLLER_PATH, A1MediatorController.PP_POLICIES, + URI uri = buildUri(null, A1MediatorController.CONTROLLER_PATH, DashboardConstants.RIC_INSTANCE_KEY, + RICInstanceMockConfiguration.INSTANCE_KEY_1, A1MediatorController.PP_POLICIES, A1MediatorMockConfiguration.AC_CONTROL_NAME); logger.info("Invoking {}", uri); ResponseEntity response = testRestTemplateStandardRole().exchange(uri, HttpMethod.GET, null, @@ -62,12 +65,13 @@ public class A1MediatorControllerTest extends AbstractControllerTest { @Test public void putTest() throws IOException { + URI uri = buildUri(null, A1MediatorController.CONTROLLER_PATH, DashboardConstants.RIC_INSTANCE_KEY, + RICInstanceMockConfiguration.INSTANCE_KEY_1, A1MediatorController.PP_POLICIES, + A1MediatorMockConfiguration.AC_CONTROL_NAME); ObjectMapper mapper = new ObjectMapper(); JsonNode body = mapper.readTree("{ \"policy\" : true }"); - URI uri = buildUri(null, A1MediatorController.CONTROLLER_PATH, A1MediatorController.PP_POLICIES, - A1MediatorMockConfiguration.AC_CONTROL_NAME); HttpEntity entity = new HttpEntity<>(body); - logger.info("Invoking {}", uri); + logger.info("Invoking {} with body {}", uri, body); ResponseEntity voidResponse = testRestTemplateAdminRole().exchange(uri, HttpMethod.PUT, entity, Void.class); Assertions.assertTrue(voidResponse.getStatusCode().is2xxSuccessful()); diff --git a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/AbstractControllerTest.java b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/AbstractControllerTest.java index d4163f0d..e9aedc47 100644 --- a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/AbstractControllerTest.java +++ b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/AbstractControllerTest.java @@ -55,13 +55,13 @@ public class AbstractControllerTest { protected TestRestTemplate restTemplate; /** - * Flexible URI builder. + * Builds URI from path components and query parameters. * * @param queryParams * Map of string-string query parameters * @param path * Array of path components. If a component has an - * embedded slash, the string is split and each + * embedded slash, that string is split and each * subcomponent is added individually. * @return URI */ diff --git a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/AdminController2.java b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/AdminController2.java index 43837524..c40c2859 100644 --- a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/AdminController2.java +++ b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/AdminController2.java @@ -21,7 +21,6 @@ package org.oransc.ric.portal.dashboard.controller; import java.lang.invoke.MethodHandles; -import org.oransc.ric.portal.dashboard.DashboardConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.MediaType; @@ -39,9 +38,6 @@ public class AdminController2 { 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 + "/admin"; - @GetMapping("throw1") public void throw1() { logger.warn("throwing RestClientResponseException"); diff --git a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/AdminControllerTest.java b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/AdminControllerTest.java index f1c26806..d6f206e8 100644 --- a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/AdminControllerTest.java +++ b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/AdminControllerTest.java @@ -30,7 +30,7 @@ import org.junit.jupiter.api.Test; import org.onap.portalsdk.core.restful.domain.EcompUser; import org.oransc.ric.portal.dashboard.DashboardConstants; import org.oransc.ric.portal.dashboard.model.ErrorTransport; -import org.oransc.ric.portal.dashboard.model.InstanceTransport; +import org.oransc.ric.portal.dashboard.model.RicInstanceKeyName; import org.oransc.ric.portal.dashboard.model.SuccessTransport; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -62,8 +62,8 @@ public class AdminControllerTest extends AbstractControllerTest { public void getInstancesTest() { URI uri = buildUri(null, AdminController.CONTROLLER_PATH, AdminController.INSTANCE_METHOD); logger.info("Invoking {}", uri); - ResponseEntity> response = testRestTemplateStandardRole().exchange(uri, HttpMethod.GET, - null, new ParameterizedTypeReference>() { + ResponseEntity> response = testRestTemplateStandardRole().exchange(uri, HttpMethod.GET, + null, new ParameterizedTypeReference>() { }); Assertions.assertFalse(response.getBody().isEmpty()); } diff --git a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/AppManagerControllerTest.java b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/AppManagerControllerTest.java index c9ec4b03..961e6931 100644 --- a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/AppManagerControllerTest.java +++ b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/AppManagerControllerTest.java @@ -30,6 +30,8 @@ import org.oransc.ric.plt.appmgr.client.model.ConfigMetadata; import org.oransc.ric.plt.appmgr.client.model.XAppConfig; import org.oransc.ric.plt.appmgr.client.model.XAppInfo; import org.oransc.ric.plt.appmgr.client.model.Xapp; +import org.oransc.ric.portal.dashboard.DashboardConstants; +import org.oransc.ric.portal.dashboard.config.RICInstanceMockConfiguration; import org.oransc.ric.portal.dashboard.model.DashboardDeployableXapps; import org.oransc.ric.portal.dashboard.model.SuccessTransport; import org.slf4j.Logger; @@ -44,7 +46,7 @@ public class AppManagerControllerTest extends AbstractControllerTest { @Test public void versionTest() { - URI uri = buildUri(null, AppManagerController.CONTROLLER_PATH, AppManagerController.VERSION_METHOD); + URI uri = buildUri(null, AppManagerController.CONTROLLER_PATH, DashboardConstants.VERSION_METHOD); logger.info("Invoking {}", uri); SuccessTransport st = restTemplate.getForObject(uri, SuccessTransport.class); Assertions.assertFalse(st.getData().toString().isEmpty()); @@ -52,7 +54,8 @@ public class AppManagerControllerTest extends AbstractControllerTest { @Test public void healthAliveTest() { - URI uri = buildUri(null, AppManagerController.CONTROLLER_PATH, AppManagerController.HEALTH_ALIVE_METHOD); + URI uri = buildUri(null, AppManagerController.CONTROLLER_PATH, DashboardConstants.RIC_INSTANCE_KEY, + RICInstanceMockConfiguration.INSTANCE_KEY_1, AppManagerController.HEALTH_ALIVE_METHOD); logger.info("Invoking {}", uri); ResponseEntity voidResponse = restTemplate.getForEntity(uri, Void.class); Assertions.assertTrue(voidResponse.getStatusCode().is2xxSuccessful()); @@ -60,7 +63,8 @@ public class AppManagerControllerTest extends AbstractControllerTest { @Test public void healthReadyTest() { - URI uri = buildUri(null, AppManagerController.CONTROLLER_PATH, AppManagerController.HEALTH_READY_METHOD); + URI uri = buildUri(null, AppManagerController.CONTROLLER_PATH, DashboardConstants.RIC_INSTANCE_KEY, + RICInstanceMockConfiguration.INSTANCE_KEY_1, AppManagerController.HEALTH_READY_METHOD); logger.info("Invoking {}", uri); ResponseEntity voidResponse = restTemplate.getForEntity(uri, Void.class); Assertions.assertTrue(voidResponse.getStatusCode().is2xxSuccessful()); @@ -68,7 +72,8 @@ public class AppManagerControllerTest extends AbstractControllerTest { @Test public void appListTest() { - URI uri = buildUri(null, AppManagerController.CONTROLLER_PATH, AppManagerController.XAPPS_LIST_METHOD); + URI uri = buildUri(null, AppManagerController.CONTROLLER_PATH, DashboardConstants.RIC_INSTANCE_KEY, + RICInstanceMockConfiguration.INSTANCE_KEY_1, AppManagerController.XAPPS_LIST_METHOD); logger.info("Invoking {}", uri); DashboardDeployableXapps apps = testRestTemplateStandardRole().getForObject(uri, DashboardDeployableXapps.class); @@ -77,7 +82,8 @@ public class AppManagerControllerTest extends AbstractControllerTest { @Test public void appStatusesTest() { - URI uri = buildUri(null, AppManagerController.CONTROLLER_PATH, AppManagerController.XAPPS_METHOD); + URI uri = buildUri(null, AppManagerController.CONTROLLER_PATH, DashboardConstants.RIC_INSTANCE_KEY, + RICInstanceMockConfiguration.INSTANCE_KEY_1, AppManagerController.XAPPS_METHOD); logger.info("Invoking {}", uri); AllDeployedXapps apps = testRestTemplateStandardRole().getForObject(uri, AllDeployedXapps.class); Assertions.assertFalse(apps.isEmpty()); @@ -85,7 +91,8 @@ public class AppManagerControllerTest extends AbstractControllerTest { @Test public void appStatusTest() { - URI uri = buildUri(null, AppManagerController.CONTROLLER_PATH, AppManagerController.XAPPS_METHOD, "app"); + URI uri = buildUri(null, AppManagerController.CONTROLLER_PATH, DashboardConstants.RIC_INSTANCE_KEY, + RICInstanceMockConfiguration.INSTANCE_KEY_1, AppManagerController.XAPPS_METHOD, "app"); logger.info("Invoking {}", uri); Xapp app = testRestTemplateStandardRole().getForObject(uri, Xapp.class); Assertions.assertFalse(app.getName().isEmpty()); @@ -93,7 +100,8 @@ public class AppManagerControllerTest extends AbstractControllerTest { @Test public void deployAppTest() { - URI uri = buildUri(null, AppManagerController.CONTROLLER_PATH, AppManagerController.XAPPS_METHOD); + URI uri = buildUri(null, AppManagerController.CONTROLLER_PATH, DashboardConstants.RIC_INSTANCE_KEY, + RICInstanceMockConfiguration.INSTANCE_KEY_1, AppManagerController.XAPPS_METHOD); logger.info("Invoking {}", uri); XAppInfo info = new XAppInfo(); Xapp app = testRestTemplateAdminRole().postForObject(uri, info, Xapp.class); @@ -102,7 +110,8 @@ public class AppManagerControllerTest extends AbstractControllerTest { @Test public void undeployAppTest() { - URI uri = buildUri(null, AppManagerController.CONTROLLER_PATH, AppManagerController.XAPPS_METHOD, "app"); + URI uri = buildUri(null, AppManagerController.CONTROLLER_PATH, DashboardConstants.RIC_INSTANCE_KEY, + RICInstanceMockConfiguration.INSTANCE_KEY_1, AppManagerController.XAPPS_METHOD, "app"); logger.info("Invoking {}", uri); ResponseEntity voidResponse = testRestTemplateAdminRole().exchange(uri, HttpMethod.DELETE, null, Void.class); @@ -111,7 +120,8 @@ public class AppManagerControllerTest extends AbstractControllerTest { @Test public void getConfigTest() { - URI uri = buildUri(null, AppManagerController.CONTROLLER_PATH, AppManagerController.CONFIG_METHOD); + URI uri = buildUri(null, AppManagerController.CONTROLLER_PATH, DashboardConstants.RIC_INSTANCE_KEY, + RICInstanceMockConfiguration.INSTANCE_KEY_1, AppManagerController.CONFIG_METHOD); logger.info("Invoking {}", uri); AllXappConfig config = testRestTemplateStandardRole().getForObject(uri, AllXappConfig.class); Assertions.assertFalse(config.isEmpty()); @@ -119,7 +129,8 @@ public class AppManagerControllerTest extends AbstractControllerTest { @Test public void createConfigTest() { - URI uri = buildUri(null, AppManagerController.CONTROLLER_PATH, AppManagerController.CONFIG_METHOD); + URI uri = buildUri(null, AppManagerController.CONTROLLER_PATH, DashboardConstants.RIC_INSTANCE_KEY, + RICInstanceMockConfiguration.INSTANCE_KEY_1, AppManagerController.CONFIG_METHOD); logger.info("Invoking {}", uri); XAppConfig newConfig = new XAppConfig(); XAppConfig response = testRestTemplateAdminRole().postForObject(uri, newConfig, XAppConfig.class); @@ -128,7 +139,8 @@ public class AppManagerControllerTest extends AbstractControllerTest { @Test public void deleteConfigTest() { - URI uri = buildUri(null, AppManagerController.CONTROLLER_PATH, AppManagerController.CONFIG_METHOD, "app"); + URI uri = buildUri(null, AppManagerController.CONTROLLER_PATH, DashboardConstants.RIC_INSTANCE_KEY, + RICInstanceMockConfiguration.INSTANCE_KEY_1, AppManagerController.CONFIG_METHOD, "app"); logger.info("Invoking {}", uri); ConfigMetadata delConfig = new ConfigMetadata(); HttpEntity entity = new HttpEntity<>(delConfig); diff --git a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/CaasIngressControllerTest.java b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/CaasIngressControllerTest.java index 41dfcaf8..b91c44c6 100644 --- a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/CaasIngressControllerTest.java +++ b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/CaasIngressControllerTest.java @@ -25,6 +25,8 @@ import java.net.URI; import org.junit.Assert; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.oransc.ric.portal.dashboard.DashboardConstants; +import org.oransc.ric.portal.dashboard.config.RICInstanceMockConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,7 +37,8 @@ public class CaasIngressControllerTest extends AbstractControllerTest { @Test public void pltTest() { final String nsPlt = "ricplt"; - URI uri = buildUri(null, CaasIngressController.CONTROLLER_PATH, CaasIngressController.PODS_METHOD, + URI uri = buildUri(null, CaasIngressController.CONTROLLER_PATH, DashboardConstants.RIC_INSTANCE_KEY, + RICInstanceMockConfiguration.INSTANCE_KEY_1, CaasIngressController.PODS_METHOD, CaasIngressController.PP_CLUSTER, CaasIngressController.CLUSTER_PLT, CaasIngressController.PP_NAMESPACE, nsPlt); logger.info("Invoking {}", uri); @@ -47,7 +50,8 @@ public class CaasIngressControllerTest extends AbstractControllerTest { @Test public void unknownClusterTest() { final String nsPlt = "ricplt"; - URI uri = buildUri(null, CaasIngressController.CONTROLLER_PATH, CaasIngressController.PODS_METHOD, + URI uri = buildUri(null, CaasIngressController.CONTROLLER_PATH, DashboardConstants.RIC_INSTANCE_KEY, + RICInstanceMockConfiguration.INSTANCE_KEY_1, CaasIngressController.PODS_METHOD, CaasIngressController.PP_CLUSTER, "cluster", CaasIngressController.PP_NAMESPACE, nsPlt); logger.info("Invoking {}", uri); String s = testRestTemplateStandardRole().getForObject(uri, String.class); @@ -58,7 +62,8 @@ public class CaasIngressControllerTest extends AbstractControllerTest { @Test public void bogusNsTest() { final String ns = "unknown"; - URI uri = buildUri(null, CaasIngressController.CONTROLLER_PATH, CaasIngressController.PODS_METHOD, + URI uri = buildUri(null, CaasIngressController.CONTROLLER_PATH, DashboardConstants.RIC_INSTANCE_KEY, + RICInstanceMockConfiguration.INSTANCE_KEY_1, CaasIngressController.PODS_METHOD, CaasIngressController.PP_CLUSTER, CaasIngressController.CLUSTER_PLT, CaasIngressController.PP_NAMESPACE, ns); logger.info("Invoking {}", uri); diff --git a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/E2ManagerControllerTest.java b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/E2ManagerControllerTest.java index ddd2b09b..e6744fee 100644 --- a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/E2ManagerControllerTest.java +++ b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/E2ManagerControllerTest.java @@ -29,7 +29,9 @@ import org.oransc.ric.e2mgr.client.model.GetNodebResponse; import org.oransc.ric.e2mgr.client.model.NodebIdentity; import org.oransc.ric.e2mgr.client.model.ResetRequest; import org.oransc.ric.e2mgr.client.model.SetupRequest; +import org.oransc.ric.portal.dashboard.DashboardConstants; import org.oransc.ric.portal.dashboard.config.E2ManagerMockConfiguration; +import org.oransc.ric.portal.dashboard.config.RICInstanceMockConfiguration; import org.oransc.ric.portal.dashboard.model.RanDetailsTransport; import org.oransc.ric.portal.dashboard.model.SuccessTransport; import org.slf4j.Logger; @@ -44,7 +46,8 @@ public class E2ManagerControllerTest extends AbstractControllerTest { private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private ResponseEntity endcSetup() { - URI uri = buildUri(null, E2ManagerController.CONTROLLER_PATH, E2ManagerController.ENDC_SETUP_METHOD); + URI uri = buildUri(null, E2ManagerController.CONTROLLER_PATH, DashboardConstants.RIC_INSTANCE_KEY, + RICInstanceMockConfiguration.INSTANCE_KEY_1, E2ManagerController.ENDC_SETUP_METHOD); logger.info("Invoking {}", uri); SetupRequest setup = new SetupRequest().ranName(E2ManagerMockConfiguration.RAN_NAME_1); HttpEntity entity = new HttpEntity<>(setup); @@ -52,7 +55,8 @@ public class E2ManagerControllerTest extends AbstractControllerTest { } private ResponseEntity reset() { - URI uri = buildUri(null, E2ManagerController.CONTROLLER_PATH, E2ManagerController.NODEB_PREFIX, "ignored", + URI uri = buildUri(null, E2ManagerController.CONTROLLER_PATH, DashboardConstants.RIC_INSTANCE_KEY, + RICInstanceMockConfiguration.INSTANCE_KEY_1, E2ManagerController.NODEB_PREFIX, "ignored", E2ManagerController.RESET_METHOD); logger.info("Invoking {}", uri); ResetRequest reset = new ResetRequest(); @@ -60,9 +64,23 @@ public class E2ManagerControllerTest extends AbstractControllerTest { return testRestTemplateAdminRole().exchange(uri, HttpMethod.PUT, entity, Void.class); } + @Test + public void endcSetupTest() { + ResponseEntity voidResponse = endcSetup(); + Assertions.assertTrue(voidResponse.getStatusCode().is2xxSuccessful()); + reset(); + } + + @Test + public void resetTest() { + ResponseEntity voidResponse = reset(); + logger.debug("resetTest: response {}", voidResponse); + Assertions.assertTrue(voidResponse.getStatusCode().is2xxSuccessful()); + } + @Test public void versionTest() { - URI uri = buildUri(null, E2ManagerController.CONTROLLER_PATH, E2ManagerController.VERSION_METHOD); + URI uri = buildUri(null, E2ManagerController.CONTROLLER_PATH, DashboardConstants.VERSION_METHOD); logger.info("Invoking {}", uri); SuccessTransport st = restTemplate.getForObject(uri, SuccessTransport.class); Assertions.assertFalse(st.getData().toString().isEmpty()); @@ -70,7 +88,8 @@ public class E2ManagerControllerTest extends AbstractControllerTest { @Test public void healthTest() { - URI uri = buildUri(null, E2ManagerController.CONTROLLER_PATH, E2ManagerController.HEALTH_METHOD); + URI uri = buildUri(null, E2ManagerController.CONTROLLER_PATH, DashboardConstants.RIC_INSTANCE_KEY, + RICInstanceMockConfiguration.INSTANCE_KEY_1, E2ManagerController.HEALTH_METHOD); logger.info("Invoking {}", uri); ResponseEntity voidResponse = restTemplate.getForEntity(uri, Void.class); Assertions.assertTrue(voidResponse.getStatusCode().is2xxSuccessful()); @@ -79,7 +98,8 @@ public class E2ManagerControllerTest extends AbstractControllerTest { @Test public void ranDetailsTest() { endcSetup(); - URI uri = buildUri(null, E2ManagerController.CONTROLLER_PATH, E2ManagerController.RAN_METHOD); + URI uri = buildUri(null, E2ManagerController.CONTROLLER_PATH, DashboardConstants.RIC_INSTANCE_KEY, + RICInstanceMockConfiguration.INSTANCE_KEY_1, E2ManagerController.RAN_METHOD); logger.info("Invoking {}", uri); ResponseEntity> response = testRestTemplateStandardRole().exchange(uri, HttpMethod.GET, null, new ParameterizedTypeReference>() { @@ -91,7 +111,8 @@ public class E2ManagerControllerTest extends AbstractControllerTest { @Test public void nodebListTest() { endcSetup(); - URI uri = buildUri(null, E2ManagerController.CONTROLLER_PATH, E2ManagerController.NODEB_LIST_METHOD); + URI uri = buildUri(null, E2ManagerController.CONTROLLER_PATH, DashboardConstants.RIC_INSTANCE_KEY, + RICInstanceMockConfiguration.INSTANCE_KEY_1, E2ManagerController.NODEB_LIST_METHOD); logger.info("Invoking {}", uri); ResponseEntity> response = testRestTemplateStandardRole().exchange(uri, HttpMethod.GET, null, new ParameterizedTypeReference>() { @@ -103,7 +124,8 @@ public class E2ManagerControllerTest extends AbstractControllerTest { @Test public void nodebStatusTest() { endcSetup(); - URI uri = buildUri(null, E2ManagerController.CONTROLLER_PATH, E2ManagerController.NODEB_SHUTDOWN_METHOD, + URI uri = buildUri(null, E2ManagerController.CONTROLLER_PATH, DashboardConstants.RIC_INSTANCE_KEY, + RICInstanceMockConfiguration.INSTANCE_KEY_1, E2ManagerController.NODEB_PREFIX, E2ManagerMockConfiguration.RAN_NAME_1); logger.info("Invoking {}", uri); GetNodebResponse response = testRestTemplateStandardRole().getForObject(uri, GetNodebResponse.class); @@ -111,16 +133,10 @@ public class E2ManagerControllerTest extends AbstractControllerTest { reset(); } - @Test - public void endcSetupTest() { - ResponseEntity voidResponse = endcSetup(); - Assertions.assertTrue(voidResponse.getStatusCode().is2xxSuccessful()); - reset(); - } - @Test public void x2SetupTest() { - URI uri = buildUri(null, E2ManagerController.CONTROLLER_PATH, E2ManagerController.X2_SETUP_METHOD); + URI uri = buildUri(null, E2ManagerController.CONTROLLER_PATH, DashboardConstants.RIC_INSTANCE_KEY, + RICInstanceMockConfiguration.INSTANCE_KEY_1, E2ManagerController.X2_SETUP_METHOD); logger.info("Invoking {}", uri); SetupRequest setup = new SetupRequest().ranName(E2ManagerMockConfiguration.RAN_NAME_1); HttpEntity entity = new HttpEntity<>(setup); @@ -133,18 +149,12 @@ public class E2ManagerControllerTest extends AbstractControllerTest { // Aka big--button test @Test public void nodebShutdownPutTest() { - URI uri = buildUri(null, E2ManagerController.CONTROLLER_PATH, E2ManagerController.NODEB_SHUTDOWN_METHOD); + URI uri = buildUri(null, E2ManagerController.CONTROLLER_PATH, DashboardConstants.RIC_INSTANCE_KEY, + RICInstanceMockConfiguration.INSTANCE_KEY_1, E2ManagerController.NODEB_SHUTDOWN_METHOD); logger.info("Invoking {}", uri); ResponseEntity voidResponse = testRestTemplateAdminRole().exchange(uri, HttpMethod.PUT, null, Void.class); logger.debug("nodebPutTest: response {}", voidResponse); Assertions.assertTrue(voidResponse.getStatusCode().is2xxSuccessful()); } - @Test - public void resetTest() { - ResponseEntity voidResponse = reset(); - logger.debug("resetTest: response {}", voidResponse); - Assertions.assertTrue(voidResponse.getStatusCode().is2xxSuccessful()); - } - } diff --git a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/model/ModelTest.java b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/model/ModelTest.java index 8aab0665..71225aad 100644 --- a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/model/ModelTest.java +++ b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/model/ModelTest.java @@ -84,15 +84,15 @@ public class ModelTest extends AbstractModelTest { logger.info(m.toString()); } - private void checkInstanceTransport(InstanceTransport m) { + private void checkInstanceTransport(RicInstanceKeyName m) { Assert.assertEquals(s1, m.getKey()); Assert.assertEquals(s2, m.getName()); } @Test public void testInstanceTransport() { - InstanceTransport m = new InstanceTransport(s1, s1); - m = new InstanceTransport(); + RicInstanceKeyName m = new RicInstanceKeyName(s1, s1); + m = new RicInstanceKeyName(); m.setKey(s1); m.setName(s2); checkInstanceTransport(m);