From: PatrikBuhr Date: Wed, 11 Nov 2020 12:14:57 +0000 (+0100) Subject: Adding ONAP PMS as a submodule. X-Git-Tag: 2.1.0~13 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=13c62d122c38b98cbdc76a4a775c6f6187e40e39;p=nonrtric.git Adding ONAP PMS as a submodule. Removing the policy agent source. Instead the same SW from ONAP is used. Change-Id: I798cb17d5550bf76b38c0fec51754c56825eb79e Signed-off-by: PatrikBuhr Issue-ID: NONRTRIC-173 --- diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..50564194 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "onap/oran"] + path = onap/oran + url = https://gerrit.onap.org/r/ccsdk/oran diff --git a/docs/api-docs.rst b/docs/api-docs.rst index 9b0608a6..94169403 100644 --- a/docs/api-docs.rst +++ b/docs/api-docs.rst @@ -34,7 +34,7 @@ See the README.md file in the nonrtric/policy-agent repo for info about how to u API Functions ------------- -See the following document for the Policy Agent API: nonrtric/policy-agent/docs/api.yaml +See the following document for the Policy Agent API: nonrtric/onap/oran/docs/offeredapis/swagger/pms-api.yaml SDNC A1 Controller ================== diff --git a/docs/developer-guide.rst b/docs/developer-guide.rst index b5fedc38..9aac33c2 100644 --- a/docs/developer-guide.rst +++ b/docs/developer-guide.rst @@ -90,7 +90,7 @@ The O-RAN Non-RT RIC Policy Agent provides a REST API for management of policice * Maps O1 resources (ManagedElement) as defined in O1 to the controlling RIC. | The Policy Agent can be accessed over the REST API or through the DMaaP Interface. The REST API is documented in the -| *nonrtric/policy-agent/docs/api.yaml* file. Please refer to the README file of Policy Agent to know more about the API's. +| *nonrtric/onap/oran/docs/offeredapis/swagger/pms-api.yaml* file. Please refer to the README file of Policy Agent to know more about the API's. Configuration of certs ---------------------- diff --git a/docs/offeredapis/swagger/pms-api.json b/docs/offeredapis/swagger/pms-api.json new file mode 120000 index 00000000..18346f59 --- /dev/null +++ b/docs/offeredapis/swagger/pms-api.json @@ -0,0 +1 @@ +../../../onap/oran/docs/offeredapis/swagger/pms-api.json \ No newline at end of file diff --git a/docs/sdnc-a1-controller-api.rst b/docs/sdnc-a1-controller-api.rst index dd855491..5e0e908b 100644 --- a/docs/sdnc-a1-controller-api.rst +++ b/docs/sdnc-a1-controller-api.rst @@ -2,14 +2,15 @@ .. http://creativecommons.org/licenses/by/4.0 .. Copyright (C) 2020 Nordix -.. _sdnc-a1-controller-api: - .. |nbsp| unicode:: 0xA0 :trim: .. |nbh| unicode:: 0x2011 :trim: +.. _sdnc-a1-controller-api: + + ###################### SDNC A1 Controller API ###################### diff --git a/onap/oran b/onap/oran new file mode 160000 index 00000000..e78c27ef --- /dev/null +++ b/onap/oran @@ -0,0 +1 @@ +Subproject commit e78c27efa1b2bbd9db762211e907777f49aba7d2 diff --git a/policy-agent/.gitignore b/policy-agent/.gitignore index a02ed34e..602050b4 100644 --- a/policy-agent/.gitignore +++ b/policy-agent/.gitignore @@ -5,3 +5,4 @@ target .checkstyle policy-agent.iml +config diff --git a/policy-agent/Dockerfile b/policy-agent/Dockerfile index 7c722e16..f64eebb6 100644 --- a/policy-agent/Dockerfile +++ b/policy-agent/Dockerfile @@ -21,23 +21,22 @@ FROM openjdk:11-jre-slim ARG JAR +EXPOSE 8081 8433 + + WORKDIR /opt/app/policy-agent RUN mkdir -p /var/log/policy-agent RUN mkdir -p /opt/app/policy-agent/etc/cert/ - EXPOSE 8081 8433 ADD /config/application.yaml /opt/app/policy-agent/config/application.yaml ADD /config/application_configuration.json /opt/app/policy-agent/data/application_configuration.json_example -ADD target/${JAR} /opt/app/policy-agent/policy-agent.jar ADD /config/keystore.jks /opt/app/policy-agent/etc/cert/keystore.jks ADD /config/truststore.jks /opt/app/policy-agent/etc/cert/truststore.jks - RUN chmod -R 777 /opt/app/policy-agent/config/ +RUN chmod -R 777 /opt/app/policy-agent/data/ +ADD target/${JAR} /opt/app/policy-agent/policy-agent.jar CMD ["java", "-jar", "/opt/app/policy-agent/policy-agent.jar"] - - - diff --git a/policy-agent/config/README b/policy-agent/config/README deleted file mode 100644 index 6e50749a..00000000 --- a/policy-agent/config/README +++ /dev/null @@ -1,41 +0,0 @@ -The keystore.jks and truststore.jks files are created by using the following commands (note that this is an example): - -1) Create a CA certificate and a private key: - -openssl genrsa -des3 -out CA-key.pem 2048 -openssl req -new -key CA-key.pem -x509 -days 1000 -out CA-cert.pem - -2) Create a keystore with a private key entry that is signed by the CA: - -keytool -genkeypair -alias policy_agent -keyalg RSA -keysize 2048 -keystore keystore.jks -validity 3650 -storepass policy_agent -keytool -certreq -alias policy_agent -file request.csr -keystore keystore.jks -ext san=dns:your.domain.com -storepass policy_agent -openssl x509 -req -days 365 -in request.csr -CA CA-cert.pem -CAkey CA-key.pem -CAcreateserial -out ca_signed-cert.pem -keytool -importcert -alias ca_cert -file CA-cert.pem -keystore keystore.jks -trustcacerts -storepass policy_agent -keytool -importcert -alias policy_agent -file ca_signed-cert.pem -keystore keystore.jks -trustcacerts -storepass policy_agent - - -3) Create a trust store containing the CA cert (to trust all certs signed by the CA): - -keytool -genkeypair -alias not_used -keyalg RSA -keysize 2048 -keystore truststore.jks -validity 3650 -storepass policy_agent -keytool -importcert -alias ca_cert -file CA-cert.pem -keystore truststore.jks -trustcacerts -storepass policy_agent - - -4) Command for listing of the contents of jks files, examples: -keytool -list -v -keystore keystore.jks -storepass policy_agent -keytool -list -v -keystore truststore.jks -storepass policy_agent - -## License - -Copyright (C) 2020 Nordix Foundation. All rights reserved. -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/policy-agent/config/application.yaml b/policy-agent/config/application.yaml deleted file mode 100644 index 4f5e2427..00000000 --- a/policy-agent/config/application.yaml +++ /dev/null @@ -1,38 +0,0 @@ -spring: - profiles: - active: prod - main: - allow-bean-definition-overriding: true - aop: - auto: false -management: - endpoints: - web: - exposure: - include: "loggers,logfile,health,info,metrics,threaddump,heapdump" - -logging: - level: - ROOT: ERROR - org.springframework: ERROR - org.springframework.data: ERROR - org.springframework.web.reactive.function.client.ExchangeFunctions: ERROR - org.oransc.policyagent: INFO - file: - name: /var/log/policy-agent/application.log -server: - port : 8433 - http-port: 8081 - ssl: - key-store-type: JKS - key-store-password: policy_agent - key-store: /opt/app/policy-agent/etc/cert/keystore.jks - key-password: policy_agent - key-alias: policy_agent -app: - filepath: /opt/app/policy-agent/data/application_configuration.json - webclient: - trust-store-used: false - trust-store-password: policy_agent - trust-store: /opt/app/policy-agent/etc/cert/truststore.jks - diff --git a/policy-agent/config/application_configuration.json b/policy-agent/config/application_configuration.json deleted file mode 100644 index 6c21b166..00000000 --- a/policy-agent/config/application_configuration.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "config": { - "//description": "Application configuration", - "controller": [ - { - "name": "controller1", - "baseUrl": "http://a1controller:8282", - "userName": "admin", - "password": "Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U" - } - ], - "ric": [ - { - "name": "ric1", - "baseUrl": "http://ric1:8085/", - "controller": "controller1", - "managedElementIds": [ - "kista_1", - "kista_2" - ] - } - ] - } -} \ No newline at end of file diff --git a/policy-agent/config/keystore.jks b/policy-agent/config/keystore.jks deleted file mode 100644 index 122997ac..00000000 Binary files a/policy-agent/config/keystore.jks and /dev/null differ diff --git a/policy-agent/config/truststore.jks b/policy-agent/config/truststore.jks deleted file mode 100644 index 60d62889..00000000 Binary files a/policy-agent/config/truststore.jks and /dev/null differ diff --git a/policy-agent/docs/api.yaml b/policy-agent/docs/api.yaml deleted file mode 100644 index ec9bbce4..00000000 --- a/policy-agent/docs/api.yaml +++ /dev/null @@ -1,650 +0,0 @@ -swagger: '2.0' -info: - description: This page lists all the rest apis for the service. - version: '1.0' - title: A1 Policy management service -host: 'localhost:8081' -basePath: / -tags: - - name: A1 Policy Management - description: Policy Controller - - name: Health check - description: Status Controller - - name: RIC Repository - description: Ric Repository Controller - - name: Service registry and supervision - description: Service Controller -paths: - /policies: - get: - tags: - - A1 Policy Management - summary: Query policies - operationId: getPoliciesUsingGET - produces: - - '*/*' - parameters: - - name: ric - in: query - description: The name of the Near-RT RIC to get policies for. - required: false - type: string - allowEmptyValue: false - - name: service - in: query - description: The name of the service to get policies for. - required: false - type: string - allowEmptyValue: false - - name: type - in: query - description: The name of the policy type to get policies for. - required: false - type: string - allowEmptyValue: false - responses: - '200': - description: Policies - schema: - type: array - items: - $ref: '#/definitions/PolicyInfo' - '401': - description: Unauthorized - '403': - description: Forbidden - '404': - description: RIC or type not found - schema: - type: string - deprecated: false - /policy: - get: - tags: - - A1 Policy Management - summary: Returns a policy configuration - operationId: getPolicyUsingGET - produces: - - '*/*' - parameters: - - name: id - in: query - description: The ID of the policy instance. - required: true - type: string - allowEmptyValue: false - responses: - '200': - description: Policy found - schema: - type: object - '401': - description: Unauthorized - '403': - description: Forbidden - '404': - description: Policy is not found - deprecated: false - put: - tags: - - A1 Policy Management - summary: Put a policy - operationId: putPolicyUsingPUT - consumes: - - application/json - produces: - - '*/*' - parameters: - - name: id - in: query - description: The ID of the policy instance. - required: true - type: string - allowEmptyValue: false - - in: body - name: jsonBody - description: jsonBody - required: true - schema: - type: object - - name: ric - in: query - description: The name of the Near-RT RIC where the policy will be created. - required: true - type: string - allowEmptyValue: false - - name: service - in: query - description: The name of the service creating the policy. - required: true - type: string - allowEmptyValue: false - - name: transient - in: query - description: If the policy is transient or not (boolean defaulted to false). A policy is transient if it will be forgotten when the service needs to reconnect to the Near-RT RIC. - required: false - type: boolean - default: false - allowEmptyValue: false - x-example: false - - name: type - in: query - description: The name of the policy type. - required: false - type: string - allowEmptyValue: false - responses: - '200': - description: Policy updated - schema: - type: object - '201': - description: Policy created - schema: - type: object - '401': - description: Unauthorized - '403': - description: Forbidden - '404': - description: RIC or policy type is not found - schema: - type: string - '423': - description: RIC is not operational - schema: - type: string - deprecated: false - delete: - tags: - - A1 Policy Management - summary: Delete a policy - operationId: deletePolicyUsingDELETE - produces: - - '*/*' - parameters: - - name: id - in: query - description: The ID of the policy instance. - required: true - type: string - allowEmptyValue: false - responses: - '200': - description: OK - schema: - type: object - '204': - description: Policy deleted - schema: - type: object - '401': - description: Unauthorized - '403': - description: Forbidden - '404': - description: Policy is not found - schema: - type: string - '423': - description: RIC is not operational - schema: - type: string - deprecated: false - /policy_ids: - get: - tags: - - A1 Policy Management - summary: 'Query policies, only IDs returned' - operationId: getPolicyIdsUsingGET - produces: - - '*/*' - parameters: - - name: ric - in: query - description: The name of the Near-RT RIC to get policies for. - required: false - type: string - allowEmptyValue: false - - name: service - in: query - description: The name of the service to get policies for. - required: false - type: string - allowEmptyValue: false - - name: type - in: query - description: The name of the policy type to get policies for. - required: false - type: string - allowEmptyValue: false - responses: - '200': - description: Policy ids - schema: - type: array - items: - type: string - '401': - description: Unauthorized - '403': - description: Forbidden - '404': - description: RIC or type not found - schema: - type: string - deprecated: false - /policy_schema: - get: - tags: - - A1 Policy Management - summary: Returns one policy type schema definition - operationId: getPolicySchemaUsingGET - produces: - - '*/*' - parameters: - - name: id - in: query - description: The ID of the policy type to get the definition for. - required: true - type: string - allowEmptyValue: false - responses: - '200': - description: Policy schema - schema: - type: object - '401': - description: Unauthorized - '403': - description: Forbidden - '404': - description: RIC is not found - schema: - type: string - deprecated: false - /policy_schemas: - get: - tags: - - A1 Policy Management - summary: Returns policy type schema definitions - operationId: getPolicySchemasUsingGET - produces: - - '*/*' - parameters: - - name: ric - in: query - description: The name of the Near-RT RIC to get the definitions for. - required: false - type: string - allowEmptyValue: false - responses: - '200': - description: Policy schemas - schema: - type: array - items: - type: object - '401': - description: Unauthorized - '403': - description: Forbidden - '404': - description: RIC is not found - schema: - type: string - deprecated: false - /policy_status: - get: - tags: - - A1 Policy Management - summary: Returns a policy status - operationId: getPolicyStatusUsingGET - produces: - - '*/*' - parameters: - - name: id - in: query - description: The ID of the policy. - required: true - type: string - allowEmptyValue: false - responses: - '200': - description: Policy status - schema: - type: object - '401': - description: Unauthorized - '403': - description: Forbidden - '404': - description: Policy is not found - schema: - type: string - deprecated: false - /policy_types: - get: - tags: - - A1 Policy Management - summary: Query policy type names - operationId: getPolicyTypesUsingGET - produces: - - '*/*' - parameters: - - name: ric - in: query - description: The name of the Near-RT RIC to get types for. - required: false - type: string - allowEmptyValue: false - responses: - '200': - description: Policy type names - schema: - type: array - items: - type: string - '401': - description: Unauthorized - '403': - description: Forbidden - '404': - description: RIC is not found - schema: - type: string - deprecated: false - /ric: - get: - tags: - - RIC Repository - summary: Returns the name of a RIC managing one Mananged Element - operationId: getRicUsingGET - produces: - - '*/*' - parameters: - - name: managedElementId - in: query - description: The ID of the Managed Element - required: true - type: string - allowEmptyValue: false - responses: - '200': - description: RIC is found - schema: - type: string - '401': - description: Unauthorized - '403': - description: Forbidden - '404': - description: RIC is not found - schema: - type: string - deprecated: false - /rics: - get: - tags: - - RIC Repository - summary: Query Near-RT RIC information - operationId: getRicsUsingGET - produces: - - '*/*' - parameters: - - name: policyType - in: query - description: The name of the policy type - required: false - type: string - allowEmptyValue: false - responses: - '200': - description: OK - schema: - type: array - items: - $ref: '#/definitions/RicInfo' - '401': - description: Unauthorized - '403': - description: Forbidden - '404': - description: Policy type is not found - schema: - type: string - deprecated: false - /service: - put: - tags: - - Service registry and supervision - summary: Register a service - operationId: putServiceUsingPUT - consumes: - - application/json - produces: - - '*/*' - parameters: - - in: body - name: registrationInfo - description: registrationInfo - required: true - schema: - $ref: '#/definitions/ServiceRegistrationInfo' - responses: - '200': - description: Service updated - schema: - type: string - '201': - description: Service created - schema: - type: string - '400': - description: The ServiceRegistrationInfo is not accepted - schema: - type: string - '401': - description: Unauthorized - '403': - description: Forbidden - '404': - description: Not Found - deprecated: false - /services: - get: - tags: - - Service registry and supervision - summary: Returns service information - operationId: getServicesUsingGET - produces: - - '*/*' - parameters: - - name: name - in: query - description: The name of the service - required: false - type: string - allowEmptyValue: false - responses: - '200': - description: OK - schema: - type: array - items: - $ref: '#/definitions/ServiceStatus' - '401': - description: Unauthorized - '403': - description: Forbidden - '404': - description: Service is not found - schema: - type: string - deprecated: false - delete: - tags: - - Service registry and supervision - summary: Delete a service - operationId: deleteServiceUsingDELETE - produces: - - '*/*' - parameters: - - name: name - in: query - description: The name of the service - required: true - type: string - allowEmptyValue: false - responses: - '200': - description: OK - schema: - type: string - '204': - description: OK - schema: - type: string - '401': - description: Unauthorized - '403': - description: Forbidden - '404': - description: Service not found - schema: - type: string - deprecated: false - /services/keepalive: - put: - tags: - - Service registry and supervision - summary: Heartbeat from a serice - operationId: keepAliveServiceUsingPUT - consumes: - - application/json - produces: - - '*/*' - parameters: - - name: name - in: query - description: The name of the service - required: true - type: string - allowEmptyValue: false - responses: - '200': - description: 'Service supervision timer refreshed, OK' - schema: - type: string - '201': - description: Created - '401': - description: Unauthorized - '403': - description: Forbidden - '404': - description: 'The service is not found, needs re-registration' - deprecated: false - /status: - get: - tags: - - Health check - summary: Returns status and statistics of this service - operationId: getStatusUsingGET - produces: - - '*/*' - responses: - '200': - description: Service is living - schema: - type: string - '401': - description: Unauthorized - '403': - description: Forbidden - '404': - description: Not Found - deprecated: false -definitions: - Mono«ResponseEntity«object»»: - type: object - title: Mono«ResponseEntity«object»» - Mono«ResponseEntity«string»»: - type: object - title: Mono«ResponseEntity«string»» - PolicyInfo: - type: object - properties: - id: - type: string - description: identity of the policy - json: - type: object - description: the configuration of the policy - lastModified: - type: string - description: 'timestamp, last modification time' - ric: - type: string - description: identity of the target Near-RT RIC - service: - type: string - description: the name of the service owning the policy - type: - type: string - description: name of the policy type - title: PolicyInfo - RicInfo: - type: object - properties: - managedElementIds: - type: array - description: O1 identities for managed entities - items: - type: string - policyTypes: - type: array - description: supported policy types - items: - type: string - ricName: - type: string - description: identity of the ric - state: - type: string - description: state info - title: RicInfo - ServiceRegistrationInfo: - type: object - required: - - serviceName - properties: - callbackUrl: - type: string - description: callback for notifying of RIC synchronization - keepAliveIntervalSeconds: - type: integer - format: int64 - description: 'keep alive interval for the service. This is a heartbeat supervision of the service, which in regular intevals must invoke a ''keepAlive'' REST call. When a service does not invoke this call within the given time, it is considered unavailble. An unavailable service will be automatically deregistered and its policies will be deleted. Value 0 means no timeout supervision.' - serviceName: - type: string - description: identity of the service - title: ServiceRegistrationInfo - ServiceStatus: - type: object - properties: - callbackUrl: - type: string - description: callback for notifying of RIC synchronization - keepAliveIntervalSeconds: - type: integer - format: int64 - description: policy keep alive timeout - serviceName: - type: string - description: identity of the service - timeSinceLastActivitySeconds: - type: integer - format: int64 - description: time since last invocation by the service - title: ServiceStatus diff --git a/policy-agent/pom.xml b/policy-agent/pom.xml index ef252aa2..41df80ef 100644 --- a/policy-agent/pom.xml +++ b/policy-agent/pom.xml @@ -352,10 +352,47 @@ sonar-maven-plugin ${sonar-maven-plugin.version} + + org.codehaus.mojo + exec-maven-plugin + + + git submodule update + initialize + + git + + submodule + update + --init + --recursive + + + + exec + + + + copy configuration + initialize + + cp + + -r + ../onap/oran/a1-policy-management/config + . + + + + exec + + + + JIRA https://jira.o-ran-sc.org/ - + \ No newline at end of file diff --git a/policy-agent/src b/policy-agent/src new file mode 120000 index 00000000..a737975d --- /dev/null +++ b/policy-agent/src @@ -0,0 +1 @@ +../onap/oran/a1-policy-management/src \ No newline at end of file diff --git a/policy-agent/src/main/java/org/oransc/policyagent/Application.java b/policy-agent/src/main/java/org/oransc/policyagent/Application.java deleted file mode 100644 index 3bc7326c..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/Application.java +++ /dev/null @@ -1,68 +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.policyagent; - -import org.oransc.policyagent.dmaap.DmaapMessageConsumer; -import org.oransc.policyagent.tasks.RefreshConfigTask; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; - -@SpringBootApplication -public class Application { - - @Autowired - private RefreshConfigTask configRefresh; - - @Autowired - private DmaapMessageConsumer dmaapMessageConsumer; - - public static void main(String[] args) { - SpringApplication.run(Application.class); - } - - /** - * Starts the configuration refresh task and reads the configuration. - * - * @param ctx the application context. - * - * @return the command line runner for the configuration refresh task. - */ - @Bean - public CommandLineRunner configRefreshRunner(ApplicationContext ctx) { - return args -> configRefresh.start(); - } - - /** - * Starts the DMaaP message consumer service. - * - * @param ctx the application context. - * - * @return the command line runner for the DMaaP message consumer service. - */ - @Bean - public CommandLineRunner dmaapMessageConsumerRunner(ApplicationContext ctx) { - return args -> dmaapMessageConsumer.start(); - } -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/BeanFactory.java b/policy-agent/src/main/java/org/oransc/policyagent/BeanFactory.java deleted file mode 100644 index 1e01247a..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/BeanFactory.java +++ /dev/null @@ -1,97 +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.policyagent; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import org.apache.catalina.connector.Connector; -import org.oransc.policyagent.clients.A1ClientFactory; -import org.oransc.policyagent.configuration.ApplicationConfig; -import org.oransc.policyagent.repository.Policies; -import org.oransc.policyagent.repository.PolicyTypes; -import org.oransc.policyagent.repository.Rics; -import org.oransc.policyagent.repository.Services; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration -class BeanFactory { - private final ApplicationConfig applicationConfig = new ApplicationConfig(); - - @Value("${server.http-port}") - private int httpPort = 0; - - @Bean - public Policies getPolicies() { - return new Policies(); - } - - @Bean - public PolicyTypes getPolicyTypes() { - return new PolicyTypes(); - } - - @Bean - public Rics getRics() { - return new Rics(); - } - - @Bean - public ApplicationConfig getApplicationConfig() { - return this.applicationConfig; - } - - @Bean - Services getServices() { - return new Services(); - } - - @Bean - A1ClientFactory getA1ClientFactory() { - return new A1ClientFactory(this.applicationConfig); - } - - @Bean - public ObjectMapper mapper() { - return new ObjectMapper(); - } - - @Bean - public ServletWebServerFactory servletContainer() { - TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory(); - if (httpPort > 0) { - tomcat.addAdditionalTomcatConnectors(getHttpConnector(httpPort)); - } - return tomcat; - } - - private static Connector getHttpConnector(int httpPort) { - Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL); - connector.setScheme("http"); - connector.setPort(httpPort); - connector.setSecure(false); - return connector; - } - -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/SwaggerConfig.java b/policy-agent/src/main/java/org/oransc/policyagent/SwaggerConfig.java deleted file mode 100644 index ddcf0d35..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/SwaggerConfig.java +++ /dev/null @@ -1,93 +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.policyagent; - -import com.google.common.base.Predicates; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; - -import springfox.documentation.builders.ApiInfoBuilder; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.service.ApiInfo; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2; - -/** - * Swagger configuration class that uses swagger2 documentation type and scans - * all the controllers under org.oransc.policyagent.controllers package. To - * access the swagger gui go to http://ip:port/swagger-ui.html - * - */ -@Configuration -@EnableSwagger2 -public class SwaggerConfig extends WebMvcConfigurationSupport { - - static final String API_TITLE = "A1 Policy management service"; - static final String DESCRIPTION = "This page lists all the rest apis for the service."; - static final String VERSION = "1.0"; - @SuppressWarnings("squid:S1075") // Refactor your code to get this URI from a customizable parameter. - static final String RESOURCES_PATH = "classpath:/META-INF/resources/"; - static final String WEBJARS_PATH = RESOURCES_PATH + "webjars/"; - static final String SWAGGER_UI = "swagger-ui.html"; - static final String WEBJARS = "/webjars/**"; - - /** - * Gets the API info. - * - * @return the API info. - */ - @Bean - public Docket api() { - return new Docket(DocumentationType.SWAGGER_2) // - .apiInfo(apiInfo()) // - .select() // - .apis(RequestHandlerSelectors.any()) // - .paths(PathSelectors.any()) // - .paths(Predicates.not(PathSelectors.regex("/error"))) // - // this endpoint is not implemented, but was visible for Swagger - .paths(Predicates.not(PathSelectors.regex("/actuator.*"))) // - // this endpoint is implemented by spring framework, exclude for now - .build(); - } - - private static ApiInfo apiInfo() { - return new ApiInfoBuilder() // - .title(API_TITLE) // - .description(DESCRIPTION) // - .version(VERSION) // - .build(); - } - - @Override - protected void addResourceHandlers(ResourceHandlerRegistry registry) { - registry.addResourceHandler(SWAGGER_UI) // - .addResourceLocations(RESOURCES_PATH); - - registry.addResourceHandler(WEBJARS) // - .addResourceLocations(WEBJARS_PATH); - } - -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/aspect/LogAspect.java b/policy-agent/src/main/java/org/oransc/policyagent/aspect/LogAspect.java deleted file mode 100644 index 93b2ec0d..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/aspect/LogAspect.java +++ /dev/null @@ -1,63 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.aspect; - -import org.aspectj.lang.JoinPoint; -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.annotation.After; -import org.aspectj.lang.annotation.Around; -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Before; -import org.aspectj.lang.reflect.MethodSignature; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; -import org.springframework.util.StopWatch; - -@Aspect -@Component -public class LogAspect { - - private static final Logger logger = LoggerFactory.getLogger(LogAspect.class); - - @Around("execution(* org.oransc.policyagent..*(..)))") - public void executimeTime(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { - final StopWatch stopWatch = new StopWatch(); - stopWatch.start(); - proceedingJoinPoint.proceed(); - stopWatch.stop(); - MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature(); - String className = methodSignature.getDeclaringType().getSimpleName(); - String methodName = methodSignature.getName(); - logger.trace("Execution time of {}.{}: {} ms", className, methodName, stopWatch.getTotalTimeMillis()); - } - - @Before("execution(* org.oransc.policyagent..*(..)))") - public void entryLog(final JoinPoint joinPoint) { - logger.trace("Entering method: {}", joinPoint.getSignature().getName()); - } - - @After("execution(* org.oransc.policyagent..*(..)))") - public void exitLog(final JoinPoint joinPoint) { - logger.trace("Exiting method: {}", joinPoint.getSignature().getName()); - } - -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/A1Client.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/A1Client.java deleted file mode 100644 index f94c2c1e..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/clients/A1Client.java +++ /dev/null @@ -1,60 +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.policyagent.clients; - -import java.util.List; - -import org.oransc.policyagent.repository.Policy; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -/** - * Common interface for 'A1' Policy access. Implementations of this interface - * adapts to the different southbound REST APIs supported. - */ -public interface A1Client { - - public enum A1ProtocolType { - UNKNOWN, // - STD_V1_1, // STD A1 version 1.1 - OSC_V1, // OSC 'A1' - SDNC_OSC_STD_V1_1, // SDNC_OSC with STD A1 version 1.1 southbound - SDNC_OSC_OSC_V1, // SDNC_OSC with OSC 'A1' southbound - SDNC_ONAP - } - - public Mono getProtocolVersion(); - - public Mono> getPolicyTypeIdentities(); - - public Mono> getPolicyIdentities(); - - public Mono getPolicyTypeSchema(String policyTypeId); - - public Mono putPolicy(Policy policy); - - public Mono deletePolicy(Policy policy); - - public Flux deleteAllPolicies(); - - public Mono getPolicyStatus(Policy policy); -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/A1ClientFactory.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/A1ClientFactory.java deleted file mode 100644 index 0860f778..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/clients/A1ClientFactory.java +++ /dev/null @@ -1,140 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.clients; - -import lombok.Getter; - -import org.oransc.policyagent.clients.A1Client.A1ProtocolType; -import org.oransc.policyagent.configuration.ApplicationConfig; -import org.oransc.policyagent.configuration.ControllerConfig; -import org.oransc.policyagent.exceptions.ServiceException; -import org.oransc.policyagent.repository.Ric; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import reactor.core.publisher.Mono; - -/** - * Factory for A1 clients that supports four different protocol versions of the - * A1 api. - */ -public class A1ClientFactory { - - private static final Logger logger = LoggerFactory.getLogger(A1ClientFactory.class); - - @Getter - private final ApplicationConfig appConfig; - - @Autowired - public A1ClientFactory(ApplicationConfig appConfig) { - this.appConfig = appConfig; - } - - /** - * Creates an A1 client with the correct A1 protocol for the provided Ric. - * - *

- * It detects the protocol version by trial and error, since there is no - * getVersion method specified in the A1 api yet. - * - *

- * As a side effect it also sets the protocol version in the provided Ric. This - * means that after the first successful creation it won't have to try which - * protocol to use, but can create the client directly. - * - * @param ric The RIC to get a client for. - * @return a client with the correct protocol, or a ServiceException if none of - * the protocols are supported by the Ric. - */ - public Mono createA1Client(Ric ric) { - return getProtocolVersion(ric) // - .flatMap(version -> createA1ClientMono(ric, version)); - } - - A1Client createClient(Ric ric, A1ProtocolType version) throws ServiceException { - if (version == A1ProtocolType.STD_V1_1) { - assertNoControllerConfig(ric, version); - return new StdA1ClientVersion1(ric.getConfig(), this.appConfig.getWebClientConfig()); - } else if (version == A1ProtocolType.OSC_V1) { - assertNoControllerConfig(ric, version); - return new OscA1Client(ric.getConfig(), this.appConfig.getWebClientConfig()); - } else if (version == A1ProtocolType.SDNC_OSC_STD_V1_1 || version == A1ProtocolType.SDNC_OSC_OSC_V1) { - return new SdncOscA1Client(version, ric.getConfig(), getControllerConfig(ric), - this.appConfig.getWebClientConfig()); - } else if (version == A1ProtocolType.SDNC_ONAP) { - return new SdncOnapA1Client(ric.getConfig(), getControllerConfig(ric), this.appConfig.getWebClientConfig()); - } else { - logger.error("Unhandled protocol: {}", version); - throw new ServiceException("Unhandled protocol"); - } - } - - private ControllerConfig getControllerConfig(Ric ric) throws ServiceException { - String controllerName = ric.getConfig().controllerName(); - if (controllerName.isEmpty()) { - ric.setProtocolVersion(A1ProtocolType.UNKNOWN); - throw new ServiceException("No controller configured for RIC: " + ric.name()); - } - try { - return this.appConfig.getControllerConfig(controllerName); - } catch (ServiceException e) { - ric.setProtocolVersion(A1ProtocolType.UNKNOWN); - throw e; - } - } - - private void assertNoControllerConfig(Ric ric, A1ProtocolType version) throws ServiceException { - if (!ric.getConfig().controllerName().isEmpty()) { - ric.setProtocolVersion(A1ProtocolType.UNKNOWN); - throw new ServiceException( - "Controller config should be empty, ric: " + ric.name() + " when using protocol version: " + version); - } - } - - private Mono createA1ClientMono(Ric ric, A1ProtocolType version) { - try { - return Mono.just(createClient(ric, version)); - } catch (ServiceException e) { - return Mono.error(e); - } - } - - private Mono getProtocolVersion(Ric ric) { - if (ric.getProtocolVersion() == A1ProtocolType.UNKNOWN) { - return fetchVersion(ric, A1ProtocolType.STD_V1_1) // - .onErrorResume(notUsed -> fetchVersion(ric, A1ProtocolType.OSC_V1)) // - .onErrorResume(notUsed -> fetchVersion(ric, A1ProtocolType.SDNC_OSC_STD_V1_1)) // - .onErrorResume(notUsed -> fetchVersion(ric, A1ProtocolType.SDNC_ONAP)) // - .doOnNext(ric::setProtocolVersion) - .doOnNext(version -> logger.debug("Established protocol version:{} for Ric: {}", version, ric.name())) // - .doOnError(notUsed -> logger.warn("Could not get protocol version from RIC: {}", ric.name())) // - .onErrorResume( - notUsed -> Mono.error(new ServiceException("Protocol negotiation failed for " + ric.name()))); - } else { - return Mono.just(ric.getProtocolVersion()); - } - } - - private Mono fetchVersion(Ric ric, A1ProtocolType protocolType) { - return createA1ClientMono(ric, protocolType) // - .flatMap(A1Client::getProtocolVersion); - } -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/A1UriBuilder.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/A1UriBuilder.java deleted file mode 100644 index 267a717e..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/clients/A1UriBuilder.java +++ /dev/null @@ -1,32 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.clients; - -/** - * Builder for A1 influenced REST APIs - */ -interface A1UriBuilder { - String createPutPolicyUri(String type, String policyId); - - String createDeleteUri(String type, String policyId); - - String createGetPolicyStatusUri(String type, String policyId); -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/AsyncRestClient.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/AsyncRestClient.java deleted file mode 100644 index 4bc29ee0..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/clients/AsyncRestClient.java +++ /dev/null @@ -1,334 +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.policyagent.clients; - -import io.netty.channel.ChannelOption; -import io.netty.handler.ssl.SslContext; -import io.netty.handler.ssl.SslContextBuilder; -import io.netty.handler.ssl.util.InsecureTrustManagerFactory; -import io.netty.handler.timeout.ReadTimeoutHandler; -import io.netty.handler.timeout.WriteTimeoutHandler; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.lang.invoke.MethodHandles; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; - -import javax.net.ssl.KeyManagerFactory; - -import org.oransc.policyagent.configuration.WebClientConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.http.client.reactive.ReactorClientHttpConnector; -import org.springframework.lang.Nullable; -import org.springframework.util.ResourceUtils; -import org.springframework.web.reactive.function.client.ExchangeStrategies; -import org.springframework.web.reactive.function.client.WebClient; -import org.springframework.web.reactive.function.client.WebClient.RequestHeadersSpec; -import org.springframework.web.reactive.function.client.WebClientResponseException; - -import reactor.core.publisher.Mono; -import reactor.netty.http.client.HttpClient; -import reactor.netty.resources.ConnectionProvider; -import reactor.netty.tcp.TcpClient; - -/** - * Generic reactive REST client. - */ -public class AsyncRestClient { - private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - private WebClient webClient = null; - private final String baseUrl; - private static final AtomicInteger sequenceNumber = new AtomicInteger(); - private final WebClientConfig clientConfig; - static KeyStore clientTrustStore = null; - private boolean sslEnabled = true; - - public AsyncRestClient(String baseUrl) { - this(baseUrl, null); - this.sslEnabled = false; - } - - public AsyncRestClient(String baseUrl, WebClientConfig config) { - this.baseUrl = baseUrl; - this.clientConfig = config; - } - - public Mono> postForEntity(String uri, @Nullable String body) { - Object traceTag = createTraceTag(); - logger.debug("{} POST uri = '{}{}''", traceTag, baseUrl, uri); - logger.trace("{} POST body: {}", traceTag, body); - Mono bodyProducer = body != null ? Mono.just(body) : Mono.empty(); - return getWebClient() // - .flatMap(client -> { - RequestHeadersSpec request = client.post() // - .uri(uri) // - .contentType(MediaType.APPLICATION_JSON) // - .body(bodyProducer, String.class); - return retrieve(traceTag, request); - }); - } - - public Mono post(String uri, @Nullable String body) { - return postForEntity(uri, body) // - .flatMap(this::toBody); - } - - public Mono postWithAuthHeader(String uri, String body, String username, String password) { - Object traceTag = createTraceTag(); - logger.debug("{} POST (auth) uri = '{}{}''", traceTag, baseUrl, uri); - logger.trace("{} POST body: {}", traceTag, body); - return getWebClient() // - .flatMap(client -> { - RequestHeadersSpec request = client.post() // - .uri(uri) // - .headers(headers -> headers.setBasicAuth(username, password)) // - .contentType(MediaType.APPLICATION_JSON) // - .bodyValue(body); - return retrieve(traceTag, request) // - .flatMap(this::toBody); - }); - } - - public Mono> putForEntity(String uri, String body) { - Object traceTag = createTraceTag(); - logger.debug("{} PUT uri = '{}{}''", traceTag, baseUrl, uri); - logger.trace("{} PUT body: {}", traceTag, body); - return getWebClient() // - .flatMap(client -> { - RequestHeadersSpec request = client.put() // - .uri(uri) // - .contentType(MediaType.APPLICATION_JSON) // - .bodyValue(body); - return retrieve(traceTag, request); - }); - } - - public Mono> putForEntity(String uri) { - Object traceTag = createTraceTag(); - logger.debug("{} PUT uri = '{}{}''", traceTag, baseUrl, uri); - logger.trace("{} PUT body: ", traceTag); - return getWebClient() // - .flatMap(client -> { - RequestHeadersSpec request = client.put() // - .uri(uri); - return retrieve(traceTag, request); - }); - } - - public Mono put(String uri, String body) { - return putForEntity(uri, body) // - .flatMap(this::toBody); - } - - public Mono> getForEntity(String uri) { - Object traceTag = createTraceTag(); - logger.debug("{} GET uri = '{}{}''", traceTag, baseUrl, uri); - return getWebClient() // - .flatMap(client -> { - RequestHeadersSpec request = client.get().uri(uri); - return retrieve(traceTag, request); - }); - } - - public Mono get(String uri) { - return getForEntity(uri) // - .flatMap(this::toBody); - } - - public Mono> deleteForEntity(String uri) { - Object traceTag = createTraceTag(); - logger.debug("{} DELETE uri = '{}{}''", traceTag, baseUrl, uri); - return getWebClient() // - .flatMap(client -> { - RequestHeadersSpec request = client.delete().uri(uri); - return retrieve(traceTag, request); - }); - } - - public Mono delete(String uri) { - return deleteForEntity(uri) // - .flatMap(this::toBody); - } - - private Mono> retrieve(Object traceTag, RequestHeadersSpec request) { - final Class clazz = String.class; - return request.retrieve() // - .toEntity(clazz) // - .doOnNext(entity -> logger.trace("{} Received: {}", traceTag, entity.getBody())) // - .doOnError(throwable -> onHttpError(traceTag, throwable)); - } - - private static Object createTraceTag() { - return sequenceNumber.incrementAndGet(); - } - - private void onHttpError(Object traceTag, Throwable t) { - if (t instanceof WebClientResponseException) { - WebClientResponseException exception = (WebClientResponseException) t; - logger.debug("{} HTTP error status = '{}', body '{}'", traceTag, exception.getStatusCode(), - exception.getResponseBodyAsString()); - } else { - logger.debug("{} HTTP error", traceTag, t); - } - } - - private Mono toBody(ResponseEntity entity) { - if (entity.getBody() == null) { - return Mono.just(""); - } else { - return Mono.just(entity.getBody()); - } - } - - private boolean isCertificateEntry(KeyStore trustStore, String alias) { - try { - return trustStore.isCertificateEntry(alias); - } catch (KeyStoreException e) { - logger.error("Error reading truststore {}", e.getMessage()); - return false; - } - } - - private Certificate getCertificate(KeyStore trustStore, String alias) { - try { - return trustStore.getCertificate(alias); - } catch (KeyStoreException e) { - logger.error("Error reading truststore {}", e.getMessage()); - return null; - } - } - - private static synchronized KeyStore getTrustStore(String trustStorePath, String trustStorePass) - throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException { - if (clientTrustStore == null) { - KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType()); - store.load(new FileInputStream(ResourceUtils.getFile(trustStorePath)), trustStorePass.toCharArray()); - clientTrustStore = store; - } - return clientTrustStore; - } - - private SslContext createSslContextRejectingUntrustedPeers(String trustStorePath, String trustStorePass, - KeyManagerFactory keyManager) - throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException { - - final KeyStore trustStore = getTrustStore(trustStorePath, trustStorePass); - List certificateList = Collections.list(trustStore.aliases()).stream() // - .filter(alias -> isCertificateEntry(trustStore, alias)) // - .map(alias -> getCertificate(trustStore, alias)) // - .collect(Collectors.toList()); - final X509Certificate[] certificates = certificateList.toArray(new X509Certificate[certificateList.size()]); - - return SslContextBuilder.forClient() // - .keyManager(keyManager) // - .trustManager(certificates) // - .build(); - } - - private SslContext createSslContext(KeyManagerFactory keyManager) - throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException { - if (this.clientConfig.isTrustStoreUsed()) { - return createSslContextRejectingUntrustedPeers(this.clientConfig.trustStore(), - this.clientConfig.trustStorePassword(), keyManager); - } else { - // Trust anyone - return SslContextBuilder.forClient() // - .keyManager(keyManager) // - .trustManager(InsecureTrustManagerFactory.INSTANCE) // - .build(); - } - } - - private TcpClient createTcpClientSecure(SslContext sslContext) { - return TcpClient.create(ConnectionProvider.newConnection()) // - .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10_000) // - .secure(c -> c.sslContext(sslContext)) // - .doOnConnected(connection -> { - connection.addHandlerLast(new ReadTimeoutHandler(30)); - connection.addHandlerLast(new WriteTimeoutHandler(30)); - }); - } - - private TcpClient createTcpClientInsecure() { - return TcpClient.create(ConnectionProvider.newConnection()) // - .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10_000) // - .doOnConnected(connection -> { - connection.addHandlerLast(new ReadTimeoutHandler(30)); - connection.addHandlerLast(new WriteTimeoutHandler(30)); - }); - } - - private WebClient createWebClient(String baseUrl, TcpClient tcpClient) { - HttpClient httpClient = HttpClient.from(tcpClient); - ReactorClientHttpConnector connector = new ReactorClientHttpConnector(httpClient); - ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder() // - .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(-1)) // - .build(); - return WebClient.builder() // - .clientConnector(connector) // - .baseUrl(baseUrl) // - .exchangeStrategies(exchangeStrategies) // - .build(); - } - - private Mono getWebClient() { - if (this.webClient == null) { - try { - if (this.sslEnabled) { - final KeyManagerFactory keyManager = - KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - final KeyStore keyStore = KeyStore.getInstance(this.clientConfig.keyStoreType()); - final String keyStoreFile = this.clientConfig.keyStore(); - final String keyStorePassword = this.clientConfig.keyStorePassword(); - final String keyPassword = this.clientConfig.keyPassword(); - try (final InputStream inputStream = new FileInputStream(keyStoreFile)) { - keyStore.load(inputStream, keyStorePassword.toCharArray()); - } - keyManager.init(keyStore, keyPassword.toCharArray()); - SslContext sslContext = createSslContext(keyManager); - TcpClient tcpClient = createTcpClientSecure(sslContext); - this.webClient = createWebClient(this.baseUrl, tcpClient); - } else { - TcpClient tcpClient = createTcpClientInsecure(); - this.webClient = createWebClient(this.baseUrl, tcpClient); - } - } catch (Exception e) { - logger.error("Could not create WebClient {}", e.getMessage()); - return Mono.error(e); - } - } - return Mono.just(this.webClient); - } - -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/OscA1Client.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/OscA1Client.java deleted file mode 100644 index a388267e..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/clients/OscA1Client.java +++ /dev/null @@ -1,213 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.clients; - -import java.lang.invoke.MethodHandles; -import java.util.List; - -import org.json.JSONObject; -import org.oransc.policyagent.configuration.RicConfig; -import org.oransc.policyagent.configuration.WebClientConfig; -import org.oransc.policyagent.repository.Policy; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -/** - * Client for accessing OSC A1 REST API - */ -@SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally -public class OscA1Client implements A1Client { - static final int CONCURRENCY_RIC = 1; // How may paralell requests that is sent to one NearRT RIC - - public static class UriBuilder implements A1UriBuilder { - private final RicConfig ricConfig; - - public UriBuilder(RicConfig ricConfig) { - this.ricConfig = ricConfig; - } - - @Override - public String createPutPolicyUri(String type, String policyId) { - return createPolicyUri(type, policyId); - } - - /** - * /a1-p/policytypes/{policy_type_id}/policies - */ - public String createGetPolicyIdsUri(String type) { - return createPolicyTypeUri(type) + "/policies"; - } - - @Override - public String createDeleteUri(String type, String policyId) { - return createPolicyUri(type, policyId); - } - - /** - * ​/a1-p​/policytypes​/{policy_type_id}​/policies​/{policy_instance_id}​/status - */ - @Override - public String createGetPolicyStatusUri(String type, String policyId) { - return createPolicyUri(type, policyId) + "/status"; - } - - /** - * ​/a1-p​/healthcheck - */ - public String createHealtcheckUri() { - return baseUri() + "/healthcheck"; - } - - /** - * /a1-p/policytypes/{policy_type_id} - */ - public String createGetSchemaUri(String type) { - return this.createPolicyTypeUri(type); - } - - /** - * ​/a1-p​/policytypes​/{policy_type_id} - */ - public String createPolicyTypesUri() { - return baseUri() + "/policytypes"; - } - - /** - * ​/a1-p​/policytypes​/{policy_type_id}​/policies​/{policy_instance_id} - */ - private String createPolicyUri(String type, String id) { - return createPolicyTypeUri(type) + "/policies/" + id; - } - - /** - * /a1-p/policytypes/{policy_type_id} - */ - private String createPolicyTypeUri(String type) { - return createPolicyTypesUri() + "/" + type; - } - - private String baseUri() { - return ricConfig.baseUrl() + "/a1-p"; - } - } - - private static final String TITLE = "title"; - private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - private final AsyncRestClient restClient; - private final UriBuilder uri; - - public OscA1Client(RicConfig ricConfig, WebClientConfig clientConfig) { - this(ricConfig, new AsyncRestClient("", clientConfig)); - } - - public OscA1Client(RicConfig ricConfig, AsyncRestClient restClient) { - this.restClient = restClient; - logger.debug("OscA1Client for ric: {}", ricConfig.name()); - - uri = new UriBuilder(ricConfig); - } - - public static Mono extractCreateSchema(String policyTypeResponse, String policyTypeId) { - try { - JSONObject obj = new JSONObject(policyTypeResponse); - JSONObject schemaObj = obj.getJSONObject("create_schema"); - schemaObj.put(TITLE, policyTypeId); - return Mono.just(schemaObj.toString()); - } catch (Exception e) { - String exceptionString = e.toString(); - logger.error("Unexpected response for policy type: {}, exception: {}", policyTypeResponse, exceptionString); - return Mono.error(e); - } - } - - @Override - public Mono> getPolicyTypeIdentities() { - return getPolicyTypeIds() // - .collectList(); - } - - @Override - public Mono> getPolicyIdentities() { - return getPolicyTypeIds() // - .flatMap(this::getPolicyIdentitiesByType) // - .collectList(); - } - - @Override - public Mono getPolicyTypeSchema(String policyTypeId) { - String schemaUri = uri.createGetSchemaUri(policyTypeId); - return restClient.get(schemaUri) // - .flatMap(response -> extractCreateSchema(response, policyTypeId)); - } - - @Override - public Mono putPolicy(Policy policy) { - String policyUri = this.uri.createPutPolicyUri(policy.type().name(), policy.id()); - return restClient.put(policyUri, policy.json()); - } - - @Override - public Mono deletePolicy(Policy policy) { - return deletePolicyById(policy.type().name(), policy.id()); - } - - @Override - public Mono getProtocolVersion() { - return restClient.get(uri.createHealtcheckUri()) // - .flatMap(notUsed -> Mono.just(A1ProtocolType.OSC_V1)); - } - - @Override - public Flux deleteAllPolicies() { - return getPolicyTypeIds() // - .flatMap(this::deletePoliciesForType, CONCURRENCY_RIC); - } - - @Override - public Mono getPolicyStatus(Policy policy) { - String statusUri = uri.createGetPolicyStatusUri(policy.type().name(), policy.id()); - return restClient.get(statusUri); - - } - - private Flux getPolicyTypeIds() { - return restClient.get(uri.createPolicyTypesUri()) // - .flatMapMany(SdncJsonHelper::parseJsonArrayOfString); - } - - private Flux getPolicyIdentitiesByType(String typeId) { - return restClient.get(uri.createGetPolicyIdsUri(typeId)) // - .flatMapMany(SdncJsonHelper::parseJsonArrayOfString); - } - - private Mono deletePolicyById(String typeId, String policyId) { - String policyUri = uri.createDeleteUri(typeId, policyId); - return restClient.delete(policyUri); - } - - private Flux deletePoliciesForType(String typeId) { - return getPolicyIdentitiesByType(typeId) // - .flatMap(policyId -> deletePolicyById(typeId, policyId), CONCURRENCY_RIC); - } -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/SdncJsonHelper.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/SdncJsonHelper.java deleted file mode 100644 index ab0d3fa8..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/clients/SdncJsonHelper.java +++ /dev/null @@ -1,120 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.clients; - -import com.google.gson.FieldNamingPolicy; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -import java.lang.invoke.MethodHandles; -import java.util.ArrayList; -import java.util.List; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -/** - * Common json functionality used by the SDNC clients - */ -@SuppressWarnings("java:S1192") // Same text in several traces -class SdncJsonHelper { - private static Gson gson = new GsonBuilder() // - .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES) // - .create(); - private static final String OUTPUT = "output"; - private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - - private SdncJsonHelper() { - } - - public static Flux parseJsonArrayOfString(String inputString) { - try { - List arrayList = new ArrayList<>(); - if (!inputString.isEmpty()) { - JSONArray jsonArray = new JSONArray(inputString); - for (int i = 0; i < jsonArray.length(); i++) { - Object value = jsonArray.get(i); - arrayList.add(value.toString()); - } - } - return Flux.fromIterable(arrayList); - } catch (JSONException ex) { // invalid json - logger.debug("Invalid json {}", ex.getMessage()); - return Flux.error(ex); - } - } - - public static String createInputJsonString(T params) { - JsonElement paramsJson = gson.toJsonTree(params); - JsonObject jsonObj = new JsonObject(); - jsonObj.add("input", paramsJson); - return gson.toJson(jsonObj); - } - - public static String createOutputJsonString(T params) { - JsonElement paramsJson = gson.toJsonTree(params); - JsonObject jsonObj = new JsonObject(); - jsonObj.add(OUTPUT, paramsJson); - return gson.toJson(jsonObj); - } - - public static Mono getOutput(String response) { - try { - JSONObject outputJson = new JSONObject(response); - JSONObject responseParams = outputJson.getJSONObject(OUTPUT); - return Mono.just(responseParams); - } catch (JSONException ex) { // invalid json - logger.debug("Invalid json {}", ex.getMessage()); - return Mono.error(ex); - } - } - - public static Mono getValueFromResponse(String response, String key) { - return getOutput(response) // - .flatMap(responseParams -> { - if (!responseParams.has(key)) { - return Mono.just(""); - } - String value = responseParams.get(key).toString(); - return Mono.just(value); - }); - } - - public static Mono extractPolicySchema(String inputString) { - try { - JSONObject jsonObject = new JSONObject(inputString); - JSONObject schemaObject = jsonObject.getJSONObject("policySchema"); - String schemaString = schemaObject.toString(); - return Mono.just(schemaString); - } catch (JSONException ex) { // invalid json - logger.debug("Invalid json {}", ex.getMessage()); - return Mono.error(ex); - } - } -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/SdncOnapA1Client.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/SdncOnapA1Client.java deleted file mode 100644 index 37e03032..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/clients/SdncOnapA1Client.java +++ /dev/null @@ -1,194 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.clients; - -import java.lang.invoke.MethodHandles; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import org.immutables.gson.Gson; -import org.immutables.value.Value; -import org.oransc.policyagent.configuration.ControllerConfig; -import org.oransc.policyagent.configuration.RicConfig; -import org.oransc.policyagent.configuration.WebClientConfig; -import org.oransc.policyagent.repository.Policy; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -/** - * Client for accessing the A1 adapter in the SDNC controller in ONAP - */ -@SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally -public class SdncOnapA1Client implements A1Client { - @Value.Immutable - @Gson.TypeAdapters - interface SdncOnapAdapterInput { - public String nearRtRicId(); - - public Optional policyTypeId(); - - public Optional policyInstanceId(); - - public Optional policyInstance(); - - public Optional> properties(); - } - - private static final String URL_PREFIX = "/A1-ADAPTER-API:"; - - private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - - private final ControllerConfig controllerConfig; - private final RicConfig ricConfig; - private final AsyncRestClient restClient; - - public SdncOnapA1Client(RicConfig ricConfig, ControllerConfig controllerConfig, WebClientConfig clientConfig) { - this(ricConfig, controllerConfig, - new AsyncRestClient(controllerConfig.baseUrl() + "/restconf/operations", clientConfig)); - logger.debug("SdncOnapA1Client for ric: {}, a1ControllerBaseUrl: {}", ricConfig.name(), - controllerConfig.baseUrl()); - } - - public SdncOnapA1Client(RicConfig ricConfig, ControllerConfig controllerConfig, AsyncRestClient restClient) { - this.ricConfig = ricConfig; - this.controllerConfig = controllerConfig; - this.restClient = restClient; - } - - @Override - public Mono> getPolicyTypeIdentities() { - return getPolicyTypeIds() // - .collectList(); - } - - @Override - public Mono> getPolicyIdentities() { - return getPolicyTypeIds() // - .flatMap(this::getPolicyIdentitiesByType) // - .collectList(); - } - - @Override - public Mono getPolicyTypeSchema(String policyTypeId) { - SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() // - .nearRtRicId(ricConfig.baseUrl()) // - .policyTypeId(policyTypeId) // - .build(); - String inputJsonString = SdncJsonHelper.createInputJsonString(inputParams); - logger.debug("POST getPolicyType inputJsonString = {}", inputJsonString); - - return restClient - .postWithAuthHeader(URL_PREFIX + "getPolicyType", inputJsonString, controllerConfig.userName(), - controllerConfig.password()) // - .flatMap(response -> SdncJsonHelper.getValueFromResponse(response, "policy-type")) // - .flatMap(SdncJsonHelper::extractPolicySchema); - } - - @Override - public Mono putPolicy(Policy policy) { - SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() // - .nearRtRicId(ricConfig.baseUrl()) // - .policyTypeId(policy.type().name()) // - .policyInstanceId(policy.id()) // - .policyInstance(policy.json()) // - .properties(new ArrayList<>()) // - .build(); - - String inputJsonString = SdncJsonHelper.createInputJsonString(inputParams); - logger.debug("POST putPolicy inputJsonString = {}", inputJsonString); - - return restClient.postWithAuthHeader(URL_PREFIX + "createPolicyInstance", inputJsonString, - controllerConfig.userName(), controllerConfig.password()); - } - - @Override - public Mono deletePolicy(Policy policy) { - return deletePolicyByTypeId(policy.type().name(), policy.id()); - } - - @Override - public Flux deleteAllPolicies() { - return getPolicyTypeIds() // - .flatMap(this::deletePoliciesForType); // - } - - @Override - public Mono getProtocolVersion() { - return getPolicyTypeIdentities() // - .flatMap(notUsed -> Mono.just(A1ProtocolType.SDNC_ONAP)); - } - - @Override - public Mono getPolicyStatus(Policy policy) { - return Mono.error(new Exception("Status not implemented in the controller")); - } - - private Flux getPolicyTypeIds() { - SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() // - .nearRtRicId(ricConfig.baseUrl()) // - .build(); - String inputJsonString = SdncJsonHelper.createInputJsonString(inputParams); - logger.debug("POST getPolicyTypeIdentities inputJsonString = {}", inputJsonString); - - return restClient - .postWithAuthHeader(URL_PREFIX + "getPolicyTypes", inputJsonString, controllerConfig.userName(), - controllerConfig.password()) // - .flatMap(response -> SdncJsonHelper.getValueFromResponse(response, "policy-type-id-list")) // - .flatMapMany(SdncJsonHelper::parseJsonArrayOfString); - } - - private Flux getPolicyIdentitiesByType(String policyTypeId) { - SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() // - .nearRtRicId(ricConfig.baseUrl()) // - .policyTypeId(policyTypeId) // - .build(); - String inputJsonString = SdncJsonHelper.createInputJsonString(inputParams); - logger.debug("POST getPolicyIdentities inputJsonString = {}", inputJsonString); - - return restClient - .postWithAuthHeader(URL_PREFIX + "getPolicyInstances", inputJsonString, controllerConfig.userName(), - controllerConfig.password()) // - .flatMap(response -> SdncJsonHelper.getValueFromResponse(response, "policy-instance-id-list")) // - .flatMapMany(SdncJsonHelper::parseJsonArrayOfString); - } - - private Flux deletePoliciesForType(String typeId) { - return getPolicyIdentitiesByType(typeId) // - .flatMap(policyId -> deletePolicyByTypeId(typeId, policyId)); // - } - - private Mono deletePolicyByTypeId(String policyTypeId, String policyId) { - SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() // - .nearRtRicId(ricConfig.baseUrl()) // - .policyTypeId(policyTypeId) // - .policyInstanceId(policyId) // - .build(); - String inputJsonString = SdncJsonHelper.createInputJsonString(inputParams); - logger.debug("POST deletePolicy inputJsonString = {}", inputJsonString); - - return restClient.postWithAuthHeader(URL_PREFIX + "deletePolicyInstance", inputJsonString, - controllerConfig.userName(), controllerConfig.password()); - } -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/SdncOscA1Client.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/SdncOscA1Client.java deleted file mode 100644 index 79a2a5ef..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/clients/SdncOscA1Client.java +++ /dev/null @@ -1,287 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.clients; - -import com.google.gson.FieldNamingPolicy; -import com.google.gson.GsonBuilder; - -import java.lang.invoke.MethodHandles; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; - -import org.immutables.value.Value; -import org.json.JSONObject; -import org.oransc.policyagent.configuration.ControllerConfig; -import org.oransc.policyagent.configuration.RicConfig; -import org.oransc.policyagent.configuration.WebClientConfig; -import org.oransc.policyagent.repository.Policy; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpStatus; -import org.springframework.web.reactive.function.client.WebClientResponseException; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -/** - * Client for accessing the A1 adapter in the SDNC controller in OSC. - */ -@SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally -public class SdncOscA1Client implements A1Client { - - static final int CONCURRENCY_RIC = 1; // How may paralell requests that is sent to one NearRT RIC - - @Value.Immutable - @org.immutables.gson.Gson.TypeAdapters - public interface AdapterRequest { - public String nearRtRicUrl(); - - public Optional body(); - } - - @Value.Immutable - @org.immutables.gson.Gson.TypeAdapters - public interface AdapterOutput { - public Optional body(); - - public int httpStatus(); - } - - static com.google.gson.Gson gson = new GsonBuilder() // - .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES) // - .create(); // - - private static final String GET_POLICY_RPC = "getA1Policy"; - private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - private final ControllerConfig controllerConfig; - private final AsyncRestClient restClient; - private final RicConfig ricConfig; - private final A1ProtocolType protocolType; - - /** - * Constructor that creates the REST client to use. - * - * @param protocolType the southbound protocol of the controller. Supported protocols are SDNC_OSC_STD_V1_1 and - * SDNC_OSC_OSC_V1 - * @param ricConfig the configuration of the Ric to communicate with - * @param controllerConfig the configuration of the SDNC controller to use - * - * @throws IllegalArgumentException when the protocolType is wrong. - */ - public SdncOscA1Client(A1ProtocolType protocolType, RicConfig ricConfig, ControllerConfig controllerConfig, - WebClientConfig clientConfig) { - this(protocolType, ricConfig, controllerConfig, - new AsyncRestClient(controllerConfig.baseUrl() + "/restconf/operations", clientConfig)); - logger.debug("SdncOscA1Client for ric: {}, a1Controller: {}", ricConfig.name(), controllerConfig); - } - - /** - * Constructor where the REST client to use is provided. - * - * @param protocolType the southbound protocol of the controller. Supported protocols are SDNC_OSC_STD_V1_1 and - * SDNC_OSC_OSC_V1 - * @param ricConfig the configuration of the Ric to communicate with - * @param controllerConfig the configuration of the SDNC controller to use - * @param restClient the REST client to use - * - * @throws IllegalArgumentException when the protocolType is wrong. - */ - public SdncOscA1Client(A1ProtocolType protocolType, RicConfig ricConfig, ControllerConfig controllerConfig, - AsyncRestClient restClient) { - if (!(A1ProtocolType.SDNC_OSC_STD_V1_1.equals(protocolType) - || A1ProtocolType.SDNC_OSC_OSC_V1.equals(protocolType))) { - throw new IllegalArgumentException("Protocol type must be " + A1ProtocolType.SDNC_OSC_STD_V1_1 + " or " - + A1ProtocolType.SDNC_OSC_OSC_V1 + ", was: " + protocolType); - } - this.restClient = restClient; - this.ricConfig = ricConfig; - this.protocolType = protocolType; - this.controllerConfig = controllerConfig; - } - - @Override - public Mono> getPolicyTypeIdentities() { - if (this.protocolType == A1ProtocolType.SDNC_OSC_STD_V1_1) { - return Mono.just(Arrays.asList("")); - } else { - OscA1Client.UriBuilder uri = new OscA1Client.UriBuilder(ricConfig); - final String ricUrl = uri.createPolicyTypesUri(); - return post(GET_POLICY_RPC, ricUrl, Optional.empty()) // - .flatMapMany(SdncJsonHelper::parseJsonArrayOfString) // - .collectList(); - } - - } - - @Override - public Mono> getPolicyIdentities() { - return getPolicyIds() // - .collectList(); - } - - @Override - public Mono getPolicyTypeSchema(String policyTypeId) { - if (this.protocolType == A1ProtocolType.SDNC_OSC_STD_V1_1) { - return Mono.just("{}"); - } else { - OscA1Client.UriBuilder uri = new OscA1Client.UriBuilder(ricConfig); - final String ricUrl = uri.createGetSchemaUri(policyTypeId); - return post(GET_POLICY_RPC, ricUrl, Optional.empty()) // - .flatMap(response -> OscA1Client.extractCreateSchema(response, policyTypeId)); - } - } - - @Override - public Mono putPolicy(Policy policy) { - return getUriBuilder() // - .flatMap(builder -> { - String ricUrl = builder.createPutPolicyUri(policy.type().name(), policy.id()); - return post("putA1Policy", ricUrl, Optional.of(policy.json())); - }); - } - - @Override - public Mono deletePolicy(Policy policy) { - return deletePolicyById(policy.type().name(), policy.id()); - } - - @Override - public Flux deleteAllPolicies() { - if (this.protocolType == A1ProtocolType.SDNC_OSC_STD_V1_1) { - return getPolicyIds() // - .flatMap(policyId -> deletePolicyById("", policyId), CONCURRENCY_RIC); // - } else { - OscA1Client.UriBuilder uriBuilder = new OscA1Client.UriBuilder(ricConfig); - return getPolicyTypeIdentities() // - .flatMapMany(Flux::fromIterable) // - .flatMap(type -> oscDeleteInstancesForType(uriBuilder, type), CONCURRENCY_RIC); - } - } - - private Flux oscGetInstancesForType(OscA1Client.UriBuilder uriBuilder, String type) { - return post(GET_POLICY_RPC, uriBuilder.createGetPolicyIdsUri(type), Optional.empty()) // - .flatMapMany(SdncJsonHelper::parseJsonArrayOfString); - } - - private Flux oscDeleteInstancesForType(OscA1Client.UriBuilder uriBuilder, String type) { - return oscGetInstancesForType(uriBuilder, type) // - .flatMap(instance -> deletePolicyById(type, instance), CONCURRENCY_RIC); - } - - @Override - public Mono getProtocolVersion() { - return tryStdProtocolVersion() // - .onErrorResume(t -> tryOscProtocolVersion()); - } - - @Override - public Mono getPolicyStatus(Policy policy) { - return getUriBuilder() // - .flatMap(builder -> { - String ricUrl = builder.createGetPolicyStatusUri(policy.type().name(), policy.id()); - return post("getA1PolicyStatus", ricUrl, Optional.empty()); - }); - } - - private Mono getUriBuilder() { - if (protocolType == A1ProtocolType.SDNC_OSC_STD_V1_1) { - return Mono.just(new StdA1ClientVersion1.UriBuilder(ricConfig)); - } else { - return Mono.just(new OscA1Client.UriBuilder(ricConfig)); - } - } - - private Mono tryOscProtocolVersion() { - OscA1Client.UriBuilder oscApiuriBuilder = new OscA1Client.UriBuilder(ricConfig); - return post(GET_POLICY_RPC, oscApiuriBuilder.createHealtcheckUri(), Optional.empty()) // - .flatMap(x -> Mono.just(A1ProtocolType.SDNC_OSC_OSC_V1)); - } - - private Mono tryStdProtocolVersion() { - StdA1ClientVersion1.UriBuilder uriBuilder = new StdA1ClientVersion1.UriBuilder(ricConfig); - return post(GET_POLICY_RPC, uriBuilder.createGetPolicyIdsUri(), Optional.empty()) // - .flatMap(x -> Mono.just(A1ProtocolType.SDNC_OSC_STD_V1_1)); - } - - private Flux getPolicyIds() { - if (this.protocolType == A1ProtocolType.SDNC_OSC_STD_V1_1) { - StdA1ClientVersion1.UriBuilder uri = new StdA1ClientVersion1.UriBuilder(ricConfig); - final String ricUrl = uri.createGetPolicyIdsUri(); - return post(GET_POLICY_RPC, ricUrl, Optional.empty()) // - .flatMapMany(SdncJsonHelper::parseJsonArrayOfString); - } else { - OscA1Client.UriBuilder uri = new OscA1Client.UriBuilder(ricConfig); - return getPolicyTypeIdentities() // - .flatMapMany(Flux::fromIterable) - .flatMap(type -> post(GET_POLICY_RPC, uri.createGetPolicyIdsUri(type), Optional.empty())) // - .flatMap(SdncJsonHelper::parseJsonArrayOfString); - } - } - - private Mono deletePolicyById(String type, String policyId) { - return getUriBuilder() // - .flatMap(builder -> { - String ricUrl = builder.createDeleteUri(type, policyId); - return post("deleteA1Policy", ricUrl, Optional.empty()); - }); - } - - private Mono post(String rpcName, String ricUrl, Optional body) { - AdapterRequest inputParams = ImmutableAdapterRequest.builder() // - .nearRtRicUrl(ricUrl) // - .body(body) // - .build(); - final String inputJsonString = SdncJsonHelper.createInputJsonString(inputParams); - logger.debug("POST inputJsonString = {}", inputJsonString); - - return restClient - .postWithAuthHeader(controllerUrl(rpcName), inputJsonString, this.controllerConfig.userName(), - this.controllerConfig.password()) // - .flatMap(this::extractResponseBody); - } - - private Mono extractResponse(JSONObject responseOutput) { - AdapterOutput output = gson.fromJson(responseOutput.toString(), ImmutableAdapterOutput.class); - Optional optionalBody = output.body(); - String body = optionalBody.isPresent() ? optionalBody.get() : ""; - if (HttpStatus.valueOf(output.httpStatus()).is2xxSuccessful()) { - return Mono.just(body); - } else { - logger.debug("Error response: {} {}", output.httpStatus(), body); - byte[] responseBodyBytes = body.getBytes(StandardCharsets.UTF_8); - WebClientResponseException responseException = new WebClientResponseException(output.httpStatus(), - "statusText", null, responseBodyBytes, StandardCharsets.UTF_8, null); - - return Mono.error(responseException); - } - } - - private Mono extractResponseBody(String responseStr) { - return SdncJsonHelper.getOutput(responseStr) // - .flatMap(this::extractResponse); - } - - private String controllerUrl(String rpcName) { - return "/A1-ADAPTER-API:" + rpcName; - } -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/StdA1ClientVersion1.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/StdA1ClientVersion1.java deleted file mode 100644 index 4ebc25c6..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/clients/StdA1ClientVersion1.java +++ /dev/null @@ -1,148 +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.policyagent.clients; - -import java.util.Arrays; -import java.util.List; - -import org.oransc.policyagent.configuration.RicConfig; -import org.oransc.policyagent.configuration.WebClientConfig; -import org.oransc.policyagent.repository.Policy; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -/** - * Client for accessing standard A1 REST API version 1.1 - */ -public class StdA1ClientVersion1 implements A1Client { - - public static class UriBuilder implements A1UriBuilder { - - private final RicConfig ricConfig; - - public UriBuilder(RicConfig ricConfig) { - this.ricConfig = ricConfig; - } - - /** - * /A1-P/v1/policies/{policyId} - */ - @Override - public String createPutPolicyUri(String type, String policyId) { - return policiesBaseUri() + policyId; - } - - /** - * /A1-P/v1/policies - */ - public String createGetPolicyIdsUri() { - return baseUri() + "/policies"; - } - - /** - * /A1-P/v1/policies/{policyId} - */ - @Override - public String createDeleteUri(String type, String policyId) { - return policiesBaseUri() + policyId; - } - - /** - * /A1-P/v1/policies/{policyId}/status - */ - public String createGetPolicyStatusUri(String type, String policyId) { - return policiesBaseUri() + policyId + "/status"; - } - - private String baseUri() { - return ricConfig.baseUrl() + "/A1-P/v1"; - } - - private String policiesBaseUri() { - return createGetPolicyIdsUri() + "/"; - } - } - - private final AsyncRestClient restClient; - private final UriBuilder uri; - - public StdA1ClientVersion1(RicConfig ricConfig, WebClientConfig webClientConfig) { - this(new AsyncRestClient("", webClientConfig), ricConfig); - } - - public StdA1ClientVersion1(AsyncRestClient restClient, RicConfig ricConfig) { - this.restClient = restClient; - this.uri = new UriBuilder(ricConfig); - } - - @Override - public Mono> getPolicyIdentities() { - return getPolicyIds() // - .collectList(); - } - - @Override - public Mono putPolicy(Policy policy) { - return restClient.put(uri.createPutPolicyUri(policy.type().name(), policy.id()), policy.json()); - } - - @Override - public Mono> getPolicyTypeIdentities() { - return Mono.just(Arrays.asList("")); - } - - @Override - public Mono getPolicyTypeSchema(String policyTypeId) { - return Mono.just("{}"); - } - - @Override - public Mono deletePolicy(Policy policy) { - return deletePolicyById(policy.id()); - } - - @Override - public Flux deleteAllPolicies() { - return getPolicyIds() // - .flatMap(this::deletePolicyById); // - } - - @Override - public Mono getProtocolVersion() { - return getPolicyIdentities() // - .flatMap(x -> Mono.just(A1ProtocolType.STD_V1_1)); - } - - @Override - public Mono getPolicyStatus(Policy policy) { - return restClient.get(uri.createGetPolicyStatusUri(policy.type().name(), policy.id())); - } - - private Flux getPolicyIds() { - return restClient.get(uri.createGetPolicyIdsUri()) // - .flatMapMany(SdncJsonHelper::parseJsonArrayOfString); - } - - private Mono deletePolicyById(String policyId) { - return restClient.delete(uri.createDeleteUri("", policyId)); - } -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfig.java b/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfig.java deleted file mode 100644 index 5e020983..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfig.java +++ /dev/null @@ -1,155 +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.policyagent.configuration; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -import javax.validation.constraints.NotEmpty; - -import lombok.Getter; - -import org.oransc.policyagent.exceptions.ServiceException; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import reactor.core.publisher.Flux; - -@EnableConfigurationProperties -@ConfigurationProperties() -public class ApplicationConfig { - @NotEmpty - @Getter - @Value("${app.filepath}") - private String localConfigurationFilePath; - - @Value("${server.ssl.key-store-type}") - private String sslKeyStoreType = ""; - - @Value("${server.ssl.key-store-password}") - private String sslKeyStorePassword = ""; - - @Value("${server.ssl.key-store}") - private String sslKeyStore = ""; - - @Value("${server.ssl.key-password}") - private String sslKeyPassword = ""; - - @Value("${app.webclient.trust-store-used}") - private boolean sslTrustStoreUsed = false; - - @Value("${app.webclient.trust-store-password}") - private String sslTrustStorePassword = ""; - - @Value("${app.webclient.trust-store}") - private String sslTrustStore = ""; - - private Map ricConfigs = new HashMap<>(); - - @Getter - private String dmaapConsumerTopicUrl; - - @Getter - private String dmaapProducerTopicUrl; - - private Map controllerConfigs = new HashMap<>(); - - public synchronized Collection getRicConfigs() { - return this.ricConfigs.values(); - } - - public WebClientConfig getWebClientConfig() { - return ImmutableWebClientConfig.builder() // - .keyStoreType(this.sslKeyStoreType) // - .keyStorePassword(this.sslKeyStorePassword) // - .keyStore(this.sslKeyStore) // - .keyPassword(this.sslKeyPassword) // - .isTrustStoreUsed(this.sslTrustStoreUsed) // - .trustStore(this.sslTrustStore) // - .trustStorePassword(this.sslTrustStorePassword) // - .build(); - } - - public synchronized ControllerConfig getControllerConfig(String name) throws ServiceException { - ControllerConfig controllerConfig = this.controllerConfigs.get(name); - if (controllerConfig == null) { - throw new ServiceException("Could not find controller config: " + name); - } - return controllerConfig; - } - - public synchronized RicConfig getRic(String ricName) throws ServiceException { - RicConfig ricConfig = this.ricConfigs.get(ricName); - if (ricConfig == null) { - throw new ServiceException("Could not find ric configuration: " + ricName); - } - return ricConfig; - } - - public static class RicConfigUpdate { - public enum Type { - ADDED, CHANGED, REMOVED - } - - @Getter - private final RicConfig ricConfig; - @Getter - private final Type type; - - RicConfigUpdate(RicConfig ric, Type event) { - this.ricConfig = ric; - this.type = event; - } - } - - public synchronized Flux setConfiguration( - ApplicationConfigParser.ConfigParserResult parserResult) { - - Collection modifications = new ArrayList<>(); - this.controllerConfigs = parserResult.controllerConfigs(); - - this.dmaapConsumerTopicUrl = parserResult.dmaapConsumerTopicUrl(); - this.dmaapProducerTopicUrl = parserResult.dmaapProducerTopicUrl(); - - Map newRicConfigs = new HashMap<>(); - for (RicConfig newConfig : parserResult.ricConfigs()) { - RicConfig oldConfig = this.ricConfigs.get(newConfig.name()); - this.ricConfigs.remove(newConfig.name()); - if (oldConfig == null) { - newRicConfigs.put(newConfig.name(), newConfig); - modifications.add(new RicConfigUpdate(newConfig, RicConfigUpdate.Type.ADDED)); - } else if (!newConfig.equals(oldConfig)) { - modifications.add(new RicConfigUpdate(newConfig, RicConfigUpdate.Type.CHANGED)); - newRicConfigs.put(newConfig.name(), newConfig); - } else { - newRicConfigs.put(oldConfig.name(), oldConfig); - } - } - for (RicConfig deletedConfig : this.ricConfigs.values()) { - modifications.add(new RicConfigUpdate(deletedConfig, RicConfigUpdate.Type.REMOVED)); - } - this.ricConfigs = newRicConfigs; - - return Flux.fromIterable(modifications); - } -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfigParser.java b/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfigParser.java deleted file mode 100644 index 14e836be..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfigParser.java +++ /dev/null @@ -1,189 +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.policyagent.configuration; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -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.Map.Entry; -import java.util.Set; - -import javax.validation.constraints.NotNull; - -import org.immutables.gson.Gson; -import org.immutables.value.Value; -import org.oransc.policyagent.exceptions.ServiceException; - -/** - * Parser for the Json representing of the component configuration. - */ -public class ApplicationConfigParser { - - private static final String CONFIG = "config"; - private static final String CONTROLLER = "controller"; - - @Value.Immutable - @Gson.TypeAdapters - public interface ConfigParserResult { - List ricConfigs(); - - Map controllerConfigs(); - - String dmaapConsumerTopicUrl(); - - String dmaapProducerTopicUrl(); - - } - - public ConfigParserResult parse(JsonObject root) throws ServiceException { - - String dmaapProducerTopicUrl = ""; - String dmaapConsumerTopicUrl = ""; - - JsonObject agentConfigJson = root.getAsJsonObject(CONFIG); - - if (agentConfigJson == null) { - throw new ServiceException("Missing root configuration \"" + CONFIG + "\" in JSON: " + root); - } - - JsonObject json = agentConfigJson.getAsJsonObject("streams_publishes"); - if (json != null) { - dmaapProducerTopicUrl = parseDmaapConfig(json); - } - - json = agentConfigJson.getAsJsonObject("streams_subscribes"); - if (json != null) { - dmaapConsumerTopicUrl = parseDmaapConfig(json); - } - - List ricConfigs = parseRics(agentConfigJson); - Map controllerConfigs = parseControllerConfigs(agentConfigJson); - checkConfigurationConsistency(ricConfigs, controllerConfigs); - - return ImmutableConfigParserResult.builder() // - .dmaapConsumerTopicUrl(dmaapConsumerTopicUrl) // - .dmaapProducerTopicUrl(dmaapProducerTopicUrl) // - .ricConfigs(ricConfigs) // - .controllerConfigs(controllerConfigs) // - .build(); - } - - private void checkConfigurationConsistency(List ricConfigs, - Map controllerConfigs) throws ServiceException { - Set ricUrls = new HashSet<>(); - Set ricNames = new HashSet<>(); - for (RicConfig ric : ricConfigs) { - if (!ricUrls.add(ric.baseUrl())) { - throw new ServiceException("Configuration error, more than one RIC URL: " + ric.baseUrl()); - } - if (!ricNames.add(ric.name())) { - throw new ServiceException("Configuration error, more than one RIC with name: " + ric.name()); - } - if (!ric.controllerName().isEmpty() && controllerConfigs.get(ric.controllerName()) == null) { - throw new ServiceException( - "Configuration error, controller configuration not found: " + ric.controllerName()); - } - - } - } - - private List parseRics(JsonObject config) throws ServiceException { - List result = new ArrayList<>(); - for (JsonElement ricElem : getAsJsonArray(config, "ric")) { - JsonObject ricAsJson = ricElem.getAsJsonObject(); - JsonElement controllerNameElement = ricAsJson.get(CONTROLLER); - ImmutableRicConfig ricConfig = ImmutableRicConfig.builder() // - .name(get(ricAsJson, "name").getAsString()) // - .baseUrl(get(ricAsJson, "baseUrl").getAsString()) // - .managedElementIds(parseManagedElementIds(get(ricAsJson, "managedElementIds").getAsJsonArray())) // - .controllerName(controllerNameElement != null ? controllerNameElement.getAsString() : "") // - .build(); - result.add(ricConfig); - } - return result; - } - - Map parseControllerConfigs(JsonObject config) throws ServiceException { - if (config.get(CONTROLLER) == null) { - return new HashMap<>(); - } - Map result = new HashMap<>(); - for (JsonElement element : getAsJsonArray(config, CONTROLLER)) { - JsonObject controllerAsJson = element.getAsJsonObject(); - ImmutableControllerConfig controllerConfig = ImmutableControllerConfig.builder() // - .name(get(controllerAsJson, "name").getAsString()) // - .baseUrl(get(controllerAsJson, "baseUrl").getAsString()) // - .password(get(controllerAsJson, "password").getAsString()) // - .userName(get(controllerAsJson, "userName").getAsString()) // ) - .build(); - - if (result.put(controllerConfig.name(), controllerConfig) != null) { - throw new ServiceException( - "Configuration error, more than one controller with name: " + controllerConfig.name()); - } - } - return result; - } - - private List parseManagedElementIds(JsonArray asJsonObject) { - Iterator iterator = asJsonObject.iterator(); - List managedElementIds = new ArrayList<>(); - while (iterator.hasNext()) { - managedElementIds.add(iterator.next().getAsString()); - - } - return managedElementIds; - } - - private static JsonElement get(JsonObject obj, String memberName) throws ServiceException { - JsonElement elem = obj.get(memberName); - if (elem == null) { - throw new ServiceException("Could not find member: '" + memberName + "' in: " + obj); - } - return elem; - } - - private JsonArray getAsJsonArray(JsonObject obj, String memberName) throws ServiceException { - return get(obj, memberName).getAsJsonArray(); - } - - private String parseDmaapConfig(JsonObject streamCfg) throws ServiceException { - Set> streamConfigEntries = streamCfg.entrySet(); - if (streamConfigEntries.size() != 1) { - throw new ServiceException( - "Invalid configuration. Number of streams must be one, config: " + streamConfigEntries); - } - JsonObject streamConfigEntry = streamConfigEntries.iterator().next().getValue().getAsJsonObject(); - JsonObject dmaapInfo = get(streamConfigEntry, "dmaap_info").getAsJsonObject(); - return getAsString(dmaapInfo, "topic_url"); - } - - private static @NotNull String getAsString(JsonObject obj, String memberName) throws ServiceException { - return get(obj, memberName).getAsString(); - } -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/configuration/AsyncConfiguration.java b/policy-agent/src/main/java/org/oransc/policyagent/configuration/AsyncConfiguration.java deleted file mode 100644 index 882f30c4..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/configuration/AsyncConfiguration.java +++ /dev/null @@ -1,45 +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.policyagent.configuration; - -import java.util.concurrent.Executor; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.scheduling.annotation.AsyncConfigurer; -import org.springframework.scheduling.annotation.EnableAsync; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; - -@Configuration -@EnableAsync -public class AsyncConfiguration implements AsyncConfigurer { - - @Override - @Bean(name = "threadPoolTaskExecutor") - public Executor getAsyncExecutor() { - // Set this configuration value from common properties file - ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); - executor.setCorePoolSize(5); - executor.setMaxPoolSize(10); - executor.setQueueCapacity(25); - return executor; - } -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/configuration/ControllerConfig.java b/policy-agent/src/main/java/org/oransc/policyagent/configuration/ControllerConfig.java deleted file mode 100644 index fa88d14b..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/configuration/ControllerConfig.java +++ /dev/null @@ -1,38 +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.policyagent.configuration; - -import org.immutables.value.Value; - -@Value.Immutable -@Value.Style(redactedMask = "####") - -public interface ControllerConfig { - public String name(); - - public String baseUrl(); - - public String userName(); - - @Value.Redacted - public String password(); - -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/configuration/RicConfig.java b/policy-agent/src/main/java/org/oransc/policyagent/configuration/RicConfig.java deleted file mode 100644 index 8de250ed..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/configuration/RicConfig.java +++ /dev/null @@ -1,37 +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.policyagent.configuration; - -import com.google.common.collect.ImmutableList; - -import org.immutables.value.Value; - -@Value.Immutable -public interface RicConfig { - public String name(); - - public String controllerName(); - - public String baseUrl(); - - public ImmutableList managedElementIds(); - -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/configuration/WebClientConfig.java b/policy-agent/src/main/java/org/oransc/policyagent/configuration/WebClientConfig.java deleted file mode 100644 index 7f0b233e..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/configuration/WebClientConfig.java +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.configuration; - -import org.immutables.value.Value; - -@Value.Immutable -@Value.Style(redactedMask = "####") -public interface WebClientConfig { - public String keyStoreType(); - - @Value.Redacted - public String keyStorePassword(); - - public String keyStore(); - - @Value.Redacted - public String keyPassword(); - - public boolean isTrustStoreUsed(); - - @Value.Redacted - public String trustStorePassword(); - - public String trustStore(); - -} 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 deleted file mode 100644 index d2ae0e0d..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyController.java +++ /dev/null @@ -1,482 +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.policyagent.controllers; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; - -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; - -import java.lang.invoke.MethodHandles; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import lombok.Getter; - -import org.oransc.policyagent.clients.A1ClientFactory; -import org.oransc.policyagent.exceptions.ServiceException; -import org.oransc.policyagent.repository.ImmutablePolicy; -import org.oransc.policyagent.repository.Lock.LockType; -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.oransc.policyagent.repository.Service; -import org.oransc.policyagent.repository.Services; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -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; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.reactive.function.client.WebClientResponseException; -import reactor.core.publisher.Mono; - -@RestController -@Api(tags = "A1 Policy Management") -public class PolicyController { - - public static class RejectionException extends Exception { - private static final long serialVersionUID = 1L; - @Getter - private final HttpStatus status; - - public RejectionException(String message, HttpStatus status) { - super(message); - this.status = status; - } - } - - @Autowired - private Rics rics; - @Autowired - private PolicyTypes policyTypes; - @Autowired - private Policies policies; - @Autowired - private A1ClientFactory a1ClientFactory; - @Autowired - private Services services; - - private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - private static Gson gson = new GsonBuilder() // - .serializeNulls() // - .create(); // - - @GetMapping("/policy_schemas") - @ApiOperation(value = "Returns policy type schema definitions") - @ApiResponses( - value = { - @ApiResponse(code = 200, message = "Policy schemas", response = Object.class, responseContainer = "List"), // - @ApiResponse(code = 404, message = "RIC is not found", response = String.class)}) - public ResponseEntity getPolicySchemas( // - @ApiParam(name = "ric", required = false, value = "The name of the Near-RT RIC to get the definitions for.") // - @RequestParam(name = "ric", required = false) String ricName) { - if (ricName == null) { - Collection types = this.policyTypes.getAll(); - return new ResponseEntity<>(toPolicyTypeSchemasJson(types), HttpStatus.OK); - } else { - try { - Collection types = rics.getRic(ricName).getSupportedPolicyTypes(); - return new ResponseEntity<>(toPolicyTypeSchemasJson(types), HttpStatus.OK); - } catch (ServiceException e) { - return new ResponseEntity<>(e.toString(), HttpStatus.NOT_FOUND); - } - } - } - - @GetMapping("/policy_schema") - @ApiOperation(value = "Returns one policy type schema definition") - @ApiResponses( - value = { // - @ApiResponse(code = 200, message = "Policy schema", response = Object.class), - @ApiResponse(code = 404, message = "RIC is not found", response = String.class)}) - public ResponseEntity getPolicySchema( // - @ApiParam(name = "id", required = true, value = "The ID of the policy type to get the definition for.") // - @RequestParam(name = "id", required = true) String id) { - try { - PolicyType type = policyTypes.getType(id); - return new ResponseEntity<>(type.schema(), HttpStatus.OK); - } catch (ServiceException e) { - return new ResponseEntity<>(e.toString(), HttpStatus.NOT_FOUND); - } - } - - @GetMapping("/policy_types") - @ApiOperation(value = "Query policy type names") - @ApiResponses( - value = { - @ApiResponse( - code = 200, - message = "Policy type names", - response = String.class, - responseContainer = "List"), - @ApiResponse(code = 404, message = "RIC is not found", response = String.class)}) - public ResponseEntity getPolicyTypes( // - @ApiParam(name = "ric", required = false, value = "The name of the Near-RT RIC to get types for.") // - @RequestParam(name = "ric", required = false) String ricName) { - if (ricName == null) { - Collection types = this.policyTypes.getAll(); - return new ResponseEntity<>(toPolicyTypeIdsJson(types), HttpStatus.OK); - } else { - try { - Collection types = rics.getRic(ricName).getSupportedPolicyTypes(); - return new ResponseEntity<>(toPolicyTypeIdsJson(types), HttpStatus.OK); - } catch (ServiceException e) { - return new ResponseEntity<>(e.toString(), HttpStatus.NOT_FOUND); - } - } - } - - @GetMapping("/policy") - @ApiOperation(value = "Returns a policy configuration") // - @ApiResponses( - value = { // - @ApiResponse(code = 200, message = "Policy found", response = Object.class), // - @ApiResponse(code = 404, message = "Policy is not found")} // - ) - public ResponseEntity getPolicy( // - @ApiParam(name = "id", required = true, value = "The ID of the policy instance.") // - @RequestParam(name = "id", required = true) String id) { - try { - Policy p = policies.getPolicy(id); - return new ResponseEntity<>(p.json(), HttpStatus.OK); - } catch (ServiceException e) { - return new ResponseEntity<>(e.getMessage(), HttpStatus.NOT_FOUND); - } - } - - @DeleteMapping("/policy") - @ApiOperation(value = "Delete a policy", response = Object.class) - @ApiResponses( - value = { // - @ApiResponse(code = 204, message = "Policy deleted", response = Object.class), - @ApiResponse(code = 404, message = "Policy is not found", response = String.class), - @ApiResponse(code = 423, message = "RIC is not operational", response = String.class)}) - public Mono> deletePolicy( // - @ApiParam(name = "id", required = true, value = "The ID of the policy instance.") // - @RequestParam(name = "id", required = true) String id) { - try { - Policy policy = policies.getPolicy(id); - keepServiceAlive(policy.ownerServiceName()); - Ric ric = policy.ric(); - return ric.getLock().lock(LockType.SHARED) // - .flatMap(notUsed -> assertRicStateIdle(ric)) // - .flatMap(notUsed -> a1ClientFactory.createA1Client(policy.ric())) // - .doOnNext(notUsed -> policies.remove(policy)) // - .flatMap(client -> client.deletePolicy(policy)) // - .doOnNext(notUsed -> ric.getLock().unlockBlocking()) // - .doOnError(notUsed -> ric.getLock().unlockBlocking()) // - .flatMap(notUsed -> Mono.just(new ResponseEntity<>(HttpStatus.NO_CONTENT))) - .onErrorResume(this::handleException); - } catch (ServiceException e) { - return Mono.just(new ResponseEntity<>(HttpStatus.NOT_FOUND)); - } - } - - @PutMapping(path = "/policy") - @ApiOperation(value = "Put a policy", response = String.class) - @ApiResponses( - value = { // - @ApiResponse(code = 201, message = "Policy created", response = Object.class), // - @ApiResponse(code = 200, message = "Policy updated", response = Object.class), // - @ApiResponse(code = 423, message = "RIC is not operational", response = String.class), // - @ApiResponse(code = 404, message = "RIC or policy type is not found", response = String.class) // - }) - public Mono> putPolicy( // - @ApiParam(name = "type", required = false, value = "The name of the policy type.") // - @RequestParam(name = "type", required = false, defaultValue = "") String typeName, // - @ApiParam(name = "id", required = true, value = "The ID of the policy instance.") // - @RequestParam(name = "id", required = true) String instanceId, // - @ApiParam(name = "ric", required = true, value = "The name of the Near-RT RIC where the policy will be " + // - "created.") // - @RequestParam(name = "ric", required = true) String ricName, // - @ApiParam(name = "service", required = true, value = "The name of the service creating the policy.") // - @RequestParam(name = "service", required = true) String service, // - @ApiParam(name = "transient", required = false, value = "If the policy is transient or not (boolean " + // - "defaulted to false). A policy is transient if it will be forgotten when the service needs to " + // - "reconnect to the Near-RT RIC.") // - @RequestParam(name = "transient", required = false, defaultValue = "false") boolean isTransient, // - @RequestBody Object jsonBody) { - - String jsonString = gson.toJson(jsonBody); - Ric ric = rics.get(ricName); - PolicyType type = policyTypes.get(typeName); - keepServiceAlive(service); - if (ric == null || type == null) { - return Mono.just(new ResponseEntity<>(HttpStatus.NOT_FOUND)); - } - Policy policy = ImmutablePolicy.builder() // - .id(instanceId) // - .json(jsonString) // - .type(type) // - .ric(ric) // - .ownerServiceName(service) // - .lastModified(getTimeStampUtc()) // - .isTransient(isTransient) // - .build(); - - final boolean isCreate = this.policies.get(policy.id()) == null; - - return ric.getLock().lock(LockType.SHARED) // - .flatMap(notUsed -> assertRicStateIdle(ric)) // - .flatMap(notUsed -> checkSupportedType(ric, type)) // - .flatMap(notUsed -> validateModifiedPolicy(policy)) // - .flatMap(notUsed -> a1ClientFactory.createA1Client(ric)) // - .flatMap(client -> client.putPolicy(policy)) // - .doOnNext(notUsed -> policies.put(policy)) // - .doOnNext(notUsed -> ric.getLock().unlockBlocking()) // - .doOnError(trowable -> ric.getLock().unlockBlocking()) // - .flatMap(notUsed -> Mono.just(new ResponseEntity<>(isCreate ? HttpStatus.CREATED : HttpStatus.OK))) // - .onErrorResume(this::handleException); - } - - @SuppressWarnings({"unchecked"}) - private Mono> createResponseEntity(String message, HttpStatus status) { - ResponseEntity re = new ResponseEntity<>((T) message, status); - return Mono.just(re); - } - - private Mono> handleException(Throwable throwable) { - if (throwable instanceof WebClientResponseException) { - WebClientResponseException e = (WebClientResponseException) throwable; - return createResponseEntity(e.getResponseBodyAsString(), e.getStatusCode()); - } else if (throwable instanceof RejectionException) { - RejectionException e = (RejectionException) throwable; - return createResponseEntity(e.getMessage(), e.getStatus()); - } else { - return createResponseEntity(throwable.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); - } - } - - private Mono validateModifiedPolicy(Policy policy) { - // Check that ric is not updated - Policy current = this.policies.get(policy.id()); - if (current != null && !current.ric().name().equals(policy.ric().name())) { - RejectionException e = new RejectionException("Policy cannot change RIC, policyId: " + current.id() + // - ", RIC name: " + current.ric().name() + // - ", new name: " + policy.ric().name(), HttpStatus.CONFLICT); - logger.debug("Request rejected, {}", e.getMessage()); - return Mono.error(e); - } - return Mono.just("OK"); - } - - private Mono checkSupportedType(Ric ric, PolicyType type) { - if (!ric.isSupportingType(type.name())) { - logger.debug("Request rejected, type not supported, RIC: {}", ric); - RejectionException e = new RejectionException( - "Type: " + type.name() + " not supported by RIC: " + ric.name(), HttpStatus.NOT_FOUND); - return Mono.error(e); - } - return Mono.just("OK"); - } - - private Mono assertRicStateIdle(Ric ric) { - if (ric.getState() == Ric.RicState.AVAILABLE) { - return Mono.just("OK"); - } else { - logger.debug("Request rejected RIC not IDLE, ric: {}", ric); - RejectionException e = new RejectionException( - "Ric is not operational, RIC name: " + ric.name() + ", state: " + ric.getState(), HttpStatus.LOCKED); - return Mono.error(e); - } - } - - @GetMapping("/policies") - @ApiOperation(value = "Query policies") - @ApiResponses( - value = { - @ApiResponse(code = 200, message = "Policies", response = PolicyInfo.class, responseContainer = "List"), - @ApiResponse(code = 404, message = "RIC or type not found", response = String.class)}) - public ResponseEntity getPolicies( // - @ApiParam(name = "type", required = false, value = "The name of the policy type to get policies for.") // - @RequestParam(name = "type", required = false) String type, // - @ApiParam(name = "ric", required = false, value = "The name of the Near-RT RIC to get policies for.") // - @RequestParam(name = "ric", required = false) String ric, // - @ApiParam(name = "service", required = false, value = "The name of the service to get policies for.") // - @RequestParam(name = "service", required = false) String service) // - { - if ((type != null && this.policyTypes.get(type) == null)) { - return new ResponseEntity<>("Policy type not found", HttpStatus.NOT_FOUND); - } - if ((ric != null && this.rics.get(ric) == null)) { - return new ResponseEntity<>("RIC not found", HttpStatus.NOT_FOUND); - } - - String filteredPolicies = policiesToJson(filter(type, ric, service)); - return new ResponseEntity<>(filteredPolicies, HttpStatus.OK); - } - - @GetMapping("/policy_ids") - @ApiOperation(value = "Query policies, only IDs returned") - @ApiResponses( - value = {@ApiResponse(code = 200, message = "Policy ids", response = String.class, responseContainer = "List"), - @ApiResponse(code = 404, message = "RIC or type not found", response = String.class)}) - public ResponseEntity getPolicyIds( // - @ApiParam(name = "type", required = false, value = "The name of the policy type to get policies for.") // - @RequestParam(name = "type", required = false) String type, // - @ApiParam(name = "ric", required = false, value = "The name of the Near-RT RIC to get policies for.") // - @RequestParam(name = "ric", required = false) String ric, // - @ApiParam(name = "service", required = false, value = "The name of the service to get policies for.") // - @RequestParam(name = "service", required = false) String service) // - { - if ((type != null && this.policyTypes.get(type) == null)) { - return new ResponseEntity<>("Policy type not found", HttpStatus.NOT_FOUND); - } - if ((ric != null && this.rics.get(ric) == null)) { - return new ResponseEntity<>("RIC not found", HttpStatus.NOT_FOUND); - } - - String policyIdsJson = toPolicyIdsJson(filter(type, ric, service)); - return new ResponseEntity<>(policyIdsJson, HttpStatus.OK); - } - - @GetMapping("/policy_status") - @ApiOperation(value = "Returns a policy status") // - @ApiResponses( - value = { // - @ApiResponse(code = 200, message = "Policy status", response = Object.class), // - @ApiResponse(code = 404, message = "Policy is not found", response = String.class)} // - ) - public Mono> getPolicyStatus( // - @ApiParam(name = "id", required = true, value = "The ID of the policy.") @RequestParam( - name = "id", // - required = true) String id) { - try { - Policy policy = policies.getPolicy(id); - - return a1ClientFactory.createA1Client(policy.ric()) // - .flatMap(client -> client.getPolicyStatus(policy)) // - .flatMap(status -> Mono.just(new ResponseEntity<>(status, HttpStatus.OK))) - .onErrorResume(this::handleException); - } catch (ServiceException e) { - return Mono.just(new ResponseEntity<>(e.getMessage(), HttpStatus.NOT_FOUND)); - } - } - - private void keepServiceAlive(String name) { - Service s = this.services.get(name); - if (s != null) { - s.keepAlive(); - } - } - - private boolean include(String filter, String value) { - return filter == null || value.equals(filter); - } - - private Collection filter(Collection collection, String type, String ric, String service) { - if (type == null && ric == null && service == null) { - return collection; - } - List filtered = new ArrayList<>(); - for (Policy p : collection) { - if (include(type, p.type().name()) && include(ric, p.ric().name()) - && include(service, p.ownerServiceName())) { - filtered.add(p); - } - } - return filtered; - } - - private Collection filter(String type, String ric, String service) { - if (type != null) { - return filter(policies.getForType(type), null, ric, service); - } else if (service != null) { - return filter(policies.getForService(service), type, ric, null); - } else if (ric != null) { - return filter(policies.getForRic(ric), type, null, service); - } else { - return policies.getAll(); - } - } - - private String policiesToJson(Collection policies) { - List v = new ArrayList<>(policies.size()); - for (Policy p : policies) { - PolicyInfo policyInfo = new PolicyInfo(); - policyInfo.id = p.id(); - policyInfo.json = fromJson(p.json()); - policyInfo.ric = p.ric().name(); - policyInfo.type = p.type().name(); - policyInfo.service = p.ownerServiceName(); - policyInfo.lastModified = p.lastModified(); - if (!policyInfo.validate()) { - logger.error("BUG, all fields must be set"); - } - v.add(policyInfo); - } - return gson.toJson(v); - } - - private Object fromJson(String jsonStr) { - return gson.fromJson(jsonStr, Object.class); - } - - private String toPolicyTypeSchemasJson(Collection types) { - StringBuilder result = new StringBuilder(); - result.append("["); - boolean first = true; - for (PolicyType t : types) { - if (!first) { - result.append(","); - } - first = false; - result.append(t.schema()); - } - result.append("]"); - return result.toString(); - } - - private String toPolicyTypeIdsJson(Collection types) { - List v = new ArrayList<>(types.size()); - for (PolicyType t : types) { - v.add(t.name()); - } - return gson.toJson(v); - } - - private String toPolicyIdsJson(Collection policies) { - List v = new ArrayList<>(policies.size()); - for (Policy p : policies) { - v.add(p.id()); - } - return gson.toJson(v); - } - - private String getTimeStampUtc() { - return java.time.Instant.now().toString(); - } - -} 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 deleted file mode 100644 index d28ce025..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyInfo.java +++ /dev/null @@ -1,57 +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.policyagent.controllers; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; - -import org.immutables.gson.Gson; - -@Gson.TypeAdapters -@ApiModel(value = "PolicyInfo") -public class PolicyInfo { - - @ApiModelProperty(value = "identity of the policy") - public String id; - - @ApiModelProperty(value = "name of the policy type") - public String type; - - @ApiModelProperty(value = "identity of the target Near-RT RIC") - public String ric; - - @ApiModelProperty(value = "the configuration of the policy") - public Object json; - - @ApiModelProperty(value = "the name of the service owning the policy") - public String service; - - @ApiModelProperty(value = "timestamp, last modification time") - public String lastModified; - - PolicyInfo() { - } - - public boolean validate() { - return id != null && type != null && ric != null && json != null && service != null && lastModified != null; - } - -} 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 deleted file mode 100644 index c75270e4..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/controllers/RicInfo.java +++ /dev/null @@ -1,51 +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.policyagent.controllers; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; - -import java.util.Collection; - -import org.immutables.gson.Gson; - -@Gson.TypeAdapters -@ApiModel(value = "RicInfo") -class RicInfo { - @ApiModelProperty(value = "identity of the ric") - public final String ricName; - - @ApiModelProperty(value = "O1 identities for managed entities") - public final Collection managedElementIds; - - @ApiModelProperty(value = "supported policy types") - public final Collection policyTypes; - - @ApiModelProperty(value = "state info") - public final String state; - - RicInfo(String name, Collection managedElementIds, Collection policyTypes, String state) { - this.ricName = name; - this.managedElementIds = managedElementIds; - this.policyTypes = policyTypes; - this.state = state; - } -} 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 deleted file mode 100644 index c3e58008..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/controllers/RicRepositoryController.java +++ /dev/null @@ -1,109 +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.policyagent.controllers; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; - -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -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.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@Api(tags = "RIC Repository") -public class RicRepositoryController { - - @Autowired - private Rics rics; - - @Autowired - PolicyTypes types; - - private static Gson gson = new GsonBuilder() // - .serializeNulls() // - .create(); // - - /** - * Example: http://localhost:8081/rics?managedElementId=kista_1 - */ - @GetMapping("/ric") - @ApiOperation(value = "Returns the name of a RIC managing one Mananged Element") - @ApiResponses( - value = { // - @ApiResponse(code = 200, message = "RIC is found", response = String.class), // - @ApiResponse(code = 404, message = "RIC is not found", response = String.class) // - }) - public ResponseEntity getRic( // - @ApiParam(name = "managedElementId", required = true, value = "The ID of the Managed Element") // - @RequestParam(name = "managedElementId", required = true) String managedElementId) { - Optional ric = this.rics.lookupRicForManagedElement(managedElementId); - - if (ric.isPresent()) { - return new ResponseEntity<>(ric.get().name(), HttpStatus.OK); - } else { - return new ResponseEntity<>("No RIC found", HttpStatus.NOT_FOUND); - } - } - - /** - * @return a Json array of all RIC data Example: http://localhost:8081/ric - */ - @GetMapping("/rics") - @ApiOperation(value = "Query Near-RT RIC information") - @ApiResponses( - value = { // - @ApiResponse(code = 200, message = "OK", response = RicInfo.class, responseContainer = "List"), // - @ApiResponse(code = 404, message = "Policy type is not found", response = String.class)}) - public ResponseEntity getRics( // - @ApiParam(name = "policyType", required = false, value = "The name of the policy type") // - @RequestParam(name = "policyType", required = false) String supportingPolicyType) { - if ((supportingPolicyType != null) && (this.types.get(supportingPolicyType) == null)) { - return new ResponseEntity<>("Policy type not found", HttpStatus.NOT_FOUND); - } - - List result = new ArrayList<>(); - for (Ric ric : rics.getRics()) { - if (supportingPolicyType == null || ric.isSupportingType(supportingPolicyType)) { - result.add(new RicInfo(ric.name(), ric.getManagedElementIds(), ric.getSupportedPolicyTypeNames(), - ric.getState().toString())); - } - } - - return new ResponseEntity<>(gson.toJson(result), HttpStatus.OK); - } - -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceController.java b/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceController.java deleted file mode 100644 index 84818304..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceController.java +++ /dev/null @@ -1,184 +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.policyagent.controllers; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; - -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; - -import java.net.MalformedURLException; -import java.net.URL; -import java.time.Duration; -import java.util.ArrayList; -import java.util.Collection; - -import org.oransc.policyagent.exceptions.ServiceException; -import org.oransc.policyagent.repository.Policies; -import org.oransc.policyagent.repository.Policy; -import org.oransc.policyagent.repository.Service; -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; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@Api(tags = "Service registry and supervision") -public class ServiceController { - - private final Services services; - private final Policies policies; - - private static Gson gson = new GsonBuilder() // - .create(); // - - @Autowired - ServiceController(Services services, Policies policies) { - this.services = services; - this.policies = policies; - } - - @GetMapping("/services") - @ApiOperation(value = "Returns service information") - @ApiResponses( - value = { // - @ApiResponse(code = 200, message = "OK", response = ServiceStatus.class, responseContainer = "List"), // - @ApiResponse(code = 404, message = "Service is not found", response = String.class)}) - public ResponseEntity getServices(// - @ApiParam(name = "name", required = false, value = "The name of the service") // - @RequestParam(name = "name", required = false) String name) { - if (name != null && this.services.get(name) == null) { - return new ResponseEntity<>("Service not found", HttpStatus.NOT_FOUND); - } - - Collection servicesStatus = new ArrayList<>(); - for (Service s : this.services.getAll()) { - if (name == null || name.equals(s.getName())) { - servicesStatus.add(toServiceStatus(s)); - } - } - - String res = gson.toJson(servicesStatus); - return new ResponseEntity<>(res, HttpStatus.OK); - } - - private ServiceStatus toServiceStatus(Service s) { - return new ServiceStatus(s.getName(), s.getKeepAliveInterval().toSeconds(), s.timeSinceLastPing().toSeconds(), - s.getCallbackUrl()); - } - - private void validateRegistrationInfo(ServiceRegistrationInfo registrationInfo) - throws ServiceException, MalformedURLException { - if (registrationInfo.serviceName.isEmpty()) { - throw new ServiceException("Missing mandatory parameter 'serviceName'"); - } - if (registrationInfo.keepAliveIntervalSeconds < 0) { - throw new ServiceException("Keepalive interval shoul be greater or equal to 0"); - } - if (!registrationInfo.callbackUrl.isEmpty()) { - new URL(registrationInfo.callbackUrl); - } - } - - @ApiOperation(value = "Register a service") - @ApiResponses( - value = { // - @ApiResponse(code = 200, message = "Service updated", response = String.class), - @ApiResponse(code = 201, message = "Service created", response = String.class), // - @ApiResponse(code = 400, message = "The ServiceRegistrationInfo is not accepted", response = String.class)}) - @PutMapping("/service") - public ResponseEntity putService(// - @RequestBody ServiceRegistrationInfo registrationInfo) { - try { - validateRegistrationInfo(registrationInfo); - final boolean isCreate = this.services.get(registrationInfo.serviceName) == null; - this.services.put(toService(registrationInfo)); - return new ResponseEntity<>("OK", isCreate ? HttpStatus.CREATED : HttpStatus.OK); - } catch (Exception e) { - return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST); - } - } - - @ApiOperation(value = "Delete a service") - @ApiResponses( - value = { // - @ApiResponse(code = 204, message = "OK"), - @ApiResponse(code = 404, message = "Service not found", response = String.class)}) - @DeleteMapping("/services") - public ResponseEntity deleteService(// - @ApiParam(name = "name", required = true, value = "The name of the service") // - @RequestParam(name = "name", required = true) String serviceName) { - try { - Service service = removeService(serviceName); - // Remove the policies from the repo and let the consistency monitoring - // do the rest. - removePolicies(service); - return new ResponseEntity<>("OK", HttpStatus.NO_CONTENT); - } catch (Exception e) { - return new ResponseEntity<>(e.getMessage(), HttpStatus.NOT_FOUND); - } - } - - @ApiOperation(value = "Heartbeat from a serice") - @ApiResponses( - value = { // - @ApiResponse(code = 200, message = "Service supervision timer refreshed, OK"), - @ApiResponse(code = 404, message = "The service is not found, needs re-registration")}) - @PutMapping("/services/keepalive") - public ResponseEntity keepAliveService(// - @ApiParam(name = "name", required = true, value = "The name of the service") // - @RequestParam(name = "name", required = true) String serviceName) { - try { - services.getService(serviceName).keepAlive(); - return new ResponseEntity<>("OK", HttpStatus.OK); - } catch (ServiceException e) { - return new ResponseEntity<>(e.getMessage(), HttpStatus.NOT_FOUND); - } - } - - private Service removeService(String name) throws ServiceException { - Service service = this.services.getService(name); // Just to verify that it exists - this.services.remove(service.getName()); - return service; - } - - private void removePolicies(Service service) { - Collection policyList = this.policies.getForService(service.getName()); - for (Policy policy : policyList) { - this.policies.remove(policy); - } - } - - private Service toService(ServiceRegistrationInfo s) { - return new Service(s.serviceName, Duration.ofSeconds(s.keepAliveIntervalSeconds), s.callbackUrl); - } - -} 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 deleted file mode 100644 index 1194e250..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceRegistrationInfo.java +++ /dev/null @@ -1,61 +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.policyagent.controllers; - -import com.google.gson.annotations.SerializedName; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; - -import org.immutables.gson.Gson; - -@Gson.TypeAdapters -@ApiModel(value = "ServiceRegistrationInfo") -public class ServiceRegistrationInfo { - - @ApiModelProperty(value = "identity of the service", required = true, allowEmptyValue = false) - @SerializedName(value = "serviceName", alternate = {"name"}) - - public String serviceName = ""; - - @ApiModelProperty( - value = "keep alive interval for the service. This is a heartbeat supervision of the service, " - + "which in regular intevals must invoke a 'keepAlive' REST call. " - + "When a service does not invoke this call within the given time, it is considered unavailble. " - + "An unavailable service will be automatically deregistered and its policies will be deleted. " - + "Value 0 means no timeout supervision.") - @SerializedName("keepAliveIntervalSeconds") - public long keepAliveIntervalSeconds = 0; - - @ApiModelProperty(value = "callback for notifying of RIC synchronization", required = false, allowEmptyValue = true) - @SerializedName("callbackUrl") - public String callbackUrl = ""; - - public ServiceRegistrationInfo() { - } - - public ServiceRegistrationInfo(String name, long keepAliveIntervalSeconds, String callbackUrl) { - this.serviceName = name; - this.keepAliveIntervalSeconds = keepAliveIntervalSeconds; - this.callbackUrl = callbackUrl; - } - -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceStatus.java b/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceStatus.java deleted file mode 100644 index 42be5744..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceStatus.java +++ /dev/null @@ -1,51 +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.policyagent.controllers; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; - -import org.immutables.gson.Gson; - -@Gson.TypeAdapters -@ApiModel(value = "ServiceStatus") -public class ServiceStatus { - - @ApiModelProperty(value = "identity of the service") - public final String serviceName; - - @ApiModelProperty(value = "policy keep alive timeout") - public final long keepAliveIntervalSeconds; - - @ApiModelProperty(value = "time since last invocation by the service") - public final long timeSinceLastActivitySeconds; - - @ApiModelProperty(value = "callback for notifying of RIC synchronization") - public String callbackUrl; - - ServiceStatus(String name, long keepAliveIntervalSeconds, long timeSincePingSeconds, String callbackUrl) { - this.serviceName = name; - this.keepAliveIntervalSeconds = keepAliveIntervalSeconds; - this.timeSinceLastActivitySeconds = timeSincePingSeconds; - this.callbackUrl = callbackUrl; - } - -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/controllers/StatusController.java b/policy-agent/src/main/java/org/oransc/policyagent/controllers/StatusController.java deleted file mode 100644 index c55d5be2..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/controllers/StatusController.java +++ /dev/null @@ -1,48 +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.policyagent.controllers; - -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; - -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; -import reactor.core.publisher.Mono; - -@RestController -@Api(tags = "Health check") -public class StatusController { - - @GetMapping("/status") - @ApiOperation(value = "Returns status and statistics of this service") - @ApiResponses( - value = { // - @ApiResponse(code = 200, message = "Service is living", response = String.class) // - }) - public Mono> getStatus() { - return Mono.just(new ResponseEntity<>("hunky dory", HttpStatus.OK)); - } - -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapMessageConsumer.java b/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapMessageConsumer.java deleted file mode 100644 index 0ee62132..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapMessageConsumer.java +++ /dev/null @@ -1,173 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.dmaap; - -import com.google.common.collect.Iterables; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonParser; - -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; - -import org.oransc.policyagent.clients.AsyncRestClient; -import org.oransc.policyagent.configuration.ApplicationConfig; -import org.oransc.policyagent.exceptions.ServiceException; -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.http.ResponseEntity; -import org.springframework.stereotype.Component; - -/** - * The class fetches incoming requests from DMAAP. It uses the timeout parameter - * that lets the MessageRouter keep the connection with the Kafka open until - * requests are sent in. - * - *

- * this service will regularly check the configuration and start polling DMaaP - * if the configuration is added. If the DMaaP configuration is removed, then - * the service will stop polling and resume checking for configuration. - * - *

- * Each received request is processed by {@link DmaapMessageHandler}. - */ -@Component -public class DmaapMessageConsumer { - - protected static final Duration TIME_BETWEEN_DMAAP_RETRIES = Duration.ofSeconds(10); - - private static final Logger logger = LoggerFactory.getLogger(DmaapMessageConsumer.class); - - private final ApplicationConfig applicationConfig; - - private DmaapMessageHandler dmaapMessageHandler = null; - - @Value("${server.http-port}") - private int localServerHttpPort; - - @Autowired - public DmaapMessageConsumer(ApplicationConfig applicationConfig) { - this.applicationConfig = applicationConfig; - } - - /** - * Starts the consumer. If there is a DMaaP configuration, it will start polling - * for messages. Otherwise it will check regularly for the configuration. - * - * @return the running thread, for test purposes. - */ - public Thread start() { - Thread thread = new Thread(this::messageHandlingLoop); - thread.start(); - return thread; - } - - private void messageHandlingLoop() { - while (!isStopped()) { - try { - if (isDmaapConfigured()) { - Iterable dmaapMsgs = fetchAllMessages(); - if (dmaapMsgs != null && Iterables.size(dmaapMsgs) > 0) { - logger.debug("Fetched all the messages from DMAAP and will start to process the messages"); - for (String msg : dmaapMsgs) { - processMsg(msg); - } - } - } else { - sleep(TIME_BETWEEN_DMAAP_RETRIES); // wait for configuration - } - } catch (Exception e) { - logger.warn("{}", e.getMessage()); - sleep(TIME_BETWEEN_DMAAP_RETRIES); - } - } - } - - protected boolean isStopped() { - return false; - } - - protected boolean isDmaapConfigured() { - String producerTopicUrl = applicationConfig.getDmaapProducerTopicUrl(); - String consumerTopicUrl = applicationConfig.getDmaapConsumerTopicUrl(); - return (!producerTopicUrl.isEmpty() && !consumerTopicUrl.isEmpty()); - } - - private static List parseMessages(String jsonString) { - JsonArray arrayOfMessages = JsonParser.parseString(jsonString).getAsJsonArray(); - List result = new ArrayList<>(); - for (JsonElement element : arrayOfMessages) { - if (element.isJsonPrimitive()) { - result.add(element.getAsString()); - } else { - String messageAsString = element.toString(); - result.add(messageAsString); - } - } - return result; - } - - protected Iterable fetchAllMessages() throws ServiceException { - String topicUrl = this.applicationConfig.getDmaapConsumerTopicUrl(); - AsyncRestClient consumer = getMessageRouterConsumer(); - ResponseEntity response = consumer.getForEntity(topicUrl).block(); - logger.debug("DMaaP consumer received {} : {}", response.getStatusCode(), response.getBody()); - if (response.getStatusCode().is2xxSuccessful()) { - return parseMessages(response.getBody()); - } else { - throw new ServiceException("Cannot fetch because of Error respons: " + response.getStatusCode().toString() - + " " + response.getBody()); - } - } - - private void processMsg(String msg) { - logger.debug("Message Reveived from DMAAP : {}", msg); - getDmaapMessageHandler().handleDmaapMsg(msg); - } - - protected DmaapMessageHandler getDmaapMessageHandler() { - if (this.dmaapMessageHandler == null) { - String agentBaseUrl = "http://localhost:" + this.localServerHttpPort; - AsyncRestClient agentClient = - new AsyncRestClient(agentBaseUrl, this.applicationConfig.getWebClientConfig()); - AsyncRestClient producer = new AsyncRestClient(this.applicationConfig.getDmaapProducerTopicUrl(), - this.applicationConfig.getWebClientConfig()); - this.dmaapMessageHandler = new DmaapMessageHandler(producer, agentClient); - } - return this.dmaapMessageHandler; - } - - protected void sleep(Duration duration) { - try { - Thread.sleep(duration.toMillis()); - } catch (Exception e) { - logger.error("Failed to put the thread to sleep", e); - } - } - - protected AsyncRestClient getMessageRouterConsumer() { - return new AsyncRestClient("", this.applicationConfig.getWebClientConfig()); - } - -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapMessageHandler.java b/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapMessageHandler.java deleted file mode 100644 index 226b54e9..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapMessageHandler.java +++ /dev/null @@ -1,157 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.dmaap; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonObject; - -import java.util.Optional; - -import org.oransc.policyagent.clients.AsyncRestClient; -import org.oransc.policyagent.dmaap.DmaapRequestMessage.Operation; -import org.oransc.policyagent.exceptions.ServiceException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.reactive.function.client.WebClientException; -import org.springframework.web.reactive.function.client.WebClientResponseException; -import reactor.core.publisher.Mono; - -/** - * The class handles incoming requests from DMAAP. - *

- * That means: invoke a REST call towards this services and to send back a response though DMAAP - */ -public class DmaapMessageHandler { - private static final Logger logger = LoggerFactory.getLogger(DmaapMessageHandler.class); - private static Gson gson = new GsonBuilder() // - .create(); // - private final AsyncRestClient dmaapClient; - private final AsyncRestClient agentClient; - - public DmaapMessageHandler(AsyncRestClient dmaapClient, AsyncRestClient agentClient) { - this.agentClient = agentClient; - this.dmaapClient = dmaapClient; - } - - public void handleDmaapMsg(String msg) { - try { - String result = this.createTask(msg).block(); - logger.debug("handleDmaapMsg: {}", result); - } catch (Exception throwable) { - logger.warn("handleDmaapMsg failure {}", throwable.getMessage()); - } - } - - Mono createTask(String msg) { - try { - DmaapRequestMessage dmaapRequestMessage = gson.fromJson(msg, ImmutableDmaapRequestMessage.class); - return this.invokePolicyAgent(dmaapRequestMessage) // - .onErrorResume(t -> handleAgentCallError(t, dmaapRequestMessage)) // - .flatMap( - response -> sendDmaapResponse(response.getBody(), dmaapRequestMessage, response.getStatusCode())); - } catch (Exception e) { - String errorMsg = "Received unparsable message from DMAAP: \"" + msg + "\", reason: " + e.getMessage(); - return Mono.error(new ServiceException(errorMsg)); // Cannot make any response - } - } - - private Mono> handleAgentCallError(Throwable error, - DmaapRequestMessage dmaapRequestMessage) { - logger.debug("Agent call failed: {}", error.getMessage()); - HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR; - String errorMessage = error.getMessage(); - if (error instanceof WebClientResponseException) { - WebClientResponseException exception = (WebClientResponseException) error; - status = exception.getStatusCode(); - errorMessage = exception.getResponseBodyAsString(); - } else if (error instanceof ServiceException) { - status = HttpStatus.BAD_REQUEST; - errorMessage = error.getMessage(); - } else if (!(error instanceof WebClientException)) { - logger.warn("Unexpected exception ", error); - } - return sendDmaapResponse(errorMessage, dmaapRequestMessage, status) // - .flatMap(notUsed -> Mono.empty()); - } - - private Mono> invokePolicyAgent(DmaapRequestMessage dmaapRequestMessage) { - DmaapRequestMessage.Operation operation = dmaapRequestMessage.operation(); - String uri = dmaapRequestMessage.url(); - - if (operation == Operation.DELETE) { - return agentClient.deleteForEntity(uri); - } else if (operation == Operation.GET) { - return agentClient.getForEntity(uri); - } else if (operation == Operation.PUT) { - return agentClient.putForEntity(uri, payload(dmaapRequestMessage)); - } else if (operation == Operation.POST) { - return agentClient.postForEntity(uri, payload(dmaapRequestMessage)); - } else { - return Mono.error(new ServiceException("Not implemented operation: " + operation)); - } - } - - private String payload(DmaapRequestMessage message) { - Optional payload = message.payload(); - if (payload.isPresent()) { - return gson.toJson(payload.get()); - } else { - logger.warn("Expected payload in message from DMAAP: {}", message); - return ""; - } - } - - private Mono sendDmaapResponse(String response, DmaapRequestMessage dmaapRequestMessage, - HttpStatus status) { - return createDmaapResponseMessage(dmaapRequestMessage, response, status) // - .flatMap(this::sendToDmaap) // - .onErrorResume(this::handleResponseCallError); - } - - private Mono sendToDmaap(String body) { - logger.debug("sendToDmaap: {} ", body); - return dmaapClient.post("", "[" + body + "]"); - } - - private Mono handleResponseCallError(Throwable t) { - logger.debug("Failed to send response to DMaaP: {}", t.getMessage()); - return Mono.empty(); - } - - private Mono createDmaapResponseMessage(DmaapRequestMessage dmaapRequestMessage, String response, - HttpStatus status) { - DmaapResponseMessage dmaapResponseMessage = ImmutableDmaapResponseMessage.builder() // - .status(status.toString()) // - .message(response == null ? "" : response) // - .type("response") // - .correlationId(dmaapRequestMessage.correlationId() == null ? "" : dmaapRequestMessage.correlationId()) // - .originatorId(dmaapRequestMessage.originatorId() == null ? "" : dmaapRequestMessage.originatorId()) // - .requestId(dmaapRequestMessage.requestId() == null ? "" : dmaapRequestMessage.requestId()) // - .timestamp(dmaapRequestMessage.timestamp() == null ? "" : dmaapRequestMessage.timestamp()) // - .build(); - String str = gson.toJson(dmaapResponseMessage); - return Mono.just(str); - - } -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapRequestMessage.java b/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapRequestMessage.java deleted file mode 100644 index c2d0d4c0..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapRequestMessage.java +++ /dev/null @@ -1,55 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.dmaap; - -import com.google.gson.JsonObject; - -import java.util.Optional; - -import org.immutables.gson.Gson; -import org.immutables.value.Value; - -@Value.Immutable -@Gson.TypeAdapters -public interface DmaapRequestMessage { - - public enum Operation { - PUT, GET, DELETE, POST - } - - String correlationId(); - - String target(); - - String timestamp(); - - String apiVersion(); - - String originatorId(); - - String requestId(); - - Operation operation(); - - String url(); - - Optional payload(); -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapResponseMessage.java b/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapResponseMessage.java deleted file mode 100644 index 35d67ff3..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapResponseMessage.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.dmaap; - -import org.immutables.gson.Gson; -import org.immutables.value.Value; - -@Value.Immutable -@Gson.TypeAdapters -public interface DmaapResponseMessage { - - String type(); - - String correlationId(); - - String timestamp(); - - String originatorId(); - - String requestId(); - - String status(); - - String message(); -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/exceptions/EnvironmentLoaderException.java b/policy-agent/src/main/java/org/oransc/policyagent/exceptions/EnvironmentLoaderException.java deleted file mode 100644 index 80673f84..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/exceptions/EnvironmentLoaderException.java +++ /dev/null @@ -1,30 +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.policyagent.exceptions; - -public class EnvironmentLoaderException extends ServiceException { - - private static final long serialVersionUID = 1L; - - public EnvironmentLoaderException(String message) { - super(message); - } -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/exceptions/ServiceException.java b/policy-agent/src/main/java/org/oransc/policyagent/exceptions/ServiceException.java deleted file mode 100644 index c5b604e2..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/exceptions/ServiceException.java +++ /dev/null @@ -1,32 +0,0 @@ -/*- - * ============LICENSE_START====================================================================== - * Copyright (C) 2019 Nordix Foundation. All rights reserved. - * =============================================================================================== - * 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.exceptions; - -public class ServiceException extends Exception { - - private static final long serialVersionUID = 1L; - - public ServiceException(String message) { - super(message); - } - - public ServiceException(String message, Exception originalException) { - super(message, originalException); - } -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/repository/Lock.java b/policy-agent/src/main/java/org/oransc/policyagent/repository/Lock.java deleted file mode 100644 index 716148fd..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/repository/Lock.java +++ /dev/null @@ -1,197 +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.policyagent.repository; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import reactor.core.publisher.Mono; -import reactor.core.publisher.MonoSink; - -/** - * A resource lock. Exclusive means that the caller takes exclusive ownership of - * the resurce. Non exclusive lock means that several users can lock the - * resource (for shared usage). - */ -public class Lock { - private static final Logger logger = LoggerFactory.getLogger(Lock.class); - - private boolean isExclusive = false; - private int lockCounter = 0; - private final List lockRequestQueue = new LinkedList<>(); - private static AsynchCallbackExecutor callbackProcessor = new AsynchCallbackExecutor(); - - public enum LockType { - EXCLUSIVE, SHARED - } - - /** The caller thread will be blocked util the lock is granted. */ - public synchronized void lockBlocking(LockType locktype) { - while (!tryLock(locktype)) { - this.waitForUnlock(); - } - } - - /** Reactive version. The Lock will be emitted when the lock is granted */ - public synchronized Mono lock(LockType lockType) { - if (tryLock(lockType)) { - return Mono.just(this); - } else { - return Mono.create(monoSink -> addToQueue(monoSink, lockType)); - } - } - - public Mono unlock() { - return Mono.create(monoSink -> { - unlockBlocking(); - monoSink.success(this); - }); - } - - public synchronized void unlockBlocking() { - if (lockCounter <= 0) { - lockCounter = -1; // Might as well stop, to make it easier to find the problem - logger.error("Number of unlocks must match the number of locks"); - } - this.lockCounter--; - if (lockCounter == 0) { - isExclusive = false; - } - this.notifyAll(); - this.processQueuedEntries(); - } - - @Override - public synchronized String toString() { - return "Lock cnt: " + this.lockCounter + " exclusive: " + this.isExclusive + " queued: " - + this.lockRequestQueue.size(); - } - - /** returns the current number of granted locks */ - public synchronized int getLockCounter() { - return this.lockCounter; - } - - private void processQueuedEntries() { - List granted = new ArrayList<>(); - for (Iterator i = lockRequestQueue.iterator(); i.hasNext();) { - LockRequest request = i.next(); - if (tryLock(request.lockType)) { - i.remove(); - granted.add(request); - } - } - callbackProcessor.addAll(granted); - } - - private synchronized void addToQueue(MonoSink callback, LockType lockType) { - lockRequestQueue.add(new LockRequest(callback, lockType, this)); - processQueuedEntries(); - } - - @SuppressWarnings("java:S2274") // Always invoke wait() and await() methods inside a loop - private synchronized void waitForUnlock() { - try { - this.wait(); - } catch (InterruptedException e) { - logger.warn("waitForUnlock interrupted", e); - Thread.currentThread().interrupt(); - } - } - - private boolean tryLock(LockType lockType) { - if (this.isExclusive) { - return false; - } - if (lockType == LockType.EXCLUSIVE && lockCounter > 0) { - return false; - } - lockCounter++; - this.isExclusive = lockType == LockType.EXCLUSIVE; - return true; - } - - /** - * Represents a queued lock request - */ - private static class LockRequest { - final MonoSink callback; - final LockType lockType; - final Lock lock; - - LockRequest(MonoSink callback, LockType lockType, Lock lock) { - this.callback = callback; - this.lockType = lockType; - this.lock = lock; - } - } - - /** - * A separate thread that calls a MonoSink to continue. This is done after a - * queued lock is granted. - */ - private static class AsynchCallbackExecutor implements Runnable { - private List lockRequestQueue = new LinkedList<>(); - - public AsynchCallbackExecutor() { - Thread thread = new Thread(this); - thread.start(); - } - - public synchronized void addAll(List requests) { - this.lockRequestQueue.addAll(requests); - this.notifyAll(); - } - - @Override - public void run() { - try { - while (true) { - for (LockRequest request : consume()) { - request.callback.success(request.lock); - } - waitForNewEntries(); - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - logger.error("Interrupted {}", e.getMessage()); - } - } - - private synchronized List consume() { - List q = this.lockRequestQueue; - this.lockRequestQueue = new LinkedList<>(); - return q; - } - - @SuppressWarnings("java:S2274") - private synchronized void waitForNewEntries() throws InterruptedException { - if (this.lockRequestQueue.isEmpty()) { - this.wait(); - } - } - } -} 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 deleted file mode 100644 index 4e2ebfa0..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/repository/Policies.java +++ /dev/null @@ -1,131 +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.policyagent.repository; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.Vector; - -import org.oransc.policyagent.exceptions.ServiceException; - -public class Policies { - private Map policiesId = new HashMap<>(); - private Map> policiesRic = new HashMap<>(); - private Map> policiesService = new HashMap<>(); - private Map> policiesType = new HashMap<>(); - - public synchronized void put(Policy policy) { - policiesId.put(policy.id(), policy); - multiMapPut(policiesRic, policy.ric().name(), policy); - multiMapPut(policiesService, policy.ownerServiceName(), policy); - multiMapPut(policiesType, policy.type().name(), policy); - } - - private void multiMapPut(Map> multiMap, String key, Policy value) { - multiMap.computeIfAbsent(key, k -> new HashMap<>()).put(value.id(), value); - } - - private void multiMapRemove(Map> multiMap, String key, Policy value) { - Map map = multiMap.get(key); - if (map != null) { - map.remove(value.id()); - if (map.isEmpty()) { - multiMap.remove(key); - } - } - } - - private Collection multiMapGet(Map> multiMap, String key) { - Map map = multiMap.get(key); - if (map == null) { - return Collections.emptyList(); - } - return new Vector<>(map.values()); - } - - public synchronized boolean containsPolicy(String id) { - return policiesId.containsKey(id); - } - - public synchronized Policy get(String id) { - return policiesId.get(id); - } - - public synchronized Policy getPolicy(String id) throws ServiceException { - Policy p = policiesId.get(id); - if (p == null) { - throw new ServiceException("Could not find policy: " + id); - } - return p; - } - - public synchronized Collection getAll() { - return new Vector<>(policiesId.values()); - } - - public synchronized Collection getForService(String service) { - return multiMapGet(policiesService, service); - } - - public synchronized Collection getForRic(String ric) { - return multiMapGet(policiesRic, ric); - } - - public synchronized Collection getForType(String type) { - return multiMapGet(policiesType, type); - } - - public synchronized Policy removeId(String id) { - Policy p = policiesId.get(id); - if (p != null) { - remove(p); - } - return p; - } - - public synchronized void remove(Policy policy) { - policiesId.remove(policy.id()); - multiMapRemove(policiesRic, policy.ric().name(), policy); - multiMapRemove(policiesService, policy.ownerServiceName(), policy); - multiMapRemove(policiesType, policy.type().name(), policy); - } - - public synchronized void removePoliciesForRic(String ricName) { - Collection policiesForRic = getForRic(ricName); - for (Policy policy : policiesForRic) { - remove(policy); - } - } - - public synchronized int size() { - return policiesId.size(); - } - - public synchronized void clear() { - while (policiesId.size() > 0) { - Set keys = policiesId.keySet(); - removeId(keys.iterator().next()); - } - } -} 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 deleted file mode 100644 index e96d2506..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/repository/Policy.java +++ /dev/null @@ -1,42 +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.policyagent.repository; - -import org.immutables.gson.Gson; -import org.immutables.value.Value; - -@Value.Immutable -@Gson.TypeAdapters -public interface Policy { - public String id(); - - public String json(); - - public String ownerServiceName(); - - public Ric ric(); - - public PolicyType type(); - - public String lastModified(); - - public boolean isTransient(); -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/repository/PolicyType.java b/policy-agent/src/main/java/org/oransc/policyagent/repository/PolicyType.java deleted file mode 100644 index 41b94985..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/repository/PolicyType.java +++ /dev/null @@ -1,32 +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.policyagent.repository; - -import org.immutables.gson.Gson; -import org.immutables.value.Value; - -@Value.Immutable -@Gson.TypeAdapters -public interface PolicyType { - public String name(); - - public String schema(); -} 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 deleted file mode 100644 index 2897a502..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/repository/PolicyTypes.java +++ /dev/null @@ -1,64 +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.policyagent.repository; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Vector; - -import org.oransc.policyagent.exceptions.ServiceException; - -public class PolicyTypes { - private Map types = new HashMap<>(); - - public synchronized PolicyType getType(String name) throws ServiceException { - PolicyType t = types.get(name); - if (t == null) { - throw new ServiceException("Could not find type: " + name); - } - return t; - } - - public synchronized PolicyType get(String name) { - return types.get(name); - } - - public synchronized void put(PolicyType type) { - types.put(type.name(), type); - } - - public synchronized boolean contains(String policyType) { - return types.containsKey(policyType); - } - - public synchronized Collection getAll() { - return new Vector<>(types.values()); - } - - public synchronized int size() { - return types.size(); - } - - public synchronized 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 deleted file mode 100644 index fb2e4b92..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/repository/Ric.java +++ /dev/null @@ -1,162 +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.policyagent.repository; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Vector; - -import lombok.Getter; -import lombok.Setter; - -import org.oransc.policyagent.clients.A1Client.A1ProtocolType; -import org.oransc.policyagent.configuration.RicConfig; - -/** - * Represents the dynamic information about a Near-RT RIC. - */ -public class Ric { - - @Setter - private RicConfig ricConfig; - private RicState state = RicState.UNAVAILABLE; - private Map supportedPolicyTypes = new HashMap<>(); - @Getter - @Setter - private A1ProtocolType protocolVersion = A1ProtocolType.UNKNOWN; - - @Getter - private final Lock lock = new Lock(); - - /** - * Creates the Ric. Initial state is {@link RicState.UNDEFINED}. - * - * @param ricConfig The {@link RicConfig} for this Ric. - */ - public Ric(RicConfig ricConfig) { - this.ricConfig = ricConfig; - } - - public String name() { - return ricConfig.name(); - } - - public RicConfig getConfig() { - return this.ricConfig; - } - - public synchronized RicState getState() { - return this.state; - } - - public synchronized void setState(RicState state) { - this.state = state; - } - - /** - * Gets the nodes managed by this Ric. - * - * @return a vector containing the nodes managed by this Ric. - */ - public synchronized Collection getManagedElementIds() { - return ricConfig.managedElementIds(); - } - - /** - * Determines if the given node is managed by this Ric. - * - * @param managedElementId the node name to check. - * @return true if the given node is managed by this Ric. - */ - public synchronized boolean isManaging(String managedElementId) { - return ricConfig.managedElementIds().contains(managedElementId); - } - - /** - * Gets the policy types supported by this Ric. - * - * @return the policy types supported by this Ric in an unmodifiable list. - */ - public synchronized Collection getSupportedPolicyTypes() { - return new Vector<>(supportedPolicyTypes.values()); - } - - public synchronized Collection getSupportedPolicyTypeNames() { - return new Vector<>(supportedPolicyTypes.keySet()); - } - - /** - * Adds a policy type as supported by this Ric. - * - * @param type the policy type to support. - */ - public synchronized void addSupportedPolicyType(PolicyType type) { - supportedPolicyTypes.put(type.name(), type); - } - - /** - * Removes all policy type as supported by this Ric. - */ - public synchronized void clearSupportedPolicyTypes() { - supportedPolicyTypes.clear(); - } - - /** - * Checks if a type is supported by this Ric. - * - * @param typeName the name of the type to check if it is supported. - * - * @return true if the given type is supported by this Ric, false otherwise. - */ - public synchronized boolean isSupportingType(String typeName) { - return supportedPolicyTypes.containsKey(typeName); - } - - @Override - public synchronized String toString() { - return Ric.class.getSimpleName() + ": " + "name: " + name() + ", state: " + state + ", baseUrl: " - + ricConfig.baseUrl() + ", managedNodes: " + ricConfig.managedElementIds(); - } - - /** - * Represents the states possible for a Ric. - */ - public enum RicState { - /** - * The agent view of the Ric may be inconsistent. - */ - UNAVAILABLE, - /** - * The normal state. Policies can be configured. - */ - AVAILABLE, - /** - * The agent is synchronizing the view of the Ric. - */ - SYNCHRONIZING, - - /** - * A consistency check between the agent and the Ric is done - */ - CONSISTENCY_CHECK - } -} 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 deleted file mode 100644 index 7faa3766..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/repository/Rics.java +++ /dev/null @@ -1,77 +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.policyagent.repository; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; -import java.util.Vector; - -import org.oransc.policyagent.exceptions.ServiceException; - -/** - * Dynamic representation of all Rics in the system. - */ -public class Rics { - Map registeredRics = new HashMap<>(); - - public synchronized void put(Ric ric) { - registeredRics.put(ric.name(), ric); - } - - public synchronized Collection getRics() { - return new Vector<>(registeredRics.values()); - } - - public synchronized Ric getRic(String name) throws ServiceException { - Ric ric = registeredRics.get(name); - if (ric == null) { - throw new ServiceException("Could not find ric: " + name); - } - return ric; - } - - public synchronized Ric get(String name) { - return registeredRics.get(name); - } - - public synchronized void remove(String name) { - registeredRics.remove(name); - } - - public synchronized int size() { - return registeredRics.size(); - } - - public synchronized void clear() { - this.registeredRics.clear(); - } - - public synchronized Optional lookupRicForManagedElement(String managedElementId) { - for (Ric ric : this.registeredRics.values()) { - if (ric.getManagedElementIds().contains(managedElementId)) { - return Optional.of(ric); - } - } - return Optional.empty(); - } -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/repository/Service.java b/policy-agent/src/main/java/org/oransc/policyagent/repository/Service.java deleted file mode 100644 index 7b2c9bde..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/repository/Service.java +++ /dev/null @@ -1,62 +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.policyagent.repository; - -import java.time.Duration; -import java.time.Instant; - -import lombok.Getter; - -public class Service { - @Getter - private final String name; - private final Duration keepAliveInterval; - private Instant lastPing; - private final String callbackUrl; - - public Service(String name, Duration keepAliveInterval, String callbackUrl) { - this.name = name; - this.keepAliveInterval = keepAliveInterval; - this.callbackUrl = callbackUrl; - keepAlive(); - } - - public synchronized Duration getKeepAliveInterval() { - return this.keepAliveInterval; - } - - public synchronized void keepAlive() { - this.lastPing = Instant.now(); - } - - public synchronized boolean isExpired() { - return this.keepAliveInterval.getSeconds() > 0 && timeSinceLastPing().compareTo(this.keepAliveInterval) > 0; - } - - public synchronized Duration timeSinceLastPing() { - return Duration.between(this.lastPing, Instant.now()); - } - - public synchronized String getCallbackUrl() { - return this.callbackUrl; - } - -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/repository/Services.java b/policy-agent/src/main/java/org/oransc/policyagent/repository/Services.java deleted file mode 100644 index 1c0e15aa..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/repository/Services.java +++ /dev/null @@ -1,69 +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.policyagent.repository; - -import java.util.HashMap; -import java.util.Map; -import java.util.Vector; - -import org.oransc.policyagent.exceptions.ServiceException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class Services { - private static final Logger logger = LoggerFactory.getLogger(Services.class); - - private Map registeredServices = new HashMap<>(); - - public synchronized Service getService(String name) throws ServiceException { - Service s = registeredServices.get(name); - if (s == null) { - throw new ServiceException("Could not find service: " + name); - } - return s; - } - - public synchronized Service get(String name) { - return registeredServices.get(name); - } - - public synchronized void put(Service service) { - logger.debug("Put service: {}", service.getName()); - service.keepAlive(); - registeredServices.put(service.getName(), service); - } - - public synchronized Iterable getAll() { - return new Vector<>(registeredServices.values()); - } - - public synchronized void remove(String name) { - registeredServices.remove(name); - } - - public synchronized int size() { - return registeredServices.size(); - } - - public synchronized void clear() { - registeredServices.clear(); - } -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/tasks/EnvironmentProcessor.java b/policy-agent/src/main/java/org/oransc/policyagent/tasks/EnvironmentProcessor.java deleted file mode 100644 index afb273d7..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/tasks/EnvironmentProcessor.java +++ /dev/null @@ -1,91 +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.policyagent.tasks; - -import java.util.Optional; -import java.util.Properties; - -import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.EnvProperties; -import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.ImmutableEnvProperties; -import org.oransc.policyagent.exceptions.EnvironmentLoaderException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import reactor.core.publisher.Mono; - -/** - * This class reads a few environment variables used for locating the Consul - * (Config Binding Service). - */ -class EnvironmentProcessor { - - private static final int DEFAULT_CONSUL_PORT = 8500; - private static final Logger logger = LoggerFactory.getLogger(EnvironmentProcessor.class); - - private EnvironmentProcessor() { - } - - static Mono readEnvironmentVariables(Properties systemEnvironment) { - - EnvProperties envProperties; - try { - envProperties = ImmutableEnvProperties.builder() // - .consulHost(getConsulHost(systemEnvironment)) // - .consulPort(getConsultPort(systemEnvironment)) // - .cbsName(getConfigBindingService(systemEnvironment)) // - .appName(getService(systemEnvironment)) // - .build(); - } catch (EnvironmentLoaderException e) { - return Mono.error(e); - } - logger.trace("Evaluated environment system variables {}", envProperties); - return Mono.just(envProperties); - } - - private static String getConsulHost(Properties systemEnvironments) throws EnvironmentLoaderException { - return Optional.ofNullable(systemEnvironments.getProperty("CONSUL_HOST")) - .orElseThrow(() -> new EnvironmentLoaderException("$CONSUL_HOST environment has not been defined")); - } - - private static Integer getConsultPort(Properties systemEnvironments) { - return Optional.ofNullable(systemEnvironments.getProperty("CONSUL_PORT")) // - .map(Integer::valueOf) // - .orElseGet(EnvironmentProcessor::getDefaultPortOfConsul); - } - - private static String getConfigBindingService(Properties systemEnvironments) throws EnvironmentLoaderException { - return Optional.ofNullable(systemEnvironments.getProperty("CONFIG_BINDING_SERVICE")) // - .orElseThrow( - () -> new EnvironmentLoaderException("$CONFIG_BINDING_SERVICE environment has not been defined")); - } - - private static String getService(Properties systemEnvironments) throws EnvironmentLoaderException { - return Optional - .ofNullable(Optional.ofNullable(systemEnvironments.getProperty("HOSTNAME")) - .orElse(systemEnvironments.getProperty("SERVICE_NAME"))) - .orElseThrow(() -> new EnvironmentLoaderException( - "Neither $HOSTNAME/$SERVICE_NAME have not been defined as system environment")); - } - - private static Integer getDefaultPortOfConsul() { - logger.warn("$CONSUL_PORT variable will be set to default port {}", DEFAULT_CONSUL_PORT); - return DEFAULT_CONSUL_PORT; - } -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/tasks/RefreshConfigTask.java b/policy-agent/src/main/java/org/oransc/policyagent/tasks/RefreshConfigTask.java deleted file mode 100644 index b99a230d..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/tasks/RefreshConfigTask.java +++ /dev/null @@ -1,263 +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.policyagent.tasks; - -import com.google.gson.GsonBuilder; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.gson.TypeAdapterFactory; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.time.Duration; -import java.util.Properties; -import java.util.ServiceLoader; - -import javax.validation.constraints.NotNull; - -import lombok.AccessLevel; -import lombok.Getter; - -import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.CbsClient; -import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.CbsClientFactory; -import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.CbsRequests; -import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.CbsRequest; -import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.EnvProperties; -import org.onap.dcaegen2.services.sdk.rest.services.model.logging.RequestDiagnosticContext; -import org.oransc.policyagent.clients.A1ClientFactory; -import org.oransc.policyagent.configuration.ApplicationConfig; -import org.oransc.policyagent.configuration.ApplicationConfig.RicConfigUpdate; -import org.oransc.policyagent.configuration.ApplicationConfigParser; -import org.oransc.policyagent.configuration.RicConfig; -import org.oransc.policyagent.repository.Policies; -import org.oransc.policyagent.repository.PolicyTypes; -import org.oransc.policyagent.repository.Ric; -import org.oransc.policyagent.repository.Rics; -import org.oransc.policyagent.repository.Services; -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.stereotype.Component; - -import reactor.core.Disposable; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -/** - * Regularly refreshes the configuration from Consul or from a local configuration file. - */ -@Component -public class RefreshConfigTask { - - private static final Logger logger = LoggerFactory.getLogger(RefreshConfigTask.class); - - @Value("#{systemEnvironment}") - public Properties systemEnvironment; - - /** - * The time between refreshes of the configuration. - */ - static final Duration CONFIG_REFRESH_INTERVAL = Duration.ofMinutes(1); - - final ApplicationConfig appConfig; - @Getter(AccessLevel.PROTECTED) - private Disposable refreshTask = null; - private boolean isConsulUsed = false; - - private final Rics rics; - private final A1ClientFactory a1ClientFactory; - private final Policies policies; - private final Services services; - private final PolicyTypes policyTypes; - - @Autowired - public RefreshConfigTask(ApplicationConfig appConfig, Rics rics, Policies policies, Services services, - PolicyTypes policyTypes, A1ClientFactory a1ClientFactory) { - this.appConfig = appConfig; - this.rics = rics; - this.policies = policies; - this.services = services; - this.policyTypes = policyTypes; - this.a1ClientFactory = a1ClientFactory; - } - - public void start() { - logger.debug("Starting refreshConfigTask"); - stop(); - refreshTask = createRefreshTask() // - .subscribe(notUsed -> logger.debug("Refreshed configuration data"), - throwable -> logger.error("Configuration refresh terminated due to exception {}", throwable.toString()), - () -> logger.error("Configuration refresh terminated")); - } - - public void stop() { - if (refreshTask != null) { - refreshTask.dispose(); - } - } - - Flux createRefreshTask() { - Flux loadFromFile = Flux.interval(Duration.ZERO, CONFIG_REFRESH_INTERVAL) // - .filter(notUsed -> !this.isConsulUsed) // - .flatMap(notUsed -> loadConfigurationFromFile()) // - .onErrorResume(this::ignoreErrorFlux) // - .doOnNext(json -> logger.debug("loadFromFile succeeded")) // - .doOnTerminate(() -> logger.error("loadFromFile Terminate")); - - Flux loadFromConsul = Flux.interval(Duration.ZERO, CONFIG_REFRESH_INTERVAL) // - .flatMap(i -> getEnvironment(systemEnvironment)) // - .flatMap(this::createCbsClient) // - .flatMap(this::getFromCbs) // - .onErrorResume(this::ignoreErrorMono) // - .doOnNext(json -> logger.debug("loadFromConsul succeeded")) // - .doOnNext(json -> this.isConsulUsed = true) // - .doOnTerminate(() -> logger.error("loadFromConsul Terminated")); - - return Flux.merge(loadFromFile, loadFromConsul) // - .flatMap(this::parseConfiguration) // - .flatMap(this::updateConfig) // - .doOnNext(this::handleUpdatedRicConfig) // - .flatMap(configUpdate -> Flux.just(configUpdate.getType())) // - .doOnTerminate(() -> logger.error("Configuration refresh task is terminated")); - } - - Mono getEnvironment(Properties systemEnvironment) { - return EnvironmentProcessor.readEnvironmentVariables(systemEnvironment) // - .onErrorResume(t -> Mono.empty()); - } - - Mono createCbsClient(EnvProperties env) { - return CbsClientFactory.createCbsClient(env) // - .onErrorResume(this::ignoreErrorMono); - } - - private Mono getFromCbs(CbsClient cbsClient) { - try { - final CbsRequest getConfigRequest = CbsRequests.getAll(RequestDiagnosticContext.create()); - return cbsClient.get(getConfigRequest) // - .onErrorResume(this::ignoreErrorMono); - } catch (Exception e) { - return ignoreErrorMono(e); - } - } - - private Flux ignoreErrorFlux(Throwable throwable) { - String errMsg = throwable.toString(); - logger.warn("Could not refresh application configuration. {}", errMsg); - return Flux.empty(); - } - - private Mono ignoreErrorMono(Throwable throwable) { - String errMsg = throwable.toString(); - logger.warn("Could not refresh application configuration. {}", errMsg); - return Mono.empty(); - } - - private Mono parseConfiguration(JsonObject jsonObject) { - try { - ApplicationConfigParser parser = new ApplicationConfigParser(); - return Mono.just(parser.parse(jsonObject)); - } catch (Exception e) { - String str = e.toString(); - logger.error("Could not parse configuration {}", str); - return Mono.empty(); - } - } - - private Flux updateConfig(ApplicationConfigParser.ConfigParserResult config) { - return this.appConfig.setConfiguration(config); - } - - boolean fileExists(String filepath) { - return (filepath != null && (new File(filepath).exists())); - } - - private void handleUpdatedRicConfig(RicConfigUpdate updatedInfo) { - synchronized (this.rics) { - String ricName = updatedInfo.getRicConfig().name(); - RicConfigUpdate.Type event = updatedInfo.getType(); - if (event == RicConfigUpdate.Type.ADDED) { - addRic(updatedInfo.getRicConfig()); - } else if (event == RicConfigUpdate.Type.REMOVED) { - rics.remove(ricName); - this.policies.removePoliciesForRic(ricName); - } else if (event == RicConfigUpdate.Type.CHANGED) { - Ric ric = this.rics.get(ricName); - if (ric == null) { - // Should not happen,just for robustness - addRic(updatedInfo.getRicConfig()); - } else { - ric.setRicConfig(updatedInfo.getRicConfig()); - } - } - } - } - - private void addRic(RicConfig config) { - Ric ric = new Ric(config); - this.rics.put(ric); - runRicSynchronization(ric); - } - - void runRicSynchronization(Ric ric) { - RicSynchronizationTask synchronizationTask = - new RicSynchronizationTask(a1ClientFactory, policyTypes, policies, services); - synchronizationTask.run(ric); - } - - /** - * Reads the configuration from file. - */ - Flux loadConfigurationFromFile() { - String filepath = appConfig.getLocalConfigurationFilePath(); - if (!fileExists(filepath)) { - return Flux.empty(); - } - - GsonBuilder gsonBuilder = new GsonBuilder(); - ServiceLoader.load(TypeAdapterFactory.class).forEach(gsonBuilder::registerTypeAdapterFactory); - - try (InputStream inputStream = createInputStream(filepath)) { - JsonObject rootObject = getJsonElement(inputStream).getAsJsonObject(); - ApplicationConfigParser appParser = new ApplicationConfigParser(); - appParser.parse(rootObject); - logger.debug("Local configuration file loaded: {}", filepath); - return Flux.just(rootObject); - } catch (Exception e) { - logger.error("Local configuration file not loaded: {}, {}", filepath, e.getMessage()); - return Flux.empty(); - } - } - - JsonElement getJsonElement(InputStream inputStream) { - return JsonParser.parseReader(new InputStreamReader(inputStream)); - } - - InputStream createInputStream(@NotNull String filepath) throws IOException { - return new BufferedInputStream(new FileInputStream(filepath)); - } -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/tasks/RicSupervision.java b/policy-agent/src/main/java/org/oransc/policyagent/tasks/RicSupervision.java deleted file mode 100644 index 228038af..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/tasks/RicSupervision.java +++ /dev/null @@ -1,212 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.tasks; - -import java.util.Collection; - -import org.oransc.policyagent.clients.A1Client; -import org.oransc.policyagent.clients.A1ClientFactory; -import org.oransc.policyagent.exceptions.ServiceException; -import org.oransc.policyagent.repository.Lock.LockType; -import org.oransc.policyagent.repository.Policies; -import org.oransc.policyagent.repository.PolicyTypes; -import org.oransc.policyagent.repository.Ric; -import org.oransc.policyagent.repository.Ric.RicState; -import org.oransc.policyagent.repository.Rics; -import org.oransc.policyagent.repository.Services; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.annotation.EnableScheduling; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -/** - * Regularly checks the existing rics towards the local repository to keep it - * consistent. When the policy types or instances in the Near-RT RIC is not - * consistent, a synchronization is performed. - */ -@Component -@EnableScheduling -@SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally -public class RicSupervision { - private static final Logger logger = LoggerFactory.getLogger(RicSupervision.class); - - private final Rics rics; - private final Policies policies; - private final PolicyTypes policyTypes; - private final A1ClientFactory a1ClientFactory; - private final Services services; - - private static class SynchStartedException extends ServiceException { - private static final long serialVersionUID = 1L; - - public SynchStartedException(String message) { - super(message); - } - } - - private static class RicData { - RicData(Ric ric, A1Client a1Client) { - this.ric = ric; - this.a1Client = a1Client; - } - - A1Client getClient() { - return a1Client; - } - - final Ric ric; - private final A1Client a1Client; - } - - @Autowired - public RicSupervision(Rics rics, Policies policies, A1ClientFactory a1ClientFactory, PolicyTypes policyTypes, - Services services) { - this.rics = rics; - this.policies = policies; - this.a1ClientFactory = a1ClientFactory; - this.policyTypes = policyTypes; - this.services = services; - } - - /** - * Regularly contacts all Rics to check if they are alive and synchronized. - */ - @Scheduled(fixedRate = 1000 * 60) - public void checkAllRics() { - logger.debug("Checking Rics starting"); - createTask().subscribe(null, null, () -> logger.debug("Checking all RICs completed")); - } - - private Flux createTask() { - return Flux.fromIterable(rics.getRics()) // - .flatMap(this::createRicData) // - .flatMap(this::checkOneRic); - } - - private Mono checkOneRic(RicData ricData) { - return checkRicState(ricData) // - .flatMap(x -> ricData.ric.getLock().lock(LockType.EXCLUSIVE)) // - .flatMap(notUsed -> setRicState(ricData)) // - .flatMap(x -> checkRicPolicies(ricData)) // - .flatMap(x -> checkRicPolicyTypes(ricData)) // - .doOnNext(x -> onRicCheckedOk(ricData)) // - .doOnError(t -> onRicCheckedError(t, ricData)) // - .onErrorResume(throwable -> Mono.empty()); - } - - private void onRicCheckedError(Throwable t, RicData ricData) { - logger.debug("Ric: {} check stopped, exception: {}", ricData.ric.name(), t.getMessage()); - if (t instanceof SynchStartedException) { - // this is just a temporary state, - ricData.ric.setState(RicState.AVAILABLE); - } else { - ricData.ric.setState(RicState.UNAVAILABLE); - } - ricData.ric.getLock().unlockBlocking(); - } - - private void onRicCheckedOk(RicData ricData) { - logger.debug("Ric: {} checked OK", ricData.ric.name()); - ricData.ric.setState(RicState.AVAILABLE); - ricData.ric.getLock().unlockBlocking(); - } - - @SuppressWarnings("squid:S2445") // Blocks should be synchronized on "private final" fields - private Mono setRicState(RicData ric) { - synchronized (ric) { - if (ric.ric.getState() == RicState.CONSISTENCY_CHECK) { - logger.debug("Ric: {} is already being checked", ric.ric.getConfig().name()); - return Mono.empty(); - } - ric.ric.setState(RicState.CONSISTENCY_CHECK); - return Mono.just(ric); - } - } - - private Mono createRicData(Ric ric) { - return Mono.just(ric) // - .flatMap(aRic -> this.a1ClientFactory.createA1Client(ric)) // - .flatMap(a1Client -> Mono.just(new RicData(ric, a1Client))); - } - - private Mono checkRicState(RicData ric) { - if (ric.ric.getState() == RicState.UNAVAILABLE) { - return startSynchronization(ric) // - .onErrorResume(t -> Mono.empty()); - } else if (ric.ric.getState() == RicState.SYNCHRONIZING || ric.ric.getState() == RicState.CONSISTENCY_CHECK) { - return Mono.empty(); - } else { - return Mono.just(ric); - } - } - - private Mono checkRicPolicies(RicData ric) { - return ric.getClient().getPolicyIdentities() // - .flatMap(ricP -> validateInstances(ricP, ric)); - } - - private Mono validateInstances(Collection ricPolicies, RicData ric) { - synchronized (this.policies) { - if (ricPolicies.size() != policies.getForRic(ric.ric.name()).size()) { - return startSynchronization(ric); - } - - for (String policyId : ricPolicies) { - if (!policies.containsPolicy(policyId)) { - return startSynchronization(ric); - } - } - return Mono.just(ric); - } - } - - private Mono checkRicPolicyTypes(RicData ric) { - return ric.getClient().getPolicyTypeIdentities() // - .flatMap(ricTypes -> validateTypes(ricTypes, ric)); - } - - private Mono validateTypes(Collection ricTypes, RicData ric) { - if (ricTypes.size() != ric.ric.getSupportedPolicyTypes().size()) { - return startSynchronization(ric); - } - for (String typeName : ricTypes) { - if (!ric.ric.isSupportingType(typeName)) { - return startSynchronization(ric); - } - } - return Mono.just(ric); - } - - private Mono startSynchronization(RicData ric) { - RicSynchronizationTask synchronizationTask = createSynchronizationTask(); - synchronizationTask.run(ric.ric); - return Mono.error(new SynchStartedException("Syncronization started")); - } - - RicSynchronizationTask createSynchronizationTask() { - return new RicSynchronizationTask(a1ClientFactory, policyTypes, policies, services); - } -} diff --git a/policy-agent/src/main/java/org/oransc/policyagent/tasks/RicSynchronizationTask.java b/policy-agent/src/main/java/org/oransc/policyagent/tasks/RicSynchronizationTask.java deleted file mode 100644 index 6ae55c46..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/tasks/RicSynchronizationTask.java +++ /dev/null @@ -1,214 +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.policyagent.tasks; - -import static org.oransc.policyagent.repository.Ric.RicState; - -import org.oransc.policyagent.clients.A1Client; -import org.oransc.policyagent.clients.A1ClientFactory; -import org.oransc.policyagent.clients.AsyncRestClient; -import org.oransc.policyagent.repository.ImmutablePolicyType; -import org.oransc.policyagent.repository.Lock.LockType; -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.Service; -import org.oransc.policyagent.repository.Services; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import reactor.core.publisher.BaseSubscriber; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.core.publisher.SignalType; - -/** - * Synchronizes the content of a RIC with the content in the repository. This - * means: - *

- * load all policy types - *

- * send all policy instances to the RIC - *

- * if that fails remove all policy instances - *

- * Notify subscribing services - */ -@SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally -public class RicSynchronizationTask { - - private static final Logger logger = LoggerFactory.getLogger(RicSynchronizationTask.class); - static final int CONCURRENCY_RIC = 1; // How may paralell requests that is sent to one NearRT RIC - - private final A1ClientFactory a1ClientFactory; - private final PolicyTypes policyTypes; - private final Policies policies; - private final Services services; - - public RicSynchronizationTask(A1ClientFactory a1ClientFactory, PolicyTypes policyTypes, Policies policies, - Services services) { - this.a1ClientFactory = a1ClientFactory; - this.policyTypes = policyTypes; - this.policies = policies; - this.services = services; - } - - public void run(Ric ric) { - logger.debug("Handling ric: {}", ric.getConfig().name()); - - if (ric.getState() == RicState.SYNCHRONIZING) { - logger.debug("Ric: {} is already being synchronized", ric.getConfig().name()); - return; - } - - ric.getLock().lock(LockType.EXCLUSIVE) // - .flatMap(notUsed -> setRicState(ric)) // - .flatMap(lock -> this.a1ClientFactory.createA1Client(ric)) // - .flatMapMany(client -> runSynchronization(ric, client)) // - .onErrorResume(throwable -> deleteAllPolicyInstances(ric, throwable)) - .subscribe(new BaseSubscriber() { - @Override - protected void hookOnError(Throwable throwable) { - logger.warn("Synchronization failure for ric: {}, reason: {}", ric.name(), throwable.getMessage()); - ric.setState(RicState.UNAVAILABLE); - } - - @Override - protected void hookOnComplete() { - onSynchronizationComplete(ric); - } - - @Override - protected void hookFinally(SignalType type) { - ric.getLock().unlockBlocking(); - } - }); - } - - @SuppressWarnings("squid:S2445") // Blocks should be synchronized on "private final" fields - private Mono setRicState(Ric ric) { - synchronized (ric) { - if (ric.getState() == RicState.SYNCHRONIZING) { - logger.debug("Ric: {} is already being synchronized", ric.getConfig().name()); - return Mono.empty(); - } - ric.setState(RicState.SYNCHRONIZING); - return Mono.just(ric); - } - } - - private Flux runSynchronization(Ric ric, A1Client a1Client) { - Flux synchronizedTypes = synchronizePolicyTypes(ric, a1Client); - Flux policiesDeletedInRic = a1Client.deleteAllPolicies(); - Flux policiesRecreatedInRic = recreateAllPoliciesInRic(ric, a1Client); - - return Flux.concat(synchronizedTypes, policiesDeletedInRic, policiesRecreatedInRic); - } - - private void onSynchronizationComplete(Ric ric) { - logger.debug("Synchronization completed for: {}", ric.name()); - ric.setState(RicState.AVAILABLE); - notifyAllServices("Synchronization completed for:" + ric.name()); - } - - private void notifyAllServices(String body) { - for (Service service : services.getAll()) { - String url = service.getCallbackUrl(); - if (url.length() > 0) { - createNotificationClient(url) // - .put("", body) // - .subscribe( // - notUsed -> logger.debug("Service {} notified", service.getName()), - throwable -> logger.warn("Service notification failed for service: {}. Cause: {}", - service.getName(), throwable.getMessage()), - () -> logger.debug("All services notified")); - } - } - } - - private Flux deleteAllPolicyInstances(Ric ric, Throwable t) { - logger.debug("Recreation of policies failed for ric: {}, reason: {}", ric.name(), t.getMessage()); - deleteAllPoliciesInRepository(ric); - - Flux synchronizedTypes = this.a1ClientFactory.createA1Client(ric) // - .flatMapMany(a1Client -> synchronizePolicyTypes(ric, a1Client)); - Flux deletePoliciesInRic = this.a1ClientFactory.createA1Client(ric) // - .flatMapMany(A1Client::deleteAllPolicies) // - .doOnComplete(() -> deleteAllPoliciesInRepository(ric)); - - return Flux.concat(synchronizedTypes, deletePoliciesInRic); - } - - AsyncRestClient createNotificationClient(final String url) { - return new AsyncRestClient(url, this.a1ClientFactory.getAppConfig().getWebClientConfig()); - } - - private Flux synchronizePolicyTypes(Ric ric, A1Client a1Client) { - return a1Client.getPolicyTypeIdentities() // - .doOnNext(x -> ric.clearSupportedPolicyTypes()) // - .flatMapMany(Flux::fromIterable) // - .doOnNext(typeId -> logger.debug("For ric: {}, handling type: {}", ric.getConfig().name(), typeId)) // - .flatMap(policyTypeId -> getPolicyType(policyTypeId, a1Client), CONCURRENCY_RIC) // - .doOnNext(ric::addSupportedPolicyType); // - } - - private Mono getPolicyType(String policyTypeId, A1Client a1Client) { - if (policyTypes.contains(policyTypeId)) { - return Mono.just(policyTypes.get(policyTypeId)); - } - return a1Client.getPolicyTypeSchema(policyTypeId) // - .flatMap(schema -> createPolicyType(policyTypeId, schema)); - } - - private Mono createPolicyType(String policyTypeId, String schema) { - PolicyType pt = ImmutablePolicyType.builder().name(policyTypeId).schema(schema).build(); - policyTypes.put(pt); - return Mono.just(pt); - } - - private void deleteAllPoliciesInRepository(Ric ric) { - for (Policy policy : policies.getForRic(ric.name())) { - this.policies.remove(policy); - } - } - - private Flux putPolicy(Policy policy, Ric ric, A1Client a1Client) { - logger.debug("Recreating policy: {}, for ric: {}", policy.id(), ric.getConfig().name()); - return a1Client.putPolicy(policy) // - .flatMapMany(notUsed -> Flux.just(policy)); - } - - private boolean checkTransient(Policy policy) { - if (policy.isTransient()) { - this.policies.remove(policy); - } - return policy.isTransient(); - } - - private Flux recreateAllPoliciesInRic(Ric ric, A1Client a1Client) { - return Flux.fromIterable(policies.getForRic(ric.name())) // - .filter(policy -> !checkTransient(policy)) // - .flatMap(policy -> putPolicy(policy, ric, a1Client), CONCURRENCY_RIC); - } - -} 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 deleted file mode 100644 index 9c555329..00000000 --- a/policy-agent/src/main/java/org/oransc/policyagent/tasks/ServiceSupervision.java +++ /dev/null @@ -1,124 +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.policyagent.tasks; - -import java.time.Duration; - -import org.oransc.policyagent.clients.A1ClientFactory; -import org.oransc.policyagent.repository.Lock; -import org.oransc.policyagent.repository.Lock.LockType; -import org.oransc.policyagent.repository.Policies; -import org.oransc.policyagent.repository.Policy; -import org.oransc.policyagent.repository.Service; -import org.oransc.policyagent.repository.Services; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.annotation.EnableScheduling; -import org.springframework.stereotype.Component; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -/** - * Periodically checks that services with a keepAliveInterval set are alive. If - * a service is deemed not alive, all the service's policies are deleted, both - * in the repository and in the affected Rics, and the service is removed from - * the repository. This means that the service needs to register again after - * this. - */ -@Component -@EnableScheduling -@SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally -public class ServiceSupervision { - private static final Logger logger = LoggerFactory.getLogger(ServiceSupervision.class); - static final int CONCURRENCY_RIC = 1; // How may paralell requests that is sent - private final Services services; - private final Policies policies; - private A1ClientFactory a1ClientFactory; - private final Duration checkInterval; - - @Autowired - public ServiceSupervision(Services services, Policies policies, A1ClientFactory a1ClientFactory) { - this(services, policies, a1ClientFactory, Duration.ofMinutes(1)); - } - - public ServiceSupervision(Services services, Policies policies, A1ClientFactory a1ClientFactory, - Duration checkInterval) { - this.services = services; - this.policies = policies; - this.a1ClientFactory = a1ClientFactory; - this.checkInterval = checkInterval; - start(); - } - - private void start() { - logger.debug("Checking services starting"); - createTask().subscribe(null, null, () -> logger.error("Checking services unexpectedly terminated")); - } - - private Flux createTask() { - return Flux.interval(this.checkInterval) // - .flatMap(notUsed -> checkAllServices()); - } - - Flux checkAllServices() { - return Flux.fromIterable(services.getAll()) // - .filter(Service::isExpired) // - .doOnNext(service -> logger.info("Service is expired: {}", service.getName())) // - .doOnNext(service -> services.remove(service.getName())) // - .flatMap(this::getAllPoliciesForService) // - .flatMap(this::deletePolicy, CONCURRENCY_RIC); - } - - @SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally - private Flux deletePolicy(Policy policy) { - Lock lock = policy.ric().getLock(); - return lock.lock(LockType.SHARED) // - .doOnNext(notUsed -> policies.remove(policy)) // - .flatMap(notUsed -> deletePolicyInRic(policy)) - .doOnNext(notUsed -> logger.debug("Policy deleted due to service inactivity: {}, service: {}", policy.id(), - policy.ownerServiceName())) // - .doOnNext(notUsed -> lock.unlockBlocking()) // - .doOnError(throwable -> lock.unlockBlocking()) // - .doOnError(throwable -> logger.debug("Failed to delete inactive policy: {}, reason: {}", policy.id(), - throwable.getMessage())) // - .flatMapMany(notUsed -> Flux.just(policy)) // - .onErrorResume(throwable -> Flux.empty()); - } - - private Flux getAllPoliciesForService(Service service) { - return Flux.fromIterable(policies.getForService(service.getName())); - } - - private Mono deletePolicyInRic(Policy policy) { - return a1ClientFactory.createA1Client(policy.ric()) // - .flatMap(client -> client.deletePolicy(policy) // - .onErrorResume(exception -> handleDeleteFromRicFailure(policy, exception)) // - .map(nothing -> policy)); - } - - private Mono handleDeleteFromRicFailure(Policy policy, Throwable e) { - logger.warn("Could not delete policy: {} from ric: {}. Cause: {}", policy.id(), policy.ric().name(), - e.getMessage()); - return Mono.empty(); - } -} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java b/policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java deleted file mode 100644 index 4de5c71f..00000000 --- a/policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java +++ /dev/null @@ -1,843 +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.policyagent; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.awaitility.Awaitility.await; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doReturn; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonParser; - -import java.nio.charset.StandardCharsets; -import java.time.Duration; -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.oransc.policyagent.clients.AsyncRestClient; -import org.oransc.policyagent.configuration.ApplicationConfig; -import org.oransc.policyagent.configuration.ImmutableRicConfig; -import org.oransc.policyagent.configuration.ImmutableWebClientConfig; -import org.oransc.policyagent.configuration.RicConfig; -import org.oransc.policyagent.configuration.WebClientConfig; -import org.oransc.policyagent.controllers.PolicyInfo; -import org.oransc.policyagent.controllers.ServiceRegistrationInfo; -import org.oransc.policyagent.controllers.ServiceStatus; -import org.oransc.policyagent.exceptions.ServiceException; -import org.oransc.policyagent.repository.ImmutablePolicy; -import org.oransc.policyagent.repository.ImmutablePolicyType; -import org.oransc.policyagent.repository.Lock.LockType; -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.Ric.RicState; -import org.oransc.policyagent.repository.Rics; -import org.oransc.policyagent.repository.Services; -import org.oransc.policyagent.tasks.RicSupervision; -import org.oransc.policyagent.tasks.ServiceSupervision; -import org.oransc.policyagent.utils.MockA1Client; -import org.oransc.policyagent.utils.MockA1ClientFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -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.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit.jupiter.SpringExtension; -import org.springframework.web.reactive.function.client.WebClientResponseException; - -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; -import reactor.util.annotation.Nullable; - -@ExtendWith(SpringExtension.class) -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -@TestPropertySource( - properties = { // - "server.ssl.key-store=./config/keystore.jks", // - "app.webclient.trust-store=./config/truststore.jks"}) -class ApplicationTest { - private static final Logger logger = LoggerFactory.getLogger(ApplicationTest.class); - - @Autowired - ApplicationContext context; - - @Autowired - private Rics rics; - - @Autowired - private Policies policies; - - @Autowired - private PolicyTypes policyTypes; - - @Autowired - MockA1ClientFactory a1ClientFactory; - - @Autowired - RicSupervision supervision; - - @Autowired - ApplicationConfig applicationConfig; - - @Autowired - Services services; - - private static Gson gson = new GsonBuilder() // - .serializeNulls() // - .create(); // - - public static class MockApplicationConfig extends ApplicationConfig { - @Override - public String getLocalConfigurationFilePath() { - return ""; // No config file loaded for the test - } - } - - /** - * Overrides the BeanFactory. - */ - @TestConfiguration - static class TestBeanFactory { - private final PolicyTypes policyTypes = new PolicyTypes(); - private final Services services = new Services(); - private final Policies policies = new Policies(); - MockA1ClientFactory a1ClientFactory = null; - - @Bean - public ApplicationConfig getApplicationConfig() { - return new MockApplicationConfig(); - } - - @Bean - MockA1ClientFactory getA1ClientFactory() { - if (a1ClientFactory == null) { - this.a1ClientFactory = new MockA1ClientFactory(this.policyTypes); - } - return this.a1ClientFactory; - } - - @Bean - public PolicyTypes getPolicyTypes() { - return this.policyTypes; - } - - @Bean - Policies getPolicies() { - return this.policies; - } - - @Bean - Services getServices() { - return this.services; - } - - @Bean - public ServiceSupervision getServiceSupervision() { - Duration checkInterval = Duration.ofMillis(1); - return new ServiceSupervision(this.services, this.policies, this.getA1ClientFactory(), checkInterval); - } - - @Bean - public ServletWebServerFactory servletContainer() { - return new TomcatServletWebServerFactory(); - } - - } - - @LocalServerPort - private int port; - - @BeforeEach - void reset() { - rics.clear(); - policies.clear(); - policyTypes.clear(); - services.clear(); - a1ClientFactory.reset(); - } - - @AfterEach - void verifyNoRicLocks() { - for (Ric ric : this.rics.getRics()) { - ric.getLock().lockBlocking(LockType.EXCLUSIVE); - ric.getLock().unlockBlocking(); - assertThat(ric.getLock().getLockCounter()).isZero(); - assertThat(ric.getState()).isEqualTo(Ric.RicState.AVAILABLE); - } - } - - @Test - void testGetRics() throws Exception { - addRic("ric1"); - this.addPolicyType("type1", "ric1"); - String url = "/rics?policyType=type1"; - String rsp = restClient().get(url).block(); - assertThat(rsp).contains("ric1"); - - // nameless type for ORAN A1 1.1 - addRic("ric2"); - this.addPolicyType("", "ric2"); - url = "/rics?policyType="; - - // This tests also validation of trusted certs restClient(true) - rsp = restClient(true).get(url).block(); - assertThat(rsp).contains("ric2") // - .doesNotContain("ric1") // - .contains("AVAILABLE"); - - // All RICs - rsp = restClient().get("/rics").block(); - assertThat(rsp).contains("ric2") // - .contains("ric1"); - - // Non existing policy type - url = "/rics?policyType=XXXX"; - testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND); - } - - @Test - void testSynchronization() throws Exception { - // Two polictypes will be put in the NearRT RICs - PolicyTypes nearRtRicPolicyTypes = new PolicyTypes(); - nearRtRicPolicyTypes.put(createPolicyType("typeName")); - nearRtRicPolicyTypes.put(createPolicyType("typeName2")); - this.a1ClientFactory.setPolicyTypes(nearRtRicPolicyTypes); - - // One type and one instance added to the agent storage - final String ric1Name = "ric1"; - Ric ric1 = addRic(ric1Name); - Policy policy2 = addPolicy("policyId2", "typeName", "service", ric1Name); - Ric ric2 = addRic("ric2"); - - getA1Client(ric1Name).putPolicy(policy2); // put it in the RIC - policies.remove(policy2); // Remove it from the repo -> should be deleted in the RIC - - String policyId = "policyId"; - Policy policy = addPolicy(policyId, "typeName", "service", ric1Name); // This should be created in the RIC - supervision.checkAllRics(); // The created policy should be put in the RIC - - // Wait until synch is completed - await().untilAsserted(() -> RicState.SYNCHRONIZING.equals(rics.getRic(ric1Name).getState())); - await().untilAsserted(() -> RicState.AVAILABLE.equals(rics.getRic(ric1Name).getState())); - await().untilAsserted(() -> RicState.AVAILABLE.equals(rics.getRic("ric2").getState())); - - Policies ricPolicies = getA1Client(ric1Name).getPolicies(); - assertThat(ricPolicies.size()).isEqualTo(1); - Policy ricPolicy = ricPolicies.get(policyId); - assertThat(ricPolicy.json()).isEqualTo(policy.json()); - - // Both types should be in the agent storage after the synch - assertThat(ric1.getSupportedPolicyTypes()).hasSize(2); - assertThat(ric2.getSupportedPolicyTypes()).hasSize(2); - } - - @Test - void testGetRicForManagedElement_thenReturnCorrectRic() throws Exception { - String ricName = "ric1"; - String managedElementId = "kista_1"; - addRic(ricName, managedElementId); - - String url = "/ric?managedElementId=" + managedElementId; - String rsp = restClient().get(url).block(); - assertThat(rsp).isEqualTo(ricName); - - // test GET RIC for ManagedElement that does not exist - url = "/ric?managedElementId=" + "junk"; - testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND); - } - - private String putPolicyUrl(String serviceName, String ricName, String policyTypeName, String policyInstanceId, - boolean isTransient) { - String url; - if (policyTypeName.isEmpty()) { - url = "/policy?id=" + policyInstanceId + "&ric=" + ricName + "&service=" + serviceName; - } else { - url = "/policy?id=" + policyInstanceId + "&ric=" + ricName + "&service=" + serviceName + "&type=" - + policyTypeName; - } - if (isTransient) { - url += "&transient=true"; - } - return url; - } - - private String putPolicyUrl(String serviceName, String ricName, String policyTypeName, String policyInstanceId) { - return putPolicyUrl(serviceName, ricName, policyTypeName, policyInstanceId, false); - } - - @Test - void testPutPolicy() throws Exception { - String serviceName = "service1"; - String ricName = "ric1"; - String policyTypeName = "type1"; - String policyInstanceId = "instance1"; - - putService(serviceName); - addPolicyType(policyTypeName, ricName); - - // PUT a transient policy - String url = putPolicyUrl(serviceName, ricName, policyTypeName, policyInstanceId, true); - final String policyBody = jsonString(); - this.rics.getRic(ricName).setState(Ric.RicState.AVAILABLE); - - restClient().put(url, policyBody).block(); - - Policy policy = policies.getPolicy(policyInstanceId); - assertThat(policy).isNotNull(); - assertThat(policy.id()).isEqualTo(policyInstanceId); - assertThat(policy.ownerServiceName()).isEqualTo(serviceName); - assertThat(policy.ric().name()).isEqualTo("ric1"); - assertThat(policy.isTransient()).isTrue(); - - // Put a non transient policy - url = putPolicyUrl(serviceName, ricName, policyTypeName, policyInstanceId); - restClient().put(url, policyBody).block(); - policy = policies.getPolicy(policyInstanceId); - assertThat(policy.isTransient()).isFalse(); - - url = "/policies"; - String rsp = restClient().get(url).block(); - assertThat(rsp).as("Response contains policy instance ID.").contains(policyInstanceId); - - url = "/policy?id=" + policyInstanceId; - rsp = restClient().get(url).block(); - assertThat(rsp).isEqualTo(policyBody); - - // Test of error codes - url = putPolicyUrl(serviceName, ricName + "XX", policyTypeName, policyInstanceId); - testErrorCode(restClient().put(url, policyBody), HttpStatus.NOT_FOUND); - - url = putPolicyUrl(serviceName, ricName, policyTypeName + "XX", policyInstanceId); - addPolicyType(policyTypeName + "XX", "otherRic"); - testErrorCode(restClient().put(url, policyBody), HttpStatus.NOT_FOUND); - - url = putPolicyUrl(serviceName, ricName, policyTypeName, policyInstanceId); - this.rics.getRic(ricName).setState(Ric.RicState.SYNCHRONIZING); - testErrorCode(restClient().put(url, policyBody), HttpStatus.LOCKED); - this.rics.getRic(ricName).setState(Ric.RicState.AVAILABLE); - } - - @Test - /** - * Test that HttpStatus and body from failing REST call to A1 is passed on to - * the caller. - * - * @throws ServiceException - */ - void testErrorFromRic() throws ServiceException { - putService("service1"); - addPolicyType("type1", "ric1"); - - String url = putPolicyUrl("service1", "ric1", "type1", "id1"); - MockA1Client a1Client = a1ClientFactory.getOrCreateA1Client("ric1"); - HttpStatus httpStatus = HttpStatus.INTERNAL_SERVER_ERROR; - String responseBody = "Refused"; - byte[] responseBodyBytes = responseBody.getBytes(StandardCharsets.UTF_8); - - WebClientResponseException a1Exception = new WebClientResponseException(httpStatus.value(), "statusText", null, - responseBodyBytes, StandardCharsets.UTF_8, null); - doReturn(Mono.error(a1Exception)).when(a1Client).putPolicy(any()); - - // PUT Policy - testErrorCode(restClient().put(url, "{}"), httpStatus, responseBody); - - // DELETE POLICY - this.addPolicy("instance1", "type1", "service1", "ric1"); - doReturn(Mono.error(a1Exception)).when(a1Client).deletePolicy(any()); - testErrorCode(restClient().delete("/policy?id=instance1"), httpStatus, responseBody); - - // GET STATUS - this.addPolicy("instance1", "type1", "service1", "ric1"); - doReturn(Mono.error(a1Exception)).when(a1Client).getPolicyStatus(any()); - testErrorCode(restClient().get("/policy_status?id=instance1"), httpStatus, responseBody); - - // Check that empty response body is OK - a1Exception = new WebClientResponseException(httpStatus.value(), "", null, null, null, null); - doReturn(Mono.error(a1Exception)).when(a1Client).getPolicyStatus(any()); - testErrorCode(restClient().get("/policy_status?id=instance1"), httpStatus); - } - - @Test - void testPutTypelessPolicy() throws Exception { - putService("service1"); - addPolicyType("", "ric1"); - String url = putPolicyUrl("service1", "ric1", "", "id1"); - restClient().put(url, jsonString()).block(); - - String rsp = restClient().get("/policies").block(); - List info = parseList(rsp, PolicyInfo.class); - assertThat(info).hasSize(1); - PolicyInfo policyInfo = info.get(0); - assertThat(policyInfo.id).isEqualTo("id1"); - assertThat(policyInfo.type).isEmpty(); - } - - @Test - void testRefuseToUpdatePolicy() throws Exception { - // Test that only the json can be changed for a already created policy - // In this case service is attempted to be changed - this.addRic("ric1"); - this.addRic("ricXXX"); - this.addPolicy("instance1", "type1", "service1", "ric1"); - this.addPolicy("instance2", "type1", "service1", "ricXXX"); - - // Try change ric1 -> ricXXX - String urlWrongRic = putPolicyUrl("service1", "ricXXX", "type1", "instance1"); - testErrorCode(restClient().put(urlWrongRic, jsonString()), HttpStatus.CONFLICT); - } - - @Test - void testGetPolicy() throws Exception { - String url = "/policy?id=id"; - Policy policy = addPolicy("id", "typeName", "service1", "ric1"); - { - String rsp = restClient().get(url).block(); - assertThat(rsp).isEqualTo(policy.json()); - } - { - policies.remove(policy); - testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND); - } - } - - @Test - void testDeletePolicy() throws Exception { - addPolicy("id", "typeName", "service1", "ric1"); - assertThat(policies.size()).isEqualTo(1); - - String url = "/policy?id=id"; - ResponseEntity entity = restClient().deleteForEntity(url).block(); - - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT); - assertThat(policies.size()).isZero(); - - // Delete a non existing policy - testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND); - } - - @Test - void testGetPolicySchemas() throws Exception { - addPolicyType("type1", "ric1"); - addPolicyType("type2", "ric2"); - - String url = "/policy_schemas"; - String rsp = this.restClient().get(url).block(); - assertThat(rsp).contains("type1") // - .contains("[{\"title\":\"type2\"}"); - - List info = parseSchemas(rsp); - assertThat(info).hasSize(2); - - url = "/policy_schemas?ric=ric1"; - rsp = restClient().get(url).block(); - assertThat(rsp).contains("type1"); - info = parseSchemas(rsp); - assertThat(info).hasSize(1); - - // Get schema for non existing RIC - url = "/policy_schemas?ric=ric1XXX"; - testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND); - } - - @Test - void testGetPolicySchema() throws Exception { - addPolicyType("type1", "ric1"); - addPolicyType("type2", "ric2"); - - String url = "/policy_schema?id=type1"; - String rsp = restClient().get(url).block(); - logger.info(rsp); - assertThat(rsp).contains("type1") // - .contains("title"); - - // Get non existing schema - url = "/policy_schema?id=type1XX"; - testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND); - } - - @Test - void testGetPolicyTypes() throws Exception { - addPolicyType("type1", "ric1"); - addPolicyType("type2", "ric2"); - - String url = "/policy_types"; - String rsp = restClient().get(url).block(); - assertThat(rsp).isEqualTo("[\"type2\",\"type1\"]"); - - url = "/policy_types?ric=ric1"; - rsp = restClient().get(url).block(); - assertThat(rsp).isEqualTo("[\"type1\"]"); - - // Get policy types for non existing RIC - url = "/policy_types?ric=ric1XXX"; - testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND); - } - - @Test - void testGetPolicies() throws Exception { - addPolicy("id1", "type1", "service1"); - - String url = "/policies"; - String rsp = restClient().get(url).block(); - logger.info(rsp); - List info = parseList(rsp, PolicyInfo.class); - assertThat(info).hasSize(1); - PolicyInfo policyInfo = info.get(0); - assert (policyInfo.validate()); - assertThat(policyInfo.id).isEqualTo("id1"); - assertThat(policyInfo.type).isEqualTo("type1"); - assertThat(policyInfo.service).isEqualTo("service1"); - } - - @Test - void testGetPoliciesFilter() throws Exception { - addPolicy("id1", "type1", "service1"); - addPolicy("id2", "type1", "service2"); - addPolicy("id3", "type2", "service1"); - - String url = "/policies?type=type1"; - String rsp = restClient().get(url).block(); - logger.info(rsp); - assertThat(rsp).contains("id1") // - .contains("id2") // - .doesNotContain("id3"); - - url = "/policies?type=type1&service=service2"; - rsp = restClient().get(url).block(); - logger.info(rsp); - assertThat(rsp).doesNotContain("id1") // - .contains("id2") // - .doesNotContain("id3"); - - // Test get policies for non existing type - url = "/policies?type=type1XXX"; - testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND); - - // Test get policies for non existing RIC - url = "/policies?ric=XXX"; - testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND); - } - - @Test - void testGetPolicyIdsFilter() throws Exception { - addPolicy("id1", "type1", "service1", "ric1"); - addPolicy("id2", "type1", "service2", "ric1"); - addPolicy("id3", "type2", "service1", "ric1"); - - String url = "/policy_ids?type=type1"; - String rsp = restClient().get(url).block(); - logger.info(rsp); - assertThat(rsp).contains("id1") // - .contains("id2") // - .doesNotContain("id3"); - - url = "/policy_ids?type=type1&service=service1&ric=ric1"; - rsp = restClient().get(url).block(); - assertThat(rsp).isEqualTo("[\"id1\"]"); - - // Test get policy ids for non existing type - url = "/policy_ids?type=type1XXX"; - testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND); - - // Test get policy ids for non existing RIC - url = "/policy_ids?ric=XXX"; - testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND); - } - - @Test - void testPutAndGetService() throws Exception { - // PUT - String serviceName = "name"; - putService(serviceName, 0, HttpStatus.CREATED); - putService(serviceName, 0, HttpStatus.OK); - - // GET one service - String url = "/services?name=name"; - String rsp = restClient().get(url).block(); - List info = parseList(rsp, ServiceStatus.class); - assertThat(info).hasSize(1); - ServiceStatus status = info.iterator().next(); - assertThat(status.keepAliveIntervalSeconds).isZero(); - assertThat(status.serviceName).isEqualTo(serviceName); - - // GET (all) - url = "/services"; - rsp = restClient().get(url).block(); - assertThat(rsp).as("Response contains service name").contains(serviceName); - logger.info(rsp); - - // Keep alive - url = "/services/keepalive?name=name"; - ResponseEntity entity = restClient().putForEntity(url).block(); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - - // DELETE service - assertThat(services.size()).isEqualTo(1); - url = "/services?name=name"; - restClient().delete(url).block(); - assertThat(services.size()).isZero(); - - // Keep alive, no registered service - testErrorCode(restClient().put("/services/keepalive?name=name", ""), HttpStatus.NOT_FOUND); - - // PUT servive with bad payload - testErrorCode(restClient().put("/service", "crap"), HttpStatus.BAD_REQUEST); - testErrorCode(restClient().put("/service", "{}"), HttpStatus.BAD_REQUEST); - testErrorCode(restClient().put("/service", createServiceJson(serviceName, -123)), HttpStatus.BAD_REQUEST); - testErrorCode(restClient().put("/service", createServiceJson(serviceName, 0, "missing.portandprotocol.com")), - HttpStatus.BAD_REQUEST); - - // GET non existing service - testErrorCode(restClient().get("/services?name=XXX"), HttpStatus.NOT_FOUND); - } - - @Test - void testServiceSupervision() throws Exception { - putService("service1", 1, HttpStatus.CREATED); - addPolicyType("type1", "ric1"); - - String url = putPolicyUrl("service1", "ric1", "type1", "instance1"); - final String policyBody = jsonString(); - restClient().put(url, policyBody).block(); - - assertThat(policies.size()).isEqualTo(1); - assertThat(services.size()).isEqualTo(1); - - // Timeout after ~1 second - await().untilAsserted(() -> assertThat(policies.size()).isZero()); - assertThat(services.size()).isZero(); - } - - @Test - void testGetPolicyStatus() throws Exception { - addPolicy("id", "typeName", "service1", "ric1"); - assertThat(policies.size()).isEqualTo(1); - - String url = "/policy_status?id=id"; - String rsp = restClient().get(url).block(); - assertThat(rsp).isEqualTo("OK"); - - // GET non existing policy status - url = "/policy_status?id=XXX"; - testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND); - } - - private Policy addPolicy(String id, String typeName, String service, String ric) throws ServiceException { - addRic(ric); - Policy policy = ImmutablePolicy.builder() // - .id(id) // - .json(jsonString()) // - .ownerServiceName(service) // - .ric(rics.getRic(ric)) // - .type(addPolicyType(typeName, ric)) // - .lastModified("lastModified") // - .isTransient(false) // - .build(); - policies.put(policy); - return policy; - } - - private Policy addPolicy(String id, String typeName, String service) throws ServiceException { - return addPolicy(id, typeName, service, "ric"); - } - - private String createServiceJson(String name, long keepAliveIntervalSeconds) { - return createServiceJson(name, keepAliveIntervalSeconds, "https://examples.javacodegeeks.com/core-java/"); - } - - private String createServiceJson(String name, long keepAliveIntervalSeconds, String url) { - ServiceRegistrationInfo service = new ServiceRegistrationInfo(name, keepAliveIntervalSeconds, url); - - String json = gson.toJson(service); - return json; - } - - private void putService(String name) { - putService(name, 0, null); - } - - private void putService(String name, long keepAliveIntervalSeconds, @Nullable HttpStatus expectedStatus) { - String url = "/service"; - String body = createServiceJson(name, keepAliveIntervalSeconds); - ResponseEntity resp = restClient().putForEntity(url, body).block(); - if (expectedStatus != null) { - assertEquals(expectedStatus, resp.getStatusCode(), ""); - } - } - - private String baseUrl() { - return "https://localhost:" + port; - } - - private String jsonString() { - return "{\"servingCellNrcgi\":\"1\"}"; - } - - @Test - void testConcurrency() throws Exception { - final Instant startTime = Instant.now(); - List threads = new ArrayList<>(); - a1ClientFactory.setResponseDelay(Duration.ofMillis(1)); - addRic("ric"); - addPolicyType("type1", "ric"); - addPolicyType("type2", "ric"); - List tests = new ArrayList<>(); - - for (int i = 0; i < 10; ++i) { - ConcurrencyTestRunnable test = - new ConcurrencyTestRunnable(restClient(), supervision, a1ClientFactory, rics, policyTypes); - Thread thread = new Thread(test, "TestThread_" + i); - thread.start(); - threads.add(thread); - tests.add(test); - } - for (Thread t : threads) { - t.join(); - } - for (ConcurrencyTestRunnable test : tests) { - assertThat(test.isFailed()).isFalse(); - } - - assertThat(policies.size()).isZero(); - logger.info("Concurrency test took " + Duration.between(startTime, Instant.now())); - } - - private AsyncRestClient restClient(boolean useTrustValidation) { - WebClientConfig config = this.applicationConfig.getWebClientConfig(); - config = ImmutableWebClientConfig.builder() // - .keyStoreType(config.keyStoreType()) // - .keyStorePassword(config.keyStorePassword()) // - .keyStore(config.keyStore()) // - .keyPassword(config.keyPassword()) // - .isTrustStoreUsed(useTrustValidation) // - .trustStore(config.trustStore()) // - .trustStorePassword(config.trustStorePassword()) // - .build(); - - return new AsyncRestClient(baseUrl(), config); - } - - private AsyncRestClient restClient() { - return restClient(false); - } - - private void testErrorCode(Mono request, HttpStatus expStatus) { - testErrorCode(request, expStatus, ""); - } - - private void testErrorCode(Mono request, HttpStatus expStatus, String responseContains) { - StepVerifier.create(request) // - .expectSubscription() // - .expectErrorMatches(t -> checkWebClientError(t, expStatus, responseContains)) // - .verify(); - } - - private boolean checkWebClientError(Throwable throwable, HttpStatus expStatus, String responseContains) { - assertTrue(throwable instanceof WebClientResponseException); - WebClientResponseException responseException = (WebClientResponseException) throwable; - assertThat(responseException.getStatusCode()).isEqualTo(expStatus); - assertThat(responseException.getResponseBodyAsString()).contains(responseContains); - return true; - } - - private MockA1Client getA1Client(String ricName) throws ServiceException { - return a1ClientFactory.getOrCreateA1Client(ricName); - } - - private PolicyType createPolicyType(String policyTypeName) { - return ImmutablePolicyType.builder() // - .name(policyTypeName) // - .schema("{\"title\":\"" + policyTypeName + "\"}") // - .build(); - } - - private PolicyType addPolicyType(String policyTypeName, String ricName) { - PolicyType type = createPolicyType(policyTypeName); - policyTypes.put(type); - addRic(ricName).addSupportedPolicyType(type); - return type; - } - - private Ric addRic(String ricName) { - return addRic(ricName, null); - } - - private Ric addRic(String ricName, String managedElement) { - if (rics.get(ricName) != null) { - return rics.get(ricName); - } - List mes = new ArrayList<>(); - if (managedElement != null) { - mes.add(managedElement); - } - RicConfig conf = ImmutableRicConfig.builder() // - .name(ricName) // - .baseUrl(ricName) // - .managedElementIds(mes) // - .controllerName("") // - .build(); - Ric ric = new Ric(conf); - ric.setState(Ric.RicState.AVAILABLE); - this.rics.put(ric); - return ric; - } - - private static List parseList(String jsonString, Class clazz) { - List result = new ArrayList<>(); - JsonArray jsonArr = JsonParser.parseString(jsonString).getAsJsonArray(); - for (JsonElement jsonElement : jsonArr) { - T json = gson.fromJson(jsonElement.toString(), clazz); - result.add(json); - } - return result; - } - - private static List parseSchemas(String jsonString) { - JsonArray arrayOfSchema = JsonParser.parseString(jsonString).getAsJsonArray(); - List result = new ArrayList<>(); - for (JsonElement schemaObject : arrayOfSchema) { - result.add(schemaObject.toString()); - } - return result; - } -} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/ConcurrencyTestRunnable.java b/policy-agent/src/test/java/org/oransc/policyagent/ConcurrencyTestRunnable.java deleted file mode 100644 index 0ca55340..00000000 --- a/policy-agent/src/test/java/org/oransc/policyagent/ConcurrencyTestRunnable.java +++ /dev/null @@ -1,146 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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 java.util.concurrent.atomic.AtomicInteger; - -import org.oransc.policyagent.clients.AsyncRestClient; -import org.oransc.policyagent.repository.ImmutablePolicy; -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.oransc.policyagent.tasks.RicSupervision; -import org.oransc.policyagent.utils.MockA1Client; -import org.oransc.policyagent.utils.MockA1ClientFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.ResponseEntity; - -/** - * Invoke operations over the NBI and start synchronizations in a separate - * thread. For test of robustness using concurrent clients. - */ -class ConcurrencyTestRunnable implements Runnable { - private static final Logger logger = LoggerFactory.getLogger(ConcurrencyTestRunnable.class); - private final AsyncRestClient webClient; - static AtomicInteger nextCount = new AtomicInteger(0); - private final int count; - private final RicSupervision supervision; - private final MockA1ClientFactory a1ClientFactory; - private final Rics rics; - private final PolicyTypes types; - private boolean failed = false; - - ConcurrencyTestRunnable(AsyncRestClient webClient, RicSupervision supervision, MockA1ClientFactory a1ClientFactory, - Rics rics, PolicyTypes types) { - this.count = nextCount.incrementAndGet(); - this.supervision = supervision; - this.a1ClientFactory = a1ClientFactory; - this.rics = rics; - this.types = types; - this.webClient = webClient; - } - - private void printStatusInfo() { - try { - String url = "/actuator/metrics/jvm.threads.live"; - ResponseEntity result = webClient.getForEntity(url).block(); - System.out.println(Thread.currentThread() + result.getBody()); - - url = "/rics"; - result = webClient.getForEntity(url).block(); - System.out.println(Thread.currentThread() + result.getBody()); - - } catch (Exception e) { - logger.error(Thread.currentThread() + "Concurrency test printStatusInfo exception " + e.toString()); - } - } - - @Override - public void run() { - try { - for (int i = 0; i < 500; ++i) { - if (i % 100 == 0) { - createInconsistency(); - this.supervision.checkAllRics(); - } - String name = "policy:" + count + ":" + i; - putPolicy(name); - putPolicy(name + "-"); - listPolicies(); - listTypes(); - deletePolicy(name); - deletePolicy(name + "-"); - } - } catch (Exception e) { - logger.error("Concurrency test exception " + e.toString()); - printStatusInfo(); - failed = true; - } - } - - public boolean isFailed() { - return this.failed; - } - - private Policy createPolicyObject(String id) { - Ric ric = this.rics.get("ric"); - PolicyType type = this.types.get("type1"); - return ImmutablePolicy.builder() // - .id(id) // - .json("{}") // - .type(type) // - .ric(ric) // - .ownerServiceName("") // - .lastModified("") // - .isTransient(false) // - .build(); - } - - private void createInconsistency() { - MockA1Client client = a1ClientFactory.getOrCreateA1Client("ric"); - Policy policy = createPolicyObject("junk"); - client.putPolicy(policy).block(); - - } - - private void listPolicies() { - String uri = "/policies"; - webClient.getForEntity(uri).block(); - } - - private void listTypes() { - String uri = "/policy_types"; - webClient.getForEntity(uri).block(); - } - - private void putPolicy(String name) { - String putUrl = "/policy?type=type1&id=" + name + "&ric=ric&service=service1"; - webClient.putForEntity(putUrl, "{}").block(); - } - - private void deletePolicy(String name) { - String deleteUrl = "/policy?id=" + name; - webClient.delete(deleteUrl).block(); - } -} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/MockPolicyAgent.java b/policy-agent/src/test/java/org/oransc/policyagent/MockPolicyAgent.java deleted file mode 100644 index f42a631f..00000000 --- a/policy-agent/src/test/java/org/oransc/policyagent/MockPolicyAgent.java +++ /dev/null @@ -1,212 +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.policyagent; - -import static org.awaitility.Awaitility.await; - -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.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.oransc.policyagent.configuration.ApplicationConfig; -import org.oransc.policyagent.repository.ImmutablePolicy; -import org.oransc.policyagent.repository.ImmutablePolicyType; -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.oransc.policyagent.utils.MockA1ClientFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -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.TestPropertySource; -import org.springframework.test.context.junit.jupiter.SpringExtension; -import org.springframework.util.StringUtils; - -@ExtendWith(SpringExtension.class) -@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT) -@TestPropertySource( - properties = { // - "server.ssl.key-store=./config/keystore.jks", // - "app.webclient.trust-store=./config/truststore.jks"}) -class MockPolicyAgent { - private static final Logger logger = LoggerFactory.getLogger(MockPolicyAgent.class); - - @Autowired - Rics rics; - - @Autowired - Policies policies; - - @Autowired - PolicyTypes policyTypes; - - @Autowired - ApplicationConfig applicationConfig; - - static class MockApplicationConfig extends ApplicationConfig { - @Override - public String getLocalConfigurationFilePath() { - URL url = MockApplicationConfig.class.getClassLoader().getResource("test_application_configuration.json"); - return url.getFile(); - } - } - - /** - * Overrides the BeanFactory. - */ - @TestConfiguration - static class TestBeanFactory { - - private final Rics rics = new Rics(); - private final Policies policies = new Policies(); - private final PolicyTypes policyTypes = new PolicyTypes(); - - @Bean - public ApplicationConfig getApplicationConfig() { - return new MockApplicationConfig(); - } - - @Bean - public MockA1ClientFactory getA1ClientFactory() { - PolicyTypes ricTypes = new PolicyTypes(); - loadTypes(ricTypes); - return new MockA1ClientFactory(ricTypes); - } - - @Bean - public Policies getPolicies() { - return this.policies; - } - - @Bean - public PolicyTypes getPolicyTypes() { - return this.policyTypes; - } - - @Bean - public Rics getRics() { - return this.rics; - } - - private static File[] getResourceFolderFiles(String folder) { - return getFile(folder).listFiles(); - } - - private static String readFile(File file) throws IOException { - return new String(Files.readAllBytes(file.toPath())); - } - - private 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).schema(schema).build(); - policyTypes.put(type); - } catch (Exception e) { - logger.error("Could not load json schema ", e); - } - } - policyTypes.put(ImmutablePolicyType.builder().name("").schema("{}").build()); - } - } - - private static File getFile(String path) { - ClassLoader loader = Thread.currentThread().getContextClassLoader(); - URL url = loader.getResource(path); - return new File(url.getPath()); - } - - @LocalServerPort - private int port; - - private void keepServerAlive() throws InterruptedException, IOException { - waitForConfigurationToBeLoaded(); - loadInstances(); - logger.info("Keeping server alive!"); - synchronized (this) { - this.wait(); - } - } - - private void waitForConfigurationToBeLoaded() throws IOException { - String json = getConfigJsonFromFile(); - try { - int noOfRicsInConfigFile = StringUtils.countOccurrencesOf(json, "baseUrl"); - await().until(() -> rics.size() == noOfRicsInConfigFile); - } catch (Exception e) { - logger.info("Loaded rics: {}, and no of rics in config file: {} never matched!", rics.size(), - StringUtils.countOccurrencesOf(json, "baseUrl")); - } - } - - private static String title(String jsonSchema) { - JsonObject parsedSchema = (JsonObject) JsonParser.parseString(jsonSchema); - String title = parsedSchema.get("title").getAsString(); - return title; - } - - private void loadInstances() throws IOException { - PolicyType unnamedPolicyType = policyTypes.get(""); - Ric ric = rics.get("ric1"); - String json = getConfigJsonFromFile(); - - Policy policy = ImmutablePolicy.builder() // - .id("typelessPolicy") // - .json(json) // - .ownerServiceName("MockPolicyAgent") // - .ric(ric) // - .type(unnamedPolicyType) // - .lastModified("now") // - .isTransient(false) // - .build(); - this.policies.put(policy); - } - - private String getConfigJsonFromFile() throws IOException { - File jsonFile = getFile("test_application_configuration.json"); - String json = new String(Files.readAllBytes(jsonFile.toPath())); - return json; - } - - @Test - @SuppressWarnings("squid:S2699") // Tests should include assertions. This test is only for keeping the server - // alive, so it will only be confusing to add an assertion. - void runMock() throws Exception { - keepServerAlive(); - } - -} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/aspect/LogAspectTest.java b/policy-agent/src/test/java/org/oransc/policyagent/aspect/LogAspectTest.java deleted file mode 100644 index ae8ed2cb..00000000 --- a/policy-agent/src/test/java/org/oransc/policyagent/aspect/LogAspectTest.java +++ /dev/null @@ -1,98 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.aspect; - -import static ch.qos.logback.classic.Level.TRACE; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.core.read.ListAppender; - -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.reflect.MethodSignature; -import org.junit.Rule; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; -import org.mockito.junit.jupiter.MockitoExtension; -import org.oransc.policyagent.utils.LoggingUtils; - -@ExtendWith(MockitoExtension.class) -class LogAspectTest { - @Rule - MockitoRule mockitoRule = MockitoJUnit.rule(); - - @Mock - private ProceedingJoinPoint proceedingJoinPoint; - - @Mock - private MethodSignature methodSignature; - - private LogAspect sampleAspect = new LogAspect(); - - @Test - void testExecutetimeTime_shouldLogTime() throws Throwable { - when(proceedingJoinPoint.getSignature()).thenReturn(methodSignature); - when(methodSignature.getDeclaringType()).thenReturn(this.getClass()); - - final ListAppender logAppender = LoggingUtils.getLogListAppender(LogAspect.class, TRACE); - - sampleAspect.executimeTime(proceedingJoinPoint); - // 'proceed()' is called exactly once - verify(proceedingJoinPoint, times(1)).proceed(); - // 'proceed(Object[])' is never called - verify(proceedingJoinPoint, never()).proceed(null); - - assertThat(logAppender.list.get(0).getFormattedMessage()).startsWith("Execution time of"); - } - - @Test - void testEntryLog_shouldLogEntry() throws Throwable { - when(proceedingJoinPoint.getSignature()).thenReturn(methodSignature); - String signature = "signature"; - when(methodSignature.getName()).thenReturn(signature); - - final ListAppender logAppender = LoggingUtils.getLogListAppender(LogAspect.class, TRACE); - - sampleAspect.entryLog(proceedingJoinPoint); - - assertThat(logAppender.list.get(0).getFormattedMessage()).isEqualTo("Entering method: " + signature); - } - - @Test - void testExitLog_shouldLogExit() throws Throwable { - when(proceedingJoinPoint.getSignature()).thenReturn(methodSignature); - String signature = "signature"; - when(methodSignature.getName()).thenReturn(signature); - - final ListAppender logAppender = LoggingUtils.getLogListAppender(LogAspect.class, TRACE); - - sampleAspect.exitLog(proceedingJoinPoint); - - assertThat(logAppender.list.get(0).getFormattedMessage()).isEqualTo("Exiting method: " + signature); - } -} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/clients/A1ClientFactoryTest.java b/policy-agent/src/test/java/org/oransc/policyagent/clients/A1ClientFactoryTest.java deleted file mode 100644 index 74cebb05..00000000 --- a/policy-agent/src/test/java/org/oransc/policyagent/clients/A1ClientFactoryTest.java +++ /dev/null @@ -1,167 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.clients; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -import java.util.Vector; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.oransc.policyagent.clients.A1Client.A1ProtocolType; -import org.oransc.policyagent.configuration.ApplicationConfig; -import org.oransc.policyagent.configuration.ControllerConfig; -import org.oransc.policyagent.configuration.ImmutableControllerConfig; -import org.oransc.policyagent.configuration.ImmutableRicConfig; -import org.oransc.policyagent.exceptions.ServiceException; -import org.oransc.policyagent.repository.Ric; - -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -@ExtendWith(MockitoExtension.class) -class A1ClientFactoryTest { - private static final String RIC_NAME = "Name"; - private static final String EXCEPTION_MESSAGE = "Error"; - - @Mock - private ApplicationConfig applicationConfigMock; - - @Mock - A1Client clientMock1; - - @Mock - A1Client clientMock2; - - @Mock - A1Client clientMock3; - - @Mock - A1Client clientMock4; - - private Ric ric; - private A1ClientFactory factoryUnderTest; - - private static ImmutableRicConfig ricConfig(String controllerName) { - return ImmutableRicConfig.builder() // - .name(RIC_NAME) // - .baseUrl("baseUrl") // - .managedElementIds(new Vector<>()) // - .controllerName(controllerName) // - .build(); - } - - @BeforeEach - void createFactoryUnderTest() { - factoryUnderTest = spy(new A1ClientFactory(applicationConfigMock)); - this.ric = new Ric(ricConfig("")); - - } - - @Test - void getProtocolVersion_ok() throws ServiceException { - whenGetProtocolVersionThrowException(clientMock1); - whenGetProtocolVersionReturn(clientMock2, A1ProtocolType.STD_V1_1); - doReturn(clientMock1, clientMock2).when(factoryUnderTest).createClient(any(), any()); - - A1Client client = factoryUnderTest.createA1Client(ric).block(); - - assertEquals(clientMock2, client, "Not correct client returned"); - assertEquals(A1ProtocolType.STD_V1_1, ric.getProtocolVersion(), "Not correct protocol"); - } - - @Test - void getProtocolVersion_ok_Last() throws ServiceException { - whenGetProtocolVersionThrowException(clientMock1, clientMock2, clientMock3); - whenGetProtocolVersionReturn(clientMock4, A1ProtocolType.STD_V1_1); - doReturn(clientMock1, clientMock2, clientMock3, clientMock4).when(factoryUnderTest).createClient(any(), any()); - - A1Client client = factoryUnderTest.createA1Client(ric).block(); - - assertEquals(clientMock4, client, "Not correct client returned"); - assertEquals(A1ProtocolType.STD_V1_1, ric.getProtocolVersion(), "Not correct protocol"); - } - - @Test - void getProtocolVersion_error() throws ServiceException { - whenGetProtocolVersionThrowException(clientMock1, clientMock2, clientMock3, clientMock4); - doReturn(clientMock1, clientMock2, clientMock3, clientMock4).when(factoryUnderTest).createClient(any(), any()); - - StepVerifier.create(factoryUnderTest.createA1Client(ric)) // - .expectSubscription() // - .expectError() // - .verify(); - - assertEquals(A1ProtocolType.UNKNOWN, ric.getProtocolVersion(), "Protocol negotiation failed for " + ric.name()); - } - - private A1Client createClient(A1ProtocolType version) throws ServiceException { - return factoryUnderTest.createClient(ric, version); - } - - @Test - void create_check_types() throws ServiceException { - assertTrue(createClient(A1ProtocolType.STD_V1_1) instanceof StdA1ClientVersion1); - assertTrue(createClient(A1ProtocolType.OSC_V1) instanceof OscA1Client); - } - - @Test - void create_check_types_controllers() throws ServiceException { - this.ric = new Ric(ricConfig("anythingButEmpty")); - whenGetGetControllerConfigReturn(); - assertTrue(createClient(A1ProtocolType.SDNC_ONAP) instanceof SdncOnapA1Client); - - whenGetGetControllerConfigReturn(); - assertTrue(createClient(A1ProtocolType.SDNC_OSC_STD_V1_1) instanceof SdncOscA1Client); - - whenGetGetControllerConfigReturn(); - assertTrue(createClient(A1ProtocolType.SDNC_OSC_OSC_V1) instanceof SdncOscA1Client); - } - - private void whenGetProtocolVersionThrowException(A1Client... clientMocks) { - for (A1Client clientMock : clientMocks) { - when(clientMock.getProtocolVersion()).thenReturn(Mono.error(new Exception(EXCEPTION_MESSAGE))); - } - } - - private void whenGetProtocolVersionReturn(A1Client clientMock, A1ProtocolType protocol) { - when(clientMock.getProtocolVersion()).thenReturn(Mono.just(protocol)); - } - - private void whenGetGetControllerConfigReturn() throws ServiceException { - ControllerConfig controllerCfg = ImmutableControllerConfig.builder() // - .name("name") // - .baseUrl("baseUrl") // - .password("pass") // - .userName("user") // - .build(); - when(applicationConfigMock.getControllerConfig(any())).thenReturn(controllerCfg); - } - -} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/clients/A1ClientHelper.java b/policy-agent/src/test/java/org/oransc/policyagent/clients/A1ClientHelper.java deleted file mode 100644 index 722fea7d..00000000 --- a/policy-agent/src/test/java/org/oransc/policyagent/clients/A1ClientHelper.java +++ /dev/null @@ -1,80 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.clients; - -import java.util.Arrays; -import java.util.Vector; - -import org.json.JSONObject; -import org.oransc.policyagent.configuration.ImmutableRicConfig; -import org.oransc.policyagent.configuration.RicConfig; -import org.oransc.policyagent.repository.ImmutablePolicy; -import org.oransc.policyagent.repository.ImmutablePolicyType; -import org.oransc.policyagent.repository.Policy; -import org.oransc.policyagent.repository.PolicyType; -import org.oransc.policyagent.repository.Ric; -import reactor.core.publisher.Mono; - -public class A1ClientHelper { - - private A1ClientHelper() { - } - - protected static Mono createOutputJsonResponse(String key, String value) { - JSONObject paramsJson = new JSONObject(); - paramsJson.put(key, value); - JSONObject responseJson = new JSONObject(); - responseJson.put("output", paramsJson); - return Mono.just(responseJson.toString()); - } - - protected static Ric createRic(String url) { - RicConfig cfg = ImmutableRicConfig.builder().name("ric") // - .baseUrl(url) // - .managedElementIds(new Vector(Arrays.asList("kista_1", "kista_2"))) // - .controllerName("") // - .build(); - return new Ric(cfg); - } - - protected static Policy createPolicy(String nearRtRicUrl, String policyId, String json, String type) { - return ImmutablePolicy.builder() // - .id(policyId) // - .json(json) // - .ownerServiceName("service") // - .ric(createRic(nearRtRicUrl)) // - .type(createPolicyType(type)) // - .lastModified("now") // - .isTransient(false) // - .build(); - } - - protected static PolicyType createPolicyType(String name) { - return ImmutablePolicyType.builder().name(name).schema("schema").build(); - } - - protected static String getCreateSchema(String policyType, String policyTypeId) { - JSONObject obj = new JSONObject(policyType); - JSONObject schemaObj = obj.getJSONObject("create_schema"); - schemaObj.put("title", policyTypeId); - return schemaObj.toString(); - } -} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/clients/AsyncRestClientTest.java b/policy-agent/src/test/java/org/oransc/policyagent/clients/AsyncRestClientTest.java deleted file mode 100644 index f3b9482d..00000000 --- a/policy-agent/src/test/java/org/oransc/policyagent/clients/AsyncRestClientTest.java +++ /dev/null @@ -1,161 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.clients; - -import io.netty.util.internal.logging.InternalLoggerFactory; -import io.netty.util.internal.logging.JdkLoggerFactory; - -import java.io.IOException; - -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.web.reactive.function.client.WebClientResponseException; - -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; -import reactor.util.Loggers; - -class AsyncRestClientTest { - private static final String BASE_URL = "BaseUrl"; - private static final String REQUEST_URL = "/test"; - private static final String USERNAME = "username"; - private static final String PASSWORD = "password"; - private static final String TEST_JSON = "{\"type\":\"type1\"}"; - private static final int SUCCESS_CODE = 200; - private static final int ERROR_CODE = 500; - - private static MockWebServer mockWebServer; - - private static AsyncRestClient clientUnderTest; - - @BeforeAll - static void init() { - // skip a lot of unnecessary logs from MockWebServer - InternalLoggerFactory.setDefaultFactory(JdkLoggerFactory.INSTANCE); - Loggers.useJdkLoggers(); - mockWebServer = new MockWebServer(); - clientUnderTest = new AsyncRestClient(mockWebServer.url(BASE_URL).toString()); - } - - @AfterAll - static void tearDown() throws IOException { - mockWebServer.shutdown(); - } - - @Test - void testGetNoError() { - mockWebServer.enqueue(new MockResponse().setResponseCode(SUCCESS_CODE) // - .setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) // - .setBody(TEST_JSON)); - - Mono returnedMono = clientUnderTest.get(REQUEST_URL); - StepVerifier.create(returnedMono).expectNext(TEST_JSON).expectComplete().verify(); - } - - @Test - void testGetError() { - mockWebServer.enqueue(new MockResponse().setResponseCode(ERROR_CODE)); - - Mono returnedMono = clientUnderTest.get(REQUEST_URL); - StepVerifier.create(returnedMono) - .expectErrorMatches(throwable -> throwable instanceof WebClientResponseException).verify(); - } - - @Test - void testPutNoError() { - mockWebServer.enqueue(new MockResponse().setResponseCode(SUCCESS_CODE) // - .setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) // - .setBody(TEST_JSON)); - - Mono returnedMono = clientUnderTest.put(REQUEST_URL, TEST_JSON); - StepVerifier.create(returnedMono).expectNext(TEST_JSON).expectComplete().verify(); - } - - @Test - void testPutError() { - mockWebServer.enqueue(new MockResponse().setResponseCode(ERROR_CODE)); - - Mono returnedMono = clientUnderTest.put(REQUEST_URL, TEST_JSON); - StepVerifier.create(returnedMono) - .expectErrorMatches(throwable -> throwable instanceof WebClientResponseException).verify(); - } - - @Test - void testDeleteNoError() { - mockWebServer.enqueue(new MockResponse().setResponseCode(SUCCESS_CODE)); - - Mono returnedMono = clientUnderTest.delete(REQUEST_URL); - StepVerifier.create(returnedMono).expectNext("").expectComplete().verify(); - } - - @Test - void testDeleteError() { - mockWebServer.enqueue(new MockResponse().setResponseCode(ERROR_CODE)); - - Mono returnedMono = clientUnderTest.delete(REQUEST_URL); - StepVerifier.create(returnedMono) - .expectErrorMatches(throwable -> throwable instanceof WebClientResponseException).verify(); - } - - @Test - void testPostNoError() { - mockWebServer.enqueue(new MockResponse().setResponseCode(SUCCESS_CODE) // - .setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) // - .setBody(TEST_JSON)); - - Mono returnedMono = clientUnderTest.post(REQUEST_URL, TEST_JSON); - StepVerifier.create(returnedMono).expectNext(TEST_JSON).expectComplete().verify(); - } - - @Test - void testPostError() { - mockWebServer.enqueue(new MockResponse().setResponseCode(ERROR_CODE)); - - Mono returnedMono = clientUnderTest.post(REQUEST_URL, TEST_JSON); - StepVerifier.create(returnedMono) - .expectErrorMatches(throwable -> throwable instanceof WebClientResponseException).verify(); - } - - @Test - void testPostWithAuthHeaderNoError() { - mockWebServer.enqueue(new MockResponse().setResponseCode(SUCCESS_CODE) // - .setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) // - .setBody(TEST_JSON)); - - Mono returnedMono = clientUnderTest.postWithAuthHeader(REQUEST_URL, TEST_JSON, USERNAME, PASSWORD); - StepVerifier.create(returnedMono).expectNext(TEST_JSON).expectComplete().verify(); - } - - @Test - void testPostWithAuthHeaderError() { - mockWebServer.enqueue(new MockResponse().setResponseCode(ERROR_CODE)); - - Mono returnedMono = clientUnderTest.postWithAuthHeader(REQUEST_URL, TEST_JSON, USERNAME, PASSWORD); - StepVerifier.create(returnedMono) - .expectErrorMatches(throwable -> throwable instanceof WebClientResponseException).verify(); - } -} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/clients/OscA1ClientTest.java b/policy-agent/src/test/java/org/oransc/policyagent/clients/OscA1ClientTest.java deleted file mode 100644 index d23276df..00000000 --- a/policy-agent/src/test/java/org/oransc/policyagent/clients/OscA1ClientTest.java +++ /dev/null @@ -1,179 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.clients; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.json.JSONException; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.junit.jupiter.MockitoExtension; -import org.oransc.policyagent.configuration.ImmutableRicConfig; -import org.oransc.policyagent.configuration.RicConfig; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -@ExtendWith(MockitoExtension.class) -class OscA1ClientTest { - - private static final String RIC_URL = "RicUrl"; - - private static final String RIC_BASE_URL = "RicBaseUrl/a1-p"; - - private static final String POLICYTYPES_IDENTITIES_URL = RIC_BASE_URL + "/policytypes"; - private static final String POLICIES = "/policies"; - private static final String POLICYTYPES_URL = RIC_BASE_URL + "/policytypes/"; - private static final String POLICY_TYPE_1_ID = "type1"; - private static final String POLICY_TYPE_2_ID = "type2"; - private static final String POLICY_TYPE_SCHEMA_VALID = "{\"type\":\"type1\"}"; - private static final String POLICY_TYPE_SCHEMA_INVALID = "\"type\":\"type1\"}"; - private static final String POLICY_1_ID = "policy1"; - private static final String POLICY_2_ID = "policy2"; - private static final String POLICY_JSON_VALID = "{\"policyId\":\"policy1\"}"; - - OscA1Client clientUnderTest; - - AsyncRestClient asyncRestClientMock; - - @BeforeEach - void init() { - RicConfig ricConfig = ImmutableRicConfig.builder() // - .name("name") // - .baseUrl("RicBaseUrl") // - .managedElementIds(new ArrayList<>()) // - .controllerName("") // - .build(); - asyncRestClientMock = mock(AsyncRestClient.class); - clientUnderTest = new OscA1Client(ricConfig, asyncRestClientMock); - } - - @Test - void testGetPolicyTypeIdentities() { - List policyTypeIds = Arrays.asList(POLICY_TYPE_1_ID, POLICY_TYPE_2_ID); - Mono policyTypeIdsResp = Mono.just(policyTypeIds.toString()); - when(asyncRestClientMock.get(anyString())).thenReturn(policyTypeIdsResp); - - Mono> returnedMono = clientUnderTest.getPolicyTypeIdentities(); - verify(asyncRestClientMock).get(POLICYTYPES_IDENTITIES_URL); - StepVerifier.create(returnedMono).expectNext(policyTypeIds).expectComplete().verify(); - } - - @Test - void testGetPolicyIdentities() { - Mono policyTypeIdsResp = Mono.just(Arrays.asList(POLICY_TYPE_1_ID, POLICY_TYPE_2_ID).toString()); - Mono policyIdsType1Resp = Mono.just(Arrays.asList(POLICY_1_ID).toString()); - Mono policyIdsType2Resp = Mono.just(Arrays.asList(POLICY_2_ID).toString()); - when(asyncRestClientMock.get(anyString())).thenReturn(policyTypeIdsResp).thenReturn(policyIdsType1Resp) - .thenReturn(policyIdsType2Resp); - - List returned = clientUnderTest.getPolicyIdentities().block(); - - assertEquals(2, returned.size(), ""); - verify(asyncRestClientMock).get(POLICYTYPES_IDENTITIES_URL); - verify(asyncRestClientMock).get(POLICYTYPES_URL + POLICY_TYPE_1_ID + POLICIES); - verify(asyncRestClientMock).get(POLICYTYPES_URL + POLICY_TYPE_2_ID + POLICIES); - } - - @Test - void testGetValidPolicyType() { - String policyType = "{\"create_schema\": " + POLICY_TYPE_SCHEMA_VALID + "}"; - Mono policyTypeResp = Mono.just(policyType); - - when(asyncRestClientMock.get(anyString())).thenReturn(policyTypeResp); - - Mono returnedMono = clientUnderTest.getPolicyTypeSchema(POLICY_TYPE_1_ID); - verify(asyncRestClientMock).get(POLICYTYPES_URL + POLICY_TYPE_1_ID); - StepVerifier.create(returnedMono).expectNext(A1ClientHelper.getCreateSchema(policyType, POLICY_TYPE_1_ID)) - .expectComplete().verify(); - } - - @Test - void testGetInValidPolicyTypeJson() { - String policyType = "{\"create_schema\": " + POLICY_TYPE_SCHEMA_INVALID + "}"; - Mono policyTypeResp = Mono.just(policyType); - - when(asyncRestClientMock.get(anyString())).thenReturn(policyTypeResp); - - Mono returnedMono = clientUnderTest.getPolicyTypeSchema(POLICY_TYPE_1_ID); - verify(asyncRestClientMock).get(POLICYTYPES_URL + POLICY_TYPE_1_ID); - StepVerifier.create(returnedMono).expectErrorMatches(throwable -> throwable instanceof JSONException).verify(); - } - - @Test - void testGetPolicyTypeWithoutCreateSchema() { - Mono policyTypeResp = Mono.just(POLICY_TYPE_SCHEMA_VALID); - - when(asyncRestClientMock.get(anyString())).thenReturn(policyTypeResp); - - Mono returnedMono = clientUnderTest.getPolicyTypeSchema(POLICY_TYPE_1_ID); - verify(asyncRestClientMock).get(POLICYTYPES_URL + POLICY_TYPE_1_ID); - StepVerifier.create(returnedMono).expectErrorMatches(throwable -> throwable instanceof Exception).verify(); - } - - @Test - void testPutPolicy() { - when(asyncRestClientMock.put(anyString(), anyString())).thenReturn(Mono.empty()); - - clientUnderTest - .putPolicy(A1ClientHelper.createPolicy(RIC_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE_1_ID)).block(); - verify(asyncRestClientMock).put(POLICYTYPES_URL + POLICY_TYPE_1_ID + POLICIES + "/" + POLICY_1_ID, - POLICY_JSON_VALID); - } - - @Test - void testDeletePolicy() { - when(asyncRestClientMock.delete(anyString())).thenReturn(Mono.empty()); - - Mono returnedMono = clientUnderTest - .deletePolicy(A1ClientHelper.createPolicy(RIC_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE_1_ID)); - verify(asyncRestClientMock).delete(POLICYTYPES_URL + POLICY_TYPE_1_ID + POLICIES + "/" + POLICY_1_ID); - StepVerifier.create(returnedMono).expectComplete().verify(); - } - - @Test - void testDeleteAllPolicies() { - Mono policyTypeIdsResp = Mono.just(Arrays.asList(POLICY_TYPE_1_ID, POLICY_TYPE_2_ID).toString()); - Mono policyIdsType1Resp = Mono.just(Arrays.asList(POLICY_1_ID).toString()); - Mono policyIdsType2Resp = Mono.just(Arrays.asList(POLICY_2_ID).toString()); - when(asyncRestClientMock.get(anyString())).thenReturn(policyTypeIdsResp).thenReturn(policyIdsType1Resp) - .thenReturn(policyIdsType2Resp); - when(asyncRestClientMock.delete(anyString())).thenReturn(Mono.empty()); - - Flux returnedFlux = clientUnderTest.deleteAllPolicies(); - StepVerifier.create(returnedFlux).expectComplete().verify(); - verify(asyncRestClientMock).get(POLICYTYPES_IDENTITIES_URL); - verify(asyncRestClientMock).get(POLICYTYPES_URL + POLICY_TYPE_1_ID + POLICIES); - verify(asyncRestClientMock).delete(POLICYTYPES_URL + POLICY_TYPE_1_ID + POLICIES + "/" + POLICY_1_ID); - verify(asyncRestClientMock).get(POLICYTYPES_URL + POLICY_TYPE_2_ID + POLICIES); - verify(asyncRestClientMock).delete(POLICYTYPES_URL + POLICY_TYPE_2_ID + POLICIES + "/" + POLICY_2_ID); - } -} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/clients/SdncOnapA1ClientTest.java b/policy-agent/src/test/java/org/oransc/policyagent/clients/SdncOnapA1ClientTest.java deleted file mode 100644 index 6b4ebd6b..00000000 --- a/policy-agent/src/test/java/org/oransc/policyagent/clients/SdncOnapA1ClientTest.java +++ /dev/null @@ -1,271 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.clients; - -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.json.JSONException; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.stubbing.OngoingStubbing; -import org.oransc.policyagent.configuration.ControllerConfig; -import org.oransc.policyagent.configuration.ImmutableControllerConfig; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -@ExtendWith(MockitoExtension.class) -class SdncOnapA1ClientTest { - private static final String CONTROLLER_USERNAME = "username"; - private static final String CONTROLLER_PASSWORD = "password"; - private static final String RIC_1_URL = "RicUrl"; - private static final String POLICYTYPES_IDENTITIES_URL = "/A1-ADAPTER-API:getPolicyTypes"; - private static final String POLICIES_IDENTITIES_URL = "/A1-ADAPTER-API:getPolicyInstances"; - private static final String POLICYTYPES_URL = "/A1-ADAPTER-API:getPolicyType"; - private static final String PUT_POLICY_URL = "/A1-ADAPTER-API:createPolicyInstance"; - private static final String DELETE_POLICY_URL = "/A1-ADAPTER-API:deletePolicyInstance"; - - private static final String POLICY_TYPE_1_ID = "type1"; - private static final String POLICY_TYPE_2_ID = "type2"; - private static final String POLICY_TYPE_SCHEMA_VALID = "{\"type\":\"type1\"}"; - private static final String POLICY_TYPE_SCHEMA_INVALID = "\"type\":\"type1\"}"; - private static final String POLICY_1_ID = "policy1"; - private static final String POLICY_2_ID = "policy2"; - private static final String POLICY_JSON_VALID = "{\"scope\":{\"ueId\":\"ue1\"}}"; - - SdncOnapA1Client clientUnderTest; - - AsyncRestClient asyncRestClientMock; - - @BeforeEach - void init() { - asyncRestClientMock = mock(AsyncRestClient.class); - ControllerConfig controllerCfg = ImmutableControllerConfig.builder() // - .name("name") // - .baseUrl("baseUrl") // - .password(CONTROLLER_PASSWORD) // - .userName(CONTROLLER_USERNAME) // - .build(); - - clientUnderTest = - new SdncOnapA1Client(A1ClientHelper.createRic(RIC_1_URL).getConfig(), controllerCfg, asyncRestClientMock); - } - - @Test - void testGetPolicyTypeIdentities() { - SdncOnapA1Client.SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() // - .nearRtRicId(RIC_1_URL) // - .build(); - String inputJsonString = SdncJsonHelper.createInputJsonString(inputParams); - - List policyTypeIds = Arrays.asList(POLICY_TYPE_1_ID, POLICY_TYPE_2_ID); - Mono policyTypeIdsResp = - A1ClientHelper.createOutputJsonResponse("policy-type-id-list", policyTypeIds.toString()); - whenAsyncPostThenReturn(policyTypeIdsResp); - - Mono> returnedMono = clientUnderTest.getPolicyTypeIdentities(); - verify(asyncRestClientMock).postWithAuthHeader(POLICYTYPES_IDENTITIES_URL, inputJsonString, CONTROLLER_USERNAME, - CONTROLLER_PASSWORD); - StepVerifier.create(returnedMono).expectNext(policyTypeIds).expectComplete().verify(); - } - - @Test - void testGetPolicyIdentities() { - SdncOnapA1Client.SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() // - .nearRtRicId(RIC_1_URL) // - .build(); - String inputJsonStringGetTypeIds = SdncJsonHelper.createInputJsonString(inputParams); - inputParams = ImmutableSdncOnapAdapterInput.builder() // - .nearRtRicId(RIC_1_URL) // - .policyTypeId(POLICY_TYPE_1_ID) // - .build(); - String inputJsonStringGetPolicyIdsType1 = SdncJsonHelper.createInputJsonString(inputParams); - inputParams = ImmutableSdncOnapAdapterInput.builder() // - .nearRtRicId(RIC_1_URL) // - .policyTypeId(POLICY_TYPE_2_ID) // - .build(); - String inputJsonStringGetPolicyIdsType2 = SdncJsonHelper.createInputJsonString(inputParams); - - List policyTypeIds = Arrays.asList(POLICY_TYPE_1_ID, POLICY_TYPE_2_ID); - Mono policyTypeIdsResp = - A1ClientHelper.createOutputJsonResponse("policy-type-id-list", policyTypeIds.toString()); - List policyIdsType1 = Arrays.asList(POLICY_1_ID); - Mono policyIdsType1Resp = - A1ClientHelper.createOutputJsonResponse("policy-instance-id-list", policyIdsType1.toString()); - List policyIdsType2 = Arrays.asList(POLICY_2_ID); - Mono policyIdsType2Resp = - A1ClientHelper.createOutputJsonResponse("policy-instance-id-list", policyIdsType2.toString()); - whenAsyncPostThenReturn(policyTypeIdsResp).thenReturn(policyIdsType1Resp).thenReturn(policyIdsType2Resp); - - Mono> returnedMono = clientUnderTest.getPolicyIdentities(); - StepVerifier.create(returnedMono).expectNext(Arrays.asList(POLICY_1_ID, POLICY_2_ID)).expectComplete().verify(); - verify(asyncRestClientMock).postWithAuthHeader(POLICYTYPES_IDENTITIES_URL, inputJsonStringGetTypeIds, - CONTROLLER_USERNAME, CONTROLLER_PASSWORD); - verify(asyncRestClientMock).postWithAuthHeader(POLICIES_IDENTITIES_URL, inputJsonStringGetPolicyIdsType1, - CONTROLLER_USERNAME, CONTROLLER_PASSWORD); - verify(asyncRestClientMock).postWithAuthHeader(POLICIES_IDENTITIES_URL, inputJsonStringGetPolicyIdsType2, - CONTROLLER_USERNAME, CONTROLLER_PASSWORD); - } - - @Test - void testGetValidPolicyType() { - SdncOnapA1Client.SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() // - .nearRtRicId(RIC_1_URL) // - .policyTypeId(POLICY_TYPE_1_ID) // - .build(); - String inputJsonString = SdncJsonHelper.createInputJsonString(inputParams); - - String policyType = "{\"policySchema\": " + POLICY_TYPE_SCHEMA_VALID + ", \"statusSchema\": {} }"; - Mono policyTypeResp = A1ClientHelper.createOutputJsonResponse("policy-type", policyType); - whenAsyncPostThenReturn(policyTypeResp); - - Mono returnedMono = clientUnderTest.getPolicyTypeSchema(POLICY_TYPE_1_ID); - verify(asyncRestClientMock).postWithAuthHeader(POLICYTYPES_URL, inputJsonString, CONTROLLER_USERNAME, - CONTROLLER_PASSWORD); - StepVerifier.create(returnedMono).expectNext(POLICY_TYPE_SCHEMA_VALID).expectComplete().verify(); - } - - @Test - void testGetInvalidPolicyType() { - SdncOnapA1Client.SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() // - .nearRtRicId(RIC_1_URL) // - .policyTypeId(POLICY_TYPE_1_ID) // - .build(); - String inputJsonString = SdncJsonHelper.createInputJsonString(inputParams); - - String policyType = "{\"policySchema\": " + POLICY_TYPE_SCHEMA_INVALID + ", \"statusSchema\": {} }"; - Mono policyTypeResp = A1ClientHelper.createOutputJsonResponse("policy-type", policyType); - whenAsyncPostThenReturn(policyTypeResp); - - Mono returnedMono = clientUnderTest.getPolicyTypeSchema(POLICY_TYPE_1_ID); - verify(asyncRestClientMock).postWithAuthHeader(POLICYTYPES_URL, inputJsonString, CONTROLLER_USERNAME, - CONTROLLER_PASSWORD); - StepVerifier.create(returnedMono).expectErrorMatches(throwable -> throwable instanceof JSONException).verify(); - } - - @Test - void testPutPolicy() { - SdncOnapA1Client.SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() // - .nearRtRicId(RIC_1_URL) // - .policyTypeId(POLICY_TYPE_1_ID) // - .policyInstanceId(POLICY_1_ID) // - .policyInstance(POLICY_JSON_VALID) // - .properties(new ArrayList()) // - .build(); - String inputJsonString = SdncJsonHelper.createInputJsonString(inputParams); - - whenAsyncPostThenReturn(Mono.empty()); - - Mono returnedMono = clientUnderTest - .putPolicy(A1ClientHelper.createPolicy(RIC_1_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE_1_ID)); - verify(asyncRestClientMock).postWithAuthHeader(PUT_POLICY_URL, inputJsonString, CONTROLLER_USERNAME, - CONTROLLER_PASSWORD); - StepVerifier.create(returnedMono).expectComplete().verify(); - } - - @Test - void testDeletePolicy() { - SdncOnapA1Client.SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() // - .nearRtRicId(RIC_1_URL) // - .policyTypeId(POLICY_TYPE_1_ID) // - .policyInstanceId(POLICY_1_ID) // - .build(); - String inputJsonString = SdncJsonHelper.createInputJsonString(inputParams); - - whenAsyncPostThenReturn(Mono.empty()); - - Mono returnedMono = clientUnderTest - .deletePolicy(A1ClientHelper.createPolicy(RIC_1_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE_1_ID)); - verify(asyncRestClientMock).postWithAuthHeader(DELETE_POLICY_URL, inputJsonString, CONTROLLER_USERNAME, - CONTROLLER_PASSWORD); - StepVerifier.create(returnedMono).expectComplete().verify(); - } - - @Test - void testDeleteAllPolicies() { - SdncOnapA1Client.SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() // - .nearRtRicId(RIC_1_URL) // - .build(); - String inputJsonStringGetTypeIds = SdncJsonHelper.createInputJsonString(inputParams); - inputParams = ImmutableSdncOnapAdapterInput.builder() // - .nearRtRicId(RIC_1_URL) // - .policyTypeId(POLICY_TYPE_1_ID) // - .build(); - String inputJsonStringGetPolicyIdsType1 = SdncJsonHelper.createInputJsonString(inputParams); - inputParams = ImmutableSdncOnapAdapterInput.builder() // - .nearRtRicId(RIC_1_URL) // - .policyTypeId(POLICY_TYPE_2_ID) // - .build(); - String inputJsonStringGetPolicyIdsType2 = SdncJsonHelper.createInputJsonString(inputParams); - inputParams = ImmutableSdncOnapAdapterInput.builder() // - .nearRtRicId(RIC_1_URL) // - .policyTypeId(POLICY_TYPE_1_ID) // - .policyInstanceId(POLICY_1_ID) // - .build(); - String inputJsonStringDeletePolicy1 = SdncJsonHelper.createInputJsonString(inputParams); - inputParams = ImmutableSdncOnapAdapterInput.builder() // - .nearRtRicId(RIC_1_URL) // - .policyTypeId(POLICY_TYPE_2_ID) // - .policyInstanceId(POLICY_2_ID) // - .build(); - String inputJsonStringDeletePolicy2 = SdncJsonHelper.createInputJsonString(inputParams); - - List policyTypeIds = Arrays.asList(POLICY_TYPE_1_ID, POLICY_TYPE_2_ID); - Mono policyTypeIdsResp = - A1ClientHelper.createOutputJsonResponse("policy-type-id-list", policyTypeIds.toString()); - List policyIdsType1 = Arrays.asList(POLICY_1_ID); - Mono policyIdsType1Resp = - A1ClientHelper.createOutputJsonResponse("policy-instance-id-list", policyIdsType1.toString()); - List policyIdsType2 = Arrays.asList(POLICY_2_ID); - Mono policyIdsType2Resp = - A1ClientHelper.createOutputJsonResponse("policy-instance-id-list", policyIdsType2.toString()); - whenAsyncPostThenReturn(policyTypeIdsResp).thenReturn(policyIdsType1Resp).thenReturn(Mono.empty()) - .thenReturn(policyIdsType2Resp).thenReturn(Mono.empty()); - - Flux returnedFlux = clientUnderTest.deleteAllPolicies(); - StepVerifier.create(returnedFlux).expectComplete().verify(); - verify(asyncRestClientMock).postWithAuthHeader(POLICYTYPES_IDENTITIES_URL, inputJsonStringGetTypeIds, - CONTROLLER_USERNAME, CONTROLLER_PASSWORD); - verify(asyncRestClientMock).postWithAuthHeader(POLICIES_IDENTITIES_URL, inputJsonStringGetPolicyIdsType1, - CONTROLLER_USERNAME, CONTROLLER_PASSWORD); - verify(asyncRestClientMock).postWithAuthHeader(DELETE_POLICY_URL, inputJsonStringDeletePolicy1, - CONTROLLER_USERNAME, CONTROLLER_PASSWORD); - verify(asyncRestClientMock).postWithAuthHeader(POLICIES_IDENTITIES_URL, inputJsonStringGetPolicyIdsType2, - CONTROLLER_USERNAME, CONTROLLER_PASSWORD); - verify(asyncRestClientMock).postWithAuthHeader(DELETE_POLICY_URL, inputJsonStringDeletePolicy2, - CONTROLLER_USERNAME, CONTROLLER_PASSWORD); - } - - private OngoingStubbing> whenAsyncPostThenReturn(Mono response) { - return when(asyncRestClientMock.postWithAuthHeader(anyString(), anyString(), anyString(), anyString())) - .thenReturn(response); - } -} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/clients/SdncOscA1ClientTest.java b/policy-agent/src/test/java/org/oransc/policyagent/clients/SdncOscA1ClientTest.java deleted file mode 100644 index a6f6187f..00000000 --- a/policy-agent/src/test/java/org/oransc/policyagent/clients/SdncOscA1ClientTest.java +++ /dev/null @@ -1,374 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.clients; - -import static org.junit.Assert.fail; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.google.gson.Gson; -import com.google.gson.JsonElement; - -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.nio.file.Files; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.stubbing.OngoingStubbing; -import org.oransc.policyagent.clients.A1Client.A1ProtocolType; -import org.oransc.policyagent.clients.ImmutableAdapterOutput.Builder; -import org.oransc.policyagent.clients.SdncOscA1Client.AdapterOutput; -import org.oransc.policyagent.clients.SdncOscA1Client.AdapterRequest; -import org.oransc.policyagent.configuration.ControllerConfig; -import org.oransc.policyagent.configuration.ImmutableControllerConfig; -import org.oransc.policyagent.repository.Policy; -import org.oransc.policyagent.repository.Ric; -import org.springframework.http.HttpStatus; -import org.springframework.web.reactive.function.client.WebClientResponseException; - -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -@ExtendWith(MockitoExtension.class) -class SdncOscA1ClientTest { - private static final String CONTROLLER_USERNAME = "username"; - private static final String CONTROLLER_PASSWORD = "password"; - private static final String RIC_1_URL = "RicUrl"; - private static final String GET_A1_POLICY_URL = "/A1-ADAPTER-API:getA1Policy"; - private static final String PUT_A1_URL = "/A1-ADAPTER-API:putA1Policy"; - private static final String DELETE_A1_URL = "/A1-ADAPTER-API:deleteA1Policy"; - private static final String GET_A1_POLICY_STATUS_URL = "/A1-ADAPTER-API:getA1PolicyStatus"; - private static final String POLICY_TYPE_1_ID = "type1"; - private static final String POLICY_1_ID = "policy1"; - private static final String POLICY_2_ID = "policy2"; - private static final String POLICY_JSON_VALID = "{\"scope\":{\"ueId\":\"ue1\"}}"; - - SdncOscA1Client clientUnderTest; - - @Mock - AsyncRestClient asyncRestClientMock; - - private ControllerConfig controllerConfig() { - return ImmutableControllerConfig.builder() // - .name("name") // - .baseUrl("baseUrl") // - .password(CONTROLLER_PASSWORD) // - .userName(CONTROLLER_USERNAME) // - .build(); - } - - @BeforeEach - void init() { - Ric ric = A1ClientHelper.createRic(RIC_1_URL); - - clientUnderTest = new SdncOscA1Client(A1ProtocolType.SDNC_OSC_STD_V1_1, ric.getConfig(), controllerConfig(), - asyncRestClientMock); - } - - @Test - void createClientWithWrongProtocol_thenErrorIsThrown() { - try { - new SdncOscA1Client(A1ProtocolType.STD_V1_1, null, null, new AsyncRestClient("", null)); - fail("Should have thrown exception."); - } catch (IllegalArgumentException e) { - return; - } - } - - @Test - void getPolicyTypeIdentities_STD() { - List policyTypeIds = clientUnderTest.getPolicyTypeIdentities().block(); - assertEquals(1, policyTypeIds.size(), "should hardcoded to one"); - assertEquals("", policyTypeIds.get(0), "should hardcoded to empty"); - } - - @Test - void getPolicyTypeIdentities_OSC() { - clientUnderTest = new SdncOscA1Client(A1ProtocolType.SDNC_OSC_OSC_V1, // - A1ClientHelper.createRic(RIC_1_URL).getConfig(), // - controllerConfig(), asyncRestClientMock); - - String response = createOkResponseWithBody(Arrays.asList(POLICY_TYPE_1_ID)); - whenAsyncPostThenReturn(Mono.just(response)); - - List policyTypeIds = clientUnderTest.getPolicyTypeIdentities().block(); - - assertEquals(1, policyTypeIds.size()); - assertEquals(POLICY_TYPE_1_ID, policyTypeIds.get(0)); - - String expUrl = RIC_1_URL + "/a1-p/policytypes"; - ImmutableAdapterRequest expectedParams = ImmutableAdapterRequest.builder() // - .nearRtRicUrl(expUrl) // - .build(); - String expInput = SdncJsonHelper.createInputJsonString(expectedParams); - verify(asyncRestClientMock).postWithAuthHeader(GET_A1_POLICY_URL, expInput, CONTROLLER_USERNAME, - CONTROLLER_PASSWORD); - } - - @Test - void getTypeSchema_STD() { - String policyType = clientUnderTest.getPolicyTypeSchema("").block(); - - assertEquals("{}", policyType); - } - - @Test - void getTypeSchema_OSC() throws IOException { - clientUnderTest = new SdncOscA1Client(A1ProtocolType.SDNC_OSC_OSC_V1, // - A1ClientHelper.createRic(RIC_1_URL).getConfig(), // - controllerConfig(), asyncRestClientMock); - - String ricResponse = loadFile("test_osc_get_schema_response.json"); - JsonElement elem = gson().fromJson(ricResponse, JsonElement.class); - String responseFromController = createOkResponseWithBody(elem); - whenAsyncPostThenReturn(Mono.just(responseFromController)); - - String response = clientUnderTest.getPolicyTypeSchema("policyTypeId").block(); - - JsonElement respJson = gson().fromJson(response, JsonElement.class); - assertEquals("policyTypeId", respJson.getAsJsonObject().get("title").getAsString(), - "title should be updated to contain policyType ID"); - } - - @Test - void parseJsonArrayOfString() { - // One integer and one string - String inputString = "[1, \"1\" ]"; - - List result = SdncJsonHelper.parseJsonArrayOfString(inputString).collectList().block(); - assertEquals(2, result.size()); - assertEquals("1", result.get(0)); - assertEquals("1", result.get(1)); - } - - @Test - void getPolicyIdentities_STD() { - - String policyIdsResp = createOkResponseWithBody(Arrays.asList(POLICY_1_ID, POLICY_2_ID)); - whenAsyncPostThenReturn(Mono.just(policyIdsResp)); - - List returned = clientUnderTest.getPolicyIdentities().block(); - - assertEquals(2, returned.size()); - - ImmutableAdapterRequest expectedParams = ImmutableAdapterRequest.builder() // - .nearRtRicUrl(policiesUrl()) // - .build(); - String expInput = SdncJsonHelper.createInputJsonString(expectedParams); - verify(asyncRestClientMock).postWithAuthHeader(GET_A1_POLICY_URL, expInput, CONTROLLER_USERNAME, - CONTROLLER_PASSWORD); - - } - - @Test - void getPolicyIdentities_OSC() { - clientUnderTest = new SdncOscA1Client(A1ProtocolType.SDNC_OSC_OSC_V1, // - A1ClientHelper.createRic(RIC_1_URL).getConfig(), // - controllerConfig(), asyncRestClientMock); - - String policytypeIdsResp = createOkResponseWithBody(Arrays.asList(POLICY_TYPE_1_ID)); - String policyIdsResp = createOkResponseWithBody(Arrays.asList(POLICY_1_ID, POLICY_2_ID)); - whenAsyncPostThenReturn(Mono.just(policytypeIdsResp)).thenReturn(Mono.just(policyIdsResp)); - - List returned = clientUnderTest.getPolicyIdentities().block(); - - assertEquals(2, returned.size()); - - ImmutableAdapterRequest expectedParams = ImmutableAdapterRequest.builder() // - .nearRtRicUrl(RIC_1_URL + "/a1-p/policytypes/type1/policies") // - .build(); - String expInput = SdncJsonHelper.createInputJsonString(expectedParams); - verify(asyncRestClientMock).postWithAuthHeader(GET_A1_POLICY_URL, expInput, CONTROLLER_USERNAME, - CONTROLLER_PASSWORD); - } - - @Test - void putPolicyValidResponse() { - whenPostReturnOkResponse(); - - String returned = clientUnderTest - .putPolicy(A1ClientHelper.createPolicy(RIC_1_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE_1_ID)) - .block(); - - assertEquals("OK", returned); - final String expUrl = policiesUrl() + "/" + POLICY_1_ID; - AdapterRequest expectedInputParams = ImmutableAdapterRequest.builder() // - .nearRtRicUrl(expUrl) // - .body(POLICY_JSON_VALID) // - .build(); - String expInput = SdncJsonHelper.createInputJsonString(expectedInputParams); - - verify(asyncRestClientMock).postWithAuthHeader(PUT_A1_URL, expInput, CONTROLLER_USERNAME, CONTROLLER_PASSWORD); - } - - @Test - void putPolicyRejected() { - final String policyJson = "{}"; - AdapterOutput adapterOutput = ImmutableAdapterOutput.builder() // - .body("NOK") // - .httpStatus(HttpStatus.BAD_REQUEST.value()) // ERROR - .build(); - - String resp = SdncJsonHelper.createOutputJsonString(adapterOutput); - whenAsyncPostThenReturn(Mono.just(resp)); - - Mono returnedMono = clientUnderTest - .putPolicy(A1ClientHelper.createPolicy(RIC_1_URL, POLICY_1_ID, policyJson, POLICY_TYPE_1_ID)); - StepVerifier.create(returnedMono) // - .expectSubscription() // - .expectErrorMatches(t -> t instanceof WebClientResponseException) // - .verify(); - - final String expUrl = policiesUrl() + "/" + POLICY_1_ID; - AdapterRequest expRequestParams = ImmutableAdapterRequest.builder() // - .nearRtRicUrl(expUrl) // - .body(policyJson) // - .build(); - String expRequest = SdncJsonHelper.createInputJsonString(expRequestParams); - verify(asyncRestClientMock).postWithAuthHeader(PUT_A1_URL, expRequest, CONTROLLER_USERNAME, - CONTROLLER_PASSWORD); - StepVerifier.create(returnedMono) - .expectErrorMatches(throwable -> throwable instanceof WebClientResponseException).verify(); - } - - @Test - void deletePolicy() { - whenPostReturnOkResponse(); - - String returned = clientUnderTest - .deletePolicy(A1ClientHelper.createPolicy(RIC_1_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE_1_ID)) - .block(); - - assertEquals("OK", returned); - final String expUrl = policiesUrl() + "/" + POLICY_1_ID; - AdapterRequest expectedInputParams = ImmutableAdapterRequest.builder() // - .nearRtRicUrl(expUrl) // - .build(); - String expInput = SdncJsonHelper.createInputJsonString(expectedInputParams); - - verify(asyncRestClientMock).postWithAuthHeader(DELETE_A1_URL, expInput, CONTROLLER_USERNAME, - CONTROLLER_PASSWORD); - } - - @Test - void getStatus() { - whenPostReturnOkResponse(); - - Policy policy = A1ClientHelper.createPolicy(RIC_1_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE_1_ID); - - String returnedStatus = clientUnderTest.getPolicyStatus(policy).block(); - - assertEquals("OK", returnedStatus, "unexpected status"); - - final String expUrl = policiesUrl() + "/" + POLICY_1_ID + "/status"; - AdapterRequest expectedInputParams = ImmutableAdapterRequest.builder() // - .nearRtRicUrl(expUrl) // - .build(); - String expInput = SdncJsonHelper.createInputJsonString(expectedInputParams); - - verify(asyncRestClientMock).postWithAuthHeader(GET_A1_POLICY_STATUS_URL, expInput, CONTROLLER_USERNAME, - CONTROLLER_PASSWORD); - } - - @Test - void getVersion_STD() { - whenPostReturnOkResponse(); - - A1ProtocolType returnedVersion = clientUnderTest.getProtocolVersion().block(); - - assertEquals(A1ProtocolType.SDNC_OSC_STD_V1_1, returnedVersion); - - whenPostReturnOkResponseNoBody(); - - returnedVersion = clientUnderTest.getProtocolVersion().block(); - - assertEquals(A1ProtocolType.SDNC_OSC_STD_V1_1, returnedVersion); - } - - @Test - void getVersion_OSC() { - clientUnderTest = new SdncOscA1Client(A1ProtocolType.SDNC_OSC_OSC_V1, // - A1ClientHelper.createRic(RIC_1_URL).getConfig(), // - controllerConfig(), asyncRestClientMock); - - whenAsyncPostThenReturn(Mono.error(new Exception("Error"))).thenReturn(Mono.just(createOkResponseString(true))); - - A1ProtocolType returnedVersion = clientUnderTest.getProtocolVersion().block(); - - assertEquals(A1ProtocolType.SDNC_OSC_OSC_V1, returnedVersion); - } - - private String policiesUrl() { - return RIC_1_URL + "/A1-P/v1/policies"; - } - - private Gson gson() { - return SdncOscA1Client.gson; - } - - private String loadFile(String fileName) throws IOException { - ClassLoader loader = Thread.currentThread().getContextClassLoader(); - URL url = loader.getResource(fileName); - File file = new File(url.getFile()); - return new String(Files.readAllBytes(file.toPath())); - } - - private void whenPostReturnOkResponse() { - whenAsyncPostThenReturn(Mono.just(createOkResponseString(true))); - } - - private void whenPostReturnOkResponseNoBody() { - whenAsyncPostThenReturn(Mono.just(createOkResponseString(false))); - } - - private String createOkResponseWithBody(Object body) { - AdapterOutput output = ImmutableAdapterOutput.builder() // - .body(gson().toJson(body)) // - .httpStatus(HttpStatus.OK.value()) // - .build(); - return SdncJsonHelper.createOutputJsonString(output); - } - - private String createOkResponseString(boolean withBody) { - Builder responseBuilder = ImmutableAdapterOutput.builder().httpStatus(HttpStatus.OK.value()); - if (withBody) { - responseBuilder.body(HttpStatus.OK.name()); - } else { - responseBuilder.body(Optional.empty()); - } - return SdncJsonHelper.createOutputJsonString(responseBuilder.build()); - } - - private OngoingStubbing> whenAsyncPostThenReturn(Mono response) { - return when(asyncRestClientMock.postWithAuthHeader(anyString(), anyString(), anyString(), anyString())) - .thenReturn(response); - } -} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/clients/StdA1ClientTest.java b/policy-agent/src/test/java/org/oransc/policyagent/clients/StdA1ClientTest.java deleted file mode 100644 index beb2ca90..00000000 --- a/policy-agent/src/test/java/org/oransc/policyagent/clients/StdA1ClientTest.java +++ /dev/null @@ -1,136 +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.policyagent.clients; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.util.Arrays; -import java.util.List; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.oransc.policyagent.configuration.RicConfig; -import org.oransc.policyagent.repository.Policy; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -@ExtendWith(MockitoExtension.class) -class StdA1ClientTest { - private static final String RIC_URL = "RicUrl"; - private static final String POLICY_TYPE_1_NAME = "type1"; - private static final String POLICY_1_ID = "policy1"; - private static final String POLICY_2_ID = "policy2"; - private static final String POLICY_JSON = "{\"policyId\":\"policy1\"}"; - private static final String POLICY_TYPE = "typeName"; - - StdA1ClientVersion1 clientUnderTest; - - @Mock - AsyncRestClient asyncRestClientMock; - - @Mock - RicConfig ricConfigMock; - - @BeforeEach - void init() { - clientUnderTest = new StdA1ClientVersion1(asyncRestClientMock, ricConfigMock); - } - - private String policiesUrl() { - return RIC_URL + "/A1-P/v1/policies"; - } - - private String policiesBaseUrl() { - return policiesUrl() + "/"; - } - - @Test - void testGetPolicyTypeIdentities() { - List policyTypeIds = clientUnderTest.getPolicyTypeIdentities().block(); - assertEquals(1, policyTypeIds.size(), "should hardcoded to one"); - assertEquals("", policyTypeIds.get(0), "should hardcoded to empty"); - } - - @Test - void testGetPolicyIdentities() { - doReturn(RIC_URL).when(ricConfigMock).baseUrl(); - Mono policyIds = Mono.just(Arrays.asList(POLICY_1_ID, POLICY_2_ID).toString()); - when(asyncRestClientMock.get(anyString())).thenReturn(policyIds); - - List result = clientUnderTest.getPolicyIdentities().block(); - assertEquals(2, result.size(), ""); - - verify(asyncRestClientMock).get(policiesUrl()); - } - - @Test - void testGetValidPolicyType() { - String policyType = clientUnderTest.getPolicyTypeSchema(POLICY_TYPE_1_NAME).block(); - assertEquals("{}", policyType, ""); - } - - @Test - void testPutPolicyValidResponse() { - doReturn(RIC_URL).when(ricConfigMock).baseUrl(); - when(asyncRestClientMock.put(anyString(), anyString())).thenReturn(Mono.just(POLICY_JSON)); - - Mono policyMono = - clientUnderTest.putPolicy(A1ClientHelper.createPolicy(RIC_URL, POLICY_1_ID, POLICY_JSON, POLICY_TYPE)); - - verify(asyncRestClientMock).put(policiesBaseUrl() + POLICY_1_ID, POLICY_JSON); - StepVerifier.create(policyMono).expectNext(POLICY_JSON).expectComplete().verify(); - } - - @Test - void testDeletePolicy() { - doReturn(RIC_URL).when(ricConfigMock).baseUrl(); - final String url = policiesBaseUrl() + POLICY_1_ID; - when(asyncRestClientMock.delete(url)).thenReturn(Mono.empty()); - - Policy policy = A1ClientHelper.createPolicy(RIC_URL, POLICY_1_ID, POLICY_JSON, POLICY_TYPE); - Mono responseMono = clientUnderTest.deletePolicy(policy); - verify(asyncRestClientMock).delete(url); - StepVerifier.create(responseMono).expectComplete().verify(); - } - - @Test - void testDeleteAllPolicies() { - doReturn(RIC_URL).when(ricConfigMock).baseUrl(); - Mono policyIds = Mono.just(Arrays.asList(POLICY_1_ID, POLICY_2_ID).toString()); - when(asyncRestClientMock.get(policiesUrl())).thenReturn(policyIds); - when(asyncRestClientMock.delete(anyString())).thenReturn(Mono.empty()); - - Flux responseFlux = clientUnderTest.deleteAllPolicies(); - StepVerifier.create(responseFlux).expectComplete().verify(); - verify(asyncRestClientMock).get(policiesUrl()); - verify(asyncRestClientMock).delete(policiesBaseUrl() + POLICY_1_ID); - verify(asyncRestClientMock).delete(policiesBaseUrl() + POLICY_2_ID); - } -} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigParserTest.java b/policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigParserTest.java deleted file mode 100644 index 5a6b0232..00000000 --- a/policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigParserTest.java +++ /dev/null @@ -1,159 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.configuration; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import com.google.common.base.Charsets; -import com.google.common.io.Resources; -import com.google.gson.Gson; -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; -import java.io.InputStreamReader; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.Map; - -import org.junit.jupiter.api.Test; -import org.oransc.policyagent.exceptions.ServiceException; - -class ApplicationConfigParserTest { - - ApplicationConfigParser parserUnderTest = new ApplicationConfigParser(); - - @Test - void whenCorrectConfig() throws Exception { - JsonObject jsonRootObject = getJsonRootObject(); - - ApplicationConfigParser.ConfigParserResult result = parserUnderTest.parse(jsonRootObject); - - String topicUrl = result.dmaapProducerTopicUrl(); - assertEquals("http://admin:admin@localhost:6845/events/A1-POLICY-AGENT-WRITE", topicUrl, "controller contents"); - - topicUrl = result.dmaapConsumerTopicUrl(); - assertEquals( - "http://admin:admin@localhost:6845/events/A1-POLICY-AGENT-READ/users/policy-agent?timeout=15000&limit=100", - topicUrl, "controller contents"); - - Map controllers = result.controllerConfigs(); - assertEquals(1, controllers.size(), "size"); - ImmutableControllerConfig expectedControllerConfig = ImmutableControllerConfig.builder() // - .baseUrl("http://localhost:8083/") // - .name("controller1") // - .userName("user") // - .password("password") // - .build(); // - assertEquals(expectedControllerConfig, controllers.get("controller1"), "controller contents"); - } - - private JsonObject getJsonRootObject() throws JsonIOException, JsonSyntaxException, IOException { - JsonObject rootObject = JsonParser.parseReader(new InputStreamReader(getCorrectJson())).getAsJsonObject(); - return rootObject; - } - - private static InputStream getCorrectJson() throws IOException { - URL url = ApplicationConfigParser.class.getClassLoader() - .getResource("test_application_configuration_with_dmaap_config.json"); - String string = Resources.toString(url, Charsets.UTF_8); - return new ByteArrayInputStream((string.getBytes(StandardCharsets.UTF_8))); - } - - @Test - void whenDmaapConfigHasSeveralStreamsPublishing() throws Exception { - JsonObject jsonRootObject = getJsonRootObject(); - JsonObject json = jsonRootObject.getAsJsonObject("config").getAsJsonObject("streams_publishes"); - JsonObject fake_info_object = new JsonObject(); - fake_info_object.addProperty("fake_info", "fake"); - json.add("fake_info_object", new Gson().toJsonTree(fake_info_object)); - DataPublishing data = new Gson().fromJson(json.toString(), DataPublishing.class); - final String expectedMessage = - "Invalid configuration. Number of streams must be one, config: " + data.toString(); - - Exception actualException = assertThrows(ServiceException.class, () -> parserUnderTest.parse(jsonRootObject)); - - assertEquals(expectedMessage, actualException.getMessage(), - "Wrong error message when the DMaaP config has several streams publishing"); - } - - class DataPublishing { - private JsonObject dmaap_publisher; - private JsonObject fake_info_object; - - @Override - public String toString() { - return String.format("[dmaap_publisher=%s, fake_info_object=%s]", dmaap_publisher.toString(), - fake_info_object.toString()); - } - } - - @Test - void whenDmaapConfigHasSeveralStreamsSubscribing() throws Exception { - JsonObject jsonRootObject = getJsonRootObject(); - JsonObject json = jsonRootObject.getAsJsonObject("config").getAsJsonObject("streams_subscribes"); - JsonObject fake_info_object = new JsonObject(); - fake_info_object.addProperty("fake_info", "fake"); - json.add("fake_info_object", new Gson().toJsonTree(fake_info_object)); - DataSubscribing data = new Gson().fromJson(json.toString(), DataSubscribing.class); - final String expectedMessage = - "Invalid configuration. Number of streams must be one, config: " + data.toString(); - - Exception actualException = assertThrows(ServiceException.class, () -> parserUnderTest.parse(jsonRootObject)); - - assertEquals(expectedMessage, actualException.getMessage(), - "Wrong error message when the DMaaP config has several streams subscribing"); - } - - private class DataSubscribing { - private JsonObject dmaap_subscriber; - private JsonObject fake_info_object; - - @Override - public String toString() { - return String.format("[dmaap_subscriber=%s, fake_info_object=%s]", dmaap_subscriber.toString(), - fake_info_object.toString()); - } - } - - @Test - void whenWrongMemberNameInObject() throws Exception { - JsonObject jsonRootObject = getJsonRootObject(); - JsonObject json = jsonRootObject.getAsJsonObject("config"); - json.remove("ric"); - final String message = "Could not find member: 'ric' in: " + json; - - Exception actualException = assertThrows(ServiceException.class, () -> parserUnderTest.parse(jsonRootObject)); - - assertEquals(message, actualException.getMessage(), "Wrong error message when wrong member name in object"); - } - - JsonObject getDmaapInfo(JsonObject jsonRootObject, String streamsPublishesOrSubscribes, - String dmaapPublisherOrSubscriber) throws Exception { - return jsonRootObject.getAsJsonObject("config").getAsJsonObject(streamsPublishesOrSubscribes) - .getAsJsonObject(dmaapPublisherOrSubscriber).getAsJsonObject("dmaap_info"); - } -} 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 deleted file mode 100644 index 5667fd25..00000000 --- a/policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigTest.java +++ /dev/null @@ -1,127 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.configuration; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Vector; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.junit.jupiter.MockitoExtension; -import org.oransc.policyagent.configuration.ApplicationConfig.RicConfigUpdate; -import org.oransc.policyagent.configuration.ApplicationConfigParser.ConfigParserResult; -import org.oransc.policyagent.exceptions.ServiceException; - -@ExtendWith(MockitoExtension.class) -class ApplicationConfigTest { - - private static final ImmutableRicConfig RIC_CONFIG_1 = ImmutableRicConfig.builder() // - .name("ric1") // - .baseUrl("ric1_url") // - .managedElementIds(new Vector<>()) // - .controllerName("") // - .build(); - - ConfigParserResult configParserResult(RicConfig... rics) { - return ImmutableConfigParserResult.builder() // - .ricConfigs(Arrays.asList(rics)) // - .dmaapConsumerTopicUrl("dmaapConsumerTopicUrl") // - .dmaapProducerTopicUrl("dmaapProducerTopicUrl") // - .controllerConfigs(new HashMap<>()) // - .build(); - } - - @Test - void gettingNotAddedRicShouldThrowException() { - ApplicationConfig appConfigUnderTest = new ApplicationConfig(); - - appConfigUnderTest.setConfiguration(configParserResult(RIC_CONFIG_1)); - - Exception exception = assertThrows(ServiceException.class, () -> { - appConfigUnderTest.getRic("name"); - }); - - assertEquals("Could not find ric configuration: name", exception.getMessage()); - } - - @Test - void addRicShouldNotifyAllObserversOfRicAdded() throws Exception { - ApplicationConfig appConfigUnderTest = new ApplicationConfig(); - - RicConfigUpdate update = appConfigUnderTest.setConfiguration(configParserResult(RIC_CONFIG_1)).blockFirst(); - assertEquals(RicConfigUpdate.Type.ADDED, update.getType()); - assertTrue(appConfigUnderTest.getRicConfigs().contains(RIC_CONFIG_1), "Ric not added to configurations."); - - assertEquals(RIC_CONFIG_1, appConfigUnderTest.getRic(RIC_CONFIG_1.name()), - "Not correct Ric retrieved from configurations."); - - update = appConfigUnderTest.setConfiguration(configParserResult(RIC_CONFIG_1)).blockFirst(); - assertNull(update, "Nothing should be updated"); - assertTrue(appConfigUnderTest.getRicConfigs().contains(RIC_CONFIG_1), "Ric should remain."); - - } - - @Test - void changedRicShouldNotifyAllObserversOfRicChanged() throws Exception { - ApplicationConfig appConfigUnderTest = new ApplicationConfig(); - - appConfigUnderTest.setConfiguration(configParserResult(RIC_CONFIG_1)); - - ImmutableRicConfig changedRicConfig = ImmutableRicConfig.builder() // - .name("ric1") // - .baseUrl("changed_ric1_url") // - .managedElementIds(new Vector<>()) // - .controllerName("") // - .build(); - - RicConfigUpdate update = appConfigUnderTest.setConfiguration(configParserResult(changedRicConfig)).blockFirst(); - - assertEquals(RicConfigUpdate.Type.CHANGED, update.getType()); - assertEquals(changedRicConfig, appConfigUnderTest.getRic(RIC_CONFIG_1.name()), - "Changed Ric not retrieved from configurations."); - } - - @Test - void removedRicShouldNotifyAllObserversOfRicRemoved() { - ApplicationConfig appConfigUnderTest = new ApplicationConfig(); - - ImmutableRicConfig ricConfig2 = ImmutableRicConfig.builder() // - .name("ric2") // - .baseUrl("ric2_url") // - .managedElementIds(new Vector<>()) // - .controllerName("") // - .build(); - - appConfigUnderTest.setConfiguration(configParserResult(RIC_CONFIG_1, ricConfig2)); - - RicConfigUpdate update = appConfigUnderTest.setConfiguration(configParserResult(ricConfig2)).blockFirst(); - - assertEquals(RicConfigUpdate.Type.REMOVED, update.getType()); - assertEquals(1, appConfigUnderTest.getRicConfigs().size(), "Ric not deleted from configurations."); - } - -} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/dmaap/DmaapMessageConsumerTest.java b/policy-agent/src/test/java/org/oransc/policyagent/dmaap/DmaapMessageConsumerTest.java deleted file mode 100644 index 92c4bb0a..00000000 --- a/policy-agent/src/test/java/org/oransc/policyagent/dmaap/DmaapMessageConsumerTest.java +++ /dev/null @@ -1,205 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.dmaap; - -import static ch.qos.logback.classic.Level.WARN; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.core.read.ListAppender; - -import java.time.Duration; -import java.util.LinkedList; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentCaptor; -import org.mockito.InOrder; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.oransc.policyagent.clients.AsyncRestClient; -import org.oransc.policyagent.configuration.ApplicationConfig; -import org.oransc.policyagent.utils.LoggingUtils; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import reactor.core.publisher.Mono; - -@ExtendWith(MockitoExtension.class) -class DmaapMessageConsumerTest { - @Mock - private ApplicationConfig applicationConfigMock; - @Mock - private AsyncRestClient messageRouterConsumerMock; - @Mock - private DmaapMessageHandler messageHandlerMock; - - private DmaapMessageConsumer messageConsumerUnderTest; - - @AfterEach - void resetLogging() { - LoggingUtils.getLogListAppender(DmaapMessageConsumer.class); - } - - @Test - void dmaapNotConfigured_thenSleepAndRetryUntilConfig() throws Exception { - messageConsumerUnderTest = spy(new DmaapMessageConsumer(applicationConfigMock)); - - doNothing().when(messageConsumerUnderTest).sleep(any(Duration.class)); - doReturn(false, false, false, true).when(messageConsumerUnderTest).isStopped(); - doReturn(false, true, true).when(messageConsumerUnderTest).isDmaapConfigured(); - doReturn(new LinkedList<>()).when(messageConsumerUnderTest).fetchAllMessages(); - - messageConsumerUnderTest.start().join(); - - InOrder orderVerifier = inOrder(messageConsumerUnderTest); - orderVerifier.verify(messageConsumerUnderTest).sleep(DmaapMessageConsumer.TIME_BETWEEN_DMAAP_RETRIES); - orderVerifier.verify(messageConsumerUnderTest).fetchAllMessages(); - } - - @Test - void dmaapConfigurationRemoved_thenStopPollingDmaapSleepAndRetry() throws Exception { - messageConsumerUnderTest = spy(new DmaapMessageConsumer(applicationConfigMock)); - - doNothing().when(messageConsumerUnderTest).sleep(any(Duration.class)); - doReturn(false, false, false, false, true).when(messageConsumerUnderTest).isStopped(); - doReturn(true, true, false).when(messageConsumerUnderTest).isDmaapConfigured(); - doReturn(new LinkedList<>()).when(messageConsumerUnderTest).fetchAllMessages(); - - messageConsumerUnderTest.start().join(); - - InOrder orderVerifier = inOrder(messageConsumerUnderTest); - orderVerifier.verify(messageConsumerUnderTest).fetchAllMessages(); - orderVerifier.verify(messageConsumerUnderTest).sleep(DmaapMessageConsumer.TIME_BETWEEN_DMAAP_RETRIES); - } - - @Test - void dmaapConfiguredAndNoMessages_thenPollOnce() throws Exception { - setUpMrConfig(); - - messageConsumerUnderTest = spy(new DmaapMessageConsumer(applicationConfigMock)); - - Mono> response = Mono.empty(); - - doReturn(false, true).when(messageConsumerUnderTest).isStopped(); - doReturn(messageRouterConsumerMock).when(messageConsumerUnderTest).getMessageRouterConsumer(); - doReturn(response).when(messageRouterConsumerMock).getForEntity(any()); - - messageConsumerUnderTest.start().join(); - - verify(messageRouterConsumerMock).getForEntity(any()); - verifyNoMoreInteractions(messageRouterConsumerMock); - } - - @Test - void dmaapConfiguredAndErrorGettingMessages_thenLogWarningAndSleep() throws Exception { - setUpMrConfig(); - - messageConsumerUnderTest = spy(new DmaapMessageConsumer(applicationConfigMock)); - - doNothing().when(messageConsumerUnderTest).sleep(any(Duration.class)); - doReturn(false, true).when(messageConsumerUnderTest).isStopped(); - doReturn(messageRouterConsumerMock).when(messageConsumerUnderTest).getMessageRouterConsumer(); - - Mono> response = Mono.just(new ResponseEntity<>("Error", HttpStatus.BAD_REQUEST)); - when(messageRouterConsumerMock.getForEntity(any())).thenReturn(response); - - final ListAppender logAppender = - LoggingUtils.getLogListAppender(DmaapMessageConsumer.class, WARN); - - messageConsumerUnderTest.start().join(); - - assertThat(logAppender.list.get(0).getFormattedMessage()) - .isEqualTo("Cannot fetch because of Error respons: 400 BAD_REQUEST Error"); - - verify(messageConsumerUnderTest).sleep(DmaapMessageConsumer.TIME_BETWEEN_DMAAP_RETRIES); - } - - @Test - void dmaapConfiguredAndOneMessage_thenPollOnceAndProcessMessage() throws Exception { - // The message from MR is here an array of Json objects - setUpMrConfig(); - messageConsumerUnderTest = spy(new DmaapMessageConsumer(applicationConfigMock)); - - String message = "{\"apiVersion\":\"1.0\"," // - + "\"operation\":\"GET\"," // - + "\"correlationId\":\"1592341013115594000\"," // - + "\"originatorId\":\"849e6c6b420\"," // - + "\"payload\":{}," // - + "\"requestId\":\"23343221\", " // - + "\"target\":\"policy-agent\"," // - + "\"timestamp\":\"2020-06-16 20:56:53.115665\"," // - + "\"type\":\"request\"," // - + "\"url\":\"/rics\"}"; - String messages = "[" + message + "]"; - - doReturn(false, true).when(messageConsumerUnderTest).isStopped(); - doReturn(messageRouterConsumerMock).when(messageConsumerUnderTest).getMessageRouterConsumer(); - - Mono> response = Mono.just(new ResponseEntity<>(messages, HttpStatus.OK)); - when(messageRouterConsumerMock.getForEntity(any())).thenReturn(response); - - doReturn(messageHandlerMock).when(messageConsumerUnderTest).getDmaapMessageHandler(); - - messageConsumerUnderTest.start().join(); - - ArgumentCaptor captor = ArgumentCaptor.forClass(String.class); - verify(messageHandlerMock).handleDmaapMsg(captor.capture()); - String messageAfterJsonParsing = captor.getValue(); - assertThat(messageAfterJsonParsing).contains("apiVersion"); - - verifyNoMoreInteractions(messageHandlerMock); - } - - @Test - void dmaapConfiguredAndOneMessage_thenPollOnceAndProcessMessage2() throws Exception { - // The message from MR is here an array of String (which is the case when the MR - // simulator is used) - setUpMrConfig(); - messageConsumerUnderTest = spy(new DmaapMessageConsumer(applicationConfigMock)); - - doReturn(false, true).when(messageConsumerUnderTest).isStopped(); - doReturn(messageRouterConsumerMock).when(messageConsumerUnderTest).getMessageRouterConsumer(); - - Mono> response = Mono.just(new ResponseEntity<>("[\"aMessage\"]", HttpStatus.OK)); - when(messageRouterConsumerMock.getForEntity(any())).thenReturn(response); - - doReturn(messageHandlerMock).when(messageConsumerUnderTest).getDmaapMessageHandler(); - - messageConsumerUnderTest.start().join(); - - verify(messageHandlerMock).handleDmaapMsg("aMessage"); - verifyNoMoreInteractions(messageHandlerMock); - } - - private void setUpMrConfig() { - when(applicationConfigMock.getDmaapConsumerTopicUrl()).thenReturn("url"); - when(applicationConfigMock.getDmaapProducerTopicUrl()).thenReturn("url"); - } -} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/dmaap/DmaapMessageHandlerTest.java b/policy-agent/src/test/java/org/oransc/policyagent/dmaap/DmaapMessageHandlerTest.java deleted file mode 100644 index f0efddcf..00000000 --- a/policy-agent/src/test/java/org/oransc/policyagent/dmaap/DmaapMessageHandlerTest.java +++ /dev/null @@ -1,290 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.oransc.policyagent.dmaap; - -import static ch.qos.logback.classic.Level.WARN; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; - -import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.core.read.ListAppender; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonObject; - -import java.io.IOException; -import java.nio.charset.Charset; -import java.util.Optional; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; -import org.oransc.policyagent.clients.AsyncRestClient; -import org.oransc.policyagent.dmaap.DmaapRequestMessage.Operation; -import org.oransc.policyagent.repository.ImmutablePolicyType; -import org.oransc.policyagent.repository.PolicyType; -import org.oransc.policyagent.utils.LoggingUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.reactive.function.client.WebClientResponseException; - -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -class DmaapMessageHandlerTest { - private static final Logger logger = LoggerFactory.getLogger(DmaapMessageHandlerTest.class); - private static final String URL = "url"; - - private final AsyncRestClient dmaapClient = mock(AsyncRestClient.class); - private final AsyncRestClient agentClient = mock(AsyncRestClient.class); - private DmaapMessageHandler testedObject; - private static Gson gson = new GsonBuilder() // - .create(); // - - @BeforeEach - private void setUp() throws Exception { - testedObject = spy(new DmaapMessageHandler(dmaapClient, agentClient)); - } - - static JsonObject payloadAsJson() { - return gson.fromJson(payloadAsString(), JsonObject.class); - } - - static String payloadAsString() { - PolicyType pt = ImmutablePolicyType.builder().name("name").schema("schema").build(); - return gson.toJson(pt); - } - - DmaapRequestMessage dmaapRequestMessage(Operation operation) { - Optional payload = - ((operation == Operation.PUT || operation == Operation.POST) ? Optional.of(payloadAsJson()) - : Optional.empty()); - return ImmutableDmaapRequestMessage.builder() // - .apiVersion("apiVersion") // - .correlationId("correlationId") // - .operation(operation) // - .originatorId("originatorId") // - .payload(payload) // - .requestId("requestId") // - .target("target") // - .timestamp("timestamp") // - .url(URL) // - .build(); - } - - private String dmaapInputMessage(Operation operation) { - return gson.toJson(dmaapRequestMessage(operation)); - } - - private Mono> okResponse() { - ResponseEntity entity = new ResponseEntity<>("OK", HttpStatus.OK); - return Mono.just(entity); - } - - private Mono> notOkResponse() { - ResponseEntity entity = new ResponseEntity<>("NOK", HttpStatus.BAD_GATEWAY); - return Mono.just(entity); - } - - @Test - void testMessageParsing() { - String message = dmaapInputMessage(Operation.DELETE); - logger.info(message); - DmaapRequestMessage parsedMessage = gson.fromJson(message, ImmutableDmaapRequestMessage.class); - assertNotNull(parsedMessage); - assertFalse(parsedMessage.payload().isPresent()); - - message = dmaapInputMessage(Operation.PUT); - logger.info(message); - parsedMessage = gson.fromJson(message, ImmutableDmaapRequestMessage.class); - assertNotNull(parsedMessage); - assertTrue(parsedMessage.payload().isPresent()); - } - - @Test - void unparseableMessage_thenWarning() { - final ListAppender logAppender = - LoggingUtils.getLogListAppender(DmaapMessageHandler.class, WARN); - - String msg = "bad message"; - testedObject.handleDmaapMsg(msg); - - assertThat(logAppender.list.get(0).getFormattedMessage()).startsWith( - "handleDmaapMsg failure org.oransc.policyagent.exceptions.ServiceException: Received unparsable " - + "message from DMAAP: \"" + msg + "\", reason: "); - } - - @Test - void successfulDelete() throws IOException { - doReturn(okResponse()).when(agentClient).deleteForEntity(anyString()); - doReturn(Mono.just("OK")).when(dmaapClient).post(anyString(), anyString()); - - String message = dmaapInputMessage(Operation.DELETE); - - StepVerifier // - .create(testedObject.createTask(message)) // - .expectSubscription() // - .expectNext("OK") // - .verifyComplete(); // - - verify(agentClient).deleteForEntity(URL); - verifyNoMoreInteractions(agentClient); - - verify(dmaapClient).post(anyString(), anyString()); - - verifyNoMoreInteractions(dmaapClient); - } - - @Test - void successfulGet() throws IOException { - doReturn(okResponse()).when(agentClient).getForEntity(anyString()); - doReturn(Mono.just("OK")).when(dmaapClient).post(anyString(), anyString()); - - StepVerifier // - .create(testedObject.createTask(dmaapInputMessage(Operation.GET))) // - .expectSubscription() // - .expectNext("OK") // - .verifyComplete(); // - - verify(agentClient).getForEntity(URL); - verifyNoMoreInteractions(agentClient); - - verify(dmaapClient).post(anyString(), anyString()); - verifyNoMoreInteractions(dmaapClient); - } - - @Test - void exceptionFromAgentWhenGet_thenPostError() throws IOException { - String errorBody = "Unavailable"; - WebClientResponseException webClientResponseException = new WebClientResponseException( - HttpStatus.SERVICE_UNAVAILABLE.value(), "", (HttpHeaders) null, errorBody.getBytes(), (Charset) null); - doReturn(Mono.error(webClientResponseException)).when(agentClient).getForEntity(anyString()); - doReturn(Mono.just("OK")).when(dmaapClient).post(anyString(), anyString()); - - StepVerifier // - .create(testedObject.createTask(dmaapInputMessage(Operation.GET))) // - .expectSubscription() // - .verifyComplete(); // - - ArgumentCaptor captor = ArgumentCaptor.forClass(String.class); - verify(dmaapClient).post(anyString(), captor.capture()); - String actualMessage = captor.getValue(); - assertThat(actualMessage).contains(HttpStatus.SERVICE_UNAVAILABLE.toString()) // - .contains(errorBody); - } - - @Test - void successfulPut() throws IOException { - doReturn(okResponse()).when(agentClient).putForEntity(anyString(), anyString()); - doReturn(Mono.just("OK")).when(dmaapClient).post(anyString(), anyString()); - - StepVerifier // - .create(testedObject.createTask(dmaapInputMessage(Operation.PUT))) // - .expectSubscription() // - .expectNext("OK") // - .verifyComplete(); // - - verify(agentClient).putForEntity(URL, payloadAsString()); - verifyNoMoreInteractions(agentClient); - - verify(dmaapClient).post(anyString(), anyString()); - verifyNoMoreInteractions(dmaapClient); - } - - @Test - void successfulPost() throws IOException { - doReturn(okResponse()).when(agentClient).postForEntity(anyString(), anyString()); - doReturn(Mono.just("OK")).when(dmaapClient).post(anyString(), anyString()); - - StepVerifier // - .create(testedObject.createTask(dmaapInputMessage(Operation.POST))) // - .expectSubscription() // - .expectNext("OK") // - .verifyComplete(); // - - verify(agentClient).postForEntity(URL, payloadAsString()); - verifyNoMoreInteractions(agentClient); - - verify(dmaapClient).post(anyString(), anyString()); - verifyNoMoreInteractions(dmaapClient); - } - - @Test - void exceptionWhenCallingPolicyAgent_thenNotFoundResponse() throws IOException { - - doReturn(notOkResponse()).when(agentClient).putForEntity(anyString(), anyString()); - doReturn(Mono.just("OK")).when(dmaapClient).post(anyString(), anyString()); - - testedObject.createTask(dmaapInputMessage(Operation.PUT)).block(); - - verify(agentClient).putForEntity(anyString(), anyString()); - verifyNoMoreInteractions(agentClient); - - ArgumentCaptor captor = ArgumentCaptor.forClass(String.class); - verify(dmaapClient).post(anyString(), captor.capture()); - String actualMessage = captor.getValue(); - assertThat(actualMessage).as("Message \"%s\" sent to DMaaP contains %s", actualMessage, HttpStatus.BAD_GATEWAY) - .contains(HttpStatus.BAD_GATEWAY.toString()); - - verifyNoMoreInteractions(dmaapClient); - } - - @Test - void unsupportedOperationInMessage_thenNotFoundResponseWithNotImplementedOperation() throws Exception { - String message = dmaapInputMessage(Operation.PUT).toString(); - String badOperation = "BAD"; - message = message.replace(Operation.PUT.toString(), badOperation); - - testedObject.handleDmaapMsg(message); - - ArgumentCaptor captor = ArgumentCaptor.forClass(String.class); - verify(dmaapClient).post(anyString(), captor.capture()); - String actualMessage = captor.getValue(); - assertThat(actualMessage).contains("Not implemented operation") // - .contains("BAD_REQUEST"); - } - - @Test - void putWithoutPayload_thenNotFoundResponseWithWarning() throws Exception { - String message = dmaapInputMessage(Operation.PUT).toString(); - message = message.replace(",\"payload\":{\"name\":\"name\",\"schema\":\"schema\"}", ""); - - final ListAppender logAppender = - LoggingUtils.getLogListAppender(DmaapMessageHandler.class, WARN); - - testedObject.handleDmaapMsg(message); - - assertThat(logAppender.list.get(0).getFormattedMessage()) - .startsWith("Expected payload in message from DMAAP: "); - } -} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/repository/LockTest.java b/policy-agent/src/test/java/org/oransc/policyagent/repository/LockTest.java deleted file mode 100644 index 4b8743ff..00000000 --- a/policy-agent/src/test/java/org/oransc/policyagent/repository/LockTest.java +++ /dev/null @@ -1,89 +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.policyagent.repository; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.io.IOException; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.junit.jupiter.MockitoExtension; -import org.oransc.policyagent.exceptions.ServiceException; -import org.oransc.policyagent.repository.Lock.LockType; - -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -@ExtendWith(MockitoExtension.class) -class LockTest { - - @SuppressWarnings("squid:S2925") // "Thread.sleep" should not be used in tests. - private void sleep() { - try { - Thread.sleep(100); - } catch (InterruptedException e) { - // Do nothing. - } - } - - private void asynchUnlock(Lock lock) { - Thread thread = new Thread(() -> { - sleep(); - lock.unlockBlocking(); - }); - thread.start(); - } - - @Test - void testLock() throws IOException, ServiceException { - Lock lock = new Lock(); - lock.lockBlocking(LockType.SHARED); - lock.unlockBlocking(); - - lock.lockBlocking(LockType.EXCLUSIVE); - asynchUnlock(lock); - - lock.lockBlocking(LockType.SHARED); - lock.unlockBlocking(); - - assertThat(lock.getLockCounter()).isZero(); - } - - @Test - void testReactiveLock() { - Lock lock = new Lock(); - - Mono seq = lock.lock(LockType.EXCLUSIVE) // - .flatMap(l -> lock.lock(LockType.EXCLUSIVE)) // - .flatMap(l -> lock.unlock()); - - asynchUnlock(lock); - StepVerifier.create(seq) // - .expectSubscription() // - .expectNext(lock) // - .verifyComplete(); - - assertThat(lock.getLockCounter()).isZero(); - - } - -} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/tasks/EnvironmentProcessorTest.java b/policy-agent/src/test/java/org/oransc/policyagent/tasks/EnvironmentProcessorTest.java deleted file mode 100644 index efabba38..00000000 --- a/policy-agent/src/test/java/org/oransc/policyagent/tasks/EnvironmentProcessorTest.java +++ /dev/null @@ -1,145 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.tasks; - -import static ch.qos.logback.classic.Level.WARN; -import static org.assertj.core.api.Assertions.assertThat; - -import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.core.read.ListAppender; - -import java.util.Properties; - -import org.junit.jupiter.api.Test; -import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.EnvProperties; -import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.ImmutableEnvProperties; -import org.oransc.policyagent.exceptions.EnvironmentLoaderException; -import org.oransc.policyagent.utils.LoggingUtils; -import reactor.test.StepVerifier; - -class EnvironmentProcessorTest { - private static final String CONSUL_HOST = "CONSUL_HOST"; - private static final String CONSUL_HOST_VALUE = "consulHost"; - - private static final String CONFIG_BINDING_SERVICE = "CONFIG_BINDING_SERVICE"; - private static final String CONFIG_BINDING_SERVICE_VALUE = "configBindingService"; - - private static final String HOSTNAME = "HOSTNAME"; - private static final String HOSTNAME_VALUE = "hostname"; - - @Test - void allPropertiesAvailableWithHostname_thenAllPropertiesAreReturnedWithGivenConsulPort() { - Properties systemEnvironment = new Properties(); - String consulPort = "8080"; - systemEnvironment.put(CONSUL_HOST, CONSUL_HOST_VALUE); - systemEnvironment.put("CONSUL_PORT", consulPort); - systemEnvironment.put(CONFIG_BINDING_SERVICE, CONFIG_BINDING_SERVICE_VALUE); - systemEnvironment.put(HOSTNAME, HOSTNAME_VALUE); - - EnvProperties expectedEnvProperties = ImmutableEnvProperties.builder() // - .consulHost(CONSUL_HOST_VALUE) // - .consulPort(Integer.valueOf(consulPort)) // - .cbsName(CONFIG_BINDING_SERVICE_VALUE) // - .appName(HOSTNAME_VALUE) // - .build(); - - StepVerifier.create(EnvironmentProcessor.readEnvironmentVariables(systemEnvironment)) - .expectNext(expectedEnvProperties).expectComplete(); - } - - @Test - void consulHostMissing_thenExceptionReturned() { - Properties systemEnvironment = new Properties(); - - StepVerifier.create(EnvironmentProcessor.readEnvironmentVariables(systemEnvironment)) - .expectErrorMatches(throwable -> throwable instanceof EnvironmentLoaderException - && throwable.getMessage().equals("$CONSUL_HOST environment has not been defined")) - .verify(); - } - - @Test - void withAllPropertiesExceptConsulPort_thenAllPropertiesAreReturnedWithDefaultConsulPortAndWarning() { - Properties systemEnvironment = new Properties(); - systemEnvironment.put(CONSUL_HOST, CONSUL_HOST_VALUE); - systemEnvironment.put(CONFIG_BINDING_SERVICE, CONFIG_BINDING_SERVICE_VALUE); - systemEnvironment.put(HOSTNAME, HOSTNAME_VALUE); - - String defaultConsulPort = "8500"; - EnvProperties expectedEnvProperties = ImmutableEnvProperties.builder() // - .consulHost(CONSUL_HOST_VALUE) // - .consulPort(Integer.valueOf(defaultConsulPort)) // - .cbsName(CONFIG_BINDING_SERVICE_VALUE) // - .appName(HOSTNAME_VALUE) // - .build(); - - final ListAppender logAppender = - LoggingUtils.getLogListAppender(EnvironmentProcessor.class, WARN); - - StepVerifier.create(EnvironmentProcessor.readEnvironmentVariables(systemEnvironment)) - .expectNext(expectedEnvProperties).expectComplete(); - - assertThat(logAppender.list.get(0).getFormattedMessage()) - .isEqualTo("$CONSUL_PORT variable will be set to default port " + defaultConsulPort); - } - - @Test - void configBindingServiceMissing_thenExceptionReturned() { - Properties systemEnvironment = new Properties(); - systemEnvironment.put(CONSUL_HOST, CONSUL_HOST_VALUE); - - StepVerifier.create(EnvironmentProcessor.readEnvironmentVariables(systemEnvironment)) - .expectErrorMatches(throwable -> throwable instanceof EnvironmentLoaderException - && throwable.getMessage().equals("$CONFIG_BINDING_SERVICE environment has not been defined")) - .verify(); - } - - @Test - void allPropertiesAvailableWithServiceName_thenAllPropertiesAreReturned() { - Properties systemEnvironment = new Properties(); - String consulPort = "8080"; - systemEnvironment.put(CONSUL_HOST, CONSUL_HOST_VALUE); - systemEnvironment.put("CONSUL_PORT", consulPort); - systemEnvironment.put(CONFIG_BINDING_SERVICE, CONFIG_BINDING_SERVICE_VALUE); - systemEnvironment.put("SERVICE_NAME", HOSTNAME_VALUE); - - EnvProperties expectedEnvProperties = ImmutableEnvProperties.builder() // - .consulHost(CONSUL_HOST_VALUE) // - .consulPort(Integer.valueOf(consulPort)) // - .cbsName(CONFIG_BINDING_SERVICE_VALUE) // - .appName(HOSTNAME_VALUE) // - .build(); - - StepVerifier.create(EnvironmentProcessor.readEnvironmentVariables(systemEnvironment)) - .expectNext(expectedEnvProperties).expectComplete(); - } - - @Test - void serviceNameAndHostnameMissing_thenExceptionIsReturned() { - Properties systemEnvironment = new Properties(); - systemEnvironment.put(CONSUL_HOST, CONSUL_HOST_VALUE); - systemEnvironment.put(CONFIG_BINDING_SERVICE, CONFIG_BINDING_SERVICE_VALUE); - - StepVerifier.create(EnvironmentProcessor.readEnvironmentVariables(systemEnvironment)) - .expectErrorMatches(throwable -> throwable instanceof EnvironmentLoaderException && throwable.getMessage() - .equals("Neither $HOSTNAME/$SERVICE_NAME have not been defined as system environment")) - .verify(); - } -} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/tasks/RefreshConfigTaskTest.java b/policy-agent/src/test/java/org/oransc/policyagent/tasks/RefreshConfigTaskTest.java deleted file mode 100644 index 673ed68a..00000000 --- a/policy-agent/src/test/java/org/oransc/policyagent/tasks/RefreshConfigTaskTest.java +++ /dev/null @@ -1,386 +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.policyagent.tasks; - -import static ch.qos.logback.classic.Level.ERROR; -import static ch.qos.logback.classic.Level.WARN; -import static org.assertj.core.api.Assertions.assertThat; -import static org.awaitility.Awaitility.await; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -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; -import java.io.InputStreamReader; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.time.Duration; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Properties; -import java.util.Vector; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.Spy; -import org.mockito.junit.jupiter.MockitoExtension; -import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.CbsClient; -import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.EnvProperties; -import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.ImmutableEnvProperties; -import org.oransc.policyagent.clients.A1ClientFactory; -import org.oransc.policyagent.configuration.ApplicationConfig; -import org.oransc.policyagent.configuration.ApplicationConfig.RicConfigUpdate.Type; -import org.oransc.policyagent.configuration.ApplicationConfigParser; -import org.oransc.policyagent.configuration.ApplicationConfigParser.ConfigParserResult; -import org.oransc.policyagent.configuration.ImmutableConfigParserResult; -import org.oransc.policyagent.configuration.ImmutableRicConfig; -import org.oransc.policyagent.configuration.RicConfig; -import org.oransc.policyagent.repository.ImmutablePolicy; -import org.oransc.policyagent.repository.ImmutablePolicyType; -import org.oransc.policyagent.repository.Policies; -import org.oransc.policyagent.repository.Policy; -import org.oransc.policyagent.repository.PolicyTypes; -import org.oransc.policyagent.repository.Ric; -import org.oransc.policyagent.repository.Rics; -import org.oransc.policyagent.repository.Services; -import org.oransc.policyagent.utils.LoggingUtils; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -@ExtendWith(MockitoExtension.class) -class RefreshConfigTaskTest { - - private static final boolean CONFIG_FILE_EXISTS = true; - private static final boolean CONFIG_FILE_DOES_NOT_EXIST = false; - - private RefreshConfigTask refreshTaskUnderTest; - - @Spy - ApplicationConfig appConfig; - - @Mock - CbsClient cbsClient; - - private static final String RIC_1_NAME = "ric1"; - private static final ImmutableRicConfig CORRECT_RIC_CONIFG = ImmutableRicConfig.builder() // - .name(RIC_1_NAME) // - .baseUrl("http://localhost:8080/") // - .managedElementIds(new Vector(Arrays.asList("kista_1", "kista_2"))) // - .controllerName("") // - .build(); - - private static EnvProperties properties() { - return ImmutableEnvProperties.builder() // - .consulHost("host") // - .consulPort(123) // - .cbsName("cbsName") // - .appName("appName") // - .build(); - } - - private RefreshConfigTask createTestObject(boolean configFileExists) { - return createTestObject(configFileExists, new Rics(), new Policies(), true); - } - - private RefreshConfigTask createTestObject(boolean configFileExists, Rics rics, Policies policies, - boolean stubConfigFileExists) { - RefreshConfigTask obj = spy(new RefreshConfigTask(appConfig, rics, policies, new Services(), new PolicyTypes(), - new A1ClientFactory(appConfig))); - if (stubConfigFileExists) { - doReturn(configFileExists).when(obj).fileExists(any()); - } - return obj; - } - - @Test - void startWithStubbedRefresh_thenTerminationLogged() { - refreshTaskUnderTest = this.createTestObject(CONFIG_FILE_DOES_NOT_EXIST, null, null, false); - doReturn(Flux.empty()).when(refreshTaskUnderTest).createRefreshTask(); - - final ListAppender logAppender = LoggingUtils.getLogListAppender(RefreshConfigTask.class, ERROR); - - refreshTaskUnderTest.start(); - - assertThat(logAppender.list.get(0).getFormattedMessage()).isEqualTo("Configuration refresh terminated"); - } - - @Test - void startWithStubbedRefreshReturnError_thenErrorAndTerminationLogged() { - refreshTaskUnderTest = this.createTestObject(CONFIG_FILE_DOES_NOT_EXIST, null, null, false); - String errorMessage = "Error"; - doReturn(Flux.error(new Exception(errorMessage))).when(refreshTaskUnderTest).createRefreshTask(); - - final ListAppender logAppender = LoggingUtils.getLogListAppender(RefreshConfigTask.class, ERROR); - - refreshTaskUnderTest.start(); - - ILoggingEvent event = logAppender.list.get(0); - assertThat(event.getFormattedMessage()) - .isEqualTo("Configuration refresh terminated due to exception java.lang.Exception: " + errorMessage); - } - - @Test - void stop_thenTaskIsDisposed() throws Exception { - refreshTaskUnderTest = this.createTestObject(CONFIG_FILE_DOES_NOT_EXIST, null, null, false); - refreshTaskUnderTest.systemEnvironment = new Properties(); - - refreshTaskUnderTest.start(); - refreshTaskUnderTest.stop(); - - assertThat(refreshTaskUnderTest.getRefreshTask().isDisposed()).as("Refresh task is disposed").isTrue(); - } - - @Test - void whenTheConfigurationFits_thenConfiguredRicsArePutInRepository() throws Exception { - refreshTaskUnderTest = this.createTestObject(CONFIG_FILE_EXISTS); - refreshTaskUnderTest.systemEnvironment = new Properties(); - // When - doReturn(getCorrectJson()).when(refreshTaskUnderTest).createInputStream(any()); - doReturn("fileName").when(appConfig).getLocalConfigurationFilePath(); - - StepVerifier // - .create(refreshTaskUnderTest.createRefreshTask()) // - .expectSubscription() // - .expectNext(Type.ADDED) // - .expectNext(Type.ADDED) // - .thenCancel() // - .verify(); - - // Then - verify(refreshTaskUnderTest).loadConfigurationFromFile(); - - verify(refreshTaskUnderTest, times(2)).runRicSynchronization(any(Ric.class)); - - Iterable ricConfigs = appConfig.getRicConfigs(); - RicConfig ricConfig = ricConfigs.iterator().next(); - assertThat(ricConfigs).isNotNull(); - assertThat(ricConfig).isEqualTo(CORRECT_RIC_CONIFG); - } - - @Test - void whenFileExistsButJsonIsIncorrect_thenNoRicsArePutInRepositoryAndErrorIsLogged() throws Exception { - refreshTaskUnderTest = this.createTestObject(CONFIG_FILE_EXISTS); - refreshTaskUnderTest.systemEnvironment = new Properties(); - - // When - doReturn(getIncorrectJson()).when(refreshTaskUnderTest).createInputStream(any()); - doReturn("fileName").when(appConfig).getLocalConfigurationFilePath(); - - final ListAppender logAppender = LoggingUtils.getLogListAppender(RefreshConfigTask.class, ERROR); - - StepVerifier // - .create(refreshTaskUnderTest.createRefreshTask()) // - .expectSubscription() // - .expectNoEvent(Duration.ofMillis(100)) // - .thenCancel() // - .verify(); - - // Then - verify(refreshTaskUnderTest).loadConfigurationFromFile(); - assertThat(appConfig.getRicConfigs()).isEmpty(); - - await().until(() -> logAppender.list.size() > 0); - assertThat(logAppender.list.get(0).getFormattedMessage()) - .startsWith("Local configuration file not loaded: fileName, "); - } - - @Test - void whenPeriodicConfigRefreshNoConsul_thenErrorIsLogged() { - refreshTaskUnderTest = this.createTestObject(CONFIG_FILE_DOES_NOT_EXIST); - refreshTaskUnderTest.systemEnvironment = new Properties(); - - EnvProperties props = properties(); - doReturn(Mono.just(props)).when(refreshTaskUnderTest).getEnvironment(any()); - - doReturn(Mono.just(cbsClient)).when(refreshTaskUnderTest).createCbsClient(props); - when(cbsClient.get(any())).thenReturn(Mono.error(new IOException())); - - final ListAppender logAppender = LoggingUtils.getLogListAppender(RefreshConfigTask.class, WARN); - - StepVerifier // - .create(refreshTaskUnderTest.createRefreshTask()) // - .expectSubscription() // - .expectNoEvent(Duration.ofMillis(1000)) // - .thenCancel() // - .verify(); - - await().until(() -> logAppender.list.size() > 0); - assertThat(logAppender.list.get(0).getFormattedMessage()) - .isEqualTo("Could not refresh application configuration. java.io.IOException"); - } - - @Test - void whenPeriodicConfigRefreshSuccess_thenNewConfigIsCreatedAndRepositoryUpdated() throws Exception { - Rics rics = new Rics(); - Policies policies = new Policies(); - refreshTaskUnderTest = this.createTestObject(CONFIG_FILE_DOES_NOT_EXIST, rics, policies, false); - refreshTaskUnderTest.systemEnvironment = new Properties(); - - RicConfig changedRicConfig = getRicConfig(RIC_1_NAME); - rics.put(new Ric(changedRicConfig)); - RicConfig removedRicConfig = getRicConfig("removed"); - Ric removedRic = new Ric(removedRicConfig); - rics.put(removedRic); - appConfig.setConfiguration(configParserResult(changedRicConfig, removedRicConfig)); - - Policy policy = getPolicy(removedRic); - policies.put(policy); - - EnvProperties props = properties(); - doReturn(Mono.just(props)).when(refreshTaskUnderTest).getEnvironment(any()); - doReturn(Mono.just(cbsClient)).when(refreshTaskUnderTest).createCbsClient(props); - - JsonObject configAsJson = getJsonRootObject(true); - String newBaseUrl = "newBaseUrl"; - modifyTheRicConfiguration(configAsJson, newBaseUrl); - when(cbsClient.get(any())).thenReturn(Mono.just(configAsJson)); - doNothing().when(refreshTaskUnderTest).runRicSynchronization(any(Ric.class)); - - StepVerifier // - .create(refreshTaskUnderTest.createRefreshTask()) // - .expectSubscription() // - .expectNext(Type.CHANGED) // - .expectNext(Type.ADDED) // - .expectNext(Type.REMOVED) // - .thenCancel() // - .verify(); - - assertThat(appConfig.getRicConfigs()).hasSize(2); - assertThat(appConfig.getRic(RIC_1_NAME).baseUrl()).isEqualTo(newBaseUrl); - String ric2Name = "ric2"; - assertThat(appConfig.getRic(ric2Name)).isNotNull(); - - assertThat(rics.size()).isEqualTo(2); - assertThat(rics.get(RIC_1_NAME).getConfig().baseUrl()).isEqualTo(newBaseUrl); - assertThat(rics.get(ric2Name)).isNotNull(); - - assertThat(policies.size()).isZero(); - } - - @Test - void whenPeriodicConfigRefreshInvalidJson_thenErrorIsLogged() throws Exception { - Rics rics = new Rics(); - Policies policies = new Policies(); - refreshTaskUnderTest = this.createTestObject(CONFIG_FILE_DOES_NOT_EXIST, rics, policies, false); - refreshTaskUnderTest.systemEnvironment = new Properties(); - - appConfig.setConfiguration(configParserResult()); - - EnvProperties props = properties(); - doReturn(Mono.just(props)).when(refreshTaskUnderTest).getEnvironment(any()); - doReturn(Mono.just(cbsClient)).when(refreshTaskUnderTest).createCbsClient(props); - - JsonObject configAsJson = getJsonRootObject(false); - when(cbsClient.get(any())).thenReturn(Mono.just(configAsJson)); - - final ListAppender logAppender = LoggingUtils.getLogListAppender(RefreshConfigTask.class, ERROR); - - StepVerifier // - .create(refreshTaskUnderTest.createRefreshTask()) // - .expectSubscription() // - .expectNoEvent(Duration.ofMillis(1000)) // - .thenCancel() // - .verify(); - - await().until(() -> logAppender.list.size() > 0); - assertThat(logAppender.list.get(0).getFormattedMessage()) - .startsWith("Could not parse configuration org.oransc.policyagent.exceptions.ServiceException: "); - } - - private RicConfig getRicConfig(String name) { - RicConfig ricConfig = ImmutableRicConfig.builder() // - .name(name) // - .baseUrl("url") // - .managedElementIds(Collections.emptyList()) // - .controllerName("controllerName") // - .build(); - return ricConfig; - } - - private Policy getPolicy(Ric ric) { - ImmutablePolicyType type = ImmutablePolicyType.builder() // - .name("type") // - .schema("{}") // - .build(); - Policy policy = ImmutablePolicy.builder() // - .id("id") // - .type(type) // - .lastModified("lastModified") // - .ric(ric) // - .json("{}") // - .ownerServiceName("ownerServiceName") // - .isTransient(false) // - .build(); - return policy; - } - - ConfigParserResult configParserResult(RicConfig... rics) { - return ImmutableConfigParserResult.builder() // - .ricConfigs(Arrays.asList(rics)) // - .dmaapConsumerTopicUrl("") // - .dmaapProducerTopicUrl("") // - .controllerConfigs(new HashMap<>()) // - .build(); - } - - private void modifyTheRicConfiguration(JsonObject configAsJson, String newBaseUrl) { - ((JsonObject) configAsJson.getAsJsonObject("config") // - .getAsJsonArray("ric").get(0)) // - .addProperty("baseUrl", newBaseUrl); - } - - private JsonObject getJsonRootObject(boolean valid) throws JsonIOException, JsonSyntaxException, IOException { - JsonObject rootObject = JsonParser - .parseReader(new InputStreamReader(valid ? getCorrectJson() : getIncorrectJson())).getAsJsonObject(); - return rootObject; - } - - private static InputStream getCorrectJson() throws IOException { - URL url = ApplicationConfigParser.class.getClassLoader().getResource("test_application_configuration.json"); - String string = Resources.toString(url, Charsets.UTF_8); - return new ByteArrayInputStream((string.getBytes(StandardCharsets.UTF_8))); - } - - private static InputStream getIncorrectJson() { - String string = "{}"; // - return new ByteArrayInputStream((string.getBytes(StandardCharsets.UTF_8))); - } -} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/tasks/RicSupervisionTest.java b/policy-agent/src/test/java/org/oransc/policyagent/tasks/RicSupervisionTest.java deleted file mode 100644 index db99728a..00000000 --- a/policy-agent/src/test/java/org/oransc/policyagent/tasks/RicSupervisionTest.java +++ /dev/null @@ -1,328 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.tasks; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Vector; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.oransc.policyagent.clients.A1Client; -import org.oransc.policyagent.clients.A1ClientFactory; -import org.oransc.policyagent.configuration.ImmutableRicConfig; -import org.oransc.policyagent.repository.ImmutablePolicy; -import org.oransc.policyagent.repository.ImmutablePolicyType; -import org.oransc.policyagent.repository.Lock.LockType; -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.Ric.RicState; -import org.oransc.policyagent.repository.Rics; -import reactor.core.publisher.Mono; - -@ExtendWith(MockitoExtension.class) -class RicSupervisionTest { - private static final String POLICY_TYPE_1_NAME = "type1"; - private static final PolicyType POLICY_TYPE_1 = ImmutablePolicyType.builder() // - .name(POLICY_TYPE_1_NAME) // - .schema("") // - .build(); - - private static final Ric RIC_1 = new Ric(ImmutableRicConfig.builder() // - .name("RIC_1") // - .baseUrl("baseUrl1") // - .managedElementIds(new Vector(Arrays.asList("kista_1", "kista_2"))) // - .controllerName("controllerName") // - .build()); - - private static final String POLICY_1_ID = "policyId1"; - private static final Policy POLICY_1 = ImmutablePolicy.builder() // - .id(POLICY_1_ID) // - .json("") // - .ownerServiceName("service") // - .ric(RIC_1) // - .type(POLICY_TYPE_1) // - .lastModified("now") // - .isTransient(false) // - .build(); - - private static final Policy POLICY_2 = ImmutablePolicy.builder() // - .id("policyId2") // - .json("") // - .ownerServiceName("service") // - .ric(RIC_1) // - .type(POLICY_TYPE_1) // - .lastModified("now") // - .isTransient(false) // - .build(); - - @Mock - private A1Client a1ClientMock; - - @Mock - private A1ClientFactory a1ClientFactory; - - @Mock - private RicSynchronizationTask synchronizationTaskMock; - - private final PolicyTypes types = new PolicyTypes(); - private Policies policies = new Policies(); - private Rics rics = new Rics(); - - @BeforeEach - void init() { - types.clear(); - policies.clear(); - rics.clear(); - RIC_1.setState(RicState.UNAVAILABLE); - RIC_1.clearSupportedPolicyTypes(); - } - - @AfterEach - void verifyNoRicLocks() { - for (Ric ric : this.rics.getRics()) { - ric.getLock().lockBlocking(LockType.EXCLUSIVE); - ric.getLock().unlockBlocking(); - assertThat(ric.getLock().getLockCounter()).isZero(); - } - } - - @Test - void whenRicIdleAndNoChangedPoliciesOrPolicyTypes_thenNoSynchronization() { - doReturn(Mono.just(a1ClientMock)).when(a1ClientFactory).createA1Client(any(Ric.class)); - RIC_1.setState(RicState.AVAILABLE); - RIC_1.addSupportedPolicyType(POLICY_TYPE_1); - rics.put(RIC_1); - - types.put(POLICY_TYPE_1); - - policies.put(POLICY_1); - - setUpGetPolicyIdentitiesToReturn(new ArrayList<>(Arrays.asList(POLICY_1_ID))); - setUpGetPolicyTypeIdentitiesToReturn(new ArrayList<>(Arrays.asList(POLICY_TYPE_1_NAME))); - - RicSupervision supervisorUnderTest = spy(new RicSupervision(rics, policies, a1ClientFactory, types, null)); - - supervisorUnderTest.checkAllRics(); - - verify(supervisorUnderTest).checkAllRics(); - verifyNoMoreInteractions(supervisorUnderTest); - } - - @Test - void whenRicUndefined_thenSynchronization() { - doReturn(Mono.just(a1ClientMock)).when(a1ClientFactory).createA1Client(any(Ric.class)); - RIC_1.setState(RicState.UNAVAILABLE); - rics.put(RIC_1); - - RicSupervision supervisorUnderTest = spy(new RicSupervision(rics, policies, a1ClientFactory, types, null)); - - doReturn(synchronizationTaskMock).when(supervisorUnderTest).createSynchronizationTask(); - - supervisorUnderTest.checkAllRics(); - - verify(supervisorUnderTest).checkAllRics(); - verify(supervisorUnderTest).createSynchronizationTask(); - verify(synchronizationTaskMock).run(RIC_1); - verifyNoMoreInteractions(supervisorUnderTest); - } - - @Test - void whenRicSynchronizing_thenNoSynchronization() { - doReturn(Mono.just(a1ClientMock)).when(a1ClientFactory).createA1Client(any(Ric.class)); - RIC_1.setState(RicState.SYNCHRONIZING); - rics.put(RIC_1); - - RicSupervision supervisorUnderTest = spy(new RicSupervision(rics, policies, a1ClientFactory, types, null)); - - supervisorUnderTest.checkAllRics(); - - verify(supervisorUnderTest).checkAllRics(); - verifyNoMoreInteractions(supervisorUnderTest); - } - - @Test - void whenRicIdleAndErrorGettingPolicyIdentities_thenNoSynchronization() { - doReturn(Mono.just(a1ClientMock)).when(a1ClientFactory).createA1Client(any(Ric.class)); - RIC_1.setState(RicState.AVAILABLE); - RIC_1.addSupportedPolicyType(POLICY_TYPE_1); - rics.put(RIC_1); - - setUpGetPolicyIdentitiesToReturn(new Exception("Failed")); - - RicSupervision supervisorUnderTest = spy(new RicSupervision(rics, policies, a1ClientFactory, types, null)); - supervisorUnderTest.checkAllRics(); - - verify(supervisorUnderTest).checkAllRics(); - verifyNoMoreInteractions(supervisorUnderTest); - assertThat(RIC_1.getState()).isEqualTo(RicState.UNAVAILABLE); - } - - @Test - void whenRicIdleAndNotSameAmountOfPolicies_thenSynchronization() { - doReturn(Mono.just(a1ClientMock)).when(a1ClientFactory).createA1Client(any(Ric.class)); - RIC_1.setState(RicState.AVAILABLE); - rics.put(RIC_1); - - policies.put(POLICY_1); - policies.put(POLICY_2); - - setUpGetPolicyIdentitiesToReturn(new ArrayList<>(Arrays.asList(POLICY_1_ID))); - - RicSupervision supervisorUnderTest = spy(new RicSupervision(rics, policies, a1ClientFactory, types, null)); - - doReturn(synchronizationTaskMock).when(supervisorUnderTest).createSynchronizationTask(); - - supervisorUnderTest.checkAllRics(); - - verify(supervisorUnderTest).checkAllRics(); - verify(supervisorUnderTest).createSynchronizationTask(); - verify(synchronizationTaskMock).run(RIC_1); - verifyNoMoreInteractions(supervisorUnderTest); - } - - @Test - void whenRicIdleAndSameAmountOfPoliciesButNotSamePolicies_thenSynchronization() { - doReturn(Mono.just(a1ClientMock)).when(a1ClientFactory).createA1Client(any(Ric.class)); - RIC_1.setState(RicState.AVAILABLE); - rics.put(RIC_1); - - policies.put(POLICY_1); - policies.put(POLICY_2); - - setUpGetPolicyIdentitiesToReturn(new ArrayList<>(Arrays.asList(POLICY_1_ID, "Another_policy"))); - - RicSupervision supervisorUnderTest = spy(new RicSupervision(rics, policies, a1ClientFactory, types, null)); - - doReturn(synchronizationTaskMock).when(supervisorUnderTest).createSynchronizationTask(); - - supervisorUnderTest.checkAllRics(); - - verify(supervisorUnderTest).checkAllRics(); - verify(supervisorUnderTest).createSynchronizationTask(); - verify(synchronizationTaskMock).run(RIC_1); - verifyNoMoreInteractions(supervisorUnderTest); - } - - @Test - void whenRicIdleAndErrorGettingPolicyTypes_thenNoSynchronization() { - doReturn(Mono.just(a1ClientMock)).when(a1ClientFactory).createA1Client(any(Ric.class)); - RIC_1.setState(RicState.AVAILABLE); - RIC_1.addSupportedPolicyType(POLICY_TYPE_1); - rics.put(RIC_1); - - setUpGetPolicyIdentitiesToReturn(Collections.emptyList()); - setUpGetPolicyTypeIdentitiesToReturn(new Exception("Failed")); - - RicSupervision supervisorUnderTest = spy(new RicSupervision(rics, policies, a1ClientFactory, types, null)); - supervisorUnderTest.checkAllRics(); - - verify(supervisorUnderTest).checkAllRics(); - verifyNoMoreInteractions(supervisorUnderTest); - } - - @Test - void whenRicIdleAndNotSameAmountOfPolicyTypes_thenSynchronization() { - doReturn(Mono.just(a1ClientMock)).when(a1ClientFactory).createA1Client(any(Ric.class)); - RIC_1.setState(RicState.AVAILABLE); - RIC_1.addSupportedPolicyType(POLICY_TYPE_1); - rics.put(RIC_1); - - types.put(POLICY_TYPE_1); - - setUpGetPolicyIdentitiesToReturn(Collections.emptyList()); - setUpGetPolicyTypeIdentitiesToReturn(new ArrayList<>(Arrays.asList(POLICY_TYPE_1_NAME, "another_policy_type"))); - - RicSupervision supervisorUnderTest = spy(new RicSupervision(rics, policies, a1ClientFactory, types, null)); - - doReturn(synchronizationTaskMock).when(supervisorUnderTest).createSynchronizationTask(); - - supervisorUnderTest.checkAllRics(); - - verify(supervisorUnderTest).checkAllRics(); - verify(supervisorUnderTest).createSynchronizationTask(); - verify(synchronizationTaskMock).run(RIC_1); - verifyNoMoreInteractions(supervisorUnderTest); - } - - @Test - void whenRicIdleAndSameAmountOfPolicyTypesButNotSameTypes_thenSynchronization() { - doReturn(Mono.just(a1ClientMock)).when(a1ClientFactory).createA1Client(any(Ric.class)); - PolicyType policyType2 = ImmutablePolicyType.builder() // - .name("policyType2") // - .schema("") // - .build(); - - RIC_1.setState(RicState.AVAILABLE); - RIC_1.addSupportedPolicyType(POLICY_TYPE_1); - RIC_1.addSupportedPolicyType(policyType2); - rics.put(RIC_1); - - setUpGetPolicyIdentitiesToReturn(Collections.emptyList()); - setUpGetPolicyTypeIdentitiesToReturn(new ArrayList<>(Arrays.asList(POLICY_TYPE_1_NAME, "another_policy_type"))); - - RicSupervision supervisorUnderTest = spy(new RicSupervision(rics, policies, a1ClientFactory, types, null)); - - doReturn(synchronizationTaskMock).when(supervisorUnderTest).createSynchronizationTask(); - - supervisorUnderTest.checkAllRics(); - - verify(supervisorUnderTest).checkAllRics(); - verify(supervisorUnderTest).createSynchronizationTask(); - verify(synchronizationTaskMock).run(RIC_1); - verifyNoMoreInteractions(supervisorUnderTest); - } - - @SuppressWarnings("unchecked") - private void setUpGetPolicyIdentitiesToReturn(Object returnValue) { - if (returnValue instanceof List) { - when(a1ClientMock.getPolicyIdentities()).thenReturn(Mono.just((List) returnValue)); - } else if (returnValue instanceof Exception) { - when(a1ClientMock.getPolicyIdentities()).thenReturn(Mono.error((Exception) returnValue)); - } - } - - @SuppressWarnings("unchecked") - private void setUpGetPolicyTypeIdentitiesToReturn(Object returnValue) { - if (returnValue instanceof List) { - when(a1ClientMock.getPolicyTypeIdentities()).thenReturn(Mono.just((List) returnValue)); - } else if (returnValue instanceof Exception) { - when(a1ClientMock.getPolicyTypeIdentities()).thenReturn(Mono.error((Exception) returnValue)); - } - } -} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/tasks/RicSynchronizationTaskTest.java b/policy-agent/src/test/java/org/oransc/policyagent/tasks/RicSynchronizationTaskTest.java deleted file mode 100644 index 6667029a..00000000 --- a/policy-agent/src/test/java/org/oransc/policyagent/tasks/RicSynchronizationTaskTest.java +++ /dev/null @@ -1,339 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.tasks; - -import static ch.qos.logback.classic.Level.WARN; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoInteractions; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.core.read.ListAppender; - -import java.time.Duration; -import java.util.Arrays; -import java.util.Collections; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.oransc.policyagent.clients.A1Client; -import org.oransc.policyagent.clients.A1ClientFactory; -import org.oransc.policyagent.clients.AsyncRestClient; -import org.oransc.policyagent.configuration.ImmutableRicConfig; -import org.oransc.policyagent.repository.ImmutablePolicy; -import org.oransc.policyagent.repository.ImmutablePolicyType; -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.Ric.RicState; -import org.oransc.policyagent.repository.Service; -import org.oransc.policyagent.repository.Services; -import org.oransc.policyagent.utils.LoggingUtils; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -@ExtendWith(MockitoExtension.class) -class RicSynchronizationTaskTest { - private static final String POLICY_TYPE_1_NAME = "type1"; - private static final PolicyType POLICY_TYPE_1 = ImmutablePolicyType.builder() // - .name(POLICY_TYPE_1_NAME) // - .schema("") // - .build(); - - private static final String RIC_1_NAME = "ric1"; - private static final Ric RIC_1 = new Ric(ImmutableRicConfig.builder() // - .name(RIC_1_NAME) // - .baseUrl("baseUrl1") // - .managedElementIds(Collections.emptyList()) // - .controllerName("controllerName") // - .build()); - - private static Policy createPolicy(String policyId, boolean isTransient) { - return ImmutablePolicy.builder() // - .id(policyId) // - .json("") // - .ownerServiceName("service") // - .ric(RIC_1) // - .type(POLICY_TYPE_1) // - .lastModified("now") // - .isTransient(isTransient) // - .build(); - } - - private static final Policy POLICY_1 = createPolicy("policyId1", false); - - private static final String SERVICE_1_NAME = "service1"; - private static final String SERVICE_1_CALLBACK_URL = "callbackUrl"; - private static final Service SERVICE_1 = new Service(SERVICE_1_NAME, Duration.ofSeconds(1), SERVICE_1_CALLBACK_URL); - - @Mock - private A1Client a1ClientMock; - - @Mock - private A1ClientFactory a1ClientFactoryMock; - - private PolicyTypes policyTypes; - private Policies policies; - private Services services; - - @BeforeEach - void init() { - policyTypes = new PolicyTypes(); - policies = new Policies(); - services = new Services(); - RIC_1.setState(RicState.UNAVAILABLE); - RIC_1.clearSupportedPolicyTypes(); - } - - @Test - void ricAlreadySynchronizing_thenNoSynchronization() { - RIC_1.setState(RicState.SYNCHRONIZING); - RIC_1.addSupportedPolicyType(POLICY_TYPE_1); - - policyTypes.put(POLICY_TYPE_1); - policies.put(POLICY_1); - - RicSynchronizationTask synchronizerUnderTest = - new RicSynchronizationTask(a1ClientFactoryMock, policyTypes, policies, services); - - synchronizerUnderTest.run(RIC_1); - - verifyNoInteractions(a1ClientMock); - - assertThat(policyTypes.size()).isEqualTo(1); - assertThat(policies.size()).isEqualTo(1); - assertThat(RIC_1.getState()).isEqualTo(RicState.SYNCHRONIZING); - assertThat(RIC_1.getSupportedPolicyTypeNames()).hasSize(1); - } - - @Test - void ricIdlePolicyTypeInRepo_thenSynchronizationWithReuseOfTypeFromRepoAndCorrectServiceNotified() { - RIC_1.setState(RicState.AVAILABLE); - - policyTypes.put(POLICY_TYPE_1); - - services.put(SERVICE_1); - Service serviceWithoutCallbackUrlShouldNotBeNotified = new Service("service2", Duration.ofSeconds(1), ""); - services.put(serviceWithoutCallbackUrlShouldNotBeNotified); - - setUpCreationOfA1Client(); - simulateRicWithOnePolicyType(); - - RicSynchronizationTask synchronizerUnderTest = - spy(new RicSynchronizationTask(a1ClientFactoryMock, policyTypes, policies, services)); - - AsyncRestClient restClientMock = setUpCreationOfAsyncRestClient(synchronizerUnderTest); - when(restClientMock.put(anyString(), anyString())).thenReturn(Mono.just("Ok")); - - synchronizerUnderTest.run(RIC_1); - - verify(a1ClientMock, times(1)).getPolicyTypeIdentities(); - verifyNoMoreInteractions(a1ClientMock); - - verify(synchronizerUnderTest).run(RIC_1); - verify(synchronizerUnderTest).createNotificationClient(SERVICE_1_CALLBACK_URL); - verifyNoMoreInteractions(synchronizerUnderTest); - - verify(restClientMock).put("", "Synchronization completed for:" + RIC_1_NAME); - verifyNoMoreInteractions(restClientMock); - - assertThat(policyTypes.size()).isEqualTo(1); - assertThat(policies.size()).isZero(); - assertThat(RIC_1.getState()).isEqualTo(RicState.AVAILABLE); - } - - @Test - void ricIdlePolicyTypeNotInRepo_thenSynchronizationWithTypeFromRic() throws Exception { - RIC_1.setState(RicState.AVAILABLE); - - setUpCreationOfA1Client(); - simulateRicWithOnePolicyType(); - String typeSchema = "schema"; - when(a1ClientMock.getPolicyTypeSchema(POLICY_TYPE_1_NAME)).thenReturn(Mono.just(typeSchema)); - - RicSynchronizationTask synchronizerUnderTest = - new RicSynchronizationTask(a1ClientFactoryMock, policyTypes, policies, services); - - synchronizerUnderTest.run(RIC_1); - - verify(a1ClientMock).getPolicyTypeIdentities(); - verifyNoMoreInteractions(a1ClientMock); - - assertThat(policyTypes.size()).isEqualTo(1); - assertThat(policyTypes.getType(POLICY_TYPE_1_NAME).schema()).isEqualTo(typeSchema); - assertThat(policies.size()).isZero(); - assertThat(RIC_1.getState()).isEqualTo(RicState.AVAILABLE); - } - - @Test - void ricIdleAndHavePolicies_thenSynchronizationWithRecreationOfPolicies() { - RIC_1.setState(RicState.AVAILABLE); - - Policy transientPolicy = createPolicy("transientPolicyId", true); - - policies.put(transientPolicy); - policies.put(POLICY_1); - - setUpCreationOfA1Client(); - simulateRicWithNoPolicyTypes(); - - when(a1ClientMock.deleteAllPolicies()).thenReturn(Flux.just("OK")); - when(a1ClientMock.putPolicy(any(Policy.class))).thenReturn(Mono.just("OK")); - - RicSynchronizationTask synchronizerUnderTest = - new RicSynchronizationTask(a1ClientFactoryMock, policyTypes, policies, services); - - synchronizerUnderTest.run(RIC_1); - - verify(a1ClientMock).deleteAllPolicies(); - verify(a1ClientMock).putPolicy(POLICY_1); - verifyNoMoreInteractions(a1ClientMock); - - assertThat(policyTypes.size()).isZero(); - assertThat(policies.size()).isEqualTo(1); // The transient policy shall be deleted - assertThat(RIC_1.getState()).isEqualTo(RicState.AVAILABLE); - } - - @Test - void ricIdleAndErrorDeletingPoliciesFirstTime_thenSynchronizationWithDeletionOfPolicies() { - RIC_1.setState(RicState.AVAILABLE); - - policies.put(POLICY_1); - - setUpCreationOfA1Client(); - simulateRicWithNoPolicyTypes(); - - when(a1ClientMock.deleteAllPolicies()) // - .thenReturn(Flux.error(new Exception("Exception"))) // - .thenReturn(Flux.just("OK")); - - RicSynchronizationTask synchronizerUnderTest = - new RicSynchronizationTask(a1ClientFactoryMock, policyTypes, policies, services); - - synchronizerUnderTest.run(RIC_1); - - verify(a1ClientMock, times(2)).deleteAllPolicies(); - verifyNoMoreInteractions(a1ClientMock); - - assertThat(policyTypes.size()).isZero(); - assertThat(policies.size()).isZero(); - assertThat(RIC_1.getState()).isEqualTo(RicState.AVAILABLE); - } - - @Test - void ricIdleAndErrorDeletingPoliciesAllTheTime_thenSynchronizationWithFailedRecovery() { - RIC_1.setState(RicState.AVAILABLE); - - policies.put(POLICY_1); - - setUpCreationOfA1Client(); - simulateRicWithNoPolicyTypes(); - - String originalErrorMessage = "Exception"; - when(a1ClientMock.deleteAllPolicies()).thenReturn(Flux.error(new Exception(originalErrorMessage))); - - RicSynchronizationTask synchronizerUnderTest = - new RicSynchronizationTask(a1ClientFactoryMock, policyTypes, policies, services); - - final ListAppender logAppender = - LoggingUtils.getLogListAppender(RicSynchronizationTask.class, WARN); - - synchronizerUnderTest.run(RIC_1); - - verifyCorrectLogMessage(0, logAppender, - "Synchronization failure for ric: " + RIC_1_NAME + ", reason: " + originalErrorMessage); - - verify(a1ClientMock, times(2)).deleteAllPolicies(); - verifyNoMoreInteractions(a1ClientMock); - - assertThat(policyTypes.size()).isZero(); - assertThat(policies.size()).isZero(); - assertThat(RIC_1.getState()).isEqualTo(RicState.UNAVAILABLE); - } - - @Test - void ricIdlePolicyTypeInRepo_thenSynchronizationWithErrorOnServiceNotificationErrorLogged() { - RIC_1.setState(RicState.AVAILABLE); - - policyTypes.put(POLICY_TYPE_1); - - services.put(SERVICE_1); - - setUpCreationOfA1Client(); - simulateRicWithOnePolicyType(); - - final ListAppender logAppender = - LoggingUtils.getLogListAppender(RicSynchronizationTask.class, WARN); - - RicSynchronizationTask synchronizerUnderTest = - spy(new RicSynchronizationTask(a1ClientFactoryMock, policyTypes, policies, services)); - - AsyncRestClient restClientMock = setUpCreationOfAsyncRestClient(synchronizerUnderTest); - String originalErrorMessage = "Exception"; - when(restClientMock.put(anyString(), anyString())).thenReturn(Mono.error(new Exception(originalErrorMessage))); - - synchronizerUnderTest.run(RIC_1); - - ILoggingEvent loggingEvent = logAppender.list.get(0); - assertThat(loggingEvent.getLevel()).isEqualTo(WARN); - verifyCorrectLogMessage(0, logAppender, - "Service notification failed for service: " + SERVICE_1_NAME + ". Cause: " + originalErrorMessage); - } - - private void setUpCreationOfA1Client() { - when(a1ClientFactoryMock.createA1Client(any(Ric.class))).thenReturn(Mono.just(a1ClientMock)); - doReturn(Flux.empty()).when(a1ClientMock).deleteAllPolicies(); - } - - private AsyncRestClient setUpCreationOfAsyncRestClient(RicSynchronizationTask synchronizerUnderTest) { - AsyncRestClient restClientMock = mock(AsyncRestClient.class); - doReturn(restClientMock).when(synchronizerUnderTest).createNotificationClient(anyString()); - return restClientMock; - } - - private void simulateRicWithOnePolicyType() { - when(a1ClientMock.getPolicyTypeIdentities()).thenReturn(Mono.just(Arrays.asList(POLICY_TYPE_1_NAME))); - } - - private void simulateRicWithNoPolicyTypes() { - when(a1ClientMock.getPolicyTypeIdentities()).thenReturn(Mono.just(Collections.emptyList())); - } - - private void verifyCorrectLogMessage(int messageIndex, ListAppender logAppender, - String expectedMessage) { - ILoggingEvent loggingEvent = logAppender.list.get(messageIndex); - assertThat(loggingEvent.getFormattedMessage()).isEqualTo(expectedMessage); - } -} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/tasks/ServiceSupervisionTest.java b/policy-agent/src/test/java/org/oransc/policyagent/tasks/ServiceSupervisionTest.java deleted file mode 100644 index 16313035..00000000 --- a/policy-agent/src/test/java/org/oransc/policyagent/tasks/ServiceSupervisionTest.java +++ /dev/null @@ -1,186 +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.policyagent.tasks; - -import static ch.qos.logback.classic.Level.WARN; -import static org.assertj.core.api.Assertions.assertThat; -import static org.awaitility.Awaitility.await; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoInteractions; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.core.read.ListAppender; - -import java.time.Duration; -import java.util.Collections; - -import org.awaitility.Durations; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.oransc.policyagent.clients.A1Client; -import org.oransc.policyagent.clients.A1ClientFactory; -import org.oransc.policyagent.configuration.ImmutableRicConfig; -import org.oransc.policyagent.configuration.RicConfig; -import org.oransc.policyagent.repository.ImmutablePolicy; -import org.oransc.policyagent.repository.ImmutablePolicyType; -import org.oransc.policyagent.repository.Policies; -import org.oransc.policyagent.repository.Policy; -import org.oransc.policyagent.repository.PolicyType; -import org.oransc.policyagent.repository.Ric; -import org.oransc.policyagent.repository.Service; -import org.oransc.policyagent.repository.Services; -import org.oransc.policyagent.utils.LoggingUtils; -import reactor.core.publisher.Mono; - -@ExtendWith(MockitoExtension.class) -class ServiceSupervisionTest { - - private static final String SERVICE_NAME = "Service name"; - private static final String RIC_NAME = "name"; - private static final String POLICY_ID = "policy"; - - @Mock - A1ClientFactory a1ClientFactoryMock; - @Mock - A1Client a1ClientMock; - - private Services services; - private Service service; - private Policies policies; - private RicConfig ricConfig = ImmutableRicConfig.builder() // - .name(RIC_NAME) // - .baseUrl("baseUrl") // - .managedElementIds(Collections.emptyList()) // - .controllerName("") // - .build(); - private Ric ric = new Ric(ricConfig); - private PolicyType policyType = ImmutablePolicyType.builder() // - .name("plicyTypeName") // - .schema("schema") // - .build(); - private Policy policy = ImmutablePolicy.builder() // - .id(POLICY_ID) // - .json("json") // - .ownerServiceName(SERVICE_NAME) // - .ric(ric) // - .type(policyType) // - .lastModified("lastModified") // - .isTransient(false) // - .build(); - - @Test - void serviceExpired_policyAndServiceAreDeletedInRepoAndPolicyIsDeletedInRic() { - setUpRepositoryWithKeepAliveInterval(Duration.ofSeconds(2)); - - setUpCreationOfA1Client(); - when(a1ClientMock.deletePolicy(any(Policy.class))).thenReturn(Mono.just("Policy deleted")); - - ServiceSupervision serviceSupervisionUnderTest = - new ServiceSupervision(services, policies, a1ClientFactoryMock); - - await().atMost(Durations.FIVE_SECONDS).with().pollInterval(Durations.ONE_SECOND).until(service::isExpired); - - serviceSupervisionUnderTest.checkAllServices().blockLast(); - - assertThat(policies.size()).isZero(); - assertThat(services.size()).isZero(); - - verify(a1ClientMock).deletePolicy(policy); - verifyNoMoreInteractions(a1ClientMock); - } - - @Test - void serviceExpiredButDeleteInRicFails_policyAndServiceAreDeletedInRepoAndErrorLoggedForRic() { - setUpRepositoryWithKeepAliveInterval(Duration.ofSeconds(2)); - - setUpCreationOfA1Client(); - String originalErrorMessage = "Failed"; - when(a1ClientMock.deletePolicy(any(Policy.class))).thenReturn(Mono.error(new Exception(originalErrorMessage))); - - ServiceSupervision serviceSupervisionUnderTest = - new ServiceSupervision(services, policies, a1ClientFactoryMock); - - await().atMost(Durations.FIVE_SECONDS).with().pollInterval(Durations.ONE_SECOND).until(service::isExpired); - - final ListAppender logAppender = LoggingUtils.getLogListAppender(ServiceSupervision.class, WARN); - - serviceSupervisionUnderTest.checkAllServices().blockLast(); - - assertThat(policies.size()).isZero(); - assertThat(services.size()).isZero(); - - ILoggingEvent loggingEvent = logAppender.list.get(0); - assertThat(loggingEvent.getLevel()).isEqualTo(WARN); - String expectedLogMessage = - "Could not delete policy: " + POLICY_ID + " from ric: " + RIC_NAME + ". Cause: " + originalErrorMessage; - assertThat(loggingEvent.getFormattedMessage()).isEqualTo(expectedLogMessage); - } - - @Test - void serviceNotExpired_shouldNotBeChecked() { - setUpRepositoryWithKeepAliveInterval(Duration.ofSeconds(2)); - - ServiceSupervision serviceSupervisionUnderTest = - new ServiceSupervision(services, policies, a1ClientFactoryMock); - - serviceSupervisionUnderTest.checkAllServices().blockLast(); - - assertThat(policies.size()).isEqualTo(1); - assertThat(services.size()).isEqualTo(1); - - verifyNoInteractions(a1ClientFactoryMock); - verifyNoInteractions(a1ClientMock); - } - - @Test - void serviceWithoutKeepAliveInterval_shouldNotBeChecked() { - setUpRepositoryWithKeepAliveInterval(Duration.ofSeconds(0)); - - ServiceSupervision serviceSupervisionUnderTest = - new ServiceSupervision(services, policies, a1ClientFactoryMock); - - serviceSupervisionUnderTest.checkAllServices().blockLast(); - - assertThat(policies.size()).isEqualTo(1); - assertThat(services.size()).isEqualTo(1); - - verifyNoInteractions(a1ClientFactoryMock); - verifyNoInteractions(a1ClientMock); - } - - private void setUpCreationOfA1Client() { - when(a1ClientFactoryMock.createA1Client(any(Ric.class))).thenReturn(Mono.just(a1ClientMock)); - } - - private void setUpRepositoryWithKeepAliveInterval(Duration keepAliveInterval) { - services = new Services(); - service = new Service(SERVICE_NAME, keepAliveInterval, "callbackUrl"); - services.put(service); - - policies = new Policies(); - policies.put(policy); - } -} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/utils/LoggingUtils.java b/policy-agent/src/test/java/org/oransc/policyagent/utils/LoggingUtils.java deleted file mode 100644 index a5940918..00000000 --- a/policy-agent/src/test/java/org/oransc/policyagent/utils/LoggingUtils.java +++ /dev/null @@ -1,60 +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.policyagent.utils; - -import ch.qos.logback.classic.Level; -import ch.qos.logback.classic.Logger; -import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.core.read.ListAppender; - -import org.slf4j.LoggerFactory; - -public class LoggingUtils { - - /** - * Returns a ListAppender that contains all logging events. Call this method right before calling the tested - * method. - * - * @return the log list appender for the given class. - */ - public static ListAppender getLogListAppender(Class logClass) { - return getLogListAppender(logClass, Level.ALL); - } - - /** - * Returns a ListAppender that contains events for the given level. Call this method right before calling the tested - * method. - * - * @param logClass class whose appender is wanted. - * @param level the log level to log at. - * - * @return the log list appender for the given class logging on the given level. - */ - public static ListAppender getLogListAppender(Class logClass, Level level) { - Logger logger = (Logger) LoggerFactory.getLogger(logClass); - logger.setLevel(level); - ListAppender listAppender = new ListAppender<>(); - listAppender.start(); - logger.addAppender(listAppender); - - return listAppender; - } -} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/utils/MockA1Client.java b/policy-agent/src/test/java/org/oransc/policyagent/utils/MockA1Client.java deleted file mode 100644 index fc0eba35..00000000 --- a/policy-agent/src/test/java/org/oransc/policyagent/utils/MockA1Client.java +++ /dev/null @@ -1,144 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2020 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.utils; - -import java.nio.charset.StandardCharsets; -import java.time.Duration; -import java.util.List; -import java.util.Vector; - -import org.oransc.policyagent.clients.A1Client; -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.springframework.http.HttpStatus; -import org.springframework.web.reactive.function.client.WebClientResponseException; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.core.publisher.MonoSink; - -public class MockA1Client implements A1Client { - Policies policies = new Policies(); - private final PolicyTypes policyTypes; - private final Duration asynchDelay; - - public MockA1Client(PolicyTypes policyTypes, Duration asynchDelay) { - this.policyTypes = policyTypes; - this.asynchDelay = asynchDelay; - } - - @Override - public Mono> getPolicyTypeIdentities() { - List result = new Vector<>(); - for (PolicyType p : this.policyTypes.getAll()) { - result.add(p.name()); - } - return mono(result); - } - - @Override - public Mono> getPolicyIdentities() { - Vector result = new Vector<>(); - for (Policy policy : policies.getAll()) { - result.add(policy.id()); - } - - return mono(result); - } - - @Override - public Mono getPolicyTypeSchema(String policyTypeId) { - try { - return mono(this.policyTypes.getType(policyTypeId).schema()); - } catch (Exception e) { - return Mono.error(e); - } - } - - @Override - public Mono putPolicy(Policy p) { - this.policies.put(p); - return mono("OK"); - - } - - @Override - public Mono deletePolicy(Policy policy) { - this.policies.remove(policy); - return mono("OK"); - } - - public Policies getPolicies() { - return this.policies; - } - - @Override - public Mono getProtocolVersion() { - return mono(A1ProtocolType.STD_V1_1); - } - - @Override - public Flux deleteAllPolicies() { - this.policies.clear(); - return mono("OK") // - .flatMapMany(Flux::just); - } - - @Override - public Mono getPolicyStatus(Policy policy) { - return mono("OK"); - } - - private Mono mono(T value) { - if (this.asynchDelay.isZero()) { - return Mono.just(value); - } else { - return Mono.create(monoSink -> asynchResponse(monoSink, value)); - } - } - - Mono monoError(String responseBody, HttpStatus status) { - byte[] responseBodyBytes = responseBody.getBytes(StandardCharsets.UTF_8); - WebClientResponseException a1Exception = new WebClientResponseException(status.value(), - status.getReasonPhrase(), null, responseBodyBytes, StandardCharsets.UTF_8, null); - return Mono.error(a1Exception); - } - - @SuppressWarnings("squid:S2925") // "Thread.sleep" should not be used in tests. - private void sleep() { - try { - Thread.sleep(this.asynchDelay.toMillis()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - private void asynchResponse(MonoSink callback, T str) { - Thread thread = new Thread(() -> { - sleep(); // Simulate a network delay - callback.success(str); - }); - thread.start(); - } - -} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/utils/MockA1ClientFactory.java b/policy-agent/src/test/java/org/oransc/policyagent/utils/MockA1ClientFactory.java deleted file mode 100644 index c77259c7..00000000 --- a/policy-agent/src/test/java/org/oransc/policyagent/utils/MockA1ClientFactory.java +++ /dev/null @@ -1,88 +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.policyagent.utils; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; - -import java.lang.invoke.MethodHandles; -import java.time.Duration; -import java.util.HashMap; -import java.util.Map; - -import org.oransc.policyagent.clients.A1Client; -import org.oransc.policyagent.clients.A1ClientFactory; -import org.oransc.policyagent.configuration.ApplicationConfig; -import org.oransc.policyagent.repository.PolicyTypes; -import org.oransc.policyagent.repository.Ric; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import reactor.core.publisher.Mono; - -public class MockA1ClientFactory extends A1ClientFactory { - private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - private final Map clients = new HashMap<>(); - private PolicyTypes policyTypes; - private Duration asynchDelay = Duration.ofSeconds(0); - - public MockA1ClientFactory(PolicyTypes policyTypes) { - super(mock(ApplicationConfig.class)); - this.policyTypes = policyTypes; - } - - @Override - public Mono createA1Client(Ric ric) { - return Mono.just(getOrCreateA1Client(ric.name())); - } - - public MockA1Client getOrCreateA1Client(String ricName) { - if (!clients.containsKey(ricName)) { - logger.debug("Creating client for RIC: {}", ricName); - MockA1Client client = spy(new MockA1Client(policyTypes, asynchDelay)); - clients.put(ricName, client); - } - return clients.get(ricName); - } - - public void setPolicyTypes(PolicyTypes policyTypes) { - this.policyTypes = policyTypes; - } - - /** - * Simulate network latency. The REST responses will be generated by separate - * threads - * - * @param delay the delay between the request and the response - */ - public void setResponseDelay(Duration delay) { - this.asynchDelay = delay; - } - - public void reset() { - this.asynchDelay = Duration.ofSeconds(0); - clients.clear(); - } - - public PolicyTypes getPolicyTypes() { - return this.policyTypes; - } - -} diff --git a/policy-agent/src/test/resources/policy_types/demo-policy-schema-1.json b/policy-agent/src/test/resources/policy_types/demo-policy-schema-1.json deleted file mode 100644 index 02bc8645..00000000 --- a/policy-agent/src/test/resources/policy_types/demo-policy-schema-1.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "STD_PolicyModelUnconstrained_0.2.0", - "description": "Standard model of a policy with unconstrained scope id combinations", - "type": "object", - "properties": { - "scope": { - "type": "object", - "properties": { - "ueId": {"type": "string"}, - "groupId": {"type": "string"}, - "sliceId": {"type": "string"}, - "qosId": {"type": "string"}, - "cellId": {"type": "string"} - }, - "minProperties": 1, - "additionalProperties": false - }, - "qosObjectives": { - "type": "object", - "properties": { - "gfbr": {"type": "number"}, - "mfbr": {"type": "number"}, - "priorityLevel": {"type": "number"}, - "pdb": {"type": "number"} - }, - "additionalProperties": false - }, - "qoeObjectives": { - "type": "object", - "properties": { - "qoeScore": {"type": "number"}, - "initialBuffering": {"type": "number"}, - "reBuffFreq": {"type": "number"}, - "stallRatio": {"type": "number"} - }, - "additionalProperties": false - }, - "resources": { - "type": "array", - "items": { - "type": "object", - "properties": { - "cellIdList": { - "type": "array", - "minItems": 1, - "uniqueItems": true, - "items": { - "type": "string" - } - }, - "preference": { - "type": "string", - "enum": [ - "SHALL", - "PREFER", - "AVOID", - "FORBID" - ] - }, - "primary": {"type": "boolean"} - }, - "additionalProperties": false, - "required": ["cellIdList", "preference"] - } - } - }, - "minProperties": 2, - "additionalProperties": false, - "required": ["scope"] -} diff --git a/policy-agent/src/test/resources/policy_types/demo-policy-schema-2.json b/policy-agent/src/test/resources/policy_types/demo-policy-schema-2.json deleted file mode 100644 index f3eb28fb..00000000 --- a/policy-agent/src/test/resources/policy_types/demo-policy-schema-2.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Example_QoETarget_1.0.0", - "description": "Example QoE Target policy type", - "type": "object", - "properties": { - "scope": { - "type": "object", - "properties": { - "ueId": { - "type": "string" - }, - "sliceId": { - "type": "string" - }, - "qosId": { - "type": "string" - }, - "cellId": { - "type": "string" - } - }, - "additionalProperties": false, - "required": [ - "ueId", - "sliceId" - ] - }, - "statement": { - "type": "object", - "properties": { - "qoeScore": { - "type": "number" - }, - "initialBuffering": { - "type": "number" - }, - "reBuffFreq": { - "type": "number" - }, - "stallRatio": { - "type": "number" - } - }, - "minProperties": 1, - "additionalProperties": false - } - } -} \ No newline at end of file diff --git a/policy-agent/src/test/resources/policy_types/demo-policy-schema-3.json b/policy-agent/src/test/resources/policy_types/demo-policy-schema-3.json deleted file mode 100644 index a73dd590..00000000 --- a/policy-agent/src/test/resources/policy_types/demo-policy-schema-3.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ERIC_QoSNudging_0.2.0", - "description": "QoS nudging policy type with priorityLevel and ueId and qosId as scope", - "type": "object", - "properties": { - "scope": { - "type": "object", - "properties": { - "ueId": {"type": "string"}, - "qosId": {"type": "string"} - }, - "additionalProperties": false, - "required": ["ueId", "qosId"] - }, - "qosObjectives": { - "type": "object", - "properties": { - "priorityLevel": {"type": "number"} - }, - "additionalProperties": false, - "required": ["priorityLevel"] - } - }, - "additionalProperties": false, - "required": ["scope", "qosObjectives"] -} diff --git a/policy-agent/src/test/resources/test_application_configuration.json b/policy-agent/src/test/resources/test_application_configuration.json deleted file mode 100644 index 3cbc371c..00000000 --- a/policy-agent/src/test/resources/test_application_configuration.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "config": { - "//description": "Application configuration", - "ric": [ - { - "name": "ric1", - "baseUrl": "http://localhost:8080/", - "managedElementIds": [ - "kista_1", - "kista_2" - ] - }, - { - "name": "ric2", - "baseUrl": "http://localhost:8081/", - "managedElementIds": [ - "kista_3", - "kista_4" - ] - } - ], - "streams_publishes": { - "dmaap_publisher": { - "type": "message_router", - "dmaap_info": { - "topic_url": "http://admin:admin@localhost:6845/events/A1-POLICY-AGENT-WRITE" - } - } - }, - "streams_subscribes": { - "dmaap_subscriber": { - "type": "message_router", - "dmaap_info": { - "topic_url": "http://admin:admin@localhost:6845/events/A1-POLICY-AGENT-READ/users/policy-agent?timeout=15000&limit=100" - } - } - } - } -} \ No newline at end of file diff --git a/policy-agent/src/test/resources/test_application_configuration_with_dmaap_config.json b/policy-agent/src/test/resources/test_application_configuration_with_dmaap_config.json deleted file mode 100644 index 61ab31e8..00000000 --- a/policy-agent/src/test/resources/test_application_configuration_with_dmaap_config.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "config": { - "controller": [ - { - "name": "controller1", - "baseUrl": "http://localhost:8083/", - "userName": "user", - "password": "password" - } - ], - "ric": [ - { - "name": "ric1", - "controller": "controller1", - "baseUrl": "http://localhost:8083/", - "managedElementIds": [ - "kista_1", - "kista_2" - ] - }, - { - "name": "ric2", - "baseUrl": "http://localhost:8085/", - "managedElementIds": [ - "kista_3", - "kista_4" - ] - } - ], - "streams_publishes": { - "dmaap_publisher": { - "type": "message_router", - "dmaap_info": { - "topic_url": "http://admin:admin@localhost:6845/events/A1-POLICY-AGENT-WRITE" - } - } - }, - "streams_subscribes": { - "dmaap_subscriber": { - "type": "message_router", - "dmaap_info": { - "topic_url": "http://admin:admin@localhost:6845/events/A1-POLICY-AGENT-READ/users/policy-agent?timeout=15000&limit=100" - } - } - } - } -} \ No newline at end of file diff --git a/policy-agent/src/test/resources/test_osc_get_schema_response.json b/policy-agent/src/test/resources/test_osc_get_schema_response.json deleted file mode 100644 index 537d86f7..00000000 --- a/policy-agent/src/test/resources/test_osc_get_schema_response.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "name": "pt1", - "description": "pt1 policy type", - "policy_type_id": 1, - "create_schema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OSC_Type1_1.0.0", - "description": "Type 1 policy type", - "type": "object", - "properties": { - "scope": { - "type": "object", - "properties": { - "ueId": { - "type": "string" - }, - "qosId": { - "type": "string" - } - }, - "additionalProperties": false, - "required": [ - "ueId", - "qosId" - ] - }, - "qosObjective": { - "type": "object", - "properties": { - "priorityLevel": { - "type": "number" - } - }, - "additionalProperties": false, - "required": [ - "priorityLevel" - ] - } - }, - "additionalProperties": false, - "required": [ - "scope", "qosObjective" - ] - } -} diff --git a/pom.xml b/pom.xml index f21502fe..92d50a61 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,6 @@ policy-agent - sdnc-a1-controller enrichment-coordinator-service r-app-catalogue