From 97ace6245fb8b7238d2f7f871797ba03df2d435f Mon Sep 17 00:00:00 2001 From: PatrikBuhr Date: Wed, 11 May 2022 13:10:40 +0200 Subject: NONRTRIC PMS, Cherry-pick the recent changes into Jakarta Release Sqasch of cherrypicked commits for the maintenance release. Issue-ID: CCSDK-3742 Signed-off-by: PatrikBuhr NONRTRIC PMS added support for custom A1 adapters Added support for added external A1-P adapter. This makes it possible to design and include adapter to APIs for accessing of A1 policies (in a NearRT-RIC) without any changes in this SW. Issue-ID: CCSDK-3655 Signed-off-by: PatrikBuhr NONRTRIC PMS added support for custom A1 adapters Updates of the json schema for configuration. Made it stricter and added the customAdapterClass prpoperty. Issue-ID: CCSDK-3655 Signed-off-by: PatrikBuhr NONRTRIC PMS removalof usage of immutable Issue-ID: CCSDK-3629 Signed-off-by: PatrikBuhr NONRTRIC PMS, Sporadic instability Attempt to stablize the synch. Issue-ID: CCSDK-3683 Signed-off-by: PatrikBuhr NONRTRIC PMS, Sporadic instability Attempt to stablize the synch. Issue-ID: CCSDK-3683 Signed-off-by: PatrikBuhr NONRTRIC PMS, Sporadic instability Some further simplifications and added test. Issue-ID: CCSDK-3683 Signed-off-by: PatrikBuhr Change-Id: I1ec98017d63047a0036db5ea12f770db00b1152b NONRTRIC PMS, updated SDNC rest interface Update path and output-json for SDNC rest interface - A1 Kohn Issue-ID: CCSDK-3193 Signed-off-by: PatrikBuhr NONRTRIC PMS, Bugfix If the auth-token-file parameter in the file application.yaml is missing, it would not default to an empty file name. Issue-ID: CCSDK-3683 Signed-off-by: PatrikBuhr NONRTRIC PMS, updated certs Updated certificate (which was expired). Issue-ID: CCSDK-3683 Signed-off-by: PatrikBuhr Change-Id: I34ffc932d855ba3b94cfff23dcb56f30780dbecc --- a1-policy-management/README.md | 2 +- a1-policy-management/api/pms-api.json | 6 +- a1-policy-management/api/pms-api.yaml | 23 +++--- a1-policy-management/config/README | 6 +- a1-policy-management/config/application.yaml | 3 +- .../config/application_configuration.json | 23 +++++- a1-policy-management/config/keystore.jks | Bin 4779 -> 5269 bytes a1-policy-management/config/truststore.jks | Bin 3587 -> 3869 bytes a1-policy-management/pom.xml | 25 +++--- .../a1policymanagementservice/SwaggerConfig.java | 3 +- .../clients/A1AdapterJsonHelper.java | 9 +- .../clients/A1Client.java | 8 +- .../clients/A1ClientFactory.java | 32 ++++++-- .../clients/AsyncRestClient.java | 6 +- .../clients/AsyncRestClientFactory.java | 14 ++-- .../clients/CcsdkA1AdapterClient.java | 74 +++++++++-------- .../clients/OscA1Client.java | 4 +- .../clients/SecurityContext.java | 4 +- .../clients/StdA1ClientVersion1.java | 2 +- .../clients/StdA1ClientVersion2.java | 11 ++- .../configuration/ApplicationConfig.java | 22 ++--- .../configuration/ApplicationConfigParser.java | 68 ++++++++------- .../configuration/ControllerConfig.java | 25 +++--- .../configuration/RicConfig.java | 27 ++++-- .../configuration/WebClientConfig.java | 43 +++++----- .../controllers/ServiceCallbackInfo.java | 4 - .../controllers/VoidResponse.java | 3 - .../controllers/v2/PolicyController.java | 4 + .../controllers/v2/PolicyIdList.java | 3 - .../controllers/v2/PolicyInfo.java | 3 - .../controllers/v2/PolicyInfoList.java | 3 - .../controllers/v2/PolicyStatusInfo.java | 3 - .../controllers/v2/PolicyTypeIdList.java | 3 - .../controllers/v2/PolicyTypeInfo.java | 3 - .../controllers/v2/RicInfo.java | 4 - .../controllers/v2/RicInfoList.java | 3 - .../controllers/v2/ServiceRegistrationInfo.java | 3 - .../controllers/v2/ServiceStatus.java | 3 - .../controllers/v2/ServiceStatusList.java | 3 - .../controllers/v2/StatusController.java | 2 - .../a1policymanagementservice/repository/Ric.java | 24 ++++-- .../tasks/RefreshConfigTask.java | 49 ++--------- .../tasks/RicSupervision.java | 86 +++++++++---------- .../tasks/RicSynchronizationTask.java | 91 +++++++++------------ .../application_configuration_schema.json | 23 ++++-- .../MockPolicyManagementService.java | 3 - .../clients/A1ClientFactoryTest.java | 51 ++++++++++-- .../clients/A1ClientHelper.java | 4 +- .../clients/CcsdkA1AdapterClientTest.java | 55 ++++--------- .../clients/OscA1ClientTest.java | 6 +- .../clients/StdA1ClientTest.java | 8 +- .../clients/StdA1ClientV2Test.java | 6 +- .../configuration/ApplicationConfigParserTest.java | 14 ++-- .../configuration/ApplicationConfigTest.java | 25 ++---- .../controllers/v2/ApplicationTest.java | 44 +++++----- .../v2/ConfigurationControllerTest.java | 20 ++--- .../tasks/RefreshConfigTaskTest.java | 12 +-- .../tasks/RicSupervisionTest.java | 43 +++++----- .../tasks/RicSynchronizationTaskTest.java | 89 ++++++++------------ .../tasks/ServiceSupervisionTest.java | 6 +- .../utils/MockA1Client.java | 24 ++++-- .../src/test/resources/keystore.jks | Bin 5019 -> 0 bytes .../resources/test_application_configuration.json | 3 +- ...pplication_configuration_with_dmaap_config.json | 5 +- .../src/test/resources/truststore.jks | Bin 3699 -> 0 bytes docs/offeredapis/swagger/pms-api.json | 6 +- docs/offeredapis/swagger/pms-api.yaml | 23 +++--- 67 files changed, 602 insertions(+), 605 deletions(-) delete mode 100644 a1-policy-management/src/test/resources/keystore.jks delete mode 100644 a1-policy-management/src/test/resources/truststore.jks diff --git a/a1-policy-management/README.md b/a1-policy-management/README.md index 5c619c23..c25b29d8 100644 --- a/a1-policy-management/README.md +++ b/a1-policy-management/README.md @@ -75,7 +75,7 @@ Sample Response Message to DMaaP: ## License ONAP : ccsdk oran -Copyright (C) 2019-2020 Nordix Foundation. All rights reserved. +Copyright (C) 2019-2022 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 diff --git a/a1-policy-management/api/pms-api.json b/a1-policy-management/api/pms-api.json index 9fc8e7bb..5c5915c5 100644 --- a/a1-policy-management/api/pms-api.json +++ b/a1-policy-management/api/pms-api.json @@ -79,7 +79,7 @@ }, "keep_alive_interval_seconds": { "format": "int64", - "description": "keep alive interval for the service. This is a heartbeat supervision of the service, which in regular intervals must invoke a 'keepalive' REST call. When a service does not invoke this call within the given time, it is considered unavailable. An unavailable service will be automatically deregistered and its policies will be deleted. Value 0 means no timeout supervision.", + "description": "keep alive interval for the service. This is used to enable optional heartbeat supervision of the service. If set (> 0) the registered service should regularly invoke a 'keepalive' REST call. When a service fails to invoke this 'keepalive' call within the configured time, the service is considered unavailable. An unavailable service will be automatically deregistered and its policies will be deleted. Value 0 means timeout supervision is disabled.", "type": "integer" } } @@ -559,7 +559,7 @@ }, "/a1-policy/v2/services/{service_id}/keepalive": {"put": { "summary": "Heartbeat indicates that the service is running", - "description": "A registered service must call this in regular intervals to indicate that it is in operation. Absence of this call will lead to that the service will be deregistered and all its policies are removed.", + "description": "A registered service should invoke this operation regularly to indicate that it is still alive. If a registered service fails to invoke this operation before the end of a timeout period the service will be deregistered and all its A1 policies wil be removed. (This timeout can be set or disabled when each service is initially registered)", "operationId": "keepAliveService", "responses": { "200": { @@ -868,7 +868,7 @@ "url": "http://www.apache.org/licenses/LICENSE-2.0" }, "description": "

General<\/h2>

The O-RAN Non-RT RIC Policy Management Service provides a REST API for management of A1 policies.
The main tasks of the service are:<\/p>

  • A1 Policy creation, modification and deletion.<\/li>
  • Monitoring and maintaining consistency of the SMO view of A1 policies and the Near-RT RICs<\/li>
  • Maintaining a view of supported Near-RT RIC policy types<\/li>
  • Supervision of using services (R-APPs). When a service is unavailable, its policies are removed.<\/li><\/ul>

    APIs provided by the service<\/h2>

    A1 Policy Management<\/h3>

    This is an API for management of A1 Policies.<\/p>

    • A1 Policy retrieval, creation, modification and deletion.<\/li>
    • Retrieval of supported A1 Policy types for a Near-RT RIC<\/li>
    • Retrieval of status for existing A1 policies<\/li><\/ul>

      Management of configuration<\/h3>

      API for updating and retrieval of the component configuration. Note that there other ways to maintain the configuration.<\/p>

      Callbacks<\/h3>

      These are endpoints that are invoked by this service. The callbacks are registered in this service at service registration.<\/p>

      NearRT-RIC Repository<\/h3>

      This is an API that provides support for looking up a NearRT-RIC. Each A1 policy is targeted for one Near-RT RIC.<\/p>

      Health Check<\/h3>

      API used for supervision of the PMS component.<\/p>

      Service Registry and Supervision<\/h3>

      API used for registering services that uses PMS. Each A1 policy is owned by a service. PMS can supervise each registered service and will automatically remove policies for unavailable services.<\/p>", - "title": "A1 Policy management service", + "title": "A1 Policy Management Service", "version": "1.1.0" }, "tags": [ diff --git a/a1-policy-management/api/pms-api.yaml b/a1-policy-management/api/pms-api.yaml index 3fd496bd..1f84399e 100644 --- a/a1-policy-management/api/pms-api.yaml +++ b/a1-policy-management/api/pms-api.yaml @@ -1,6 +1,6 @@ openapi: 3.0.1 info: - title: A1 Policy management service + title: A1 Policy Management Service description:

      General

      The O-RAN Non-RT RIC Policy Management Service provides a REST API for management of A1 policies.
      The main tasks of the service are:

      • A1 Policy creation, modification and deletion.
      • Monitoring and maintaining @@ -434,9 +434,11 @@ paths: tags: - Service Registry and Supervision summary: Heartbeat indicates that the service is running - description: A registered service must call this in regular intervals to indicate - that it is in operation. Absence of this call will lead to that the service - will be deregistered and all its policies are removed. + description: A registered service should invoke this operation regularly to + indicate that it is still alive. If a registered service fails to invoke this + operation before the end of a timeout period the service will be deregistered + and all its A1 policies wil be removed. (This timeout can be set or disabled + when each service is initially registered) operationId: keepAliveService parameters: - name: service_id @@ -896,12 +898,13 @@ components: description: identity of the service keep_alive_interval_seconds: type: integer - description: keep alive interval for the service. This is a heartbeat supervision - of the service, which in regular intervals must invoke a 'keepalive' REST - call. When a service does not invoke this call within the given time, - it is considered unavailable. An unavailable service will be automatically - deregistered and its policies will be deleted. Value 0 means no timeout - supervision. + description: keep alive interval for the service. This is used to enable + optional heartbeat supervision of the service. If set (> 0) the registered + service should regularly invoke a 'keepalive' REST call. When a service + fails to invoke this 'keepalive' call within the configured time, the + service is considered unavailable. An unavailable service will be automatically + deregistered and its policies will be deleted. Value 0 means timeout supervision + is disabled. format: int64 description: Information for one service policy_info_list_v2: diff --git a/a1-policy-management/config/README b/a1-policy-management/config/README index b54a6751..42e0b7bd 100644 --- a/a1-policy-management/config/README +++ b/a1-policy-management/config/README @@ -3,13 +3,15 @@ The keystore.jks and truststore.jks files are created by using the following com 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 +openssl req -new -key CA-key.pem -x509 -days 3600 -out CA-cert.pem 2) Create a keystore with a private key entry that is signed by the CA: +Note: the "your name" must be "localhost" for the unittest to work. + 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 +openssl x509 -req -days 3650 -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 diff --git a/a1-policy-management/config/application.yaml b/a1-policy-management/config/application.yaml index 7628624d..f0f53375 100644 --- a/a1-policy-management/config/application.yaml +++ b/a1-policy-management/config/application.yaml @@ -56,6 +56,8 @@ server: key-store: /opt/app/policy-agent/etc/cert/keystore.jks key-password: policy_agent key-alias: policy_agent + # trust-store-password: + # trust-store: app: # Location of the component configuration file. filepath: /opt/app/policy-agent/data/application_configuration.json @@ -80,4 +82,3 @@ app: # A file containing an authorization token, which shall be inserted in each HTTP header (authorization). # If the file name is empty, no authorization token is sent. auth-token-file: - diff --git a/a1-policy-management/config/application_configuration.json b/a1-policy-management/config/application_configuration.json index 6187c866..29d59232 100644 --- a/a1-policy-management/config/application_configuration.json +++ b/a1-policy-management/config/application_configuration.json @@ -1,6 +1,6 @@ { "description": "Application configuration", - "config": { + "config": { "controller": [ { "name": "controller1", @@ -13,12 +13,29 @@ { "name": "ric1", "baseUrl": "http://ric1:8085/", - "controller": "controller1", "managedElementIds": [ "kista_1", "kista_2" ] + }, + { + "name": "ric2", + "baseUrl": "http://localhost:8081/", + "customAdapterClass": "org.onap.ccsdk.oran.a1policymanagementservice.clients.StdA1ClientVersion2$Factory", + "managedElementIds": [ + "kista_3", + "kista_4" + ] + }, + { + "name": "ric3", + "baseUrl": "http://ric1:8085/", + "controller": "controller1", + "managedElementIds": [ + "kista_5", + "kista_6" + ] } ] } -} +} \ No newline at end of file diff --git a/a1-policy-management/config/keystore.jks b/a1-policy-management/config/keystore.jks index 48c3b33c..563c67b3 100644 Binary files a/a1-policy-management/config/keystore.jks and b/a1-policy-management/config/keystore.jks differ diff --git a/a1-policy-management/config/truststore.jks b/a1-policy-management/config/truststore.jks index 760261eb..50a0f9e9 100644 Binary files a/a1-policy-management/config/truststore.jks and b/a1-policy-management/config/truststore.jks differ diff --git a/a1-policy-management/pom.xml b/a1-policy-management/pom.xml index da44d2a0..be981787 100644 --- a/a1-policy-management/pom.xml +++ b/a1-policy-management/pom.xml @@ -35,7 +35,7 @@ 11 11 3.0.0 - 2.9.0 + 2.9.0 20220320 2.13.0 2.5.0 @@ -49,11 +49,6 @@ ${project.version} - - org.springdoc - springdoc-openapi-ui - 1.6.6 - org.springframework.boot spring-boot @@ -122,15 +117,9 @@ guava - org.immutables - value - ${immutable.version} - provided - - - org.immutables + com.google.code.gson gson - ${immutable.version} + ${gson.version} org.json @@ -174,6 +163,12 @@ runtime + + org.springdoc + springdoc-openapi-ui + 1.6.6 + test + org.springframework.boot spring-boot-test @@ -430,4 +425,4 @@ - + \ No newline at end of file diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/SwaggerConfig.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/SwaggerConfig.java index 774b2363..4e4ec2d5 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/SwaggerConfig.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/SwaggerConfig.java @@ -60,7 +60,8 @@ public class SwaggerConfig { "
      • A1 Policy creation, modification and deletion.
      • " + // "
      • Monitoring and maintaining consistency of the SMO view of A1 policies and the Near-RT RICs
      • " + // "
      • Maintaining a view of supported Near-RT RIC policy types
      • " + // - "
      • Supervision of using services (R-APPs). When a service is unavailable, its policies are removed.
      • " + // + "
      • Supervision of using services (R-APPs). When a service is unavailable, its policies are removed.
      • " + + // "
      " + // "

      APIs provided by the service

      " + // H3 + PolicyController.API_NAME + H3_END + // diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1AdapterJsonHelper.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1AdapterJsonHelper.java index d4c264da..60dca3b4 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1AdapterJsonHelper.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1AdapterJsonHelper.java @@ -31,7 +31,6 @@ 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; @@ -47,7 +46,7 @@ class A1AdapterJsonHelper { private static Gson gson = new GsonBuilder() // .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES) // .create(); - private static final String OUTPUT = "output"; + private static final String OUTPUT = "A1-ADAPTER-API:output"; private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private A1AdapterJsonHelper() {} @@ -63,7 +62,7 @@ class A1AdapterJsonHelper { } } return Flux.fromIterable(arrayList); - } catch (JSONException ex) { // invalid json + } catch (Exception ex) { // invalid json logger.debug("Invalid json {}", ex.getMessage()); return Flux.error(ex); } @@ -88,7 +87,7 @@ class A1AdapterJsonHelper { JSONObject outputJson = new JSONObject(response); JSONObject responseParams = outputJson.getJSONObject(OUTPUT); return Mono.just(responseParams); - } catch (JSONException ex) { // invalid json + } catch (Exception ex) { // invalid json logger.debug("Invalid json {}", ex.getMessage()); return Mono.error(ex); } @@ -110,7 +109,7 @@ class A1AdapterJsonHelper { JSONObject schemaObject = jsonObject.getJSONObject("policySchema"); String schemaString = schemaObject.toString(); return Mono.just(schemaString); - } catch (JSONException ex) { // invalid json + } catch (Exception ex) { // invalid json logger.debug("Invalid json {}", ex.getMessage()); return Mono.error(ex); } diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1Client.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1Client.java index 5e498e4b..a691ee1e 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1Client.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1Client.java @@ -22,6 +22,7 @@ package org.onap.ccsdk.oran.a1policymanagementservice.clients; import java.util.List; +import org.onap.ccsdk.oran.a1policymanagementservice.configuration.RicConfig; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policy; import reactor.core.publisher.Flux; @@ -33,6 +34,10 @@ import reactor.core.publisher.Mono; */ public interface A1Client { + public interface Factory { + A1Client create(RicConfig ricConfig, AsyncRestClientFactory restClientFactory); + } + public enum A1ProtocolType { UNKNOWN, // STD_V1_1, // STD A1 version 1.1 @@ -40,7 +45,8 @@ public interface A1Client { OSC_V1, // OSC 'A1' CCSDK_A1_ADAPTER_STD_V1_1, // CCSDK_A1_ADAPTER with STD A1 version 1.1 southbound CCSDK_A1_ADAPTER_STD_V2_0_0, // CCSDK_A1_ADAPTER with STD A1 version 2.0.0 southbound - CCSDK_A1_ADAPTER_OSC_V1 // CCSDK_A1_ADAPTER with OSC 'A1' southbound + CCSDK_A1_ADAPTER_OSC_V1, // CCSDK_A1_ADAPTER with OSC 'A1' southbound + CUSTOM_PROTOCOL // Some other protocol handled by some custom A1 adapter class. } public Mono getProtocolVersion(); diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactory.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactory.java index 1d465c3a..75ba2515 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactory.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactory.java @@ -20,9 +20,12 @@ package org.onap.ccsdk.oran.a1policymanagementservice.clients; +import java.lang.reflect.Constructor; + import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1Client.A1ProtocolType; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ControllerConfig; +import org.onap.ccsdk.oran.a1policymanagementservice.configuration.RicConfig; import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.ServiceException; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Ric; import org.slf4j.Logger; @@ -83,6 +86,8 @@ public class A1ClientFactory { || version == A1ProtocolType.CCSDK_A1_ADAPTER_OSC_V1 || version == A1ProtocolType.CCSDK_A1_ADAPTER_STD_V2_0_0) { return new CcsdkA1AdapterClient(version, ric.getConfig(), getControllerConfig(ric), this.restClientFactory); + } else if (version == A1ProtocolType.CUSTOM_PROTOCOL) { + return createCustomAdapter(ric); } else { logger.error("Unhandled protocol: {}", version); throw new ServiceException("Unhandled protocol"); @@ -90,7 +95,7 @@ public class A1ClientFactory { } private ControllerConfig getControllerConfig(Ric ric) throws ServiceException { - String controllerName = ric.getConfig().controllerName(); + String controllerName = ric.getConfig().getControllerName(); if (controllerName.isEmpty()) { ric.setProtocolVersion(A1ProtocolType.UNKNOWN); throw new ServiceException("No controller configured for Near-RT RIC: " + ric.id()); @@ -103,8 +108,27 @@ public class A1ClientFactory { } } + private A1Client createCustomAdapter(Ric ric) throws ServiceException { + try { + Class clazz = Class.forName(ric.getConfig().getCustomAdapterClass()); + if (A1Client.class.isAssignableFrom(clazz)) { + Constructor constructor = clazz.getConstructor(RicConfig.class, AsyncRestClientFactory.class); + return (A1Client) constructor.newInstance(ric.getConfig(), this.restClientFactory); + } else if (A1Client.Factory.class.isAssignableFrom(clazz)) { + A1Client.Factory factory = (A1Client.Factory) clazz.getDeclaredConstructor().newInstance(); + return factory.create(ric.getConfig(), this.restClientFactory); + } else { + throw new ServiceException("The custom class must either implement A1Client.Factory or A1Client"); + } + } catch (ClassNotFoundException e) { + throw new ServiceException("Could not find class: " + ric.getConfig().getCustomAdapterClass(), e); + } catch (Exception e) { + throw new ServiceException("Cannot create custom adapter: " + ric.getConfig().getCustomAdapterClass(), e); + } + } + private void assertNoControllerConfig(Ric ric, A1ProtocolType version) throws ServiceException { - if (!ric.getConfig().controllerName().isEmpty()) { + if (!ric.getConfig().getControllerName().isEmpty()) { ric.setProtocolVersion(A1ProtocolType.UNKNOWN); throw new ServiceException( "Controller config should be empty, ric: " + ric.id() + " when using protocol version: " + version); @@ -128,9 +152,7 @@ public class A1ClientFactory { .doOnNext(ric::setProtocolVersion) .doOnNext(version -> logger.debug("Established protocol version:{} for Near-RT RIC: {}", version, ric.id())) // - .doOnError(notUsed -> logger.warn("Could not get protocol version from Near-RT RIC: {}", ric.id())) // - .onErrorResume( - notUsed -> Mono.error(new ServiceException("Protocol negotiation failed for " + ric.id()))); + .doOnError(notUsed -> logger.warn("Could not get protocol version from Near-RT RIC: {}", ric.id())); } else { return Mono.just(ric.getProtocolVersion()); } diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/AsyncRestClient.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/AsyncRestClient.java index 959d85e2..c4afdb2f 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/AsyncRestClient.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/AsyncRestClient.java @@ -154,8 +154,8 @@ public class AsyncRestClient { } private boolean isHttpProxyConfigured() { - return httpProxyConfig != null && httpProxyConfig.httpProxyPort() > 0 - && !httpProxyConfig.httpProxyHost().isEmpty(); + return httpProxyConfig != null && httpProxyConfig.getHttpProxyPort() > 0 + && !httpProxyConfig.getHttpProxyHost().isEmpty(); } private HttpClient buildHttpClient() { @@ -172,7 +172,7 @@ public class AsyncRestClient { if (isHttpProxyConfigured()) { httpClient = httpClient.proxy(proxy -> proxy.type(ProxyProvider.Proxy.HTTP) - .host(httpProxyConfig.httpProxyHost()).port(httpProxyConfig.httpProxyPort())); + .host(httpProxyConfig.getHttpProxyHost()).port(httpProxyConfig.getHttpProxyPort())); } return httpClient; } diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/AsyncRestClientFactory.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/AsyncRestClientFactory.java index 844db540..204af9c0 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/AsyncRestClientFactory.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/AsyncRestClientFactory.java @@ -60,7 +60,7 @@ public class AsyncRestClientFactory { public AsyncRestClientFactory(WebClientConfig clientConfig, SecurityContext securityContext) { if (clientConfig != null) { this.sslContextFactory = new CachingSslContextFactory(clientConfig); - this.httpProxyConfig = clientConfig.httpProxyConfig(); + this.httpProxyConfig = clientConfig.getHttpProxyConfig(); } else { logger.warn("No configuration for web client defined, HTTPS will not work"); this.sslContextFactory = null; @@ -105,8 +105,8 @@ public class AsyncRestClientFactory { private SslContext createSslContext(KeyManagerFactory keyManager) throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException { if (this.clientConfig.isTrustStoreUsed()) { - return createSslContextRejectingUntrustedPeers(this.clientConfig.trustStore(), - this.clientConfig.trustStorePassword(), keyManager); + return createSslContextRejectingUntrustedPeers(this.clientConfig.getTrustStore(), + this.clientConfig.getTrustStorePassword(), keyManager); } else { // Trust anyone return SslContextBuilder.forClient() // @@ -154,10 +154,10 @@ public class AsyncRestClientFactory { private KeyManagerFactory createKeyManager() throws NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableKeyException, KeyStoreException { 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(); + final KeyStore keyStore = KeyStore.getInstance(this.clientConfig.getKeyStoreType()); + final String keyStoreFile = this.clientConfig.getKeyStore(); + final String keyStorePassword = this.clientConfig.getKeyStorePassword(); + final String keyPassword = this.clientConfig.getKeyPassword(); try (final InputStream inputStream = new FileInputStream(keyStoreFile)) { keyStore.load(inputStream, keyStorePassword.toCharArray()); } diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/CcsdkA1AdapterClient.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/CcsdkA1AdapterClient.java index c3f00407..df6faade 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/CcsdkA1AdapterClient.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/CcsdkA1AdapterClient.java @@ -29,10 +29,12 @@ import java.util.Arrays; import java.util.List; import java.util.Optional; -import org.immutables.value.Value; +import lombok.Getter; + import org.json.JSONObject; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ControllerConfig; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.RicConfig; +import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.ServiceException; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,20 +52,30 @@ public class CcsdkA1AdapterClient implements A1Client { static final int CONCURRENCY_RIC = 1; // How many paralell requests that is sent to one NearRT RIC - @Value.Immutable - @org.immutables.gson.Gson.TypeAdapters - public interface AdapterRequest { - public String nearRtRicUrl(); + @Getter + public static class AdapterRequest { + private String nearRtRicUrl = null; + private String body = null; + + public AdapterRequest(String url, String body) { + this.nearRtRicUrl = url; + this.body = body; + } - public Optional body(); + public AdapterRequest() {} } - @Value.Immutable - @org.immutables.gson.Gson.TypeAdapters - public interface AdapterOutput { - public Optional body(); + @Getter + public static class AdapterOutput { + private String body = null; + private int httpStatus = 0; + + public AdapterOutput(int status, String body) { + this.httpStatus = status; + this.body = body; + } - public int httpStatus(); + public AdapterOutput() {} } static com.google.gson.Gson gson = new GsonBuilder() // @@ -93,7 +105,7 @@ public class CcsdkA1AdapterClient implements A1Client { public CcsdkA1AdapterClient(A1ProtocolType protocolType, RicConfig ricConfig, ControllerConfig controllerConfig, AsyncRestClientFactory restClientFactory) { this(protocolType, ricConfig, controllerConfig, - restClientFactory.createRestClientNoHttpProxy(controllerConfig.baseUrl() + "/restconf/operations")); + restClientFactory.createRestClientNoHttpProxy(controllerConfig.getBaseUrl() + "/rests/operations")); } /** @@ -119,11 +131,11 @@ public class CcsdkA1AdapterClient implements A1Client { this.ricConfig = ricConfig; this.protocolType = protocolType; this.controllerConfig = controllerConfig; - logger.debug("CcsdkA1AdapterClient for ric: {}, a1Controller: {}", ricConfig.ricId(), controllerConfig); + logger.debug("CcsdkA1AdapterClient for ric: {}, a1Controller: {}", ricConfig.getRicId(), controllerConfig); } else { + logger.error("Not supported protocoltype: {}", protocolType); throw new IllegalArgumentException("Not handeled protocolversion: " + protocolType); } - } @Override @@ -135,7 +147,6 @@ public class CcsdkA1AdapterClient implements A1Client { .flatMapMany(A1AdapterJsonHelper::parseJsonArrayOfString) // .collectList(); } - } @Override @@ -162,7 +173,7 @@ public class CcsdkA1AdapterClient implements A1Client { } else if (this.protocolType == A1ProtocolType.CCSDK_A1_ADAPTER_STD_V2_0_0) { return StdA1ClientVersion2.extractPolicySchema(controllerResponse, policyTypeId); } else { - throw new NullPointerException("Not supported"); + return Mono.error(new ServiceException("Not supported " + this.protocolType)); } } @@ -223,6 +234,7 @@ public class CcsdkA1AdapterClient implements A1Client { } else if (protocolType == A1ProtocolType.CCSDK_A1_ADAPTER_OSC_V1) { return new OscA1Client.UriBuilder(ricConfig); } + logger.error("Not supported protocoltype: {}", protocolType); throw new NullPointerException(); } @@ -265,29 +277,27 @@ public class CcsdkA1AdapterClient implements A1Client { } private Mono post(String rpcName, String ricUrl, Optional body) { - AdapterRequest inputParams = ImmutableAdapterRequest.builder() // - .nearRtRicUrl(ricUrl) // - .body(body) // - .build(); + AdapterRequest inputParams = new AdapterRequest(ricUrl, body.isPresent() ? body.get() : null); + final String inputJsonString = A1AdapterJsonHelper.createInputJsonString(inputParams); logger.debug("POST inputJsonString = {}", inputJsonString); return restClient - .postWithAuthHeader(controllerUrl(rpcName), inputJsonString, this.controllerConfig.userName(), - this.controllerConfig.password()) // - .flatMap(this::extractResponseBody); + .postWithAuthHeader(controllerUrl(rpcName), inputJsonString, this.controllerConfig.getUserName(), + this.controllerConfig.getPassword()) // + .flatMap(resp -> extractResponseBody(resp, ricUrl)); } - 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()) { + private Mono extractResponse(JSONObject responseOutput, String ricUrl) { + AdapterOutput output = gson.fromJson(responseOutput.toString(), AdapterOutput.class); + + String body = output.body == null ? "" : output.body; + if (HttpStatus.valueOf(output.httpStatus).is2xxSuccessful()) { return Mono.just(body); } else { - logger.debug("Error response: {} {}", output.httpStatus(), body); + logger.debug("Error response: {} {}, from: {}", output.httpStatus, body, ricUrl); byte[] responseBodyBytes = body.getBytes(StandardCharsets.UTF_8); - HttpStatus httpStatus = HttpStatus.valueOf(output.httpStatus()); + HttpStatus httpStatus = HttpStatus.valueOf(output.httpStatus); WebClientResponseException responseException = new WebClientResponseException(httpStatus.value(), httpStatus.getReasonPhrase(), null, responseBodyBytes, StandardCharsets.UTF_8, null); @@ -295,9 +305,9 @@ public class CcsdkA1AdapterClient implements A1Client { } } - private Mono extractResponseBody(String responseStr) { + private Mono extractResponseBody(String responseStr, String ricUrl) { return A1AdapterJsonHelper.getOutput(responseStr) // - .flatMap(this::extractResponse); + .flatMap(responseOutput -> extractResponse(responseOutput, ricUrl)); } private String controllerUrl(String rpcName) { diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/OscA1Client.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/OscA1Client.java index 78a418ab..dfe33e7d 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/OscA1Client.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/OscA1Client.java @@ -110,7 +110,7 @@ public class OscA1Client implements A1Client { } private String baseUri() { - return ricConfig.baseUrl() + "/a1-p"; + return ricConfig.getBaseUrl() + "/a1-p"; } } @@ -125,7 +125,7 @@ public class OscA1Client implements A1Client { public OscA1Client(RicConfig ricConfig, AsyncRestClient restClient) { this.restClient = restClient; - logger.debug("OscA1Client for ric: {}", ricConfig.ricId()); + logger.debug("OscA1Client for ric: {}", ricConfig.getRicId()); uri = new UriBuilder(ricConfig); } diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/SecurityContext.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/SecurityContext.java index 3566aada..fe7c11f0 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/SecurityContext.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/SecurityContext.java @@ -47,7 +47,7 @@ public class SecurityContext { @Setter private Path authTokenFilePath; - public SecurityContext(@Value("${app.auth-token-file:\"\"}") String authTokenFilename) { + public SecurityContext(@Value("${app.auth-token-file:}") String authTokenFilename) { if (!authTokenFilename.isEmpty()) { this.authTokenFilePath = Path.of(authTokenFilename); } @@ -63,7 +63,7 @@ public class SecurityContext { } try { long lastModified = authTokenFilePath.toFile().lastModified(); - if (lastModified != this.tokenTimestamp) { + if (tokenTimestamp == 0 || lastModified != this.tokenTimestamp) { this.authToken = Files.readString(authTokenFilePath); this.tokenTimestamp = lastModified; } diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/StdA1ClientVersion1.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/StdA1ClientVersion1.java index b158ad25..5eae7759 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/StdA1ClientVersion1.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/StdA1ClientVersion1.java @@ -75,7 +75,7 @@ public class StdA1ClientVersion1 implements A1Client { } private String baseUri() { - return ricConfig.baseUrl() + "/A1-P/v1"; + return ricConfig.getBaseUrl() + "/A1-P/v1"; } private String policiesBaseUri() { diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/StdA1ClientVersion2.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/StdA1ClientVersion2.java index d0f4da28..0022057b 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/StdA1ClientVersion2.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/StdA1ClientVersion2.java @@ -41,6 +41,13 @@ import reactor.core.publisher.Mono; public class StdA1ClientVersion2 implements A1Client { static final int CONCURRENCY_RIC = 1; // How many paralell requests that is sent to one NearRT RIC + public static class Factory implements A1Client.Factory { + @Override + public A1Client create(RicConfig ricConfig, AsyncRestClientFactory restClientFactory) { + return new StdA1ClientVersion2(ricConfig, restClientFactory); + } + } + public static class OranV2UriBuilder implements A1UriBuilder { private final RicConfig ricConfig; @@ -114,7 +121,7 @@ public class StdA1ClientVersion2 implements A1Client { } private String baseUri() { - return ricConfig.baseUrl() + "/A1-P/v2"; + return ricConfig.getBaseUrl() + "/A1-P/v2"; } } @@ -129,7 +136,7 @@ public class StdA1ClientVersion2 implements A1Client { public StdA1ClientVersion2(RicConfig ricConfig, AsyncRestClient restClient) { this.restClient = restClient; - logger.debug("OscA1Client for ric: {}", ricConfig.ricId()); + logger.debug("OscA1Client for ric: {}", ricConfig.getRicId()); uriBuiler = new OranV2UriBuilder(ricConfig); } diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfig.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfig.java index 236d4381..0e2294fc 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfig.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfig.java @@ -100,13 +100,13 @@ public class ApplicationConfig { public WebClientConfig getWebClientConfig() { if (this.webClientConfig == null) { - HttpProxyConfig httpProxyConfig = ImmutableHttpProxyConfig.builder() // + HttpProxyConfig httpProxyConfig = HttpProxyConfig.builder() // .httpProxyHost(this.httpProxyHost) // .httpProxyPort(this.httpProxyPort) // .httpProxyType(ProxyProvider.Proxy.valueOf(this.httpProxyType)) // .build(); - this.webClientConfig = ImmutableWebClientConfig.builder() // + this.webClientConfig = WebClientConfig.builder() // .keyStoreType(this.sslKeyStoreType) // .keyStorePassword(this.sslKeyStorePassword) // .keyStore(this.sslKeyStore) // @@ -156,23 +156,23 @@ public class ApplicationConfig { ApplicationConfigParser.ConfigParserResult parserResult) { Collection modifications = new ArrayList<>(); - this.controllerConfigs = parserResult.controllerConfigs(); + this.controllerConfigs = parserResult.getControllerConfigs(); - this.dmaapConsumerTopicUrl = parserResult.dmaapConsumerTopicUrl(); - this.dmaapProducerTopicUrl = parserResult.dmaapProducerTopicUrl(); + this.dmaapConsumerTopicUrl = parserResult.getDmaapConsumerTopicUrl(); + this.dmaapProducerTopicUrl = parserResult.getDmaapProducerTopicUrl(); Map newRicConfigs = new HashMap<>(); - for (RicConfig newConfig : parserResult.ricConfigs()) { - RicConfig oldConfig = this.ricConfigs.get(newConfig.ricId()); - this.ricConfigs.remove(newConfig.ricId()); + for (RicConfig newConfig : parserResult.getRicConfigs()) { + RicConfig oldConfig = this.ricConfigs.get(newConfig.getRicId()); + this.ricConfigs.remove(newConfig.getRicId()); if (oldConfig == null) { - newRicConfigs.put(newConfig.ricId(), newConfig); + newRicConfigs.put(newConfig.getRicId(), 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.ricId(), newConfig); + newRicConfigs.put(newConfig.getRicId(), newConfig); } else { - newRicConfigs.put(oldConfig.ricId(), oldConfig); + newRicConfigs.put(oldConfig.getRicId(), oldConfig); } } for (RicConfig deletedConfig : this.ricConfigs.values()) { diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfigParser.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfigParser.java index 726d67fc..3990bc7b 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfigParser.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfigParser.java @@ -41,8 +41,9 @@ import java.util.Set; import javax.validation.constraints.NotNull; -import org.immutables.gson.Gson; -import org.immutables.value.Value; +import lombok.Builder; +import lombok.Getter; + import org.json.JSONObject; import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.ServiceException; import org.slf4j.Logger; @@ -63,16 +64,19 @@ public class ApplicationConfigParser { this.applicationConfig = applicationConfig; } - @Value.Immutable - @Gson.TypeAdapters - public interface ConfigParserResult { - List ricConfigs(); + @Builder + @Getter + public static class ConfigParserResult { + private List ricConfigs; - Map controllerConfigs(); + @Builder.Default + private Map controllerConfigs = new HashMap<>(); - String dmaapConsumerTopicUrl(); + @Builder.Default + private String dmaapConsumerTopicUrl = ""; - String dmaapProducerTopicUrl(); + @Builder.Default + private String dmaapProducerTopicUrl = ""; } @@ -103,7 +107,7 @@ public class ApplicationConfigParser { Map controllerConfigs = parseControllerConfigs(pmsConfigJson); checkConfigurationConsistency(ricConfigs, controllerConfigs); - return ImmutableConfigParserResult.builder() // + return ConfigParserResult.builder() // .dmaapConsumerTopicUrl(dmaapConsumerTopicUrl) // .dmaapProducerTopicUrl(dmaapProducerTopicUrl) // .ricConfigs(ricConfigs) // @@ -147,15 +151,15 @@ public class ApplicationConfigParser { 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 (!ricUrls.add(ric.getBaseUrl())) { + throw new ServiceException("Configuration error, more than one RIC URL: " + ric.getBaseUrl()); } - if (!ricNames.add(ric.ricId())) { - throw new ServiceException("Configuration error, more than one RIC with name: " + ric.ricId()); + if (!ricNames.add(ric.getRicId())) { + throw new ServiceException("Configuration error, more than one RIC with name: " + ric.getRicId()); } - if (!ric.controllerName().isEmpty() && controllerConfigs.get(ric.controllerName()) == null) { + if (!ric.getControllerName().isEmpty() && controllerConfigs.get(ric.getControllerName()) == null) { throw new ServiceException( - "Configuration error, controller configuration not found: " + ric.controllerName()); + "Configuration error, controller configuration not found: " + ric.getControllerName()); } } } @@ -163,23 +167,31 @@ public class ApplicationConfigParser { 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); - RicConfig ricConfig = ImmutableRicConfig.builder() // - .ricId(get(ricAsJson, "name", "id", "ricId").getAsString()) // - .baseUrl(get(ricAsJson, "baseUrl").getAsString()) // - .managedElementIds(parseManagedElementIds(get(ricAsJson, "managedElementIds").getAsJsonArray())) // - .controllerName(controllerNameElement != null ? controllerNameElement.getAsString() : "") // + JsonObject ricJsonObj = ricElem.getAsJsonObject(); + RicConfig ricConfig = RicConfig.builder() // + .ricId(get(ricJsonObj, "name", "id", "ricId").getAsString()) // + .baseUrl(get(ricJsonObj, "baseUrl").getAsString()) // + .managedElementIds(parseManagedElementIds(get(ricJsonObj, "managedElementIds").getAsJsonArray())) // + .controllerName(getString(ricJsonObj, CONTROLLER, "")) + .customAdapterClass(getString(ricJsonObj, "customAdapterClass", "")) // .build(); - if (!ricConfig.baseUrl().isEmpty()) { + if (!ricConfig.getBaseUrl().isEmpty()) { result.add(ricConfig); } else { - logger.error("RIC configuration error {}, baseUrl is empty", ricConfig.ricId()); + logger.error("RIC configuration error {}, baseUrl is empty", ricConfig.getRicId()); } } return result; } + String getString(JsonObject obj, String name, String defaultValue) { + JsonElement elem = obj.get(name); + if (elem != null) { + return elem.getAsString(); + } + return defaultValue; + } + Map parseControllerConfigs(JsonObject config) throws ServiceException { if (config.get(CONTROLLER) == null) { return new HashMap<>(); @@ -187,16 +199,16 @@ public class ApplicationConfigParser { Map result = new HashMap<>(); for (JsonElement element : getAsJsonArray(config, CONTROLLER)) { JsonObject controllerAsJson = element.getAsJsonObject(); - ImmutableControllerConfig controllerConfig = ImmutableControllerConfig.builder() // + ControllerConfig controllerConfig = ControllerConfig.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) { + if (result.put(controllerConfig.getName(), controllerConfig) != null) { throw new ServiceException( - "Configuration error, more than one controller with name: " + controllerConfig.name()); + "Configuration error, more than one controller with name: " + controllerConfig.getName()); } } return result; diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ControllerConfig.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ControllerConfig.java index 5f00cf69..1c52edc2 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ControllerConfig.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ControllerConfig.java @@ -20,19 +20,22 @@ package org.onap.ccsdk.oran.a1policymanagementservice.configuration; -import org.immutables.value.Value; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; -@Value.Immutable -@Value.Style(redactedMask = "####") +@Builder +@Getter +@EqualsAndHashCode +@ToString +public class ControllerConfig { + private String name; -public interface ControllerConfig { - public String name(); + private String baseUrl; - public String baseUrl(); - - public String userName(); - - @Value.Redacted - public String password(); + private String userName; + @ToString.Exclude + private String password; } diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/RicConfig.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/RicConfig.java index 7f7f9f5e..ffe853f5 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/RicConfig.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/RicConfig.java @@ -20,18 +20,29 @@ package org.onap.ccsdk.oran.a1policymanagementservice.configuration; -import com.google.common.collect.ImmutableList; +import java.util.ArrayList; +import java.util.Collection; -import org.immutables.value.Value; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; -@Value.Immutable -public interface RicConfig { - public String ricId(); +@Builder +@Getter +@EqualsAndHashCode +@ToString +public class RicConfig { + private String ricId; - public String controllerName(); + @Builder.Default + private String controllerName = ""; - public String baseUrl(); + private String baseUrl; - public ImmutableList managedElementIds(); + @Builder.Default + private Collection managedElementIds = new ArrayList<>(); + @Builder.Default + private String customAdapterClass = ""; } diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/WebClientConfig.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/WebClientConfig.java index 1e5d7ffa..e71f8557 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/WebClientConfig.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/WebClientConfig.java @@ -20,38 +20,41 @@ package org.onap.ccsdk.oran.a1policymanagementservice.configuration; -import org.immutables.value.Value; +import lombok.Builder; +import lombok.Getter; +import lombok.ToString; import reactor.netty.transport.ProxyProvider; -@Value.Immutable -@Value.Style(redactedMask = "####") -public interface WebClientConfig { - public String keyStoreType(); +@Builder +@Getter +@ToString +public class WebClientConfig { + private String keyStoreType; - @Value.Redacted - public String keyStorePassword(); + private String keyStorePassword; - public String keyStore(); + private String keyStore; - @Value.Redacted - public String keyPassword(); + @ToString.Exclude + private String keyPassword; - public boolean isTrustStoreUsed(); + private boolean isTrustStoreUsed; - @Value.Redacted - public String trustStorePassword(); + private String trustStorePassword; - public String trustStore(); + private String trustStore; - @Value.Immutable - public interface HttpProxyConfig { - public String httpProxyHost(); + @Builder + @Getter + @ToString + public static class HttpProxyConfig { + private String httpProxyHost; - public int httpProxyPort(); + private int httpProxyPort; - public ProxyProvider.Proxy httpProxyType(); + private ProxyProvider.Proxy httpProxyType; } - public HttpProxyConfig httpProxyConfig(); + private HttpProxyConfig httpProxyConfig; } diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/ServiceCallbackInfo.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/ServiceCallbackInfo.java index 7d89206c..c5436cd3 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/ServiceCallbackInfo.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/ServiceCallbackInfo.java @@ -25,9 +25,6 @@ import com.google.gson.annotations.SerializedName; import io.swagger.v3.oas.annotations.media.Schema; -import org.immutables.gson.Gson; - -@Gson.TypeAdapters @Schema(name = "service_callback_info_v2", description = "Information transferred as in Service callbacks (callback_url)") public class ServiceCallbackInfo { @@ -35,7 +32,6 @@ public class ServiceCallbackInfo { private static final String EVENT_TYPE_DESCRIPTION = "values:\n" // + "AVAILABLE: the Near-RT RIC has become available for A1 Policy management"; - @Gson.TypeAdapters @Schema(name = "event_type_v2", description = EVENT_TYPE_DESCRIPTION) public enum EventType { AVAILABLE diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/VoidResponse.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/VoidResponse.java index 754d1694..6470abfe 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/VoidResponse.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/VoidResponse.java @@ -22,9 +22,6 @@ package org.onap.ccsdk.oran.a1policymanagementservice.controllers; import io.swagger.v3.oas.annotations.media.Schema; -import org.immutables.gson.Gson; - -@Gson.TypeAdapters @Schema(name = "void", description = "Void/empty") public class VoidResponse { private VoidResponse() {} diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyController.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyController.java index 62018424..500ddd2a 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyController.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyController.java @@ -66,6 +66,7 @@ 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.WebClientException; import org.springframework.web.reactive.function.client.WebClientResponseException; import reactor.core.publisher.Mono; @@ -277,6 +278,9 @@ public class PolicyController { if (throwable instanceof WebClientResponseException) { WebClientResponseException e = (WebClientResponseException) throwable; return ErrorResponse.createMono(e.getResponseBodyAsString(), e.getStatusCode()); + } else if (throwable instanceof WebClientException) { + WebClientException e = (WebClientException) throwable; + return ErrorResponse.createMono(e.getMessage(), HttpStatus.BAD_GATEWAY); } else if (throwable instanceof RejectionException) { RejectionException e = (RejectionException) throwable; return ErrorResponse.createMono(e.getMessage(), e.getStatus()); diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyIdList.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyIdList.java index cc9b83aa..4e55c506 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyIdList.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyIdList.java @@ -27,9 +27,6 @@ import io.swagger.v3.oas.annotations.media.Schema; import java.util.Collection; -import org.immutables.gson.Gson; - -@Gson.TypeAdapters @Schema(name = "policy_id_list_v2", description = "A list of policy identities") public class PolicyIdList { diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyInfo.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyInfo.java index 2e19a3de..55a9343d 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyInfo.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyInfo.java @@ -25,9 +25,6 @@ import com.google.gson.annotations.SerializedName; import io.swagger.v3.oas.annotations.media.Schema; -import org.immutables.gson.Gson; - -@Gson.TypeAdapters @Schema(name = "policy_info_v2", description = "Information for one A1-P Policy") public class PolicyInfo { diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyInfoList.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyInfoList.java index 08923fd9..04f7e1ec 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyInfoList.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyInfoList.java @@ -27,9 +27,6 @@ import io.swagger.v3.oas.annotations.media.Schema; import java.util.Collection; -import org.immutables.gson.Gson; - -@Gson.TypeAdapters @Schema(name = "policy_info_list_v2", description = "List of policy information") public class PolicyInfoList { diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyStatusInfo.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyStatusInfo.java index bc95e54f..c19c4a0d 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyStatusInfo.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyStatusInfo.java @@ -27,9 +27,6 @@ import io.swagger.v3.oas.annotations.media.Schema; import java.time.Instant; -import org.immutables.gson.Gson; - -@Gson.TypeAdapters @Schema(name = "policy_status_info_v2", description = "Status for one A1-P Policy") public class PolicyStatusInfo { diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyTypeIdList.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyTypeIdList.java index deedf2f7..c2610b07 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyTypeIdList.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyTypeIdList.java @@ -27,9 +27,6 @@ import io.swagger.v3.oas.annotations.media.Schema; import java.util.Collection; -import org.immutables.gson.Gson; - -@Gson.TypeAdapters @Schema(name = "policytype_id_list_v2", description = "Information about policy types") public class PolicyTypeIdList { diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyTypeInfo.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyTypeInfo.java index b619e44b..591c1caf 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyTypeInfo.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyTypeInfo.java @@ -27,9 +27,6 @@ import com.google.gson.annotations.SerializedName; import io.swagger.v3.oas.annotations.media.Schema; -import org.immutables.gson.Gson; - -@Gson.TypeAdapters @Schema(name = "policytype_v2", description = "Policy type") public class PolicyTypeInfo { diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/RicInfo.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/RicInfo.java index 38797cae..44927707 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/RicInfo.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/RicInfo.java @@ -27,13 +27,9 @@ import io.swagger.v3.oas.annotations.media.Schema; import java.util.Collection; -import org.immutables.gson.Gson; - -@Gson.TypeAdapters @Schema(name = "ric_info_v2", description = "Information for a Near-RT RIC") public class RicInfo { - @Gson.TypeAdapters @Schema(name = "ric_state_v2", description = "Represents the states for a Near-RT RIC") public enum RicState { UNAVAILABLE, AVAILABLE, SYNCHRONIZING, CONSISTENCY_CHECK diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/RicInfoList.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/RicInfoList.java index 05b9569e..f5612f9c 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/RicInfoList.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/RicInfoList.java @@ -27,9 +27,6 @@ import io.swagger.v3.oas.annotations.media.Schema; import java.util.Collection; -import org.immutables.gson.Gson; - -@Gson.TypeAdapters @Schema(name = "ric_info_list_v2", description = "List of Near-RT RIC information") public class RicInfoList { diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ServiceRegistrationInfo.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ServiceRegistrationInfo.java index 17277c9a..0f975c24 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ServiceRegistrationInfo.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ServiceRegistrationInfo.java @@ -25,9 +25,6 @@ import com.google.gson.annotations.SerializedName; import io.swagger.v3.oas.annotations.media.Schema; -import org.immutables.gson.Gson; - -@Gson.TypeAdapters @Schema(name = "service_registration_info_v2", description = "Information for one service") public class ServiceRegistrationInfo { diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ServiceStatus.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ServiceStatus.java index 02869485..f25aff0e 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ServiceStatus.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ServiceStatus.java @@ -25,9 +25,6 @@ import com.google.gson.annotations.SerializedName; import io.swagger.v3.oas.annotations.media.Schema; -import org.immutables.gson.Gson; - -@Gson.TypeAdapters @Schema(name = "service_status_v2") public class ServiceStatus { diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ServiceStatusList.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ServiceStatusList.java index 981c95b6..e6aa8d41 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ServiceStatusList.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ServiceStatusList.java @@ -27,9 +27,6 @@ import io.swagger.v3.oas.annotations.media.Schema; import java.util.Collection; -import org.immutables.gson.Gson; - -@Gson.TypeAdapters @Schema(name = "service_list_v2", description = "List of service information") public class ServiceStatusList { diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/StatusController.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/StatusController.java index df9dfd19..28d434b7 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/StatusController.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/StatusController.java @@ -27,7 +27,6 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; -import org.immutables.gson.Gson; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -45,7 +44,6 @@ public class StatusController { public static final String API_NAME = "Health Check"; public static final String API_DESCRIPTION = ""; - @Gson.TypeAdapters @Schema(name = "status_info_v2") class StatusInfo { @Schema(description = "status text") diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/Ric.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/Ric.java index f43737f5..2971feb2 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/Ric.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/Ric.java @@ -30,17 +30,20 @@ import lombok.Setter; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1Client.A1ProtocolType; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.RicConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Holds information about a Near-RT RIC. */ public class Ric { + private static final Logger logger = LoggerFactory.getLogger(Ric.class); @Setter private RicConfig ricConfig; private RicState state = RicState.UNAVAILABLE; private Map supportedPolicyTypes = new HashMap<>(); - @Getter + @Setter private A1ProtocolType protocolVersion = A1ProtocolType.UNKNOWN; @@ -54,11 +57,11 @@ public class Ric { */ public Ric(RicConfig ricConfig) { this.ricConfig = ricConfig; - this.lock = new Lock(ricConfig.ricId()); + this.lock = new Lock(ricConfig.getRicId()); } public String id() { - return ricConfig.ricId(); + return ricConfig.getRicId(); } public RicConfig getConfig() { @@ -70,16 +73,25 @@ public class Ric { } public synchronized void setState(RicState state) { + logger.debug("Ric {} state set to {}", getConfig().getRicId(), state); this.state = state; } + public synchronized A1ProtocolType getProtocolVersion() { + if (this.ricConfig.getCustomAdapterClass().isEmpty()) { + return this.protocolVersion; + } else { + return A1ProtocolType.CUSTOM_PROTOCOL; + } + } + /** * Gets the nodes managed by this Ric. * * @return a vector containing the nodes managed by this Ric. */ public synchronized Collection getManagedElementIds() { - return new Vector<>(ricConfig.managedElementIds()); + return new Vector<>(ricConfig.getManagedElementIds()); } /** @@ -89,7 +101,7 @@ public class Ric { * @return true if the given node is managed by this Ric. */ public synchronized boolean isManaging(String managedElementId) { - return ricConfig.managedElementIds().contains(managedElementId); + return ricConfig.getManagedElementIds().contains(managedElementId); } /** @@ -135,7 +147,7 @@ public class Ric { @Override public synchronized String toString() { return Ric.class.getSimpleName() + ": " + "name: " + id() + ", state: " + state + ", baseUrl: " - + ricConfig.baseUrl() + ", managedNodes: " + ricConfig.managedElementIds(); + + ricConfig.getBaseUrl() + ", managedNodes: " + ricConfig.getManagedElementIds(); } /** diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTask.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTask.java index e3d489b5..983e92e6 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTask.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTask.java @@ -36,11 +36,9 @@ import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationCo import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig.RicConfigUpdate; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfigParser; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ConfigurationFile; -import org.onap.ccsdk.oran.a1policymanagementservice.controllers.ServiceCallbacks; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policies; import org.onap.ccsdk.oran.a1policymanagementservice.repository.PolicyTypes; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Ric; -import org.onap.ccsdk.oran.a1policymanagementservice.repository.Ric.RicState; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Rics; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Services; import org.slf4j.Logger; @@ -130,7 +128,7 @@ public class RefreshConfigTask { .flatMap(this::parseConfiguration) // .flatMap(this::updateConfig, CONCURRENCY) // .flatMap(this::handleUpdatedRicConfig) // - .doOnTerminate(() -> logger.error("Configuration refresh task is terminated")); + .doFinally(signal -> logger.error("Configuration refresh task is terminated: {}", signal)); } private Flux regularInterval() { @@ -170,40 +168,16 @@ public class RefreshConfigTask { return new RicSynchronizationTask(a1ClientFactory, policyTypes, policies, services, restClientFactory, rics); } - /** - * for an added RIC after a restart it is nesessary to get the suypported policy - * types from the RIC unless a full synchronization is wanted. - * - * @param ric the ric to get supprted types from - * @return the same ric - */ - private Mono trySyncronizeSupportedTypes(Ric ric) { - logger.debug("Synchronizing policy types for new RIC: {}", ric.id()); - // Synchronize the policy types - ric.setState(RicState.SYNCHRONIZING); - return this.a1ClientFactory.createA1Client(ric) // - .flatMapMany(client -> synchronizationTask().synchronizePolicyTypes(ric, client)) // - .collectList() // - .map(list -> ric) // - .doOnNext(notUsed -> ric.setState(RicState.AVAILABLE)) // - .doOnError(t -> { - logger.warn("Failed to synchronize types in new RIC: {}, reason: {}", ric.id(), t.getMessage()); - ric.setState(RicState.UNAVAILABLE); // - }) // - .onErrorResume(t -> Mono.just(ric)); - } - public Mono handleUpdatedRicConfig(RicConfigUpdate updatedInfo) { synchronized (this.rics) { - String ricId = updatedInfo.getRicConfig().ricId(); + String ricId = updatedInfo.getRicConfig().getRicId(); RicConfigUpdate.Type event = updatedInfo.getType(); if (event == RicConfigUpdate.Type.ADDED) { logger.debug("RIC added {}", ricId); - - return trySyncronizeSupportedTypes(new Ric(updatedInfo.getRicConfig())) // - .doOnNext(this::addRic) // - .flatMap(this::notifyServicesRicAvailable) // - .flatMap(notUsed -> Mono.just(event)); + Ric ric = new Ric(updatedInfo.getRicConfig()); + this.addRic(ric); + return this.synchronizationTask().synchronizeRic(ric) // + .map(notUsed -> event); } else if (event == RicConfigUpdate.Type.REMOVED) { logger.debug("RIC removed {}", ricId); Ric ric = rics.remove(ricId); @@ -231,17 +205,6 @@ public class RefreshConfigTask { logger.debug("Added RIC: {}", ric.id()); } - private Mono notifyServicesRicAvailable(Ric ric) { - if (ric.getState() == RicState.AVAILABLE) { - ServiceCallbacks callbacks = new ServiceCallbacks(this.restClientFactory); - return callbacks.notifyServicesRicAvailable(ric, services) // - .collectList() // - .map(list -> ric); - } else { - return Mono.just(ric); - } - } - /** * Reads the configuration from file. */ diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSupervision.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSupervision.java index 8926ec16..e3edaf44 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSupervision.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSupervision.java @@ -64,11 +64,11 @@ public class RicSupervision { private final Services services; private final AsyncRestClientFactory restClientFactory; - private static class SynchStartedException extends ServiceException { + private static class SynchNeededException extends ServiceException { private static final long serialVersionUID = 1L; - public SynchStartedException(String message) { - super(message); + public SynchNeededException(RicData ric) { + super("SynchNeededException for " + ric.ric.id()); } } @@ -106,68 +106,61 @@ public class RicSupervision { createTask().subscribe(null, null, () -> logger.debug("Checking all RICs completed")); } - private Flux createTask() { + private Flux createTask() { return Flux.fromIterable(rics.getRics()) // .flatMap(this::createRicData) // - .flatMap(this::checkOneRic, CONCURRENCY); + .onErrorResume(t -> Flux.empty()) // + .flatMap(this::checkOneRic, CONCURRENCY) // + .map(ricData -> ricData.ric); } private Mono checkOneRic(RicData ricData) { - return checkRicState(ricData) // - .flatMap(x -> ricData.ric.getLock().lock(LockType.EXCLUSIVE, "checkOneRic")) // - .flatMap(notUsed -> setRicState(ricData)) // + if (ricData.ric.getState() == RicState.CONSISTENCY_CHECK || ricData.ric.getState() == RicState.SYNCHRONIZING) { + logger.debug("Skipping check ric: {}, state: {}", ricData.ric.id(), ricData.ric.getState()); + return Mono.empty(); // Skip, already in progress + } + return ricData.ric.getLock().lock(LockType.EXCLUSIVE, "checkOneRic") // + .flatMap(lock -> synchIfUnavailable(ricData)) // + .doOnNext(ric -> ricData.ric.setState(RicState.CONSISTENCY_CHECK)) // .flatMap(x -> checkRicPolicies(ricData)) // .flatMap(x -> checkRicPolicyTypes(ricData)) // .doOnNext(x -> onRicCheckedOk(ricData)) // - .doOnError(t -> onRicCheckedError(t, ricData)) // + .onErrorResume(t -> onRicCheckedError(t, ricData)) // + .doFinally(sig -> ricData.ric.getLock().unlockBlocking()) // .onErrorResume(throwable -> Mono.empty()); } - private void onRicCheckedError(Throwable t, RicData ricData) { + private Mono synchIfUnavailable(RicData ric) { + if (ric.ric.getState() == RicState.UNAVAILABLE) { + return Mono.error(new SynchNeededException(ric)); + } else { + return Mono.just(ric); + } + } + + private Mono onRicCheckedError(Throwable t, RicData ricData) { logger.debug("Ric: {} check stopped, exception: {}", ricData.ric.id(), t.getMessage()); - if (!(t instanceof SynchStartedException)) { - // If synch is started, the synch will set the final state - ricData.ric.setState(RicState.UNAVAILABLE); + ricData.ric.setState(RicState.UNAVAILABLE); + if ((t instanceof SynchNeededException)) { + return startSynchronization(ricData); + } else { + logger.warn("RicSupervision, ric: {}, exception: {}", ricData.ric.id(), t.getMessage()); + return Mono.empty(); } - ricData.ric.getLock().unlockBlocking(); } private void onRicCheckedOk(RicData ricData) { logger.debug("Ric: {} checked OK", ricData.ric.id()); 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().ricId()); - 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)) // + return this.a1ClientFactory.createA1Client(ric) // + .doOnError(t -> logger.debug("Could not create A1 client for ric: {}, reason: {}", ric.id(), + t.getMessage())) // .map(a1Client -> new RicData(ric, a1Client)); } - private Mono checkRicState(RicData ric) { - if (ric.ric.getState() == RicState.UNAVAILABLE) { - logger.debug("RicSupervision, starting ric: {} synchronization (state == UNAVAILABLE)", ric.ric.id()); - 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)); @@ -178,14 +171,14 @@ public class RicSupervision { if (ricPolicies.size() != policies.getForRic(ric.ric.id()).size()) { logger.debug("RicSupervision, starting ric: {} synchronization (noOfPolicices == {}, expected == {})", ric.ric.id(), ricPolicies.size(), policies.getForRic(ric.ric.id()).size()); - return startSynchronization(ric); + return Mono.error(new SynchNeededException(ric)); } for (String policyId : ricPolicies) { if (!policies.containsPolicy(policyId)) { logger.debug("RicSupervision, starting ric: {} synchronization (unexpected policy in RIC: {})", ric.ric.id(), policyId); - return startSynchronization(ric); + return Mono.error(new SynchNeededException(ric)); } } return Mono.just(ric); @@ -202,22 +195,23 @@ public class RicSupervision { logger.debug( "RicSupervision, starting ric: {} synchronization (unexpected numer of policy types in RIC: {}, expected: {})", ric.ric.id(), ricTypes.size(), ric.ric.getSupportedPolicyTypes().size()); - return startSynchronization(ric); + return Mono.error(new SynchNeededException(ric)); } for (String typeName : ricTypes) { if (!ric.ric.isSupportingType(typeName)) { logger.debug("RicSupervision, starting ric: {} synchronization (unexpected policy type: {})", ric.ric.id(), typeName); - return startSynchronization(ric); + return Mono.error(new SynchNeededException(ric)); } } return Mono.just(ric); } private Mono startSynchronization(RicData ric) { + logger.debug("RicSupervision, starting ric: {} synchronization, state: {}", ric.ric.id(), ric.ric.getState()); RicSynchronizationTask synchronizationTask = createSynchronizationTask(); return synchronizationTask.synchronizeRic(ric.ric) // - .flatMap(notUsed -> Mono.error(new SynchStartedException("Syncronization started"))); + .flatMap(notUsed -> Mono.just(ric)); } diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSynchronizationTask.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSynchronizationTask.java index 6305abf0..b3afa7cd 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSynchronizationTask.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSynchronizationTask.java @@ -36,8 +36,8 @@ import org.onap.ccsdk.oran.a1policymanagementservice.repository.Rics; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Services; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.web.reactive.function.client.WebClientResponseException; -import reactor.core.publisher.BaseSubscriber; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.core.publisher.SignalType; @@ -78,61 +78,69 @@ public class RicSynchronizationTask { } public void run(Ric ric) { - logger.debug("Ric synchronization task created: {}", ric.getConfig().ricId()); + logger.debug("Ric synchronization task created: {}", ric.getConfig().getRicId()); if (ric.getState() == RicState.SYNCHRONIZING) { - logger.debug("Ric: {} is already being synchronized", ric.getConfig().ricId()); + logger.debug("Ric: {} is already being synchronized", ric.getConfig().getRicId()); return; } ric.getLock().lock(LockType.EXCLUSIVE, "RicSynchronizationTask") // .flatMap(notUsed -> synchronizeRic(ric)) // - .subscribe(new BaseSubscriber() { - - @Override - protected void hookFinally(SignalType type) { - ric.getLock().unlockBlocking(); - } - }); + .doFinally(sig -> ric.getLock().unlockBlocking()) // + .subscribe(); } public Mono synchronizeRic(Ric ric) { - return setRicState(ric) // - .flatMap(lock -> this.a1ClientFactory.createA1Client(ric)) // + return this.a1ClientFactory.createA1Client(ric) // + .doOnNext(client -> ric.setState(RicState.SYNCHRONIZING)) // .flatMapMany(client -> runSynchronization(ric, client)) // - .onErrorResume(throwable -> deleteAllPolicyInstances(ric, throwable)) // - .collectList() // - .map(notUsed -> ric) // .doOnError(t -> { // logger.warn("Synchronization failure for ric: {}, reason: {}", ric.id(), t.getMessage()); // - ric.setState(RicState.UNAVAILABLE); // + deletePoliciesIfNotRecreatable(t, ric); }) // + .collectList() // .flatMap(notUsed -> onSynchronizationComplete(ric)) // - .onErrorResume(t -> Mono.just(ric)); + .onErrorResume(t -> Mono.just(ric)) // + .doFinally(signal -> onFinally(signal, ric)); + } + + private void onFinally(SignalType signal, Ric ric) { + if (ric.getState().equals(RicState.SYNCHRONIZING)) { + logger.debug("Resetting ric state after failed synch, ric: {}, signal: {}", ric.id(), signal); + ric.setState(RicState.UNAVAILABLE); // + } + } + + /** + * If a 4xx error is received, allpolicies are deleted. This is just to avoid + * cyclical receovery due to that the NearRT RIC cannot accept a previously + * policy. + */ + private void deletePoliciesIfNotRecreatable(Throwable throwable, Ric ric) { + if (throwable instanceof WebClientResponseException) { + WebClientResponseException responseException = (WebClientResponseException) throwable; + if (responseException.getStatusCode().is4xxClientError()) { + deleteAllPoliciesInRepository(ric); + } + } + } + + private void deleteAllPoliciesInRepository(Ric ric) { + for (Policy policy : policies.getForRic(ric.id())) { + this.policies.remove(policy); + } } public 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().ricId(), typeId)) // + .doOnNext(typeId -> logger.debug("For ric: {}, handling type: {}", ric.getConfig().getRicId(), typeId)) // .flatMap(policyTypeId -> getPolicyType(policyTypeId, a1Client), CONCURRENCY_RIC) // .doOnNext(ric::addSupportedPolicyType); // } - @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().ricId()); - return Mono.empty(); - } - logger.debug("Ric state set to SYNCHRONIZING: {}", ric.getConfig().ricId()); - ric.setState(RicState.SYNCHRONIZING); - return Mono.just(ric); - } - } - private Flux runSynchronization(Ric ric, A1Client a1Client) { Flux synchronizedTypes = synchronizePolicyTypes(ric, a1Client); Flux policiesDeletedInRic = a1Client.deleteAllPolicies(); @@ -154,19 +162,6 @@ public class RicSynchronizationTask { .map(list -> ric); } - private Flux deleteAllPolicyInstances(Ric ric, Throwable t) { - logger.warn("Recreation of policies failed for ric: {}, reason: {}", ric.id(), 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); - } - private Mono getPolicyType(String policyTypeId, A1Client a1Client) { if (policyTypes.contains(policyTypeId)) { return Mono.just(policyTypes.get(policyTypeId)); @@ -181,14 +176,8 @@ public class RicSynchronizationTask { return pt; } - private void deleteAllPoliciesInRepository(Ric ric) { - for (Policy policy : policies.getForRic(ric.id())) { - this.policies.remove(policy); - } - } - private Flux putPolicy(Policy policy, Ric ric, A1Client a1Client) { - logger.trace("Recreating policy: {}, for ric: {}", policy.getId(), ric.getConfig().ricId()); + logger.trace("Recreating policy: {}, for ric: {}", policy.getId(), ric.getConfig().getRicId()); return a1Client.putPolicy(policy) // .flatMapMany(notUsed -> Flux.just(policy)); } diff --git a/a1-policy-management/src/main/resources/application_configuration_schema.json b/a1-policy-management/src/main/resources/application_configuration_schema.json index 05135e7c..947db33e 100644 --- a/a1-policy-management/src/main/resources/application_configuration_schema.json +++ b/a1-policy-management/src/main/resources/application_configuration_schema.json @@ -54,6 +54,9 @@ }, "controller": { "type": "string" + }, + "customAdapterClass" : { + "type": "string" }, "managedElementIds": { "type": "array", @@ -94,18 +97,21 @@ }, "required": [ "topic_url" - ] + ], + "additionalProperties": false } }, "required": [ "type", "dmaap_info" - ] + ], + "additionalProperties": false } }, "required": [ "dmaap_publisher" - ] + ], + "additionalProperties": false }, "streams_subscribes": { "type": "object", @@ -125,18 +131,21 @@ }, "required": [ "topic_url" - ] + ], + "additionalProperties": false } }, "required": [ "type", "dmaap_info" - ] + ], + "additionalProperties": false } }, "required": [ "dmaap_subscriber" - ] + ], + "additionalProperties": false } }, "required": [ @@ -148,4 +157,4 @@ "required": [ "config" ] -} \ No newline at end of file +} diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/MockPolicyManagementService.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/MockPolicyManagementService.java index 3cb1d91d..3b7695e8 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/MockPolicyManagementService.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/MockPolicyManagementService.java @@ -32,7 +32,6 @@ import java.nio.file.Files; import java.time.Instant; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policies; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policy; @@ -50,10 +49,8 @@ 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", // diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactoryTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactoryTest.java index 645f2353..424668fc 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactoryTest.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactoryTest.java @@ -27,8 +27,7 @@ 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.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -37,8 +36,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1Client.A1ProtocolType; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ControllerConfig; -import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ImmutableControllerConfig; -import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ImmutableRicConfig; +import org.onap.ccsdk.oran.a1policymanagementservice.configuration.RicConfig; import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.ServiceException; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Ric; @@ -68,21 +66,24 @@ class A1ClientFactoryTest { private Ric ric; private A1ClientFactory factoryUnderTest; - private static ImmutableRicConfig ricConfig(String controllerName) { - return ImmutableRicConfig.builder() // + private static RicConfig ricConfig(String controllerName, String customAdapter) { + return RicConfig.builder() // .ricId(RIC_NAME) // .baseUrl("baseUrl") // - .managedElementIds(new Vector<>()) // .controllerName(controllerName) // + .customAdapterClass(customAdapter) // .build(); } + private static RicConfig ricConfig(String controllerName) { + return ricConfig(controllerName, ""); + } + @BeforeEach void createFactoryUnderTest() { SecurityContext sec = new SecurityContext(""); factoryUnderTest = spy(new A1ClientFactory(applicationConfigMock, sec)); this.ric = new Ric(ricConfig("")); - } @Test @@ -109,6 +110,38 @@ class A1ClientFactoryTest { assertEquals(A1ProtocolType.STD_V1_1, ric.getProtocolVersion(), "Not correct protocol"); } + public static class CustomA1AdapterFactory implements A1Client.Factory { + @Override + public A1Client create(RicConfig ricConfig, AsyncRestClientFactory restClientFactory) { + return new StdA1ClientVersion2(ricConfig, restClientFactory); + } + } + + @Test + void testCustomAdapterCreation() { + + Ric ric = new Ric(ricConfig("", CustomA1AdapterFactory.class.getName())); + A1Client client = factoryUnderTest.createA1Client(ric).block(); + + assertEquals(client.getClass(), StdA1ClientVersion2.class); + + ric = new Ric(ricConfig("", "org.onap.ccsdk.oran.a1policymanagementservice.clients.StdA1ClientVersion2")); + client = factoryUnderTest.createA1Client(ric).block(); + + assertEquals(client.getClass(), StdA1ClientVersion2.class); + + ric = new Ric( + ricConfig("", "org.onap.ccsdk.oran.a1policymanagementservice.clients.StdA1ClientVersion2$Factory")); + client = factoryUnderTest.createA1Client(ric).block(); + + assertEquals(client.getClass(), StdA1ClientVersion2.class); + + Exception e = Assertions.assertThrows(Exception.class, () -> { + factoryUnderTest.createClient(new Ric(ricConfig("", "junk")), A1ProtocolType.CUSTOM_PROTOCOL); + }); + assertEquals("Could not find class: junk", e.getMessage()); + } + @Test void getProtocolVersion_error() throws ServiceException { whenGetProtocolVersionThrowException(clientMock1, clientMock2, clientMock3, clientMock4); @@ -155,7 +188,7 @@ class A1ClientFactoryTest { } private void whenGetGetControllerConfigReturn() throws ServiceException { - ControllerConfig controllerCfg = ImmutableControllerConfig.builder() // + ControllerConfig controllerCfg = ControllerConfig.builder() // .name("name") // .baseUrl("baseUrl") // .password("pass") // diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientHelper.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientHelper.java index eb007138..56dc7ed6 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientHelper.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientHelper.java @@ -25,7 +25,6 @@ import java.util.Arrays; import java.util.Vector; import org.json.JSONObject; -import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ImmutableRicConfig; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.RicConfig; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policy; import org.onap.ccsdk.oran.a1policymanagementservice.repository.PolicyType; @@ -45,10 +44,9 @@ public class A1ClientHelper { } protected static Ric createRic(String url) { - RicConfig cfg = ImmutableRicConfig.builder().ricId("ric") // + RicConfig cfg = RicConfig.builder().ricId("ric") // .baseUrl(url) // .managedElementIds(new Vector(Arrays.asList("kista_1", "kista_2"))) // - .controllerName("") // .build(); return new Ric(cfg); } diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/CcsdkA1AdapterClientTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/CcsdkA1AdapterClientTest.java index f49020ee..15e4983c 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/CcsdkA1AdapterClientTest.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/CcsdkA1AdapterClientTest.java @@ -35,7 +35,6 @@ 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.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -45,9 +44,7 @@ import org.mockito.stubbing.OngoingStubbing; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1Client.A1ProtocolType; import org.onap.ccsdk.oran.a1policymanagementservice.clients.CcsdkA1AdapterClient.AdapterOutput; import org.onap.ccsdk.oran.a1policymanagementservice.clients.CcsdkA1AdapterClient.AdapterRequest; -import org.onap.ccsdk.oran.a1policymanagementservice.clients.ImmutableAdapterOutput.Builder; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ControllerConfig; -import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ImmutableControllerConfig; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policy; import org.springframework.http.HttpStatus; import org.springframework.web.reactive.function.client.WebClientResponseException; @@ -74,7 +71,7 @@ class CcsdkA1AdapterClientTest { AsyncRestClient asyncRestClientMock; private ControllerConfig controllerConfig() { - return ImmutableControllerConfig.builder() // + return ControllerConfig.builder() // .name("name") // .baseUrl("baseUrl") // .password(CONTROLLER_PASSWORD) // @@ -113,9 +110,8 @@ class CcsdkA1AdapterClientTest { assertEquals(1, policyTypeIds.size()); assertEquals(POLICY_TYPE_1_ID, policyTypeIds.get(0)); - ImmutableAdapterRequest expectedParams = ImmutableAdapterRequest.builder() // - .nearRtRicUrl(expUrl) // - .build(); + AdapterRequest expectedParams = new AdapterRequest(expUrl, null); + String expInput = A1AdapterJsonHelper.createInputJsonString(expectedParams); verify(asyncRestClientMock).postWithAuthHeader(GET_A1_POLICY_URL, expInput, CONTROLLER_USERNAME, CONTROLLER_PASSWORD); @@ -160,9 +156,8 @@ class CcsdkA1AdapterClientTest { assertEquals(policyTypeId, respJson.getAsJsonObject().get("title").getAsString(), "title should be updated to contain policyType ID"); - ImmutableAdapterRequest expectedParams = ImmutableAdapterRequest.builder() // - .nearRtRicUrl(expUrl) // - .build(); + AdapterRequest expectedParams = new AdapterRequest(expUrl, null); + String expInput = A1AdapterJsonHelper.createInputJsonString(expectedParams); verify(asyncRestClientMock).postWithAuthHeader(GET_A1_POLICY_URL, expInput, CONTROLLER_USERNAME, @@ -205,9 +200,8 @@ class CcsdkA1AdapterClientTest { assertEquals(1, returned.size()); for (String expUrl : expUrls) { - ImmutableAdapterRequest expectedParams = ImmutableAdapterRequest.builder() // - .nearRtRicUrl(expUrl) // - .build(); + AdapterRequest expectedParams = new AdapterRequest(expUrl, null); + String expInput = A1AdapterJsonHelper.createInputJsonString(expectedParams); verify(asyncRestClientMock).postWithAuthHeader(GET_A1_POLICY_URL, expInput, CONTROLLER_USERNAME, CONTROLLER_PASSWORD); @@ -246,10 +240,7 @@ class CcsdkA1AdapterClientTest { .block(); assertEquals("OK", returned); - AdapterRequest expectedInputParams = ImmutableAdapterRequest.builder() // - .nearRtRicUrl(expUrl) // - .body(POLICY_JSON_VALID) // - .build(); + AdapterRequest expectedInputParams = new AdapterRequest(expUrl, POLICY_JSON_VALID); String expInput = A1AdapterJsonHelper.createInputJsonString(expectedInputParams); verify(asyncRestClientMock).postWithAuthHeader(PUT_A1_URL, expInput, CONTROLLER_USERNAME, CONTROLLER_PASSWORD); @@ -282,10 +273,7 @@ class CcsdkA1AdapterClientTest { controllerConfig(), asyncRestClientMock); final String policyJson = "{}"; - AdapterOutput adapterOutput = ImmutableAdapterOutput.builder() // - .body("NOK") // - .httpStatus(HttpStatus.BAD_REQUEST.value()) // ERROR - .build(); + AdapterOutput adapterOutput = new AdapterOutput(HttpStatus.BAD_REQUEST.value(), "NOK"); String resp = A1AdapterJsonHelper.createOutputJsonString(adapterOutput); whenAsyncPostThenReturn(Mono.just(resp)); @@ -311,9 +299,8 @@ class CcsdkA1AdapterClientTest { clientUnderTest.deleteAllPolicies().blockLast(); - ImmutableAdapterRequest expectedParams = ImmutableAdapterRequest.builder() // - .nearRtRicUrl(expUrl) // - .build(); + AdapterRequest expectedParams = new AdapterRequest(expUrl, null); + String expInput = A1AdapterJsonHelper.createInputJsonString(expectedParams); verify(asyncRestClientMock).postWithAuthHeader(DELETE_A1_URL, expInput, CONTROLLER_USERNAME, CONTROLLER_PASSWORD); @@ -363,9 +350,8 @@ class CcsdkA1AdapterClientTest { assertEquals("OK", response); String expUrl = RIC_1_URL + "/A1-P/v2/policytypes/type1/policies/policy1/status"; - ImmutableAdapterRequest expectedParams = ImmutableAdapterRequest.builder() // - .nearRtRicUrl(expUrl) // - .build(); + AdapterRequest expectedParams = new AdapterRequest(expUrl, null); + String expInput = A1AdapterJsonHelper.createInputJsonString(expectedParams); verify(asyncRestClientMock).postWithAuthHeader(GET_A1_POLICY_STATUS_URL, expInput, CONTROLLER_USERNAME, CONTROLLER_PASSWORD); @@ -392,21 +378,14 @@ class CcsdkA1AdapterClientTest { } private String createOkResponseWithBody(Object body) { - AdapterOutput output = ImmutableAdapterOutput.builder() // - .body(gson().toJson(body)) // - .httpStatus(HttpStatus.OK.value()) // - .build(); + AdapterOutput output = new AdapterOutput(HttpStatus.OK.value(), gson().toJson(body)); return A1AdapterJsonHelper.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 A1AdapterJsonHelper.createOutputJsonString(responseBuilder.build()); + String body = withBody ? HttpStatus.OK.name() : null; + AdapterOutput output = new AdapterOutput(HttpStatus.OK.value(), body); + return A1AdapterJsonHelper.createOutputJsonString(output); } private OngoingStubbing> whenAsyncPostThenReturn(Mono response) { diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/OscA1ClientTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/OscA1ClientTest.java index 6aacc914..2ff07f15 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/OscA1ClientTest.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/OscA1ClientTest.java @@ -26,7 +26,6 @@ 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; @@ -35,7 +34,6 @@ 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.onap.ccsdk.oran.a1policymanagementservice.configuration.ImmutableRicConfig; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.RicConfig; import reactor.core.publisher.Flux; @@ -66,11 +64,9 @@ class OscA1ClientTest { @BeforeEach void init() { - RicConfig ricConfig = ImmutableRicConfig.builder() // + RicConfig ricConfig = RicConfig.builder() // .ricId("name") // .baseUrl("RicBaseUrl") // - .managedElementIds(new ArrayList<>()) // - .controllerName("") // .build(); asyncRestClientMock = mock(AsyncRestClient.class); clientUnderTest = new OscA1Client(ricConfig, asyncRestClientMock); diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/StdA1ClientTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/StdA1ClientTest.java index b4709767..db4c79cd 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/StdA1ClientTest.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/StdA1ClientTest.java @@ -80,7 +80,7 @@ class StdA1ClientTest { @Test void testGetPolicyIdentities() { - doReturn(RIC_URL).when(ricConfigMock).baseUrl(); + doReturn(RIC_URL).when(ricConfigMock).getBaseUrl(); Mono policyIds = Mono.just(Arrays.asList(POLICY_1_ID, POLICY_2_ID).toString()); when(asyncRestClientMock.get(anyString())).thenReturn(policyIds); @@ -98,7 +98,7 @@ class StdA1ClientTest { @Test void testPutPolicyValidResponse() { - doReturn(RIC_URL).when(ricConfigMock).baseUrl(); + doReturn(RIC_URL).when(ricConfigMock).getBaseUrl(); when(asyncRestClientMock.put(anyString(), anyString())).thenReturn(Mono.just(POLICY_JSON)); Mono policyMono = @@ -110,7 +110,7 @@ class StdA1ClientTest { @Test void testDeletePolicy() { - doReturn(RIC_URL).when(ricConfigMock).baseUrl(); + doReturn(RIC_URL).when(ricConfigMock).getBaseUrl(); final String url = policiesBaseUrl() + POLICY_1_ID; when(asyncRestClientMock.delete(url)).thenReturn(Mono.empty()); @@ -122,7 +122,7 @@ class StdA1ClientTest { @Test void testDeleteAllPolicies() { - doReturn(RIC_URL).when(ricConfigMock).baseUrl(); + doReturn(RIC_URL).when(ricConfigMock).getBaseUrl(); 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()); diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/StdA1ClientV2Test.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/StdA1ClientV2Test.java index de55882b..95c20426 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/StdA1ClientV2Test.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/StdA1ClientV2Test.java @@ -28,7 +28,6 @@ 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; @@ -38,7 +37,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; import org.mockito.junit.jupiter.MockitoExtension; -import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ImmutableRicConfig; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.RicConfig; import reactor.core.publisher.Flux; @@ -69,11 +67,9 @@ class StdA1ClientV2Test { @BeforeEach void init() { - RicConfig ricConfig = ImmutableRicConfig.builder() // + RicConfig ricConfig = RicConfig.builder() // .ricId("name") // .baseUrl(RIC_URL) // - .managedElementIds(new ArrayList<>()) // - .controllerName("") // .build(); asyncRestClientMock = mock(AsyncRestClient.class); clientUnderTest = new StdA1ClientVersion2(ricConfig, asyncRestClientMock); diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfigParserTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfigParserTest.java index 4a4e8a33..8e3e3a5d 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfigParserTest.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfigParserTest.java @@ -59,25 +59,27 @@ class ApplicationConfigParserTest { ApplicationConfigParser.ConfigParserResult result = parserUnderTest.parse(jsonRootObject); - String topicUrl = result.dmaapProducerTopicUrl(); + String topicUrl = result.getDmaapProducerTopicUrl(); assertEquals("http://admin:admin@localhost:6845/events/A1-POLICY-AGENT-WRITE", topicUrl, "controller contents"); - topicUrl = result.dmaapConsumerTopicUrl(); + topicUrl = result.getDmaapConsumerTopicUrl(); 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(); + Map controllers = result.getControllerConfigs(); assertEquals(1, controllers.size(), "size"); - ImmutableControllerConfig expectedControllerConfig = ImmutableControllerConfig.builder() // + ControllerConfig expectedControllerConfig = ControllerConfig.builder() // .baseUrl("http://localhost:8083/") // .name("controller1") // .userName("user") // .password("password") // .build(); // - assertEquals(expectedControllerConfig, controllers.get("controller1"), "controller contents"); - assertEquals(2, result.ricConfigs().size()); + ControllerConfig actual = controllers.get("controller1"); + assertEquals(expectedControllerConfig, actual, "controller contents"); + + assertEquals(2, result.getRicConfigs().size()); } private JsonObject getJsonRootObject() throws JsonIOException, JsonSyntaxException, IOException { diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfigTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfigTest.java index 7a075428..abf91f20 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfigTest.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfigTest.java @@ -26,7 +26,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Arrays; import java.util.HashMap; import java.util.List; -import java.util.Vector; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -37,29 +36,23 @@ import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationCo @ExtendWith(MockitoExtension.class) class ApplicationConfigTest { - private static final ImmutableRicConfig RIC_CONFIG_1 = ImmutableRicConfig.builder() // + private static final RicConfig RIC_CONFIG_1 = RicConfig.builder() // .ricId("ric1") // .baseUrl("ric1_url") // - .managedElementIds(new Vector<>()) // - .controllerName("") // .build(); - private static final ImmutableRicConfig RIC_CONFIG_2 = ImmutableRicConfig.builder() // + private static final RicConfig RIC_CONFIG_2 = RicConfig.builder() // .ricId("ric2") // .baseUrl("ric1_url") // - .managedElementIds(new Vector<>()) // - .controllerName("") // .build(); - private static final ImmutableRicConfig RIC_CONFIG_3 = ImmutableRicConfig.builder() // + private static final RicConfig RIC_CONFIG_3 = RicConfig.builder() // .ricId("ric3") // .baseUrl("ric1_url") // - .managedElementIds(new Vector<>()) // - .controllerName("") // .build(); ConfigParserResult configParserResult(RicConfig... rics) { - return ImmutableConfigParserResult.builder() // + return ConfigParserResult.builder() // .ricConfigs(Arrays.asList(rics)) // .dmaapConsumerTopicUrl("dmaapConsumerTopicUrl") // .dmaapProducerTopicUrl("dmaapProducerTopicUrl") // @@ -77,7 +70,7 @@ class ApplicationConfigTest { assertEquals(RicConfigUpdate.Type.ADDED, update.get(0).getType()); assertTrue(appConfigUnderTest.getRicConfigs().contains(RIC_CONFIG_1), "Ric not added to configurations."); - assertEquals(RIC_CONFIG_1, appConfigUnderTest.getRic(RIC_CONFIG_1.ricId()), + assertEquals(RIC_CONFIG_1, appConfigUnderTest.getRic(RIC_CONFIG_1.getRicId()), "Not correct Ric retrieved from configurations."); update = appConfigUnderTest.setConfiguration(configParserResult(RIC_CONFIG_1)).collectList().block(); @@ -98,11 +91,9 @@ class ApplicationConfigTest { .setConfiguration(configParserResult(RIC_CONFIG_1, RIC_CONFIG_2, RIC_CONFIG_3)).collectList().block(); assertEquals(3, update.size()); - ImmutableRicConfig changedRicConfig = ImmutableRicConfig.builder() // - .ricId(RIC_CONFIG_1.ricId()) // + RicConfig changedRicConfig = RicConfig.builder() // + .ricId(RIC_CONFIG_1.getRicId()) // .baseUrl("changed_ric1_url") // - .managedElementIds(new Vector<>()) // - .controllerName("") // .build(); update = appConfigUnderTest.setConfiguration(configParserResult(changedRicConfig, RIC_CONFIG_2, RIC_CONFIG_3)) @@ -110,7 +101,7 @@ class ApplicationConfigTest { assertEquals(1, update.size()); assertEquals(RicConfigUpdate.Type.CHANGED, update.get(0).getType()); - assertEquals(changedRicConfig, appConfigUnderTest.getRic(RIC_CONFIG_1.ricId()), + assertEquals(changedRicConfig, appConfigUnderTest.getRic(RIC_CONFIG_1.getRicId()), "Changed Ric not retrieved from configurations."); } diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ApplicationTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ApplicationTest.java index 569cb577..04845244 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ApplicationTest.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ApplicationTest.java @@ -46,15 +46,12 @@ import java.util.List; import org.json.JSONObject; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1ClientFactory; import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClient; import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClientFactory; import org.onap.ccsdk.oran.a1policymanagementservice.clients.SecurityContext; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig.RicConfigUpdate; -import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ImmutableRicConfig; -import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ImmutableWebClientConfig; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.RicConfig; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.WebClientConfig; import org.onap.ccsdk.oran.a1policymanagementservice.controllers.ServiceCallbackInfo; @@ -90,18 +87,16 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; 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=./src/test/resources/keystore.jks", // - "app.webclient.trust-store=./src/test/resources/truststore.jks", // + "server.ssl.key-store=./config/keystore.jks", // + "app.webclient.trust-store=./config/truststore.jks", // "app.webclient.trust-store-used=true", // "app.vardata-directory=./target/testdata", // "app.filepath=" // @@ -319,8 +314,10 @@ class ApplicationTest { @Test void testTrustValidation() { addRic("ric1"); + String rsp = restClient(true).get("/rics").block(); // restClient(true) enables trust validation assertThat(rsp).contains("ric1"); + } @Test @@ -922,15 +919,20 @@ class ApplicationTest { final Instant startTime = Instant.now(); List threads = new ArrayList<>(); List tests = new ArrayList<>(); - a1ClientFactory.setResponseDelay(Duration.ofMillis(1)); + a1ClientFactory.setResponseDelay(Duration.ofMillis(2)); addRic("ric"); addPolicyType("type1", "ric"); addPolicyType("type2", "ric"); + final String NON_RESPONDING_RIC = "NonRespondingRic"; + Ric nonRespondingRic = addRic(NON_RESPONDING_RIC); + MockA1Client a1Client = a1ClientFactory.getOrCreateA1Client(NON_RESPONDING_RIC); + a1Client.setErrorInject("errorInject"); + for (int i = 0; i < 10; ++i) { AsyncRestClient restClient = restClient(); - ConcurrencyTestRunnable test = - new ConcurrencyTestRunnable(restClient, supervision, a1ClientFactory, rics, policyTypes); + ConcurrencyTestRunnable test = new ConcurrencyTestRunnable(restClient, supervision, a1ClientFactory, rics, + policyTypes); Thread thread = new Thread(test, "TestThread_" + i); thread.start(); threads.add(thread); @@ -944,19 +946,22 @@ class ApplicationTest { } assertThat(policies.size()).isZero(); logger.info("Concurrency test took " + Duration.between(startTime, Instant.now())); + + assertThat(nonRespondingRic.getState()).isEqualTo(RicState.UNAVAILABLE); + nonRespondingRic.setState(RicState.AVAILABLE); } private AsyncRestClient restClient(String baseUrl, boolean useTrustValidation) { WebClientConfig config = this.applicationConfig.getWebClientConfig(); - config = ImmutableWebClientConfig.builder() // - .keyStoreType(config.keyStoreType()) // - .keyStorePassword(config.keyStorePassword()) // - .keyStore(config.keyStore()) // - .keyPassword(config.keyPassword()) // + config = WebClientConfig.builder() // + .keyStoreType(config.getKeyStoreType()) // + .keyStorePassword(config.getKeyStorePassword()) // + .keyStore(config.getKeyStore()) // + .keyPassword(config.getKeyPassword()) // .isTrustStoreUsed(useTrustValidation) // - .trustStore(config.trustStore()) // - .trustStorePassword(config.trustStorePassword()) // - .httpProxyConfig(config.httpProxyConfig()) // + .trustStore(config.getTrustStore()) // + .trustStorePassword(config.getTrustStorePassword()) // + .httpProxyConfig(config.getHttpProxyConfig()) // .build(); AsyncRestClientFactory f = new AsyncRestClientFactory(config, new SecurityContext("")); @@ -1041,11 +1046,10 @@ class ApplicationTest { if (managedElement != null) { mes.add(managedElement); } - return ImmutableRicConfig.builder() // + return RicConfig.builder() // .ricId(ricId) // .baseUrl(ricId) // .managedElementIds(mes) // - .controllerName("") // .build(); } diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConfigurationControllerTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConfigurationControllerTest.java index d500ba3e..51a68389 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConfigurationControllerTest.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConfigurationControllerTest.java @@ -30,13 +30,11 @@ import java.time.Duration; import org.apache.commons.io.FileUtils; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.io.TempDir; import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClient; import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClientFactory; import org.onap.ccsdk.oran.a1policymanagementservice.clients.SecurityContext; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig; -import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ImmutableWebClientConfig; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.WebClientConfig; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Rics; import org.onap.ccsdk.oran.a1policymanagementservice.tasks.RefreshConfigTask; @@ -52,13 +50,11 @@ import org.springframework.context.annotation.Bean; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; 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; -@ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @TestPropertySource(properties = { // "server.ssl.key-store=./config/keystore.jks", // @@ -166,15 +162,15 @@ class ConfigurationControllerTest { private AsyncRestClient restClient() { WebClientConfig config = this.applicationConfig.getWebClientConfig(); - config = ImmutableWebClientConfig.builder() // - .keyStoreType(config.keyStoreType()) // - .keyStorePassword(config.keyStorePassword()) // - .keyStore(config.keyStore()) // - .keyPassword(config.keyPassword()) // + config = WebClientConfig.builder() // + .keyStoreType(config.getKeyStoreType()) // + .keyStorePassword(config.getKeyStorePassword()) // + .keyStore(config.getKeyStore()) // + .keyPassword(config.getKeyPassword()) // .isTrustStoreUsed(false) // - .trustStore(config.trustStore()) // - .trustStorePassword(config.trustStorePassword()) // - .httpProxyConfig(config.httpProxyConfig()) // + .trustStore(config.getTrustStore()) // + .trustStorePassword(config.getTrustStorePassword()) // + .httpProxyConfig(config.getHttpProxyConfig()) // .build(); AsyncRestClientFactory f = new AsyncRestClientFactory(config, new SecurityContext("")); diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTaskTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTaskTest.java index f09bd05d..2ecb9c28 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTaskTest.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTaskTest.java @@ -38,7 +38,6 @@ import java.io.IOException; import java.net.URL; import java.time.Duration; import java.util.Arrays; -import java.util.HashMap; import java.util.Optional; import java.util.Properties; import java.util.Vector; @@ -55,8 +54,6 @@ import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationCo import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfigParser; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfigParser.ConfigParserResult; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ConfigurationFile; -import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ImmutableConfigParserResult; -import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ImmutableRicConfig; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.RicConfig; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policies; import org.onap.ccsdk.oran.a1policymanagementservice.repository.PolicyTypes; @@ -77,11 +74,10 @@ class RefreshConfigTaskTest { ConfigurationFile configurationFileMock; private static final String RIC_1_NAME = "ric1"; - private static final RicConfig CORRECT_RIC_CONIFG = ImmutableRicConfig.builder() // + private static final RicConfig CORRECT_RIC_CONIFG = RicConfig.builder() // .ricId(RIC_1_NAME) // .baseUrl("http://localhost:8080/") // .managedElementIds(new Vector(Arrays.asList("kista_1", "kista_2"))) // - .controllerName("") // .build(); private RefreshConfigTask createTestObject(boolean configFileExists) { @@ -91,6 +87,7 @@ class RefreshConfigTaskTest { private RefreshConfigTask createTestObject(boolean configFileExists, Rics rics, Policies policies, boolean stubConfigFileExists) { SecurityContext secContext = new SecurityContext(""); + RefreshConfigTask obj = spy(new RefreshConfigTask(configurationFileMock, appConfig, rics, policies, new Services(appConfig), new PolicyTypes(appConfig), new A1ClientFactory(appConfig, secContext), secContext)); @@ -147,11 +144,8 @@ class RefreshConfigTaskTest { } ConfigParserResult configParserResult(RicConfig... rics) { - return ImmutableConfigParserResult.builder() // + return ConfigParserResult.builder() // .ricConfigs(Arrays.asList(rics)) // - .dmaapConsumerTopicUrl("") // - .dmaapProducerTopicUrl("") // - .controllerConfigs(new HashMap<>()) // .build(); } diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSupervisionTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSupervisionTest.java index b76131df..b2bf58e4 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSupervisionTest.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSupervisionTest.java @@ -24,8 +24,8 @@ 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.times; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import java.time.Instant; @@ -45,7 +45,7 @@ import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1Client; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1ClientFactory; import org.onap.ccsdk.oran.a1policymanagementservice.clients.SecurityContext; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig; -import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ImmutableRicConfig; +import org.onap.ccsdk.oran.a1policymanagementservice.configuration.RicConfig; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Lock; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Lock.LockType; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policies; @@ -65,7 +65,7 @@ class RicSupervisionTest { .schema("") // .build(); - private static final Ric RIC_1 = new Ric(ImmutableRicConfig.builder() // + private static final Ric RIC_1 = new Ric(RicConfig.builder() // .ricId("ric_1") // .baseUrl("baseUrl1") // .managedElementIds(new Vector(Arrays.asList("kista_1", "kista_2"))) // @@ -148,7 +148,8 @@ class RicSupervisionTest { supervisorUnderTest.checkAllRics(); verify(supervisorUnderTest).checkAllRics(); - verifyNoMoreInteractions(supervisorUnderTest); + verify(synchronizationTaskMock, times(0)).synchronizeRic(RIC_1); + assertThat(RIC_1.getState()).isEqualTo(RicState.AVAILABLE); } @Test @@ -156,18 +157,13 @@ class RicSupervisionTest { doReturn(Mono.just(a1ClientMock)).when(a1ClientFactory).createA1Client(any(Ric.class)); RIC_1.setState(RicState.UNAVAILABLE); rics.put(RIC_1); - RicSupervision supervisorUnderTest = spy(createRicSupervision()); - doReturn(synchronizationTaskMock).when(supervisorUnderTest).createSynchronizationTask(); doReturn(Mono.just(RIC_1)).when(synchronizationTaskMock).synchronizeRic(any()); - supervisorUnderTest.checkAllRics(); - - verify(supervisorUnderTest).checkAllRics(); - verify(supervisorUnderTest).createSynchronizationTask(); verify(synchronizationTaskMock).synchronizeRic(RIC_1); - verifyNoMoreInteractions(supervisorUnderTest); + + assertThat(RIC_1.getState()).isEqualTo(RicState.UNAVAILABLE); } @Test @@ -181,7 +177,8 @@ class RicSupervisionTest { supervisorUnderTest.checkAllRics(); verify(supervisorUnderTest).checkAllRics(); - verifyNoMoreInteractions(supervisorUnderTest); + verify(synchronizationTaskMock, times(0)).synchronizeRic(RIC_1); + assertThat(RIC_1.getState()).isEqualTo(RicState.SYNCHRONIZING); } @Test @@ -197,7 +194,8 @@ class RicSupervisionTest { supervisorUnderTest.checkAllRics(); verify(supervisorUnderTest).checkAllRics(); - verifyNoMoreInteractions(supervisorUnderTest); + verify(synchronizationTaskMock, times(0)).synchronizeRic(RIC_1); + assertThat(RIC_1.getState()).isEqualTo(RicState.UNAVAILABLE); } @@ -219,9 +217,9 @@ class RicSupervisionTest { supervisorUnderTest.checkAllRics(); verify(supervisorUnderTest).checkAllRics(); - verify(supervisorUnderTest).createSynchronizationTask(); verify(synchronizationTaskMock).synchronizeRic(RIC_1); - verifyNoMoreInteractions(supervisorUnderTest); + + assertThat(RIC_1.getState()).isEqualTo(RicState.UNAVAILABLE); } @Test @@ -242,9 +240,9 @@ class RicSupervisionTest { supervisorUnderTest.checkAllRics(); verify(supervisorUnderTest).checkAllRics(); - verify(supervisorUnderTest).createSynchronizationTask(); verify(synchronizationTaskMock).synchronizeRic(RIC_1); - verifyNoMoreInteractions(supervisorUnderTest); + + assertThat(RIC_1.getState()).isEqualTo(RicState.UNAVAILABLE); } @Test @@ -261,7 +259,9 @@ class RicSupervisionTest { supervisorUnderTest.checkAllRics(); verify(supervisorUnderTest).checkAllRics(); - verifyNoMoreInteractions(supervisorUnderTest); + verify(synchronizationTaskMock, times(0)).synchronizeRic(RIC_1); + + assertThat(RIC_1.getState()).isEqualTo(RicState.UNAVAILABLE); } @Test @@ -283,9 +283,9 @@ class RicSupervisionTest { supervisorUnderTest.checkAllRics(); verify(supervisorUnderTest).checkAllRics(); - verify(supervisorUnderTest).createSynchronizationTask(); verify(synchronizationTaskMock).synchronizeRic(RIC_1); - verifyNoMoreInteractions(supervisorUnderTest); + + assertThat(RIC_1.getState()).isEqualTo(RicState.UNAVAILABLE); } @Test @@ -311,9 +311,8 @@ class RicSupervisionTest { supervisorUnderTest.checkAllRics(); verify(supervisorUnderTest).checkAllRics(); - verify(supervisorUnderTest).createSynchronizationTask(); verify(synchronizationTaskMock).synchronizeRic(RIC_1); - verifyNoMoreInteractions(supervisorUnderTest); + assertThat(RIC_1.getState()).isEqualTo(RicState.UNAVAILABLE); } @SuppressWarnings("unchecked") diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSynchronizationTaskTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSynchronizationTaskTest.java index a5795ac9..6386441c 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSynchronizationTaskTest.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSynchronizationTaskTest.java @@ -46,7 +46,8 @@ import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1ClientFactory; import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClientFactory; import org.onap.ccsdk.oran.a1policymanagementservice.clients.SecurityContext; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig; -import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ImmutableRicConfig; +import org.onap.ccsdk.oran.a1policymanagementservice.configuration.RicConfig; +import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.ServiceException; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policies; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policy; import org.onap.ccsdk.oran.a1policymanagementservice.repository.PolicyType; @@ -56,6 +57,8 @@ import org.onap.ccsdk.oran.a1policymanagementservice.repository.Ric.RicState; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Rics; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Service; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Services; +import org.springframework.web.reactive.function.client.WebClientRequestException; +import org.springframework.web.reactive.function.client.WebClientResponseException; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -105,10 +108,9 @@ class RicSynchronizationTaskTest { @BeforeEach void init() { - ric1 = new Ric(ImmutableRicConfig.builder() // + ric1 = new Ric(RicConfig.builder() // .ricId(RIC_1_NAME) // .baseUrl("baseUrl1") // - .managedElementIds(Collections.emptyList()) // .controllerName("controllerName") // .build()); policy1 = createPolicy("policyId1", false); @@ -148,6 +150,35 @@ class RicSynchronizationTaskTest { assertThat(ric1.getSupportedPolicyTypeNames()).hasSize(1); } + @Test + void ricIdleAndErrorDeletingPoliciesAllTheTime_thenSynchronizationWithFailedRecovery() { + setUpCreationOfA1Client(); + simulateRicWithNoPolicyTypes(); + policies.put(policy1); + WebClientResponseException exception = new WebClientResponseException(404, "", null, null, null); + when(a1ClientMock.deleteAllPolicies()).thenReturn(Flux.error(exception)); + RicSynchronizationTask synchronizerUnderTest = createTask(); + ric1.setState(RicState.AVAILABLE); + synchronizerUnderTest.run(ric1); + await().untilAsserted(() -> RicState.UNAVAILABLE.equals(ric1.getState())); + assertThat(policies.size()).isZero(); + assertThat(ric1.getState()).isEqualTo(RicState.UNAVAILABLE); + } + + @Test + void testConnectionError() { + setUpCreationOfA1Client(); + simulateRicWithNoPolicyTypes(); + policies.put(policy1); + WebClientRequestException exception = + new WebClientRequestException(new ServiceException("x"), null, null, null); + when(a1ClientMock.deleteAllPolicies()).thenReturn(Flux.error(exception)); + RicSynchronizationTask synchronizerUnderTest = createTask(); + ric1.setState(RicState.AVAILABLE); + synchronizerUnderTest.run(ric1); + await().untilAsserted(() -> RicState.UNAVAILABLE.equals(ric1.getState())); + } + @Test void ricIdlePolicyTypeInRepo_thenSynchronizationWithReuseOfTypeFromRepoAndCorrectServiceNotified() { rics.put(ric1); @@ -234,58 +265,6 @@ class RicSynchronizationTaskTest { assertThat(ric1.getState()).isEqualTo(RicState.AVAILABLE); } - @Test - void ricIdleAndErrorDeletingPoliciesFirstTime_thenSynchronizationWithDeletionOfPolicies() { - ric1.setState(RicState.AVAILABLE); - rics.put(ric1); - - policies.put(policy1); - - setUpCreationOfA1Client(); - simulateRicWithNoPolicyTypes(); - - when(a1ClientMock.deleteAllPolicies()) // - .thenReturn(Flux.error(new Exception("Exception"))) // - .thenReturn(Flux.just("OK")); - - RicSynchronizationTask synchronizerUnderTest = createTask(); - - ric1.setState(RicState.UNAVAILABLE); - synchronizerUnderTest.run(ric1); - await().untilAsserted(() -> RicState.AVAILABLE.equals(ric1.getState())); - - verify(a1ClientMock, times(2)).deleteAllPolicies(); - verifyNoMoreInteractions(a1ClientMock); - - assertThat(policyTypes.size()).isZero(); - assertThat(policies.size()).isZero(); - assertThat(ric1.getState()).isEqualTo(RicState.AVAILABLE); - } - - @Test - void ricIdleAndErrorDeletingPoliciesAllTheTime_thenSynchronizationWithFailedRecovery() { - setUpCreationOfA1Client(); - simulateRicWithNoPolicyTypes(); - - policies.put(policy1); - - String originalErrorMessage = "Exception"; - when(a1ClientMock.deleteAllPolicies()).thenReturn(Flux.error(new Exception(originalErrorMessage))); - - RicSynchronizationTask synchronizerUnderTest = createTask(); - - ric1.setState(RicState.AVAILABLE); - synchronizerUnderTest.run(ric1); - await().untilAsserted(() -> RicState.UNAVAILABLE.equals(ric1.getState())); - - verify(a1ClientMock, times(2)).deleteAllPolicies(); - verifyNoMoreInteractions(a1ClientMock); - - assertThat(policyTypes.size()).isZero(); - assertThat(policies.size()).isZero(); - assertThat(ric1.getState()).isEqualTo(RicState.UNAVAILABLE); - } - private void setUpCreationOfA1Client() { when(a1ClientFactoryMock.createA1Client(any(Ric.class))).thenReturn(Mono.just(a1ClientMock)); doReturn(Flux.empty()).when(a1ClientMock).deleteAllPolicies(); diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/ServiceSupervisionTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/ServiceSupervisionTest.java index 294b220c..c8c7c723 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/ServiceSupervisionTest.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/ServiceSupervisionTest.java @@ -34,7 +34,6 @@ import ch.qos.logback.core.read.ListAppender; import java.time.Duration; import java.time.Instant; -import java.util.Collections; import org.awaitility.Durations; import org.junit.jupiter.api.Test; @@ -44,7 +43,6 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1Client; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1ClientFactory; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig; -import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ImmutableRicConfig; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.RicConfig; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policies; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policy; @@ -70,11 +68,9 @@ class ServiceSupervisionTest { private Services services; private Service service; private Policies policies; - private RicConfig ricConfig = ImmutableRicConfig.builder() // + private RicConfig ricConfig = RicConfig.builder() // .ricId(RIC_NAME) // .baseUrl("baseUrl") // - .managedElementIds(Collections.emptyList()) // - .controllerName("") // .build(); private Ric ric = new Ric(ricConfig); private PolicyType policyType = PolicyType.builder() // diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/utils/MockA1Client.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/utils/MockA1Client.java index 2a3b28ef..b76f1e72 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/utils/MockA1Client.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/utils/MockA1Client.java @@ -28,6 +28,8 @@ import java.time.Duration; import java.util.List; import java.util.Vector; +import lombok.Setter; + import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1Client; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policies; @@ -44,7 +46,12 @@ import reactor.core.publisher.MonoSink; public class MockA1Client implements A1Client { Policies policies; private final PolicyTypes policyTypes; - private final Duration asynchDelay; + + @Setter + private Duration asynchDelay; + + @Setter + private String errorInject; public MockA1Client(String ricId, ApplicationConfig appConfig, PolicyTypes policyTypes, Duration asynchDelay) { this.policyTypes = policyTypes; @@ -117,14 +124,19 @@ public class MockA1Client implements A1Client { } private Mono mono(T value) { - if (this.asynchDelay.isZero()) { - return Mono.just(value); - } else { - return Mono.create(monoSink -> asynchResponse(monoSink, value)); + Mono res = Mono.just(value); + if (!this.asynchDelay.isZero()) { + res = Mono.create(monoSink -> asynchResponse(monoSink, value)); } + + if (this.errorInject != null) { + res = res.flatMap(x -> monoError(this.errorInject, HttpStatus.BAD_GATEWAY)); + } + + return res; } - public static Mono monoError(String responseBody, HttpStatus status) { + public static 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); diff --git a/a1-policy-management/src/test/resources/keystore.jks b/a1-policy-management/src/test/resources/keystore.jks deleted file mode 100644 index 675785b4..00000000 Binary files a/a1-policy-management/src/test/resources/keystore.jks and /dev/null differ diff --git a/a1-policy-management/src/test/resources/test_application_configuration.json b/a1-policy-management/src/test/resources/test_application_configuration.json index 959f53fd..fef2382a 100644 --- a/a1-policy-management/src/test/resources/test_application_configuration.json +++ b/a1-policy-management/src/test/resources/test_application_configuration.json @@ -1,4 +1,4 @@ -{ +{ "config": { "description": "Application configuration", "ric": [ @@ -13,6 +13,7 @@ { "name": "ric2", "baseUrl": "http://localhost:8081/", + "customAdapterClass": "org.onap.ccsdk.oran.a1policymanagementservice.clients.StdA1ClientVersion2$Factory", "managedElementIds": [ "kista_3", "kista_4" diff --git a/a1-policy-management/src/test/resources/test_application_configuration_with_dmaap_config.json b/a1-policy-management/src/test/resources/test_application_configuration_with_dmaap_config.json index b00720c3..6e1de75e 100644 --- a/a1-policy-management/src/test/resources/test_application_configuration_with_dmaap_config.json +++ b/a1-policy-management/src/test/resources/test_application_configuration_with_dmaap_config.json @@ -1,6 +1,6 @@ { "config": { - "//description" : "Test", + "description": "Test", "controller": [ { "name": "controller1", @@ -14,6 +14,7 @@ "name": "ric1", "controller": "controller1", "baseUrl": "http://localhost:8083/", + "customAdapterClass": "org.onap.ccsdk.oran.a1policymanagementservice.clients.StdA1ClientVersion2$Factory", "managedElementIds": [ "kista_1", "kista_2" @@ -53,4 +54,4 @@ } } } -} +} \ No newline at end of file diff --git a/a1-policy-management/src/test/resources/truststore.jks b/a1-policy-management/src/test/resources/truststore.jks deleted file mode 100644 index e883cd67..00000000 Binary files a/a1-policy-management/src/test/resources/truststore.jks and /dev/null differ diff --git a/docs/offeredapis/swagger/pms-api.json b/docs/offeredapis/swagger/pms-api.json index 9fc8e7bb..5c5915c5 100644 --- a/docs/offeredapis/swagger/pms-api.json +++ b/docs/offeredapis/swagger/pms-api.json @@ -79,7 +79,7 @@ }, "keep_alive_interval_seconds": { "format": "int64", - "description": "keep alive interval for the service. This is a heartbeat supervision of the service, which in regular intervals must invoke a 'keepalive' REST call. When a service does not invoke this call within the given time, it is considered unavailable. An unavailable service will be automatically deregistered and its policies will be deleted. Value 0 means no timeout supervision.", + "description": "keep alive interval for the service. This is used to enable optional heartbeat supervision of the service. If set (> 0) the registered service should regularly invoke a 'keepalive' REST call. When a service fails to invoke this 'keepalive' call within the configured time, the service is considered unavailable. An unavailable service will be automatically deregistered and its policies will be deleted. Value 0 means timeout supervision is disabled.", "type": "integer" } } @@ -559,7 +559,7 @@ }, "/a1-policy/v2/services/{service_id}/keepalive": {"put": { "summary": "Heartbeat indicates that the service is running", - "description": "A registered service must call this in regular intervals to indicate that it is in operation. Absence of this call will lead to that the service will be deregistered and all its policies are removed.", + "description": "A registered service should invoke this operation regularly to indicate that it is still alive. If a registered service fails to invoke this operation before the end of a timeout period the service will be deregistered and all its A1 policies wil be removed. (This timeout can be set or disabled when each service is initially registered)", "operationId": "keepAliveService", "responses": { "200": { @@ -868,7 +868,7 @@ "url": "http://www.apache.org/licenses/LICENSE-2.0" }, "description": "

      General<\/h2>

      The O-RAN Non-RT RIC Policy Management Service provides a REST API for management of A1 policies.
      The main tasks of the service are:<\/p>

      • A1 Policy creation, modification and deletion.<\/li>
      • Monitoring and maintaining consistency of the SMO view of A1 policies and the Near-RT RICs<\/li>
      • Maintaining a view of supported Near-RT RIC policy types<\/li>
      • Supervision of using services (R-APPs). When a service is unavailable, its policies are removed.<\/li><\/ul>

        APIs provided by the service<\/h2>

        A1 Policy Management<\/h3>

        This is an API for management of A1 Policies.<\/p>

        • A1 Policy retrieval, creation, modification and deletion.<\/li>
        • Retrieval of supported A1 Policy types for a Near-RT RIC<\/li>
        • Retrieval of status for existing A1 policies<\/li><\/ul>

          Management of configuration<\/h3>

          API for updating and retrieval of the component configuration. Note that there other ways to maintain the configuration.<\/p>

          Callbacks<\/h3>

          These are endpoints that are invoked by this service. The callbacks are registered in this service at service registration.<\/p>

          NearRT-RIC Repository<\/h3>

          This is an API that provides support for looking up a NearRT-RIC. Each A1 policy is targeted for one Near-RT RIC.<\/p>

          Health Check<\/h3>

          API used for supervision of the PMS component.<\/p>

          Service Registry and Supervision<\/h3>

          API used for registering services that uses PMS. Each A1 policy is owned by a service. PMS can supervise each registered service and will automatically remove policies for unavailable services.<\/p>", - "title": "A1 Policy management service", + "title": "A1 Policy Management Service", "version": "1.1.0" }, "tags": [ diff --git a/docs/offeredapis/swagger/pms-api.yaml b/docs/offeredapis/swagger/pms-api.yaml index 3fd496bd..1f84399e 100644 --- a/docs/offeredapis/swagger/pms-api.yaml +++ b/docs/offeredapis/swagger/pms-api.yaml @@ -1,6 +1,6 @@ openapi: 3.0.1 info: - title: A1 Policy management service + title: A1 Policy Management Service description:

          General

          The O-RAN Non-RT RIC Policy Management Service provides a REST API for management of A1 policies.
          The main tasks of the service are:

          • A1 Policy creation, modification and deletion.
          • Monitoring and maintaining @@ -434,9 +434,11 @@ paths: tags: - Service Registry and Supervision summary: Heartbeat indicates that the service is running - description: A registered service must call this in regular intervals to indicate - that it is in operation. Absence of this call will lead to that the service - will be deregistered and all its policies are removed. + description: A registered service should invoke this operation regularly to + indicate that it is still alive. If a registered service fails to invoke this + operation before the end of a timeout period the service will be deregistered + and all its A1 policies wil be removed. (This timeout can be set or disabled + when each service is initially registered) operationId: keepAliveService parameters: - name: service_id @@ -896,12 +898,13 @@ components: description: identity of the service keep_alive_interval_seconds: type: integer - description: keep alive interval for the service. This is a heartbeat supervision - of the service, which in regular intervals must invoke a 'keepalive' REST - call. When a service does not invoke this call within the given time, - it is considered unavailable. An unavailable service will be automatically - deregistered and its policies will be deleted. Value 0 means no timeout - supervision. + description: keep alive interval for the service. This is used to enable + optional heartbeat supervision of the service. If set (> 0) the registered + service should regularly invoke a 'keepalive' REST call. When a service + fails to invoke this 'keepalive' call within the configured time, the + service is considered unavailable. An unavailable service will be automatically + deregistered and its policies will be deleted. Value 0 means timeout supervision + is disabled. format: int64 description: Information for one service policy_info_list_v2: -- cgit 1.2.3-korg