From: PatrikBuhr Date: Tue, 10 Dec 2019 14:17:06 +0000 (+0100) Subject: Dashboard using policy agent NBI X-Git-Tag: 1.0.1~71^2 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=8831a02bce715562f3cacce1691bf4d9d3af206b;p=nonrtric.git Dashboard using policy agent NBI Change-Id: I21081d49a1ce3704a4e88e009ae92003efa96d18 Issue-ID: NONRTRIC-84 Signed-off-by: PatrikBuhr --- diff --git a/dashboard/a1-controller-client/.gitignore b/dashboard/a1-controller-client/.gitignore deleted file mode 100644 index 212de161..00000000 --- a/dashboard/a1-controller-client/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -*.class - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -*.war -*.ear - -# exclude jar for gradle wrapper -!gradle/wrapper/*.jar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* - -# build files -**/target -target -.gradle -build - -logs/ -bin/ diff --git a/dashboard/a1-controller-client/README.md b/dashboard/a1-controller-client/README.md deleted file mode 100644 index b93a390b..00000000 --- a/dashboard/a1-controller-client/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# A1 Controller Client Generator - -This projects generates a REST client library from the OpenAPI specification -file stored here and packages it in a jar. - -## Eclipse and STS Users - -The Swagger Codegen maven plugin is not supported in Eclipse/STS. You can -limp along by taking these steps: - -1. Generate the code using maven: - mvn install -2. Add this folder to the project build path: - target/generated-sources/swagger/src/main/java - -## License - -Copyright (C) 2019 Nordix Foundation -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. diff --git a/dashboard/a1-controller-client/pom.xml b/dashboard/a1-controller-client/pom.xml deleted file mode 100644 index 4011bfb6..00000000 --- a/dashboard/a1-controller-client/pom.xml +++ /dev/null @@ -1,177 +0,0 @@ - - - - 4.0.0 - - org.o-ran-sc.nonrt.ric-dashboard - ric-dash-parent - 1.0.0-SNAPSHOT - - - org.o-ran-sc.ric.plt.a1controller.client - a1-controller-client - RIC A1 Controller client - 0.1.0-SNAPSHOT - - UTF-8 - UTF-8 - - 0 - - org.oransc.ric.a1controller.client - - - - - - javax.annotation - javax.annotation-api - - - io.swagger.core.v3 - swagger-annotations - 2.0.8 - - - org.springframework - spring-context - - - - org.springframework - spring-web - - - - com.fasterxml.jackson.core - jackson-core - - - com.fasterxml.jackson.core - jackson-annotations - - - com.fasterxml.jackson.core - jackson-databind - - - com.fasterxml.jackson.jaxrs - jackson-jaxrs-json-provider - - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - - - - org.junit.jupiter - junit-jupiter-api - test - - - org.slf4j - slf4j-api - - - - - - - io.swagger.codegen.v3 - swagger-codegen-maven-plugin - 3.0.8 - - - - generate - - - ${project.basedir}/src/main/resources/a1_controller_0.1.0.yaml - java - ${client.base.package.name} - ${client.base.package.name}.model - ${client.base.package.name}.api - ${client.base.package.name}.invoker - - ${project.groupId} - ${project.artifactId} - ${project.version} - resttemplate - true - java8 - Apache 2.0 - https://www.apache.org/licenses/LICENSE-2.0 - - - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - true - - - ${project.version}-b${build.number} - - - - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - io.swagger.codegen.v3 - swagger-codegen-maven-plugin - [1.0,) - - generate - - - - - - - - - - - - - - diff --git a/dashboard/a1-controller-client/src/main/resources/a1_controller_0.1.0.yaml b/dashboard/a1-controller-client/src/main/resources/a1_controller_0.1.0.yaml deleted file mode 100644 index 86bb8234..00000000 --- a/dashboard/a1-controller-client/src/main/resources/a1_controller_0.1.0.yaml +++ /dev/null @@ -1,555 +0,0 @@ -# ================================================================================== -# Copyright (c) 2019 Nordix Foundation. -# -# 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. -# ================================================================================== -openapi: 3.0.0 -info: - version: 1.0.0 - title: RIC A1 -paths: - '/A1-ADAPTER-API:getNearRT-RICs': - post: - description: > - Get a list of all nearRT-RICs - tags: - - A1 Controller - operationId: a1.controller.get_all_nearrt_rics - responses: - '200': - description: > - Successfully got the response. - content: - application/json: - schema: - "$ref": "#/components/schemas/output_NRRids_list_code_schema" - - '/A1-ADAPTER-API:getHealthCheck': - post: - description: > - Get health status for a Near-RT-RIC. true - health ok, false - health is not ok. - tags: - - A1 Controller - operationId: a1.controller.get_healthcheck - requestBody: - required: true - content: - application/json: - schema: - "$ref": "#/components/schemas/input_NRRid_schema" - responses: - '200': - description: > - Successfully got the response. - content: - application/json: - schema: - "$ref": "#/components/schemas/output_healthstatus_code_schema" - - '/A1-ADAPTER-API:getPolicyTypes': - post: - description: > - Get a list of all registered policy-type-ids. - tags: - - A1 Controller - operationId: a1.controller.get_all_policy_types - requestBody: - required: true - content: - application/json: - schema: - "$ref": "#/components/schemas/input_NRRid_schema" - responses: - '200': - description: > - Successfully got the response. - content: - application/json: - schema: - "$ref": "#/components/schemas/output_PTids_list_code_schema" - - '/A1-ADAPTER-API:createPolicyType': - post: - description: > - Create a policy type. - tags: - - A1 Controller - operationId: a1.controller.create_policy_type - requestBody: - required: true - content: - application/json: - schema: - "$ref": "#/components/schemas/input_NRRid_PTid_desc_name_PT_schema" - responses: - '200': - description: > - Successfully got the response. - content: - application/json: - schema: - "$ref": "#/components/schemas/output_code_schema" - - '/A1-ADAPTER-API:getPolicyType': - post: - description: > - Get a policy type. - tags: - - A1 Controller - operationId: a1.controller.get_policy_type - requestBody: - required: true - content: - application/json: - schema: - "$ref": "#/components/schemas/input_NRRid_PTid_schema" - responses: - '200': - description: > - Successfully got the response. - content: - application/json: - schema: - "$ref": "#/components/schemas/output_desc_name_PT_code_schema" - - '/A1-ADAPTER-API:deletePolicyType': - post: - description: > - Delete a policy type. - tags: - - A1 Controller - operationId: a1.controller.delete_policy_type - requestBody: - required: true - content: - application/json: - schema: - "$ref": "#/components/schemas/input_NRRid_PTid_schema" - responses: - '200': - description: > - Successfully got the response. - content: - application/json: - schema: - "$ref": "#/components/schemas/output_code_schema" - - '/A1-ADAPTER-API:getPolicyInstances': - post: - description: > - Get a list of all policy-instance-ids for this policy-type-id. - tags: - - A1 Controller - operationId: a1.controller.get_all_instances_for_type - requestBody: - required: true - content: - application/json: - schema: - "$ref": "#/components/schemas/input_NRRid_PTid_schema" - responses: - '200': - description: > - Successfully got the response. - content: - application/json: - schema: - "$ref": "#/components/schemas/output_PIids_list_code_schema" - - '/A1-ADAPTER-API:createPolicyInstance': - post: - description: > - Create a policy instance. - tags: - - A1 Controller - operationId: a1.controller.create_policy_instance - requestBody: - required: true - content: - application/json: - schema: - "$ref": "#/components/schemas/input_NRRid_PTid_PIid_PI_schema" - responses: - '200': - description: > - Successfully got the response. - content: - application/json: - schema: - "$ref": "#/components/schemas/output_code_schema" - - '/A1-ADAPTER-API:getPolicyInstance': - post: - description: > - Get a policy instance. - tags: - - A1 Controller - operationId: a1.controller.get_policy_instance - requestBody: - required: true - content: - application/json: - schema: - "$ref": "#/components/schemas/input_NRRid_PTid_PIid_schema" - responses: - '200': - description: > - Successfully got the response. - content: - application/json: - schema: - "$ref": "#/components/schemas/output_PI_code_schema" - - '/A1-ADAPTER-API:deletePolicyInstance': - post: - description: > - Delete a policy instance. - tags: - - A1 Controller - operationId: a1.controller.delete_policy_instance - requestBody: - required: true - content: - application/json: - schema: - "$ref": "#/components/schemas/input_NRRid_PTid_PIid_schema" - responses: - '200': - description: > - Successfully got the response. - content: - application/json: - schema: - "$ref": "#/components/schemas/output_code_schema" - - '/A1-ADAPTER-API:getStatus': - post: - description: > - Get the status for a policy instance. - tags: - - A1 Controller - operationId: a1.controller.get_policy_instance_status - requestBody: - required: true - content: - application/json: - schema: - "$ref": "#/components/schemas/input_NRRid_PTid_PIid_schema" - responses: - '200': - description: > - Successfully got the response. - content: - application/json: - schema: - "$ref": "#/components/schemas/output_status_code_schema" - -components: - schemas: - input_NRRid_schema: - type: object - required: - - input - additionalProperties: false - properties: - input: - type: object - required: - - near-rt-ric-id - additionalProperties: false - properties: - near-rt-ric-id: - "$ref": "#/components/schemas/near_rt_ric_id" - - input_NRRid_PTid_schema: - type: object - required: - - input - additionalProperties: false - properties: - input: - type: object - required: - - near-rt-ric-id - - policy-type-id - additionalProperties: false - properties: - near-rt-ric-id: - "$ref": "#/components/schemas/near_rt_ric_id" - policy-type-id: - "$ref": "#/components/schemas/policy_type_id" - - input_NRRid_PTid_PIid_schema: - type: object - required: - - input - additionalProperties: false - properties: - input: - type: object - required: - - near-rt-ric-id - - policy-type-id - - policy-instance-id - additionalProperties: false - properties: - near-rt-ric-id: - "$ref": "#/components/schemas/near_rt_ric_id" - policy-type-id: - "$ref": "#/components/schemas/policy_type_id" - policy-instance-id: - "$ref": "#/components/schemas/policy_instance_id" - - input_NRRid_PTid_PIid_PI_schema: - type: object - required: - - input - additionalProperties: false - properties: - input: - type: object - required: - - near-rt-ric-id - - policy-type-id - - policy-instance-id - - policy-instance - additionalProperties: false - properties: - near-rt-ric-id: - "$ref": "#/components/schemas/near_rt_ric_id" - policy-type-id: - "$ref": "#/components/schemas/policy_type_id" - policy-instance-id: - "$ref": "#/components/schemas/policy_instance_id" - policy-instance: - "$ref": "#/components/schemas/policy_instance" - - input_NRRid_PTid_desc_name_PT_schema: - type: object - required: - - input - additionalProperties: false - properties: - input: - type: object - required: - - near-rt-ric-id - - policy-type-id - - description - - name - - policy-type - additionalProperties: false - properties: - near-rt-ric-id: - "$ref": "#/components/schemas/near_rt_ric_id" - policy-type-id: - "$ref": "#/components/schemas/policy_type_id" - description: - type: string - name: - type: string - policy-type: - "$ref": "#/components/schemas/policy_type" - - output_NRRids_list_code_schema: - type: object - required: - - output - additionalProperties: false - properties: - output: - type: object - required: - - near-rt-ric-id-list - - code - additionalProperties: false - properties: - near-rt-ric-id-list: - type: array - items: - "$ref": "#/components/schemas/near_rt_ric_id" - code: - type: string - - output_healthstatus_code_schema: - type: object - required: - - output - additionalProperties: false - properties: - output: - type: object - required: - - health-status - - code - additionalProperties: false - properties: - health-status: - type: boolean - code: - type: string - - output_desc_name_PT_code_schema: - type: object - required: - - output - additionalProperties: false - properties: - output: - type: object - required: - - description - - name - - policy_type - - code - additionalProperties: false - properties: - description: - type: string - name: - type: string - policy-type: - "$ref": "#/components/schemas/policy_type" - code: - type: string - - output_PTids_list_code_schema: - type: object - required: - - output - additionalProperties: false - properties: - output: - type: object - required: - - policy-type-id-list - - code - additionalProperties: false - properties: - policy-type-id-list: - type: array - items: - "$ref": "#/components/schemas/policy_type_id" - code: - type: string - - output_PIids_list_code_schema: - type: object - required: - - output - additionalProperties: false - properties: - output: - type: object - required: - - policy-instance-id-list - - code - additionalProperties: false - properties: - policy-instance-id-list: - type: array - items: - "$ref": "#/components/schemas/policy_instance_id" - code: - type: string - - output_PI_code_schema: - type: object - required: - - output - additionalProperties: false - properties: - output: - type: object - required: - - policy-instance - - code - additionalProperties: false - properties: - policy-instance: - "$ref": "#/components/schemas/policy_instance" - code: - type: string - - output_code_schema: - type: object - required: - - output - additionalProperties: false - properties: - output: - type: object - required: - - code - additionalProperties: false - properties: - code: - type: string - - output_status_code_schema: - type: object - required: - - output - additionalProperties: false - properties: - output: - type: object - required: - - status - - code - additionalProperties: false - properties: - status: - type: string - code: - type: string - - near_rt_ric_id: - description: > - represents a near RT RIC identifier. Currently this can be any string. - type: string - example: near-rt-ric-1 - - policy_type_id: - description: > - represents a policy type identifier. Currently this is an integer. - type: integer - example: 20000 - - policy_instance_id: - description: > - represents a policy instance identifier. UUIDs are advisable but can be any string - type: string - example: 3d2157af-6a8f-4a7c-810f-38c2f824bf12 - - policy_type: - description: > - represents a policy type. String is used for now to represent this - type: string - example: - "{type: A}" - - policy_instance: - description: > - represents a policy instance. String is used for now to represent this - type: string - example: - "{slice_id: slice-1, priority_level: high}" - - securitySchemes: - basicAuth: - type: http - scheme: basic - -security: - - basicAuth: [] \ No newline at end of file diff --git a/dashboard/a1-controller-client/src/test/java/org/oransc/ric/portal/dashboard/a1controller/client/test/A1ControllerClientTest.java b/dashboard/a1-controller-client/src/test/java/org/oransc/ric/portal/dashboard/a1controller/client/test/A1ControllerClientTest.java deleted file mode 100644 index cbafba42..00000000 --- a/dashboard/a1-controller-client/src/test/java/org/oransc/ric/portal/dashboard/a1controller/client/test/A1ControllerClientTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2019 Nordix Foundation - * %% - * 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.a1controller.client.test; - -import java.lang.invoke.MethodHandles; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.oransc.ric.a1controller.client.api.A1ControllerApi; -import org.oransc.ric.a1controller.client.invoker.ApiClient; -import org.oransc.ric.a1controller.client.model.InputNRRidPTidPIidPISchema; -import org.oransc.ric.a1controller.client.model.InputNRRidPTidPIidPISchemaInput; -import org.oransc.ric.a1controller.client.model.InputNRRidPTidPIidSchema; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.web.client.RestClientException; - -/** - * Demonstrates use of the generated A1 controller client. - * - * The tests fail because no server is available. - */ -public class A1ControllerClientTest { - - private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - - @Test - public void demo() { - ApiClient apiClient = new ApiClient(); - apiClient.setBasePath("http://localhost:30099/"); - A1ControllerApi a1Api = new A1ControllerApi(apiClient); - try { - Object o = a1Api.a1ControllerGetPolicyInstance(new InputNRRidPTidPIidSchema()); - logger.info( - "getPolicy answered code {}, content {} ", apiClient.getStatusCode().toString(), o.toString()); - Assertions.assertTrue(apiClient.getStatusCode().is2xxSuccessful()); - } catch (RestClientException e) { - logger.error("getPolicy failed: {}", e.toString()); - } - try { - String policy = "{}"; - InputNRRidPTidPIidPISchema body = new InputNRRidPTidPIidPISchema(); - InputNRRidPTidPIidPISchemaInput input = new InputNRRidPTidPIidPISchemaInput(); - input.setNearRtRicId("1"); - input.setPolicyTypeId(1); - input.setPolicyInstanceId("1"); - input.setPolicyInstance("{}"); - body.setInput(input); - a1Api.a1ControllerCreatePolicyInstance(body); - logger.info("putPolicy answered: {}", apiClient.getStatusCode().toString()); - Assertions.assertTrue(apiClient.getStatusCode().is2xxSuccessful()); - } catch (RestClientException e) { - logger.error("getPolicy failed: {}", e.toString()); - } - } -} diff --git a/dashboard/pom.xml b/dashboard/pom.xml index 1473449f..8c2b0dc1 100644 --- a/dashboard/pom.xml +++ b/dashboard/pom.xml @@ -44,8 +44,7 @@ limitations under the License. ========================LICENSE_START================================= ========================LICENSE_END=================================== - - a1-controller-client + webapp-frontend webapp-backend diff --git a/dashboard/webapp-backend/pom.xml b/dashboard/webapp-backend/pom.xml index 215ec758..80bb585f 100644 --- a/dashboard/webapp-backend/pom.xml +++ b/dashboard/webapp-backend/pom.xml @@ -1,5 +1,8 @@ - - - 4.0.0 - - org.o-ran-sc.nonrt.ric-dashboard - ric-dash-parent - 1.0.0-SNAPSHOT - - ric-dash-be - NonRT RIC Dashboard Webapp backend - - 2.9.2 - - 0 - - - - onap-releases - ONAP - Release Repository - https://nexus.onap.org/content/repositories/releases - - - - - - org.o-ran-sc.ric.plt.a1controller.client - a1-controller-client - 0.1.0-SNAPSHOT - - - org.onap.portal.sdk - epsdk-fw - 2.6.0 - - - commons-logging - commons-logging - - - log4j - log4j - - - log4j - apache-log4j-extras - - - org.slf4j - slf4j-log4j12 - - - junit - junit - - - commons-fileupload - commons-fileupload - - - commons-beanutils - commons-beanutils - - - - org.powermock - powermock-module-junit4 - - - - org.powermock - powermock-api-mockito - - - - - org.springframework.boot - spring-boot-starter-security - - - org.springframework.boot - spring-boot-starter-web - - - org.slf4j - slf4j-api - - - - org.slf4j - jcl-over-slf4j - - - ch.qos.logback - logback-classic - - - ch.qos.logback - logback-core - - - io.springfox - springfox-swagger2 - ${springfox.version} - - - io.springfox - springfox-swagger-ui - ${springfox.version} - - - - - org.mockito - mockito-core - test - - - org.springframework.boot - spring-boot-starter-test - test - - - org.junit.jupiter - junit-jupiter-api - test - - - org.junit.jupiter - junit-jupiter-engine - test - - - org.junit.platform - junit-platform-launcher - - 1.4.2 - test - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - org.codehaus.mojo - license-maven-plugin - - - src - - - **/*.json - - - - + 0 + + + + onap-releases + ONAP - Release Repository + https://nexus.onap.org/content/repositories/releases + + + + + + org.onap.portal.sdk + epsdk-fw + 2.6.0 + + + commons-logging + commons-logging + + + log4j + log4j + + + log4j + apache-log4j-extras + + + org.slf4j + slf4j-log4j12 + + + junit + junit + + + commons-fileupload + commons-fileupload + + + commons-beanutils + commons-beanutils + + + + org.powermock + powermock-module-junit4 + + + + org.powermock + powermock-api-mockito + + + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-web + + + org.slf4j + slf4j-api + + + + org.slf4j + jcl-over-slf4j + + + ch.qos.logback + logback-classic + + + ch.qos.logback + logback-core + + + io.springfox + springfox-swagger2 + ${springfox.version} + + + io.springfox + springfox-swagger-ui + ${springfox.version} + + + org.immutables + value + ${immutable.version} + provided + + + org.immutables + gson + ${immutable.version} + + + + + org.mockito + mockito-core + test + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.junit.platform + junit-platform-launcher + + 1.4.2 + test + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.codehaus.mojo + license-maven-plugin + + + src + + + **/*.json + + + + - - org.apache.maven.plugins - maven-jar-plugin - - - - true - - - ${project.version}-b${build.number} - - - - - - maven-resources-plugin - - - copy-resources - validate - - copy-resources - - - ${project.build.directory}/classes/resources/ - - - ${project.parent.basedir}/webapp-frontend/dist/dashApp/ - - - - - - - - - org.apache.maven.plugins - maven-deploy-plugin - - true - - - - org.jacoco - jacoco-maven-plugin - 0.8.4 - - - default-prepare-agent - - prepare-agent - - - - default-report - prepare-package - - report - - - - - - - io.fabric8 - docker-maven-plugin - 0.30.0 - - true - - ${env.CONTAINER_PULL_REGISTRY} - ${env.CONTAINER_PUSH_REGISTRY} - - - - - o-ran-sc/nonrtric-dashboard:${project.version} - - openjdk:11-jre-slim - - - ${project.version} - - - artifact - - - - mkdir /logs - chmod -R 777 /logs - - - - - java - -Xms128m - -Xmx256m - -cp - maven:maven/${project.artifactId}-${project.version}.${project.packaging} - -Dloader.main=org.oransc.ric.portal.dashboard.DashboardApplication - -Djava.security.egd=file:/dev/./urandom - org.springframework.boot.loader.PropertiesLauncher - - - - - - - - - - - build - push - - - - - - + + org.apache.maven.plugins + maven-jar-plugin + + + + true + + + ${project.version}-b${build.number} + + + + + + maven-resources-plugin + + + copy-resources + validate + + copy-resources + + + ${project.build.directory}/classes/resources/ + + + ${project.parent.basedir}/webapp-frontend/dist/dashApp/ + + + + + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + org.jacoco + jacoco-maven-plugin + 0.8.4 + + + default-prepare-agent + + prepare-agent + + + + default-report + prepare-package + + report + + + + + + + io.fabric8 + docker-maven-plugin + 0.30.0 + + true + + ${env.CONTAINER_PULL_REGISTRY} + ${env.CONTAINER_PUSH_REGISTRY} + + + + + o-ran-sc/nonrtric-dashboard:${project.version} + + openjdk:11-jre-slim + + + ${project.version} + + + artifact + + + + mkdir /logs + chmod -R 777 /logs + + + + + java + -Xms128m + -Xmx256m + -cp + maven:maven/${project.artifactId}-${project.version}.${project.packaging} + -Dloader.main=org.oransc.ric.portal.dashboard.DashboardApplication + -Djava.security.egd=file:/dev/./urandom + org.springframework.boot.loader.PropertiesLauncher + + + + + + + + + + + build + push + + + + + + diff --git a/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/DashboardConstants.java b/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/DashboardConstants.java index d61ce1dd..b82aa647 100644 --- a/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/DashboardConstants.java +++ b/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/DashboardConstants.java @@ -38,7 +38,7 @@ public abstract class DashboardConstants { private static final String ROLE_PREFIX = "ROLE_"; public static final String ROLE_ADMIN = ROLE_PREFIX + ROLE_NAME_ADMIN; public static final String ROLE_STANDARD = ROLE_PREFIX + ROLE_NAME_STANDARD; - public static final String A1_CONTROLLER_USERNAME = "admin"; - public static final String A1_CONTROLLER_PASSWORD = "Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U"; + public static final String POLICY_CONTROLLER_USERNAME = "admin"; + public static final String POLICY_CONTROLLER_PASSWORD = "Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U"; } diff --git a/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/A1ControllerConfiguration.java b/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/A1ControllerConfiguration.java deleted file mode 100644 index ffdcacd8..00000000 --- a/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/A1ControllerConfiguration.java +++ /dev/null @@ -1,74 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2019 Nordix Foundation - * %% - * 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.a1controller.client.api.A1ControllerApi; -import org.oransc.ric.a1controller.client.invoker.ApiClient; -import org.oransc.ric.portal.dashboard.DashboardConstants; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -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 controller client as a bean to be managed by the Spring - * container. - */ -@Configuration -@Profile("!test") -public class A1ControllerConfiguration { - - private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - public static final String A1_CONTROLLER_USERNAME = DashboardConstants.A1_CONTROLLER_USERNAME; - public static final String A1_CONTROLLER_PASSWORD = DashboardConstants.A1_CONTROLLER_PASSWORD; - - // Populated by the autowired constructor - private final String a1ControllerUrl; - - @Autowired - public A1ControllerConfiguration(@Value("${a1controller.url.prefix}") final String urlPrefix, // - @Value("${a1controller.url.suffix}") final String urlSuffix) { - logger.debug("ctor prefix '{}' suffix '{}'", urlPrefix, urlSuffix); - a1ControllerUrl = new DefaultUriBuilderFactory(urlPrefix.trim()).builder().path(urlSuffix.trim()).build().normalize() - .toString(); - logger.info("Configuring A1 Controller at URL {}", a1ControllerUrl); - } - - private ApiClient apiClient() { - ApiClient apiClient = new ApiClient(new RestTemplate()); - apiClient.setBasePath(a1ControllerUrl); - apiClient.setUsername(A1_CONTROLLER_USERNAME); - apiClient.setPassword(A1_CONTROLLER_PASSWORD); - return apiClient; - } - - @Bean - // The bean (method) name must be globally unique - public A1ControllerApi a1ControllerApi() { - return new A1ControllerApi(apiClient()); - } - -} diff --git a/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/WebSecurityConfiguration.java b/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/WebSecurityConfiguration.java index 0a7f02ca..85a96d0a 100644 --- a/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/WebSecurityConfiguration.java +++ b/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/WebSecurityConfiguration.java @@ -23,9 +23,9 @@ package org.oransc.ric.portal.dashboard.config; import java.io.IOException; import java.lang.invoke.MethodHandles; import java.lang.reflect.InvocationTargetException; + import org.onap.portalsdk.core.onboarding.util.PortalApiConstants; import org.oransc.ric.portal.dashboard.DashboardUserManager; -import org.oransc.ric.portal.dashboard.controller.A1Controller; import org.oransc.ric.portal.dashboard.controller.SimpleErrorController; import org.oransc.ric.portal.dashboard.portalapi.PortalAuthManager; import org.oransc.ric.portal.dashboard.portalapi.PortalAuthenticationFilter; @@ -43,6 +43,7 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import org.springframework.security.web.csrf.CookieCsrfTokenRepository; +import org.oransc.ric.portal.dashboard.controller.PolicyController; @Configuration @EnableWebSecurity @@ -71,7 +72,7 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { DashboardUserManager userManager; @Override - protected void configure(HttpSecurity http) throws Exception { + protected void configure(HttpSecurity http) throws Exception { logger.debug("configure: portalapi.username {}", userName); // A chain of ".and()" always baffles me http.authorizeRequests().anyRequest().authenticated(); @@ -90,7 +91,7 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { "/swagger-ui.html", // "/webjars/**", // PortalApiConstants.API_PREFIX + "/**", // - A1Controller.CONTROLLER_PATH + "/" + A1Controller.VERSION_METHOD, // + PolicyController.CONTROLLER_PATH + "/" + PolicyController.VERSION_METHOD, // SimpleErrorController.ERROR_PATH }; @Override diff --git a/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/A1Controller.java b/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/A1Controller.java deleted file mode 100644 index 08b485e8..00000000 --- a/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/A1Controller.java +++ /dev/null @@ -1,250 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2019 Nordix Foundation - * %% - * 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.controller; - -import java.lang.invoke.MethodHandles; -import java.util.List; -import javax.servlet.http.HttpServletResponse; -import org.oransc.ric.a1controller.client.api.A1ControllerApi; -import org.oransc.ric.a1controller.client.model.InputNRRidPTidPIidPISchema; -import org.oransc.ric.a1controller.client.model.InputNRRidPTidPIidPISchemaInput; -import org.oransc.ric.a1controller.client.model.InputNRRidPTidPIidSchema; -import org.oransc.ric.a1controller.client.model.InputNRRidPTidPIidSchemaInput; -import org.oransc.ric.a1controller.client.model.InputNRRidPTidSchema; -import org.oransc.ric.a1controller.client.model.InputNRRidPTidSchemaInput; -import org.oransc.ric.a1controller.client.model.InputNRRidSchema; -import org.oransc.ric.a1controller.client.model.InputNRRidSchemaInput; -import org.oransc.ric.a1controller.client.model.OutputCodeSchema; -import org.oransc.ric.a1controller.client.model.OutputDescNamePTCodeSchema; -import org.oransc.ric.a1controller.client.model.OutputDescNamePTCodeSchemaOutput; -import org.oransc.ric.a1controller.client.model.OutputPICodeSchema; -import org.oransc.ric.a1controller.client.model.OutputPIidsListCodeSchema; -import org.oransc.ric.a1controller.client.model.OutputPTidsListCodeSchema; -import org.oransc.ric.portal.dashboard.DashboardApplication; -import org.oransc.ric.portal.dashboard.DashboardConstants; -import org.oransc.ric.portal.dashboard.exceptions.HttpBadRequestException; -import org.oransc.ric.portal.dashboard.exceptions.HttpInternalServerErrorException; -import org.oransc.ric.portal.dashboard.exceptions.HttpNotFoundException; -import org.oransc.ric.portal.dashboard.exceptions.HttpNotImplementedException; -import org.oransc.ric.portal.dashboard.model.PolicyInstance; -import org.oransc.ric.portal.dashboard.model.PolicyInstances; -import org.oransc.ric.portal.dashboard.model.PolicyType; -import org.oransc.ric.portal.dashboard.model.PolicyTypes; -import org.oransc.ric.portal.dashboard.model.SuccessTransport; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.security.access.annotation.Secured; -import org.springframework.util.Assert; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import io.swagger.annotations.ApiOperation; - -/** - * Proxies calls from the front end to the A1 Controller via the A1 Mediator - * API. - * - * If a method throws RestClientResponseException, it is handled by - * {@link CustomResponseEntityExceptionHandler#handleProxyMethodException(Exception, - * org.springframework.web.context.request.WebRequest)} - * which returns status 502. All other exceptions are handled by Spring which - * returns status 500. - */ -@RestController -@RequestMapping(value = A1Controller.CONTROLLER_PATH, produces = MediaType.APPLICATION_JSON_VALUE) -public class A1Controller { - - private static final String NEAR_RT_RIC_ID = "NearRtRic1"; - - 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 + "/policy"; - // Endpoints - public static final String VERSION_METHOD = DashboardConstants.VERSION_METHOD; - public static final String POLICY_TYPES_METHOD = "policytypes"; - public static final String POLICY_TYPE_ID_NAME = "policy_type_id"; - public static final String POLICIES_NAME = "policies"; - public static final String POLICY_INSTANCE_ID_NAME = "policy_instance_id"; - - // Populated by the autowired constructor - private final A1ControllerApi a1ControllerApi; - - @Autowired - public A1Controller(final A1ControllerApi A1ControllerApi) { - Assert.notNull(A1ControllerApi, "API must not be null"); - this.a1ControllerApi = A1ControllerApi; - if (logger.isDebugEnabled()) - logger.debug("ctor: configured with client type {}", A1ControllerApi.getClass().getName()); - } - - @ApiOperation(value = "Gets the A1 client library MANIFEST.MF property Implementation-Version.", - response = SuccessTransport.class) - @GetMapping(VERSION_METHOD) - // No role required - public SuccessTransport getA1ControllerClientVersion() { - return new SuccessTransport(200, DashboardApplication.getImplementationVersion(A1ControllerApi.class)); - } - - /* - * The fields are defined in the A1Control Typescript interface. - */ - @ApiOperation(value = "Gets the policy types from Near Realtime-RIC via the A1 Controller API") - @GetMapping(POLICY_TYPES_METHOD) - @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD }) - public Object getAllPolicyTypes(HttpServletResponse response) { - logger.debug("getAllPolicyTypes"); - InputNRRidSchemaInput nrrid = new InputNRRidSchemaInput(); - nrrid.setNearRtRicId(NEAR_RT_RIC_ID); - InputNRRidSchema inputSchema = new InputNRRidSchema(); - inputSchema.setInput(nrrid); - OutputPTidsListCodeSchema outputPTidsListCodeSchema = - a1ControllerApi.a1ControllerGetAllPolicyTypes(inputSchema); - checkHttpError(outputPTidsListCodeSchema.getOutput().getCode()); - List policyTypeIds = outputPTidsListCodeSchema.getOutput().getPolicyTypeIdList(); - PolicyTypes policyTypes = new PolicyTypes(); - InputNRRidPTidSchema typeSchema = new InputNRRidPTidSchema(); - InputNRRidPTidSchemaInput typeId = new InputNRRidPTidSchemaInput(); - typeId.setNearRtRicId(NEAR_RT_RIC_ID); - for (Integer policyTypeId : policyTypeIds) { - typeId.setPolicyTypeId(policyTypeId); - typeSchema.setInput(typeId); - OutputDescNamePTCodeSchema controllerGetPolicyType = - a1ControllerApi.a1ControllerGetPolicyType(typeSchema); - checkHttpError(controllerGetPolicyType.getOutput().getCode()); - OutputDescNamePTCodeSchemaOutput policyTypeSchema = controllerGetPolicyType.getOutput(); - PolicyType type = new PolicyType(policyTypeId, policyTypeSchema.getName(), - policyTypeSchema.getPolicyType().toString()); - policyTypes.add(type); - } - return policyTypes; - } - - @ApiOperation(value = "Returns the policy instances for the given policy type.") - @GetMapping(POLICY_TYPES_METHOD + "/{" + POLICY_TYPE_ID_NAME + "}/" + POLICIES_NAME) - @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD }) - public Object getPolicyInstances(@PathVariable(POLICY_TYPE_ID_NAME) String policyTypeIdString) { - logger.debug("getPolicyInstances {}", policyTypeIdString); - InputNRRidPTidSchemaInput typeIdInput = new InputNRRidPTidSchemaInput(); - typeIdInput.setNearRtRicId(NEAR_RT_RIC_ID); - Integer policyTypeId = Integer.decode(policyTypeIdString); - typeIdInput.setPolicyTypeId(policyTypeId); - InputNRRidPTidSchema inputSchema = new InputNRRidPTidSchema(); - inputSchema.setInput(typeIdInput); - OutputPIidsListCodeSchema controllerGetAllInstancesForType = - a1ControllerApi.a1ControllerGetAllInstancesForType(inputSchema); - checkHttpError(controllerGetAllInstancesForType.getOutput().getCode()); - List instancesForType = controllerGetAllInstancesForType.getOutput().getPolicyInstanceIdList(); - PolicyInstances instances = new PolicyInstances(); - InputNRRidPTidPIidSchemaInput instanceIdInput = new InputNRRidPTidPIidSchemaInput(); - instanceIdInput.setNearRtRicId(NEAR_RT_RIC_ID); - instanceIdInput.setPolicyTypeId(policyTypeId); - InputNRRidPTidPIidSchema instanceInputSchema = new InputNRRidPTidPIidSchema(); - for (String instanceId : instancesForType) { - instanceIdInput.setPolicyInstanceId(instanceId); - instanceInputSchema.setInput(instanceIdInput); - OutputPICodeSchema policyInstance = - a1ControllerApi.a1ControllerGetPolicyInstance(instanceInputSchema); - checkHttpError(policyInstance.getOutput().getCode()); - PolicyInstance instance = - new PolicyInstance(instanceId, policyInstance.getOutput().getPolicyInstance()); - instances.add(instance); - } - return instances; - } - - @ApiOperation(value = "Returns a policy instance of a type") - @GetMapping(POLICY_TYPES_METHOD + "/{" + POLICY_TYPE_ID_NAME + "}/" + POLICIES_NAME + "/{" - + POLICY_INSTANCE_ID_NAME + "}") - @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD }) - public Object getPolicyInstance(@PathVariable(POLICY_TYPE_ID_NAME) String policyTypeIdString, - @PathVariable(POLICY_INSTANCE_ID_NAME) String policyInstanceId) { - logger.debug("getPolicyInstance {}:{}", policyTypeIdString, policyInstanceId); - InputNRRidPTidPIidSchemaInput instanceIdInput = new InputNRRidPTidPIidSchemaInput(); - instanceIdInput.setNearRtRicId(NEAR_RT_RIC_ID); - instanceIdInput.setPolicyTypeId(Integer.decode(policyTypeIdString)); - instanceIdInput.setPolicyInstanceId(policyInstanceId); - InputNRRidPTidPIidSchema inputSchema = new InputNRRidPTidPIidSchema(); - inputSchema.setInput(instanceIdInput); - OutputPICodeSchema policyInstance = a1ControllerApi.a1ControllerGetPolicyInstance(inputSchema); - checkHttpError(policyInstance.getOutput().getCode()); - return policyInstance.getOutput().getPolicyInstance(); - } - - @ApiOperation(value = "Creates the policy instances for the given policy type.") - @PutMapping(POLICY_TYPES_METHOD + "/{" + POLICY_TYPE_ID_NAME + "}/" + POLICIES_NAME + "/{" - + POLICY_INSTANCE_ID_NAME + "}") - @Secured({ DashboardConstants.ROLE_ADMIN }) - public void putPolicyInstance(@PathVariable(POLICY_TYPE_ID_NAME) String policyTypeIdString, - @PathVariable(POLICY_INSTANCE_ID_NAME) String policyInstanceId, @RequestBody String instance) { - logger.debug("putPolicyInstance typeId: {}, instanceId: {}, instance: {}", policyTypeIdString, - policyInstanceId, instance); - InputNRRidPTidPIidPISchemaInput createInstanceInput = new InputNRRidPTidPIidPISchemaInput(); - createInstanceInput.setNearRtRicId(NEAR_RT_RIC_ID); - createInstanceInput.setPolicyTypeId(Integer.decode(policyTypeIdString)); - createInstanceInput.setPolicyInstanceId(policyInstanceId); - createInstanceInput.setPolicyInstance(instance); - InputNRRidPTidPIidPISchema inputSchema = new InputNRRidPTidPIidPISchema(); - inputSchema.setInput(createInstanceInput); - OutputCodeSchema outputCodeSchema = a1ControllerApi.a1ControllerCreatePolicyInstance(inputSchema); - checkHttpError(outputCodeSchema.getOutput().getCode()); - } - - @ApiOperation(value = "Deletes the policy instances for the given policy type.") - @DeleteMapping(POLICY_TYPES_METHOD + "/{" + POLICY_TYPE_ID_NAME + "}/" + POLICIES_NAME + "/{" - + POLICY_INSTANCE_ID_NAME + "}") - @Secured({ DashboardConstants.ROLE_ADMIN }) - public void deletePolicyInstance(@PathVariable(POLICY_TYPE_ID_NAME) String policyTypeIdString, - @PathVariable(POLICY_INSTANCE_ID_NAME) String policyInstanceId) { - logger.debug("deletePolicyInstance typeId: {}, instanceId: {}", policyTypeIdString, policyInstanceId); - InputNRRidPTidPIidSchemaInput instanceIdInput = new InputNRRidPTidPIidSchemaInput(); - instanceIdInput.setNearRtRicId(NEAR_RT_RIC_ID); - instanceIdInput.setPolicyTypeId(Integer.decode(policyTypeIdString)); - instanceIdInput.setPolicyInstanceId(policyInstanceId); - InputNRRidPTidPIidSchema inputSchema = new InputNRRidPTidPIidSchema(); - inputSchema.setInput(instanceIdInput); - OutputCodeSchema outputCodeSchema = a1ControllerApi.a1ControllerDeletePolicyInstance(inputSchema); - checkHttpError(outputCodeSchema.getOutput().getCode()); - } - - private void checkHttpError(String httpCode) { - logger.debug("Http Response Code: {}", httpCode); - if (httpCode.equals(String.valueOf(HttpStatus.NOT_FOUND.value()))) { - logger.error("Caught HttpNotFoundException"); - throw new HttpNotFoundException("Not Found Exception"); - } else if (httpCode.equals(String.valueOf(HttpStatus.BAD_REQUEST.value()))) { - logger.error("Caught HttpBadRequestException"); - throw new HttpBadRequestException("Bad Request Exception"); - } else if (httpCode.equals(String.valueOf(HttpStatus.INTERNAL_SERVER_ERROR.value()))) { - logger.error("Caught HttpInternalServerErrorException"); - throw new HttpInternalServerErrorException("Internal Server Error Exception"); - } else if (httpCode.equals(String.valueOf(HttpStatus.NOT_IMPLEMENTED.value()))) { - logger.error("Caught HttpNotImplementedException"); - throw new HttpNotImplementedException("Not Implemented Exception"); - } - } -} diff --git a/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/PolicyController.java b/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/PolicyController.java new file mode 100644 index 00000000..8af4e97a --- /dev/null +++ b/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/PolicyController.java @@ -0,0 +1,161 @@ +/*- + * ========================LICENSE_START================================= + * O-RAN-SC + * %% + * Copyright (C) 2019 Nordix Foundation + * %% + * 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.controller; + +import java.lang.invoke.MethodHandles; + +import javax.servlet.http.HttpServletResponse; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import org.oransc.ric.portal.dashboard.DashboardApplication; +import org.oransc.ric.portal.dashboard.DashboardConstants; +import org.oransc.ric.portal.dashboard.exceptions.HttpBadRequestException; +import org.oransc.ric.portal.dashboard.exceptions.HttpInternalServerErrorException; +import org.oransc.ric.portal.dashboard.exceptions.HttpNotFoundException; +import org.oransc.ric.portal.dashboard.exceptions.HttpNotImplementedException; +import org.oransc.ric.portal.dashboard.model.PolicyInstances; +import org.oransc.ric.portal.dashboard.model.PolicyTypes; +import org.oransc.ric.portal.dashboard.model.SuccessTransport; +import org.oransc.ric.portal.dashboard.policyagentapi.PolicyAgentApi; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.security.access.annotation.Secured; +import org.springframework.util.Assert; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import io.swagger.annotations.ApiOperation; + +/** + * Proxies calls from the front end to the Policy agent API. + * + * If a method throws RestClientResponseException, it is handled by + * {@link CustomResponseEntityExceptionHandler#handleProxyMethodException(Exception, org.springframework.web.context.request.WebRequest)} + * which returns status 502. All other exceptions are handled by Spring which + * returns status 500. + */ +@RestController +@RequestMapping(value = PolicyController.CONTROLLER_PATH, produces = MediaType.APPLICATION_JSON_VALUE) +public class PolicyController { + + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + private static Gson gson = new GsonBuilder() // + .serializeNulls() // + .create(); // + + // Publish paths in constants so tests are easy to write + public static final String CONTROLLER_PATH = DashboardConstants.ENDPOINT_PREFIX + "/policy"; + // Endpoints + public static final String VERSION_METHOD = DashboardConstants.VERSION_METHOD; + public static final String POLICY_TYPES_METHOD = "policytypes"; + public static final String POLICY_TYPE_ID_NAME = "policy_type_id"; + public static final String POLICIES_NAME = "policies"; + public static final String POLICY_INSTANCE_ID_NAME = "policy_instance_id"; + + // Populated by the autowired constructor + private final PolicyAgentApi policyAgentApi; + + @Autowired + public PolicyController(final PolicyAgentApi policyAgentApi) { + Assert.notNull(policyAgentApi, "API must not be null"); + this.policyAgentApi = policyAgentApi; + logger.debug("ctor: configured with client type {}", policyAgentApi.getClass().getName()); + } + + /* + * The fields are defined in the Policy Control Typescript interface. + */ + @ApiOperation(value = "Gets the policy types from Near Realtime-RIC") + @GetMapping(POLICY_TYPES_METHOD) + @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD }) + public PolicyTypes getAllPolicyTypes(HttpServletResponse response) { + logger.debug("getAllPolicyTypes"); + return this.policyAgentApi.getAllPolicyTypes(); + } + + @ApiOperation(value = "Returns the policy instances for the given policy type.") + @GetMapping(POLICY_TYPES_METHOD + "/{" + POLICY_TYPE_ID_NAME + "}/" + POLICIES_NAME) + @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD }) + public String getPolicyInstances(@PathVariable(POLICY_TYPE_ID_NAME) String policyTypeIdString) { + logger.debug("getPolicyInstances {}", policyTypeIdString); + + PolicyInstances i = this.policyAgentApi.getPolicyInstancesForType(policyTypeIdString); + String json = gson.toJson(i); + return json; + } + + @ApiOperation(value = "Returns a policy instance of a type") + @GetMapping(POLICY_TYPES_METHOD + "/{" + POLICY_TYPE_ID_NAME + "}/" + POLICIES_NAME + "/{" + POLICY_INSTANCE_ID_NAME + + "}") + @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD }) + public String getPolicyInstance(@PathVariable(POLICY_TYPE_ID_NAME) String policyTypeIdString, + @PathVariable(POLICY_INSTANCE_ID_NAME) String policyInstanceId) { + logger.debug("getPolicyInstance {}:{}", policyTypeIdString, policyInstanceId); + return this.policyAgentApi.getPolicyInstance(policyInstanceId); + } + + @ApiOperation(value = "Creates the policy instances for the given policy type.") + @PutMapping(POLICY_TYPES_METHOD + "/{" + POLICY_TYPE_ID_NAME + "}/" + POLICIES_NAME + "/{" + POLICY_INSTANCE_ID_NAME + + "}") + @Secured({ DashboardConstants.ROLE_ADMIN }) + public void putPolicyInstance(@PathVariable(POLICY_TYPE_ID_NAME) String policyTypeIdString, + @PathVariable(POLICY_INSTANCE_ID_NAME) String policyInstanceId, @RequestBody String instance) { + logger.debug("putPolicyInstance typeId: {}, instanceId: {}, instance: {}", policyTypeIdString, policyInstanceId, + instance); + this.policyAgentApi.putPolicy(policyTypeIdString, policyInstanceId, instance); + } + + @ApiOperation(value = "Deletes the policy instances for the given policy type.") + @DeleteMapping(POLICY_TYPES_METHOD + "/{" + POLICY_TYPE_ID_NAME + "}/" + POLICIES_NAME + "/{" + + POLICY_INSTANCE_ID_NAME + "}") + @Secured({ DashboardConstants.ROLE_ADMIN }) + public void deletePolicyInstance(@PathVariable(POLICY_TYPE_ID_NAME) String policyTypeIdString, + @PathVariable(POLICY_INSTANCE_ID_NAME) String policyInstanceId) { + logger.debug("deletePolicyInstance typeId: {}, instanceId: {}", policyTypeIdString, policyInstanceId); + this.policyAgentApi.deletePolicy(policyInstanceId); + } + + private void checkHttpError(String httpCode) { + logger.debug("Http Response Code: {}", httpCode); + if (httpCode.equals(String.valueOf(HttpStatus.NOT_FOUND.value()))) { + logger.error("Caught HttpNotFoundException"); + throw new HttpNotFoundException("Not Found Exception"); + } else if (httpCode.equals(String.valueOf(HttpStatus.BAD_REQUEST.value()))) { + logger.error("Caught HttpBadRequestException"); + throw new HttpBadRequestException("Bad Request Exception"); + } else if (httpCode.equals(String.valueOf(HttpStatus.INTERNAL_SERVER_ERROR.value()))) { + logger.error("Caught HttpInternalServerErrorException"); + throw new HttpInternalServerErrorException("Internal Server Error Exception"); + } else if (httpCode.equals(String.valueOf(HttpStatus.NOT_IMPLEMENTED.value()))) { + logger.error("Caught HttpNotImplementedException"); + throw new HttpNotImplementedException("Not Implemented Exception"); + } + } +} diff --git a/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/PolicyInstance.java b/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/PolicyInfo.java similarity index 56% rename from dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/PolicyInstance.java rename to dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/PolicyInfo.java index b699b3c1..ca1b79d4 100644 --- a/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/PolicyInstance.java +++ b/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/PolicyInfo.java @@ -19,30 +19,23 @@ */ package org.oransc.ric.portal.dashboard.model; -public class PolicyInstance implements IDashboardResponse { - private String instanceId; - private Object instance; - - public PolicyInstance(String id, Object instance) { - this.instanceId = id; - this.instance = instance; - } - - public String getInstanceId() { - return instanceId; - } - public void setInstanceId(String instanceId) { - this.instanceId = instanceId; - } - public Object getInstance() { - return instance; - } - public void setInstance(Object instance) { - this.instance = instance; - } - - @Override - public String toString() { - return PolicyInstance.class.getName() + ": [id:" + instanceId + ", instance: " + instance + "]"; - } +import org.immutables.gson.Gson; +import org.immutables.value.Value; + +@Value.Immutable +@Gson.TypeAdapters +public interface PolicyInfo { + + public String id(); + + public String type(); + + public String ric(); + + public String json(); + + public String service(); + + public String lastModified(); + } diff --git a/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/PolicyInstances.java b/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/PolicyInstances.java index c7504874..eb6b4555 100644 --- a/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/PolicyInstances.java +++ b/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/PolicyInstances.java @@ -21,7 +21,7 @@ package org.oransc.ric.portal.dashboard.model; import java.util.ArrayList; -public class PolicyInstances extends ArrayList { +public class PolicyInstances extends ArrayList { private static final long serialVersionUID = -928428052502491021L; diff --git a/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/PolicyType.java b/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/PolicyType.java index efe40107..ea51cc50 100644 --- a/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/PolicyType.java +++ b/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/PolicyType.java @@ -23,29 +23,17 @@ import com.fasterxml.jackson.annotation.JsonProperty; public class PolicyType { - @JsonProperty("policy_type_id") - Integer policyTypeId; - @JsonProperty("name") String name; @JsonProperty("schema") String schema; - public PolicyType(Integer policyId, String name, String schema) { - this.policyTypeId = policyId; + public PolicyType(String name, String schema) { this.name = name; this.schema = schema; } - public Integer getPolicyTypeId() { - return policyTypeId; - } - - public void setPolicyTypeId(Integer policyTypeId) { - this.policyTypeId = policyTypeId; - } - public String getName() { return name; } @@ -64,6 +52,6 @@ public class PolicyType { @Override public String toString() { - return "[policy_type_id:" + policyTypeId + ", name:" + name + ", schema:" + schema + "]"; + return "[name:" + name + ", schema:" + schema + "]"; } } diff --git a/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/policyagentapi/PolicyAgentApi.java b/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/policyagentapi/PolicyAgentApi.java new file mode 100644 index 00000000..41f3c12e --- /dev/null +++ b/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/policyagentapi/PolicyAgentApi.java @@ -0,0 +1,37 @@ +/*- + * ========================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.policyagentapi; + +import org.oransc.ric.portal.dashboard.model.PolicyInstances; +import org.oransc.ric.portal.dashboard.model.PolicyTypes; +import org.springframework.web.client.RestClientException; + +public interface PolicyAgentApi { + + public PolicyTypes getAllPolicyTypes() throws RestClientException; + + public PolicyInstances getPolicyInstancesForType(String type); + + public String getPolicyInstance(String id) throws RestClientException; + + public void putPolicy(String policyTypeIdString, String policyInstanceId, String json) throws RestClientException; + + public void deletePolicy(String policyInstanceId) throws RestClientException; +} diff --git a/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/policyagentapi/PolicyAgentApiImpl.java b/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/policyagentapi/PolicyAgentApiImpl.java new file mode 100644 index 00000000..8236de1d --- /dev/null +++ b/dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/policyagentapi/PolicyAgentApiImpl.java @@ -0,0 +1,145 @@ +/*- + * ========================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.policyagentapi; + +import org.oransc.ric.portal.dashboard.DashboardConstants; +import org.oransc.ric.portal.dashboard.model.ImmutablePolicyInfo; +import org.oransc.ric.portal.dashboard.model.PolicyInfo; +import org.oransc.ric.portal.dashboard.model.PolicyInstances; +import org.oransc.ric.portal.dashboard.model.PolicyType; +import org.oransc.ric.portal.dashboard.model.PolicyTypes; +import org.springframework.beans.factory.annotation.Autowired; + +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; + +import java.util.List; +import java.util.Map; +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Type; + +import com.google.gson.GsonBuilder; +import com.google.gson.annotations.SerializedName; +import com.google.gson.reflect.TypeToken; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.immutables.gson.Gson; +import org.immutables.value.Value; + +@Component("PolicyAgentApi") +public class PolicyAgentApiImpl implements PolicyAgentApi { + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + RestTemplate restTemplate = new RestTemplate(); + + private static com.google.gson.Gson gson = new GsonBuilder() // + .serializeNulls() // + .create(); // + + private final String urlPrefix; + + @Autowired + public PolicyAgentApiImpl( + @org.springframework.beans.factory.annotation.Value("${policycontroller.url.prefix}") final String urlPrefix) { + logger.debug("ctor prefix '{}'", urlPrefix); + this.urlPrefix = urlPrefix; + } + + private String baseUrl() { + return urlPrefix; + } + + @Value.Immutable + @Gson.TypeAdapters + interface PolicyTypeInfo { + + public String name(); + + public String schema(); + } + + private PolicyType toPolicyType(PolicyTypeInfo i) { + return new PolicyType(i.name(), i.schema()); + } + + @Override + public PolicyTypes getAllPolicyTypes() throws RestClientException { + String url = baseUrl() + "/policy_types"; + String rsp = this.restTemplate.getForObject(url, String.class); + + Type listType = new TypeToken>() { + }.getType(); + List rspParsed = gson.fromJson(rsp, listType); + + PolicyTypes result = new PolicyTypes(); + for (PolicyTypeInfo i : rspParsed) { + result.add(toPolicyType(i)); + } + return result; + } + + @Override + public PolicyInstances getPolicyInstancesForType(String type) { + String url = baseUrl() + "/policies?type={type}"; + Map uriVariables = Map.of("type", type); + String rsp = this.restTemplate.getForObject(url, String.class, uriVariables); + + Type listType = new TypeToken>() { + }.getType(); + List rspParsed = gson.fromJson(rsp, listType); + + PolicyInstances result = new PolicyInstances(); + for (PolicyInfo p : rspParsed) { + result.add(p); + } + return result; + + } + + @Override + public String getPolicyInstance(String id) throws RestClientException { + String url = baseUrl() + "/policy?instance={id}"; + Map uriVariables = Map.of("id", id); + + return this.restTemplate.getForObject(url, String.class, uriVariables); + } + + @Override + public void putPolicy(String policyTypeIdString, String policyInstanceId, String json) throws RestClientException { + String url = baseUrl() + "/policy?type={type}&instance={instance}&ric={ric}&service={service}"; + Map uriVariables = Map.of( // + "type", policyTypeIdString, // + "instance", policyInstanceId, // + "ric", "ric1", // TODO + "service", "dashboard"); + + this.restTemplate.put(url, json, uriVariables); + } + + @Override + public void deletePolicy(String policyInstanceId) throws RestClientException { + String url = baseUrl() + "/policy?instance={instance}"; + Map uriVariables = Map.of("instance", policyInstanceId); + this.restTemplate.delete(url, uriVariables); + } + +} diff --git a/dashboard/webapp-backend/src/main/resources/application.properties b/dashboard/webapp-backend/src/main/resources/application.properties index 3aa2406f..b7753a7b 100644 --- a/dashboard/webapp-backend/src/main/resources/application.properties +++ b/dashboard/webapp-backend/src/main/resources/application.properties @@ -44,9 +44,8 @@ portalapi.password = # endpoint URLs must be supplied at deployment time # NOTE: change a1controller.url.prefix to http://localhost:8282 when running # dashboard locally (i.e., not inside the docker container) -# A1 Controller -a1controller.url.prefix = http://a1-controller-container:8181 -a1controller.url.suffix = /restconf/operations +policycontroller.url.prefix = http://localhost:8081 + # Kubernetes API via https://github.com/nokia/caas-ingress # Set insecure=true to disable SSL certificate and hostname checking diff --git a/dashboard/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/DashboardTestServer.java b/dashboard/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/DashboardTestServer.java index df1a51c8..a6c0a1e3 100644 --- a/dashboard/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/DashboardTestServer.java +++ b/dashboard/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/DashboardTestServer.java @@ -19,6 +19,8 @@ */ package org.oransc.ric.portal.dashboard; +import static org.junit.jupiter.api.Assertions.assertEquals; + import java.lang.invoke.MethodHandles; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledIfSystemProperty; @@ -45,7 +47,6 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; */ @ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT) -@ActiveProfiles("test") public class DashboardTestServer { private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); @@ -65,5 +66,6 @@ public class DashboardTestServer { } catch (Exception ex) { logger.warn(ex.toString()); } + assertEquals(1, 2); } } diff --git a/dashboard/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/A1ControllerMockConfiguration.java b/dashboard/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/A1ControllerMockConfiguration.java deleted file mode 100644 index 5706a913..00000000 --- a/dashboard/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/A1ControllerMockConfiguration.java +++ /dev/null @@ -1,333 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2019 Nordix Foundation - * %% - * 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 static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import com.fasterxml.jackson.core.JsonProcessingException; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.lang.invoke.MethodHandles; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -import org.oransc.ric.a1controller.client.api.A1ControllerApi; -import org.oransc.ric.a1controller.client.invoker.ApiClient; -import org.oransc.ric.a1controller.client.model.InputNRRidPTidPIidPISchema; -import org.oransc.ric.a1controller.client.model.InputNRRidPTidPIidSchema; -import org.oransc.ric.a1controller.client.model.InputNRRidPTidSchema; -import org.oransc.ric.a1controller.client.model.InputNRRidSchema; -import org.oransc.ric.a1controller.client.model.OutputCodeSchema; -import org.oransc.ric.a1controller.client.model.OutputCodeSchemaOutput; -import org.oransc.ric.a1controller.client.model.OutputDescNamePTCodeSchema; -import org.oransc.ric.a1controller.client.model.OutputDescNamePTCodeSchemaOutput; -import org.oransc.ric.a1controller.client.model.OutputPICodeSchema; -import org.oransc.ric.a1controller.client.model.OutputPICodeSchemaOutput; -import org.oransc.ric.a1controller.client.model.OutputPIidsListCodeSchema; -import org.oransc.ric.a1controller.client.model.OutputPIidsListCodeSchemaOutput; -import org.oransc.ric.a1controller.client.model.OutputPTidsListCodeSchema; -import org.oransc.ric.a1controller.client.model.OutputPTidsListCodeSchemaOutput; -import org.oransc.ric.portal.dashboard.model.PolicyType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -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.http.HttpStatus; - -/** - * Creates a mock implementation of the A1 controller client API. - */ -@Profile("test") -@Configuration -public class A1ControllerMockConfiguration { - - private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - - // A "control" is an element in the XApp descriptor - 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; - - public A1ControllerMockConfiguration() { - logger.info("Configuring mock A1 Mediator"); - } - - private ApiClient apiClient() { - ApiClient mockClient = mock(ApiClient.class); - when(mockClient.getStatusCode()).thenReturn(HttpStatus.OK); - return mockClient; - } - - @Bean - // Use the same name as regular configuration - public A1ControllerApi a1ControllerApi() { - ApiClient apiClient = apiClient(); - A1ControllerApi mockApi = mock(A1ControllerApi.class); - - when(mockApi.getApiClient()).thenReturn(apiClient); - - doAnswer(inv -> { - if (delayMs > 0) { - logger.debug("a1ControllerGetHandler sleeping {}", delayMs); - Thread.sleep(delayMs); - } - List types = database.getTypes(); - OutputPTidsListCodeSchemaOutput output = new OutputPTidsListCodeSchemaOutput(); - output.setPolicyTypeIdList(types); - output.setCode(String.valueOf(HttpStatus.OK.value())); - OutputPTidsListCodeSchema outputSchema = new OutputPTidsListCodeSchema(); - outputSchema.setOutput(output); - return outputSchema; - }).when(mockApi).a1ControllerGetAllPolicyTypes(any(InputNRRidSchema.class)); - - doAnswer(inv -> { - if (delayMs > 0) { - logger.debug("a1ControllerGetPolicyType sleeping {}", delayMs); - Thread.sleep(delayMs); - } - InputNRRidPTidSchema input = inv.getArgument(0); - PolicyType policyType = database.getPolicyType(input.getInput().getPolicyTypeId()); - OutputDescNamePTCodeSchemaOutput type = new OutputDescNamePTCodeSchemaOutput(); - type.setName(policyType.getName()); - type.setPolicyType(database.normalize(policyType.getSchema())); - type.setCode(String.valueOf(HttpStatus.OK.value())); - OutputDescNamePTCodeSchema outputSchema = new OutputDescNamePTCodeSchema(); - outputSchema.setOutput(type); - return outputSchema; - }).when(mockApi).a1ControllerGetPolicyType(any(InputNRRidPTidSchema.class)); - - doAnswer(inv -> { - if (delayMs > 0) { - logger.debug("a1ControllerGetHandler sleeping {}", delayMs); - Thread.sleep(delayMs); - } - InputNRRidPTidSchema input = inv.getArgument(0); - List instances = database.getInstances(Optional.of(input.getInput().getPolicyTypeId())); - OutputPIidsListCodeSchemaOutput instancesOutput = new OutputPIidsListCodeSchemaOutput(); - instancesOutput.setPolicyInstanceIdList(instances); - instancesOutput.setCode(String.valueOf(HttpStatus.OK.value())); - OutputPIidsListCodeSchema outputSchema = new OutputPIidsListCodeSchema(); - outputSchema.setOutput(instancesOutput); - return outputSchema; - }).when(mockApi).a1ControllerGetAllInstancesForType(any(InputNRRidPTidSchema.class)); - - doAnswer(inv -> { - if (delayMs > 0) { - logger.debug("a1ControllerGetHandler sleeping {}", delayMs); - Thread.sleep(delayMs); - } - InputNRRidPTidPIidSchema input = inv.getArgument(0); - Integer polcyTypeId = input.getInput().getPolicyTypeId(); - String instanceId = input.getInput().getPolicyInstanceId(); - String instance = database.normalize(database.getInstance(polcyTypeId, instanceId)); - OutputPICodeSchemaOutput instanceOutput = new OutputPICodeSchemaOutput(); - instanceOutput.setPolicyInstance(instance); - instanceOutput.setCode(String.valueOf(HttpStatus.OK.value())); - OutputPICodeSchema outputSchema = new OutputPICodeSchema(); - outputSchema.setOutput(instanceOutput); - return outputSchema; - }).when(mockApi).a1ControllerGetPolicyInstance(any(InputNRRidPTidPIidSchema.class)); - - doAnswer(inv -> { - if (delayMs > 0) { - logger.debug("a1ControllerGetHandler sleeping {}", delayMs); - Thread.sleep(delayMs); - } - InputNRRidPTidPIidPISchema input = inv.getArgument(0); - Integer polcyTypeId = input.getInput().getPolicyTypeId(); - String instanceId = input.getInput().getPolicyInstanceId(); - String instance = input.getInput().getPolicyInstance(); - database.putInstance(polcyTypeId, instanceId, instance); - OutputCodeSchemaOutput outputCodeSchemaOutput = new OutputCodeSchemaOutput(); - outputCodeSchemaOutput.setCode(String.valueOf(HttpStatus.CREATED.value())); - OutputCodeSchema outputCodeSchema = new OutputCodeSchema(); - outputCodeSchema.setOutput(outputCodeSchemaOutput); - return outputCodeSchema; - }).when(mockApi).a1ControllerCreatePolicyInstance(any(InputNRRidPTidPIidPISchema.class)); - - doAnswer(inv -> { - if (delayMs > 0) { - logger.debug("a1ControllerGetHandler sleeping {}", delayMs); - Thread.sleep(delayMs); - } - InputNRRidPTidPIidSchema input = inv.getArgument(0); - Integer polcyTypeId = input.getInput().getPolicyTypeId(); - String instanceId = input.getInput().getPolicyInstanceId(); - database.deleteInstance(polcyTypeId, instanceId); - OutputCodeSchemaOutput outputCodeSchemaOutput = new OutputCodeSchemaOutput(); - outputCodeSchemaOutput.setCode(String.valueOf(HttpStatus.NO_CONTENT.value())); - OutputCodeSchema outputCodeSchema = new OutputCodeSchema(); - outputCodeSchema.setOutput(outputCodeSchemaOutput); - return outputCodeSchema; - }).when(mockApi).a1ControllerDeletePolicyInstance(any(InputNRRidPTidPIidSchema.class)); - - return mockApi; - } - - class Database { - - public class PolicyException extends Exception { - - private static final long serialVersionUID = 1L; - - public PolicyException(String message) { - super(message); - System.out.println("**** Exception " + message); - } - } - - private class PolicyTypeHolder { - PolicyTypeHolder(PolicyType pt) { - this.policyType = pt; - } - - String getInstance(String instanceId) throws PolicyException { - String instance = instances.get(instanceId); - if (instance == null) { - throw new PolicyException("Instance not found: " + instanceId); - } - return instance; - } - - PolicyType getPolicyType() { - return policyType; - } - - void putInstance(String id, String data) { - instances.put(id, data); - } - - void deleteInstance(String id) { - instances.remove(id); - } - - List getInstances() { - return new ArrayList<>(instances.keySet()); - } - - private final PolicyType policyType; - private Map instances = new HashMap<>(); - } - - Database() { - String schema = getStringFromFile("anr-policy-schema.json"); - PolicyType policy = new PolicyType(1, "ANR", schema); - types.put(1, new PolicyTypeHolder(policy)); - - schema = getStringFromFile("demo-policy-schema-1.json"); - policy = new PolicyType(2, "type2", schema); - types.put(2, new PolicyTypeHolder(policy)); - - schema = getStringFromFile("demo-policy-schema-2.json"); - policy = new PolicyType(3, "type3", schema); - types.put(3, new PolicyTypeHolder(policy)); - - schema = getStringFromFile("demo-policy-schema-3.json"); - policy = new PolicyType(4, "type4", schema); - types.put(4, new PolicyTypeHolder(policy)); - try { - putInstance(1, "ANR-1", getStringFromFile("anr-policy-instance.json")); - } catch (JsonProcessingException | PolicyException e) { - // Nothing - } - } - - private String getStringFromFile(String path) { - try { - InputStream inputStream = MethodHandles.lookup().lookupClass().getClassLoader() - .getResourceAsStream(path); - return new BufferedReader(new InputStreamReader(inputStream)).lines().collect(Collectors.joining("\n")); - } catch (Exception e) { - logger.error("Cannot read file :" + path, e); - return ""; - } - } - - String normalize(String str) { - return str.replace('\n', ' '); - } - - void putInstance(Integer typeId, String instanceId, String instanceData) - throws JsonProcessingException, PolicyException { - PolicyTypeHolder type = getTypeHolder(typeId); - type.putInstance(instanceId, instanceData); - } - - void deleteInstance(Integer typeId, String instanceId) throws JsonProcessingException, PolicyException { - PolicyTypeHolder type = getTypeHolder(typeId); - type.deleteInstance(instanceId); - } - - String getInstance(Integer typeId, String instanceId) throws JsonProcessingException, PolicyException { - return getTypeHolder(typeId).getInstance(instanceId); - } - - List getTypes() { - return new ArrayList<>(types.keySet()); - } - - List getInstances(Optional typeId) throws PolicyException { - if (typeId.isPresent()) { - return getTypeHolder(typeId.get()).getInstances(); - } else { - Set res = new HashSet(); - for (Iterator i = types.values().iterator(); i.hasNext();) { - res.addAll(i.next().getInstances()); - } - return new ArrayList<>(res); - } - } - - private PolicyTypeHolder getTypeHolder(Integer typeId) throws PolicyException { - PolicyTypeHolder typeHolder = types.get(typeId); - if (typeHolder == null) { - throw new PolicyException("Type not found: " + typeId); - } - return typeHolder; - } - - private PolicyType getPolicyType(Integer typeId) throws PolicyException { - PolicyTypeHolder typeHolder = getTypeHolder(typeId); - return typeHolder.getPolicyType(); - } - - private Map types = new HashMap<>(); - - } - - private final Database database = new Database(); -} diff --git a/dashboard/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/PolicyControllerMockConfiguration.java b/dashboard/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/PolicyControllerMockConfiguration.java new file mode 100644 index 00000000..4213488e --- /dev/null +++ b/dashboard/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/PolicyControllerMockConfiguration.java @@ -0,0 +1,182 @@ +/*- + * ========================LICENSE_START================================= + * O-RAN-SC + * %% + * Copyright (C) 2019 Nordix Foundation + * %% + * 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.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.invoke.MethodHandles; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.oransc.ric.portal.dashboard.model.ImmutablePolicyInfo; +import org.oransc.ric.portal.dashboard.model.PolicyInfo; +import org.oransc.ric.portal.dashboard.model.PolicyInstances; +import org.oransc.ric.portal.dashboard.model.PolicyType; +import org.oransc.ric.portal.dashboard.model.PolicyTypes; +import org.oransc.ric.portal.dashboard.policyagentapi.PolicyAgentApi; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.web.client.RestClientException; + +/** + * Creates a mock implementation of the policy controller client API. + */ +@TestConfiguration +public class PolicyControllerMockConfiguration { + + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + @Bean + public PolicyAgentApi policyAgentApi() { + MockPolicyAgentApi apiClient = new MockPolicyAgentApi(); + return apiClient; + } + + class MockPolicyAgentApi implements PolicyAgentApi { + private final Database database = new Database(); + + @Override + public String getPolicyInstance(String id) throws RestClientException { + return database.getInstance(id); + } + + @Override + public void putPolicy(String policyTypeIdString, String policyInstanceId, String json) + throws RestClientException { + database.putInstance(policyTypeIdString, policyInstanceId, json); + } + + @Override + public void deletePolicy(String policyInstanceId) throws RestClientException { + database.deleteInstance(policyInstanceId); + } + + @Override + public PolicyTypes getAllPolicyTypes() throws RestClientException { + PolicyTypes result = new PolicyTypes(); + result.addAll(database.getTypes()); + return result; + } + + @Override + public PolicyInstances getPolicyInstancesForType(String type) { + PolicyInstances result = new PolicyInstances(); + List inst = database.getInstances(Optional.of(type)); + result.addAll(inst); + return result; + } + + } + + class Database { + + Database() { + String schema = getStringFromFile("anr-policy-schema.json"); + PolicyType policy = new PolicyType("ANR", schema); + types.put("ANR", policy); + + schema = getStringFromFile("demo-policy-schema-1.json"); + policy = new PolicyType("type2", schema); + types.put("type2", policy); + + schema = getStringFromFile("demo-policy-schema-2.json"); + policy = new PolicyType("type3", schema); + types.put("type3", policy); + + schema = getStringFromFile("demo-policy-schema-3.json"); + policy = new PolicyType("type4", schema); + types.put("type4", policy); + try { + putInstance("ANR", "ANR-1", getStringFromFile("anr-policy-instance.json")); + } catch (Exception e) { + // Nothing + } + } + + private String getStringFromFile(String path) { + try { + InputStream inputStream = MethodHandles.lookup().lookupClass().getClassLoader() + .getResourceAsStream(path); + return new BufferedReader(new InputStreamReader(inputStream)).lines().collect(Collectors.joining("\n")); + } catch (Exception e) { + logger.error("Cannot read file :" + path, e); + return ""; + } + } + + String normalize(String str) { + return str.replace('\n', ' '); + } + + private String getTimeStampUTC() { + return java.time.Instant.now().toString(); + } + + void putInstance(String typeId, String instanceId, String instanceData) { + PolicyInfo i = ImmutablePolicyInfo.builder().json(instanceData).lastModified(getTimeStampUTC()) + .id(instanceId).ric("ricXX").service("service").type(typeId).build(); + instances.put(instanceId, i); + } + + public void deleteInstance(String instanceId) { + instances.remove(instanceId); + } + + String getInstance(String id) throws RestClientException { + PolicyInfo i = instances.get(id); + if (i == null) { + throw new RestClientException("Type not found: " + id); + } + return i.json(); + } + + public Collection getTypes() { + return types.values(); + } + + public List getInstances(Optional typeId) { + ArrayList result = new ArrayList<>(); + for (PolicyInfo i : instances.values()) { + if (typeId.isPresent()) { + if (i.type().equals(typeId.get())) { + result.add(i); + } + + } else { + result.add(i); + } + } + return result; + } + + private Map types = new HashMap<>(); + private Map instances = new HashMap<>(); + + } + +} diff --git a/dashboard/webapp-frontend/src/app/interfaces/policy.types.ts b/dashboard/webapp-frontend/src/app/interfaces/policy.types.ts index e694bb6e..b6ecce62 100644 --- a/dashboard/webapp-frontend/src/app/interfaces/policy.types.ts +++ b/dashboard/webapp-frontend/src/app/interfaces/policy.types.ts @@ -21,15 +21,17 @@ // Models of data used by the Policy Control export interface PolicyType { - policy_type_id: number; name: string; schema: string; schemaObject: any; } export interface PolicyInstance { - instanceId: string; - instance: string; + id: string; + json: string; + ric: string; + service: string; + lastModified: string; } export interface PolicyInstanceAck { diff --git a/dashboard/webapp-frontend/src/app/policy-control/policy-instance-dialog.component.ts b/dashboard/webapp-frontend/src/app/policy-control/policy-instance-dialog.component.ts index d69400d0..5b5cc00e 100644 --- a/dashboard/webapp-frontend/src/app/policy-control/policy-instance-dialog.component.ts +++ b/dashboard/webapp-frontend/src/app/policy-control/policy-instance-dialog.component.ts @@ -80,7 +80,6 @@ export class PolicyInstanceDialogComponent implements OnInit, AfterViewInit { public policyInstanceId: string; public policyTypeName: string; darkMode: boolean; - private policyTypeId: number; constructor( @@ -93,7 +92,6 @@ export class PolicyInstanceDialogComponent implements OnInit, AfterViewInit { this.formActive = false; this.policyInstanceId = data.instanceId; this.policyTypeName = data.name; - this.policyTypeId = data.policyTypeId; this.jsonSchemaObject = data.createSchema; this.jsonObject = this.parseJson(data.instanceJson); } @@ -115,7 +113,7 @@ export class PolicyInstanceDialogComponent implements OnInit, AfterViewInit { } const policyJson: string = this.prettyLiveFormData; const self: PolicyInstanceDialogComponent = this; - this.dataService.putPolicy(this.policyTypeId, this.policyInstanceId, policyJson).subscribe( + this.dataService.putPolicy(this.policyTypeName, this.policyInstanceId, policyJson).subscribe( { next(value) { self.notificationService.success('Policy ' + self.policyTypeName + ':' + self.policyInstanceId + ' submitted'); @@ -194,10 +192,9 @@ export class PolicyInstanceDialogComponent implements OnInit, AfterViewInit { } export function getPolicyDialogProperties(policyType: PolicyType, instance: PolicyInstance, darkMode: boolean): MatDialogConfig { - const policyTypeId = policyType.policy_type_id; const createSchema = policyType.schemaObject; - const instanceId = instance ? instance.instanceId : null; - const instanceJson = instance ? instance.instance : null; + const instanceId = instance ? instance.id : null; + const instanceJson = instance ? instance.json : null; const name = policyType.name; return { maxWidth: '1200px', @@ -207,7 +204,6 @@ export function getPolicyDialogProperties(policyType: PolicyType, instance: Poli disableClose: false, panelClass: darkMode ? 'dark-theme' : '', data: { - policyTypeId, createSchema, instanceId, instanceJson, diff --git a/dashboard/webapp-frontend/src/app/policy-control/policy-instance.component.html b/dashboard/webapp-frontend/src/app/policy-control/policy-instance.component.html index e1a67dd5..8c305e41 100644 --- a/dashboard/webapp-frontend/src/app/policy-control/policy-instance.component.html +++ b/dashboard/webapp-frontend/src/app/policy-control/policy-instance.component.html @@ -22,7 +22,25 @@ Instance - {{element.instanceId}} + {{element.id}} + + + + + Ric + {{element.ric}} + + + + + Owner + {{element.service}} + + + + + Last modified + {{toLocalTime(element.lastModified)}} @@ -42,9 +60,10 @@ No records found. - + - + diff --git a/dashboard/webapp-frontend/src/app/policy-control/policy-instance.component.scss b/dashboard/webapp-frontend/src/app/policy-control/policy-instance.component.scss index b6a29a4a..6a18c342 100644 --- a/dashboard/webapp-frontend/src/app/policy-control/policy-instance.component.scss +++ b/dashboard/webapp-frontend/src/app/policy-control/policy-instance.component.scss @@ -19,13 +19,21 @@ */ .instances-table { - width: 60%; - min-width: 600px; + width: 90%; + min-width: 1200px; margin-top: 10px; margin-bottom: 10px; background-color: grayscale($color: #eeeaea); } +.mat-column-instanceId { + word-wrap: break-word; + white-space: unset; + flex: 0 0 28%; + width: 28%; +} + + .table-dark { background-color: #2d2d3d; } diff --git a/dashboard/webapp-frontend/src/app/policy-control/policy-instance.component.ts b/dashboard/webapp-frontend/src/app/policy-control/policy-instance.component.ts index b62deb4f..ecf6f36c 100644 --- a/dashboard/webapp-frontend/src/app/policy-control/policy-instance.component.ts +++ b/dashboard/webapp-frontend/src/app/policy-control/policy-instance.component.ts @@ -76,9 +76,9 @@ export class PolicyInstanceComponent implements OnInit, AfterViewInit { } modifyInstance(instance: PolicyInstance): void { - this.policySvc.getPolicy(this.policyType.policy_type_id, instance.instanceId).subscribe( + this.policySvc.getPolicy(this.policyType.name, instance.id).subscribe( (refreshedJson: any) => { - instance.instance = JSON.stringify(refreshedJson); + instance.json = JSON.stringify(refreshedJson); this.dialog.open(PolicyInstanceDialogComponent, getPolicyDialogProperties(this.policyType, instance, this.darkMode)); }, (httpError: HttpErrorResponse) => { @@ -92,13 +92,20 @@ export class PolicyInstanceComponent implements OnInit, AfterViewInit { return this.instanceDataSource.rowCount > 0; } + toLocalTime(utcTime: string): string { + const date = new Date(utcTime); + const toutc = date.toUTCString(); + return new Date(toutc + " UTC").toLocaleString(); + + } + deleteInstance(instance: PolicyInstance): void { this.confirmDialogService .openConfirmDialog('Are you sure you want to delete this policy instance?') .afterClosed().subscribe( (res: any) => { if (res) { - this.policySvc.deletePolicy(this.policyType.policy_type_id, instance.instanceId) + this.policySvc.deletePolicy(this.policyType.name, instance.id) .subscribe( (response: HttpResponse) => { switch (response.status) { diff --git a/dashboard/webapp-frontend/src/app/policy-control/policy-instance.datasource.ts b/dashboard/webapp-frontend/src/app/policy-control/policy-instance.datasource.ts index 53a6239e..b82ee753 100644 --- a/dashboard/webapp-frontend/src/app/policy-control/policy-instance.datasource.ts +++ b/dashboard/webapp-frontend/src/app/policy-control/policy-instance.datasource.ts @@ -51,7 +51,7 @@ export class PolicyInstanceDataSource extends DataSource { loadTable() { this.loadingSubject.next(true); - this.policySvc.getPolicyInstances(this.policyType.policy_type_id) + this.policySvc.getPolicyInstances(this.policyType.name) .pipe( catchError((her: HttpErrorResponse) => { this.notificationService.error('Failed to get policy instances: ' + her.message); @@ -88,7 +88,10 @@ export class PolicyInstanceDataSource extends DataSource { return data.sort((a, b) => { const isAsc = this.sort.direction === 'asc'; switch (this.sort.active) { - case 'instanceId': return compare(a.instanceId, b.instanceId, isAsc); + case 'instanceId': return compare(a.id, b.id, isAsc); + case 'ric': return compare(a.ric, b.ric, isAsc); + case 'service': return compare(a.service, b.service, isAsc); + case 'lastModified': return compare(a.lastModified, b.lastModified, isAsc) default: return 0; } }); diff --git a/dashboard/webapp-frontend/src/app/rd-routing.module.ts b/dashboard/webapp-frontend/src/app/rd-routing.module.ts index 520f9a53..57b9d57c 100644 --- a/dashboard/webapp-frontend/src/app/rd-routing.module.ts +++ b/dashboard/webapp-frontend/src/app/rd-routing.module.ts @@ -22,20 +22,20 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { Routes, RouterModule } from '@angular/router'; import { MainComponent } from './main/main.component'; -import { PolicyControlComponent} from './policy-control/policy-control.component'; +import { PolicyControlComponent } from './policy-control/policy-control.component'; const routes: Routes = [ - {path: '', component: MainComponent}, - {path: 'policy', component: PolicyControlComponent} + { path: '', component: MainComponent }, + { path: 'policy', component: PolicyControlComponent } ]; @NgModule({ - imports: [ - CommonModule, - RouterModule.forRoot(routes)], - exports: [ - RouterModule + imports: [ + CommonModule, + RouterModule.forRoot(routes)], + exports: [ + RouterModule ], declarations: [] }) diff --git a/dashboard/webapp-frontend/src/app/services/policy/policy.service.ts b/dashboard/webapp-frontend/src/app/services/policy/policy.service.ts index 1c870818..fc0f306c 100644 --- a/dashboard/webapp-frontend/src/app/services/policy/policy.service.ts +++ b/dashboard/webapp-frontend/src/app/services/policy/policy.service.ts @@ -66,7 +66,7 @@ export class PolicyService { return this.httpClient.get(url); } - getPolicyInstances(policyTypeId: number): Observable { + getPolicyInstances(policyTypeId: string): Observable { const url = this.buildPath(this.policyTypePath, policyTypeId, this.policyPath); return this.httpClient.get(url); } @@ -75,7 +75,7 @@ export class PolicyService { * Gets policy parameters. * @returns Observable that should yield a policy instance */ - getPolicy(policyTypeId: number, policyInstanceId: string): Observable { + getPolicy(policyTypeId: string, policyInstanceId: string): Observable { const url = this.buildPath(this.policyTypePath, policyTypeId, this.policyPath, policyInstanceId); return this.httpClient.get(url); } @@ -87,7 +87,7 @@ export class PolicyService { * @param policyJson Json with the policy content * @returns Observable that should yield a response code, no data */ - putPolicy(policyTypeId: number, policyInstanceId: string, policyJson: string): Observable { + putPolicy(policyTypeId: string, policyInstanceId: string, policyJson: string): Observable { const url = this.buildPath(this.policyTypePath, policyTypeId, this.policyPath, policyInstanceId); return this.httpClient.put(url, policyJson, { observe: 'response' }); } @@ -97,7 +97,7 @@ export class PolicyService { * @param policyTypeId * @returns Observable that should yield a response code, no data */ - deletePolicy(policyTypeId: number, policyInstanceId: string): Observable { + deletePolicy(policyTypeId: string, policyInstanceId: string): Observable { const url = this.buildPath(this.policyTypePath, policyTypeId, this.policyPath, policyInstanceId); return this.httpClient.delete(url, { observe: 'response' }); } diff --git a/policy-agent/config/application.yaml b/policy-agent/config/application.yaml index ee59a268..b3df5f10 100644 --- a/policy-agent/config/application.yaml +++ b/policy-agent/config/application.yaml @@ -2,7 +2,7 @@ spring: profiles: active: prod main: - allow-bean-definition-overriding: true + allow-bean-definition-overriding: true management: endpoints: web: @@ -19,3 +19,5 @@ logging: file: /var/log/ONAP/application.log app: filepath: /opt/app/policy-agent/config/application_configuration.json +server: + port : 8081 diff --git a/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyController.java b/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyController.java index 8e34aa9e..c0932a4c 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyController.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyController.java @@ -30,6 +30,7 @@ import org.oransc.policyagent.exceptions.ServiceException; import org.oransc.policyagent.repository.ImmutablePolicy; import org.oransc.policyagent.repository.Policies; import org.oransc.policyagent.repository.Policy; +import org.oransc.policyagent.repository.PolicyType; import org.oransc.policyagent.repository.PolicyTypes; import org.oransc.policyagent.repository.Ric; import org.oransc.policyagent.repository.Rics; @@ -37,6 +38,7 @@ import org.oransc.policyagent.repository.Services; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -48,7 +50,7 @@ public class PolicyController { private final ApplicationConfig appConfig; private final Rics rics; - private final PolicyTypes types; + private final PolicyTypes policyTypes; private final Policies policies; private final Services services; private static Gson gson = new GsonBuilder() // @@ -58,12 +60,19 @@ public class PolicyController { @Autowired PolicyController(ApplicationConfig config, PolicyTypes types, Policies policies, Rics rics, Services services) { this.appConfig = config; - this.types = types; + this.policyTypes = types; this.policies = policies; this.rics = rics; this.services = services; } + @GetMapping("/policy_types") + public ResponseEntity getPolicyTypes() { + + Collection types = this.policyTypes.getAll(); + return new ResponseEntity(policyTypesToJson(types), HttpStatus.OK); + } + @GetMapping("/policy") public ResponseEntity getPolicy( // @RequestParam(name = "instance", required = true) String instance) { @@ -75,6 +84,14 @@ public class PolicyController { } } + @DeleteMapping("/policy") + public ResponseEntity deletePolicy( // + @RequestParam(name = "instance", required = true) String instance) { + + Policy p = policies.removeId(instance); + return new ResponseEntity("OK", HttpStatus.OK); + } + @GetMapping("/policies") public ResponseEntity getPolicies( // @RequestParam(name = "type", required = false) String type, // @@ -96,7 +113,7 @@ public class PolicyController { result = policies.getAll(); } - return new ResponseEntity(toJson(result), HttpStatus.OK); + return new ResponseEntity(policiesToJson(result), HttpStatus.OK); } private boolean include(String filter, String value) { @@ -117,19 +134,38 @@ public class PolicyController { return filtered; } - private String toJson(Collection policies) { + private String policiesToJson(Collection policies) { Vector v = new Vector<>(policies.size()); for (Policy p : policies) { PolicyInfo policyInfo = ImmutablePolicyInfo.builder() // .json(p.json()) // - .name(p.id()) // + .id(p.id()) // .ric(p.ric().name()) // - .type(p.type().name()).build(); + .type(p.type().name()) // + .service(p.ownerServiceName()) // + .lastModified(p.lastModified()) // + .build(); v.add(policyInfo); } return gson.toJson(v); } + private String policyTypesToJson(Collection types) { + Vector v = new Vector<>(types.size()); + for (PolicyType t : types) { + PolicyTypeInfo policyInfo = ImmutablePolicyTypeInfo.builder() // + .schema(t.jsonSchema()) // + .name(t.name()) // + .build(); + v.add(policyInfo); + } + return gson.toJson(v); + } + + private String getTimeStampUTC() { + return java.time.Instant.now().toString(); + } + @PutMapping(path = "/policy") public ResponseEntity putPolicy( // @RequestParam(name = "type", required = true) String type, // @@ -139,14 +175,15 @@ public class PolicyController { @RequestBody String jsonBody) { try { - services.getService(service).ping(); + // services.getService(service).ping(); Ric ricObj = rics.getRic(ric); Policy policy = ImmutablePolicy.builder() // .id(instanceId) // .json(jsonBody) // - .type(types.getType(type)) // + .type(policyTypes.getType(type)) // .ric(ricObj) // .ownerServiceName(service) // + .lastModified(getTimeStampUTC()) // .build(); policies.put(policy); return new ResponseEntity(HttpStatus.OK); diff --git a/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyInfo.java b/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyInfo.java index f1268942..eb54ba93 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyInfo.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyInfo.java @@ -19,7 +19,6 @@ */ package org.oransc.policyagent.controllers; -import com.google.gson.annotations.SerializedName; import org.immutables.gson.Gson; import org.immutables.value.Value; @@ -28,15 +27,16 @@ import org.immutables.value.Value; @Gson.TypeAdapters interface PolicyInfo { - @SerializedName("id") - public String name(); + public String id(); - @SerializedName("type") public String type(); - @SerializedName("ric") public String ric(); - @SerializedName("json") public String json(); + + public String service(); + + public String lastModified(); + } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyTypeInfo.java b/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyTypeInfo.java new file mode 100644 index 00000000..efd749a4 --- /dev/null +++ b/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyTypeInfo.java @@ -0,0 +1,33 @@ +/*- + * ========================LICENSE_START================================= + * O-RAN-SC + * %% + * Copyright (C) 2019 Nordix Foundation + * %% + * 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.policyagent.controllers; + + +import org.immutables.gson.Gson; +import org.immutables.value.Value; + +@Value.Immutable +@Gson.TypeAdapters +public interface PolicyTypeInfo { + + public String name(); + + public String schema(); +} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/controllers/RicInfo.java b/policy-agent/src/main/java/org/oransc/policyagent/controllers/RicInfo.java index 04e2cc56..11391514 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/controllers/RicInfo.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/controllers/RicInfo.java @@ -19,7 +19,6 @@ */ package org.oransc.policyagent.controllers; -import com.google.gson.annotations.SerializedName; import java.util.Vector; @@ -30,9 +29,7 @@ import org.immutables.value.Value; @Gson.TypeAdapters interface RicInfo { - @SerializedName("name") public String name(); - @SerializedName("nodeNames") - public Vector managedElementIds(); + public Vector nodeNames(); } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/controllers/RicRepositoryController.java b/policy-agent/src/main/java/org/oransc/policyagent/controllers/RicRepositoryController.java index 5980fa40..960532a0 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/controllers/RicRepositoryController.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/controllers/RicRepositoryController.java @@ -95,7 +95,7 @@ public class RicRepositoryController { for (Ric ric : rics.getRics()) { result.add(ImmutableRicInfo.builder() // .name(ric.name()) // - .managedElementIds(ric.getManagedNodes()) // + .nodeNames(ric.getManagedNodes()) // .build()); } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceRegistrationInfo.java b/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceRegistrationInfo.java index ede35dea..fe920a92 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceRegistrationInfo.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceRegistrationInfo.java @@ -19,7 +19,6 @@ */ package org.oransc.policyagent.controllers; -import com.google.gson.annotations.SerializedName; import org.immutables.gson.Gson; import org.immutables.value.Value; @@ -28,10 +27,8 @@ import org.immutables.value.Value; @Gson.TypeAdapters public interface ServiceRegistrationInfo { - @SerializedName("name") public String name(); - @SerializedName("keepAlive") public long keepAliveInterval(); } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/repository/Policies.java b/policy-agent/src/main/java/org/oransc/policyagent/repository/Policies.java index cddd8a37..daaa193c 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/repository/Policies.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/repository/Policies.java @@ -100,7 +100,7 @@ public class Policies { public synchronized Policy removeId(String id) { Policy p = policiesId.get(id); - if (p == null) { + if (p != null) { remove(p); } return p; @@ -111,7 +111,16 @@ public class Policies { multiMapRemove(policiesRic, policy.ric().name(), policy); multiMapRemove(policiesService, policy.ownerServiceName(), policy); multiMapRemove(policiesType, policy.type().name(), policy); + } + public synchronized int size() { + return policiesId.size(); + } + + public void clear() { + for (String id : policiesId.keySet()) { + removeId(id); + } } } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/repository/Policy.java b/policy-agent/src/main/java/org/oransc/policyagent/repository/Policy.java index 0f7105a7..038e484e 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/repository/Policy.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/repository/Policy.java @@ -34,4 +34,6 @@ public interface Policy { public Ric ric(); public PolicyType type(); + + public String lastModified(); } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/repository/PolicyTypes.java b/policy-agent/src/main/java/org/oransc/policyagent/repository/PolicyTypes.java index f686ee4c..63450cb3 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/repository/PolicyTypes.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/repository/PolicyTypes.java @@ -20,6 +20,7 @@ package org.oransc.policyagent.repository; +import java.util.Collection; import java.util.HashMap; import java.util.Map; @@ -47,7 +48,15 @@ public class PolicyTypes { return types.containsKey(policyType.name()); } + public synchronized Collection getAll() { + return types.values(); + } + public int size() { return types.size(); } + + public void clear() { + this.types.clear(); + } } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/repository/Ric.java b/policy-agent/src/main/java/org/oransc/policyagent/repository/Ric.java index 7580bf8e..3caadaed 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/repository/Ric.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/repository/Ric.java @@ -23,6 +23,7 @@ package org.oransc.policyagent.repository; import java.util.Collections; import java.util.List; import java.util.Vector; + import org.oransc.policyagent.configuration.RicConfig; import org.oransc.policyagent.repository.Ric.RicState; @@ -139,7 +140,7 @@ public class Ric { * * @param type the type to check if it is supported. * - * @return true if the given type issupported by this Ric, false otherwise. + * @return true if the given type issupported by this Ric, false otherwise. */ public boolean isSupportingType(PolicyType type) { return supportedPolicyTypes.contains(type); diff --git a/policy-agent/src/main/java/org/oransc/policyagent/repository/Rics.java b/policy-agent/src/main/java/org/oransc/policyagent/repository/Rics.java index 5c286bc8..9ea6db64 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/repository/Rics.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/repository/Rics.java @@ -45,4 +45,8 @@ public class Rics { public int size() { return rics.size(); } + + public void clear() { + this.rics.clear(); + } } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/tasks/ServiceSupervision.java b/policy-agent/src/main/java/org/oransc/policyagent/tasks/ServiceSupervision.java index 03479dde..acb546bc 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/tasks/ServiceSupervision.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/tasks/ServiceSupervision.java @@ -68,16 +68,11 @@ public class ServiceSupervision { .filter(service -> service.isExpired()) // .doOnNext(service -> logger.info("Service is expired:" + service.getName())) .flatMap(service -> getAllPolicies(service)) // - .flatMap(policy -> deletePolicy(policy)); + .doOnNext(policy -> this.policies.remove(policy)); } Flux getAllPolicies(Service service) { return Flux.fromIterable(policies.getForService(service.getName())); } - Flux deletePolicy(Policy policy) { - this.policies.remove(policy); - return Flux.just(policy); - } - } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/tasks/StartupService.java b/policy-agent/src/main/java/org/oransc/policyagent/tasks/StartupService.java index a6accbbf..1fa0aa81 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/tasks/StartupService.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/tasks/StartupService.java @@ -21,6 +21,7 @@ package org.oransc.policyagent.tasks; import java.util.Vector; + import org.oransc.policyagent.clients.RicClient; import org.oransc.policyagent.configuration.ApplicationConfig; import org.oransc.policyagent.configuration.RicConfig; diff --git a/policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java b/policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java index 3b98ef56..df26ba4f 100644 --- a/policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java +++ b/policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java @@ -24,14 +24,21 @@ import static org.junit.Assert.assertFalse; import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; import java.net.URL; +import java.util.List; +import java.util.Vector; import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; import org.junit.runner.RunWith; import org.oransc.policyagent.configuration.ApplicationConfig; +import org.oransc.policyagent.configuration.ImmutableRicConfig; +import org.oransc.policyagent.configuration.RicConfig; import org.oransc.policyagent.controllers.ImmutableServiceRegistrationInfo; import org.oransc.policyagent.controllers.ImmutableServiceStatus; +import org.oransc.policyagent.controllers.PolicyTypeInfo; import org.oransc.policyagent.controllers.ServiceRegistrationInfo; import org.oransc.policyagent.controllers.ServiceStatus; import org.oransc.policyagent.exceptions.ServiceException; @@ -41,6 +48,7 @@ import org.oransc.policyagent.repository.Policies; import org.oransc.policyagent.repository.Policy; import org.oransc.policyagent.repository.PolicyType; import org.oransc.policyagent.repository.PolicyTypes; +import org.oransc.policyagent.repository.Ric; import org.oransc.policyagent.repository.Rics; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -70,7 +78,7 @@ public class ApplicationTest { .serializeNulls() // .create(); // - static class MockApplicationConfig extends ApplicationConfig { + public static class MockApplicationConfig extends ApplicationConfig { @Override public void initialize() { URL url = MockApplicationConfig.class.getClassLoader().getResource("test_application_configuration.json"); @@ -82,29 +90,36 @@ public class ApplicationTest { * overrides the BeanFactory */ @TestConfiguration - static class BeanFactory { + static class TestBeanFactory { @Bean public ApplicationConfig getApplicationConfig() { return new MockApplicationConfig(); } - } @LocalServerPort private int port; - private RestTemplate restTemplate = new RestTemplate(); + private final RestTemplate restTemplate = new RestTemplate(); + + @BeforeEach + public void reset() { + rics.clear(); + policies.clear(); + policyTypes.clear(); + assertThat(policies.size()).isEqualTo(0); + } @Test - public void getRics() throws Exception { + public void testGetRics() throws Exception { String url = baseUrl() + "/rics"; String rsp = this.restTemplate.getForObject(url, String.class); assertThat(rsp).contains("kista_1"); } @Test - public void getRic() throws Exception { + public void testGetRic() throws Exception { String url = baseUrl() + "/ric?managedElementId=kista_1"; String rsp = this.restTemplate.getForObject(url, String.class); assertThat(rsp).isEqualTo("ric1"); @@ -113,7 +128,7 @@ public class ApplicationTest { // managedElmentId -> nodeName @Test - public void putPolicy() throws Exception { + public void testPutPolicy() throws Exception { putService("service1"); String url = baseUrl() + "/policy?type=type1&instance=instance1&ric=ric1&service=service1"; @@ -127,6 +142,10 @@ public class ApplicationTest { assertThat(policy).isNotNull(); assertThat(policy.id()).isEqualTo("instance1"); assertThat(policy.ownerServiceName()).isEqualTo("service1"); + + url = baseUrl() + "/policies"; + String rsp = this.restTemplate.getForObject(url, String.class); + System.out.println(rsp); } private PolicyType addPolicyType(String name) { @@ -139,25 +158,38 @@ public class ApplicationTest { return type; } - private Policy addPolicy(String id, String typeName, String service) throws ServiceException { + private Ric addRic(String name) { + Vector mes = new Vector<>(); + RicConfig conf = ImmutableRicConfig.builder().name(name).baseUrl("baseUrl").managedElementIds(mes).build(); + Ric ric = new Ric(conf); + this.rics.put(ric); + return ric; + } + + private Policy addPolicy(String id, String typeName, String service, String ric) throws ServiceException { + addRic(ric); Policy p = ImmutablePolicy.builder().id(id) // .json("{}") // .ownerServiceName(service) // - .ric(rics.getRic("ric1")) // + .ric(rics.getRic(ric)) // .type(addPolicyType(typeName)) // - .build(); + .lastModified("lastModified").build(); policies.put(p); return p; } + private Policy addPolicy(String id, String typeName, String service) throws ServiceException { + return addPolicy(id, typeName, service, "ric"); + } + private String baseUrl() { return "http://localhost:" + port; } @Test - public void getPolicy() throws Exception { + public void testGetPolicy() throws Exception { String url = baseUrl() + "/policy?instance=id"; - Policy policy = addPolicy("id", "typeName", "service1"); + Policy policy = addPolicy("id", "typeName", "service1", "ric1"); { String rsp = this.restTemplate.getForObject(url, String.class); assertThat(rsp).isEqualTo(policy.json()); @@ -170,7 +202,43 @@ public class ApplicationTest { } @Test - public void getPolicies() throws Exception { + public void testDeletePolicy() throws Exception { + reset(); + String url = baseUrl() + "/policy?instance=id"; + addPolicy("id", "typeName", "service1", "ric1"); + assertThat(policies.size()).isEqualTo(1); + + this.restTemplate.delete(url); + + assertThat(policies.size()).isEqualTo(0); + } + + public static List parseList(String json, Class clazz) { + if (null == json) { + return null; + } + return gson.fromJson(json, new TypeToken() {}.getType()); + } + + @Test + public void testGetPolicyTypes() throws Exception { + String url = baseUrl() + "/policy_types"; + reset(); + addPolicy("id1", "type1", "service1"); + addPolicy("id2", "type2", "service2"); + + String rsp = this.restTemplate.getForObject(url, String.class); + System.out.println(rsp); + assertThat(rsp).contains("type1"); + assertThat(rsp).contains("type2"); + + List info = parseList(rsp, PolicyTypeInfo.class); + System.out.println(info.size()); + + } + + @Test + public void testGetPolicies() throws Exception { String url = baseUrl() + "/policies"; addPolicy("id1", "type1", "service1"); addPolicy("id2", "type2", "service2"); @@ -182,7 +250,7 @@ public class ApplicationTest { } @Test - public void getPoliciesFilter() throws Exception { + public void testGetPoliciesFilter() throws Exception { addPolicy("id1", "type1", "service1"); addPolicy("id2", "type1", "service2"); addPolicy("id3", "type2", "service1"); @@ -202,19 +270,22 @@ public class ApplicationTest { assertFalse(rsp.contains("id3")); } - private void putService(String name) { - String url = baseUrl() + "/service"; - + private String createServiceJson(String name) { ServiceRegistrationInfo service = ImmutableServiceRegistrationInfo.builder() // .keepAliveInterval(1) // .name(name) // .build(); String json = gson.toJson(service); - this.restTemplate.put(url, json); + return json; + } + + private void putService(String name) { + String url = baseUrl() + "/service"; + this.restTemplate.put(url, createServiceJson(name)); } @Test - public void putAndGetService() throws Exception { + public void testPutAndGetService() throws Exception { putService("name"); String url = baseUrl() + "/service?name=name"; diff --git a/policy-agent/src/test/java/org/oransc/policyagent/MockPolicyAgent.java b/policy-agent/src/test/java/org/oransc/policyagent/MockPolicyAgent.java new file mode 100644 index 00000000..d02522c5 --- /dev/null +++ b/policy-agent/src/test/java/org/oransc/policyagent/MockPolicyAgent.java @@ -0,0 +1,130 @@ +/*- + * ========================LICENSE_START================================= + * O-RAN-SC + * %% + * Copyright (C) 2019 Nordix Foundation + * %% + * 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.policyagent; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.nio.file.Files; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.oransc.policyagent.configuration.ApplicationConfig; +import org.oransc.policyagent.repository.ImmutablePolicyType; +import org.oransc.policyagent.repository.Policies; +import org.oransc.policyagent.repository.PolicyType; +import org.oransc.policyagent.repository.PolicyTypes; +import org.oransc.policyagent.repository.Rics; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.context.annotation.Bean; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT) +public class MockPolicyAgent { + + @Autowired + private Rics rics; + + @Autowired + private Policies policies; + + @Autowired + private PolicyTypes policyTypes; + + static class MockApplicationConfig extends ApplicationConfig { + @Override + public void initialize() { + URL url = MockApplicationConfig.class.getClassLoader().getResource("test_application_configuration.json"); + loadConfigurationFromFile(url.getFile()); + } + } + + /** + * overrides the BeanFactory + */ + @TestConfiguration + static class TestBeanFactory { + + @Bean + public ApplicationConfig getApplicationConfig() { + return new MockApplicationConfig(); + } + } + + @LocalServerPort + private int port; + + public void keepServerAlive() { + System.out.println("Keeping server alive!"); + try { + synchronized (this) { + this.wait(); + } + } catch (Exception ex) { + System.out.println("Unexpected: " + ex.toString()); + } + } + + private static File[] getResourceFolderFiles(String folder) { + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + URL url = loader.getResource(folder); + String path = url.getPath(); + return new File(path).listFiles(); + } + + private static String readFile(File file) throws IOException { + return new String(Files.readAllBytes(file.toPath())); + } + + private static String title(String jsonSchema) { + JsonObject parsedSchema = (JsonObject) new JsonParser().parse(jsonSchema); + String title = parsedSchema.get("title").getAsString(); + return title; + } + + private static void loadTypes(PolicyTypes policyTypes) { + File[] files = getResourceFolderFiles("policy_types/"); + for (File file : files) { + try { + String schema = readFile(file); + String typeName = title(schema); + PolicyType type = ImmutablePolicyType.builder().name(typeName).jsonSchema(schema).build(); + policyTypes.put(type); + } catch (Exception e) { + System.out.println("Could not load json schema " + e); + } + } + } + + @Test + public void runMock() throws Exception { + loadTypes(this.policyTypes); + keepServerAlive(); + } + +} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigTest.java b/policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigTest.java index 830a821c..34ebdf99 100644 --- a/policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigTest.java +++ b/policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigTest.java @@ -31,12 +31,14 @@ import static org.mockito.Mockito.verify; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.read.ListAppender; + import com.google.common.base.Charsets; import com.google.common.io.Resources; import com.google.gson.JsonIOException; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonSyntaxException; + import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; @@ -46,6 +48,7 @@ import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Properties; import java.util.Vector; + import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.CbsClient; @@ -53,6 +56,7 @@ import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.EnvProperti import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.ImmutableEnvProperties; import org.oransc.policyagent.exceptions.ServiceException; import org.oransc.policyagent.utils.LoggingUtils; + import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; diff --git a/policy-agent/src/test/java/org/oransc/policyagent/tasks/StartupServiceTest.java b/policy-agent/src/test/java/org/oransc/policyagent/tasks/StartupServiceTest.java index d08077f1..4dcceb6c 100644 --- a/policy-agent/src/test/java/org/oransc/policyagent/tasks/StartupServiceTest.java +++ b/policy-agent/src/test/java/org/oransc/policyagent/tasks/StartupServiceTest.java @@ -30,6 +30,7 @@ import static org.mockito.Mockito.when; import static org.oransc.policyagent.repository.Ric.RicState.ACTIVE; import java.util.Vector; + import org.junit.jupiter.api.Test; import org.oransc.policyagent.clients.RicClient; import org.oransc.policyagent.configuration.ApplicationConfig;