Merge "Add docker-compose file for ECS"
authorJohn Keeney <john.keeney@est.tech>
Wed, 25 Nov 2020 10:21:43 +0000 (10:21 +0000)
committerGerrit Code Review <gerrit@o-ran-sc.org>
Wed, 25 Nov 2020 10:21:43 +0000 (10:21 +0000)
221 files changed:
.gitignore
.gitmodules [new file with mode: 0644]
docs/.project [deleted file]
docs/api-docs.rst
docs/conf.py
docs/developer-guide.rst
docs/images/NonRtRicComponents.png [deleted file]
docs/images/swagger.png [new file with mode: 0644]
docs/images/yaml_logo.png [new file with mode: 0644]
docs/index.rst
docs/installation-guide.rst [deleted file]
docs/offeredapis/swagger/ecs-api.json [moved from enrichment-coordinator-service/docs/api.json with 73% similarity]
docs/offeredapis/swagger/pms-api.json [new symlink]
docs/overview.rst
docs/policy-agent-api.rst [deleted file]
docs/requirements-docs.txt
docs/sdnc-a1-controller-api.rst [deleted file]
enrichment-coordinator-service/.gitignore [new file with mode: 0644]
enrichment-coordinator-service/Dockerfile
enrichment-coordinator-service/config/application.yaml
enrichment-coordinator-service/src/main/java/org/oransc/enrichment/BeanFactory.java
enrichment-coordinator-service/src/main/java/org/oransc/enrichment/clients/ProducerCallbacks.java [deleted file]
enrichment-coordinator-service/src/main/java/org/oransc/enrichment/configuration/ApplicationConfig.java
enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/ErrorResponse.java
enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/VoidResponse.java
enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/consumer/ConsumerCallbacks.java [new file with mode: 0644]
enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/consumer/ConsumerConsts.java
enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/consumer/ConsumerController.java
enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/consumer/ConsumerEiJobInfo.java
enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/consumer/ConsumerEiJobStatus.java
enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/consumer/ConsumerEiTypeInfo.java
enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/producer/ProducerCallbacks.java [new file with mode: 0644]
enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/producer/ProducerController.java
enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/producer/ProducerJobInfo.java [moved from enrichment-coordinator-service/src/main/java/org/oransc/enrichment/clients/ProducerJobInfo.java with 94% similarity]
enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/producer/ProducerRegistrationInfo.java
enrichment-coordinator-service/src/main/java/org/oransc/enrichment/repository/EiJob.java
enrichment-coordinator-service/src/main/java/org/oransc/enrichment/repository/EiJobs.java
enrichment-coordinator-service/src/main/java/org/oransc/enrichment/repository/EiProducer.java
enrichment-coordinator-service/src/main/java/org/oransc/enrichment/repository/EiProducers.java
enrichment-coordinator-service/src/main/java/org/oransc/enrichment/repository/EiTypes.java
enrichment-coordinator-service/src/main/java/org/oransc/enrichment/tasks/ProducerSupervision.java
enrichment-coordinator-service/src/test/java/org/oransc/enrichment/ApplicationTest.java
enrichment-coordinator-service/src/test/java/org/oransc/enrichment/controller/ConsumerSimulatorController.java [new file with mode: 0644]
enrichment-coordinator-service/src/test/java/org/oransc/enrichment/controller/ProducerSimulatorController.java
onap/oran [new submodule]
policy-agent/.gitignore
policy-agent/Dockerfile
policy-agent/config/README [deleted file]
policy-agent/config/application.yaml [deleted file]
policy-agent/config/application_configuration.json [deleted file]
policy-agent/config/keystore.jks [deleted file]
policy-agent/config/truststore.jks [deleted file]
policy-agent/docs/api.yaml [deleted file]
policy-agent/pom.xml
policy-agent/src [new symlink]
policy-agent/src/main/java/org/oransc/policyagent/Application.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/BeanFactory.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/SwaggerConfig.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/aspect/LogAspect.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/clients/A1Client.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/clients/A1ClientFactory.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/clients/AsyncRestClient.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/clients/OscA1Client.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/clients/SdncJsonHelper.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/clients/SdncOnapA1Client.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/clients/SdncOscA1Client.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/clients/StdA1ClientVersion1.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfig.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfigParser.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/configuration/AsyncConfiguration.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/configuration/ControllerConfig.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/configuration/WebClientConfig.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyController.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyInfo.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/controllers/RicInfo.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/controllers/RicRepositoryController.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceController.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceRegistrationInfo.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceStatus.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/controllers/StatusController.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapMessageConsumer.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapMessageHandler.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapRequestMessage.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapResponseMessage.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/exceptions/ServiceException.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/repository/Lock.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/repository/Policies.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/repository/Policy.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/repository/PolicyType.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/repository/PolicyTypes.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/repository/Ric.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/repository/Rics.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/repository/Service.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/repository/Services.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/tasks/EnvironmentProcessor.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/tasks/RefreshConfigTask.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/tasks/RicSupervision.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/tasks/RicSynchronizationTask.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/tasks/ServiceSupervision.java [deleted file]
policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java [deleted file]
policy-agent/src/test/java/org/oransc/policyagent/ConcurrencyTestRunnable.java [deleted file]
policy-agent/src/test/java/org/oransc/policyagent/MockPolicyAgent.java [deleted file]
policy-agent/src/test/java/org/oransc/policyagent/aspect/LogAspectTest.java [deleted file]
policy-agent/src/test/java/org/oransc/policyagent/clients/A1ClientFactoryTest.java [deleted file]
policy-agent/src/test/java/org/oransc/policyagent/clients/A1ClientHelper.java [deleted file]
policy-agent/src/test/java/org/oransc/policyagent/clients/AsyncRestClientTest.java [deleted file]
policy-agent/src/test/java/org/oransc/policyagent/clients/OscA1ClientTest.java [deleted file]
policy-agent/src/test/java/org/oransc/policyagent/clients/SdncOnapA1ClientTest.java [deleted file]
policy-agent/src/test/java/org/oransc/policyagent/clients/SdncOscA1ClientTest.java [deleted file]
policy-agent/src/test/java/org/oransc/policyagent/clients/StdA1ClientTest.java [deleted file]
policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigParserTest.java [deleted file]
policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigTest.java [deleted file]
policy-agent/src/test/java/org/oransc/policyagent/dmaap/DmaapMessageConsumerTest.java [deleted file]
policy-agent/src/test/java/org/oransc/policyagent/dmaap/DmaapMessageHandlerTest.java [deleted file]
policy-agent/src/test/java/org/oransc/policyagent/repository/LockTest.java [deleted file]
policy-agent/src/test/java/org/oransc/policyagent/tasks/EnvironmentProcessorTest.java [deleted file]
policy-agent/src/test/java/org/oransc/policyagent/tasks/RefreshConfigTaskTest.java [deleted file]
policy-agent/src/test/java/org/oransc/policyagent/tasks/RicSupervisionTest.java [deleted file]
policy-agent/src/test/java/org/oransc/policyagent/tasks/RicSynchronizationTaskTest.java [deleted file]
policy-agent/src/test/java/org/oransc/policyagent/tasks/ServiceSupervisionTest.java [deleted file]
policy-agent/src/test/java/org/oransc/policyagent/utils/LoggingUtils.java [deleted file]
policy-agent/src/test/java/org/oransc/policyagent/utils/MockA1Client.java [deleted file]
policy-agent/src/test/java/org/oransc/policyagent/utils/MockA1ClientFactory.java [deleted file]
policy-agent/src/test/resources/policy_types/demo-policy-schema-1.json [deleted file]
policy-agent/src/test/resources/policy_types/demo-policy-schema-2.json [deleted file]
policy-agent/src/test/resources/policy_types/demo-policy-schema-3.json [deleted file]
policy-agent/src/test/resources/test_application_configuration.json [deleted file]
policy-agent/src/test/resources/test_application_configuration_with_dmaap_config.json [deleted file]
pom.xml
r-app-catalogue/.gitignore [new file with mode: 0644]
r-app-catalogue/Dockerfile [new file with mode: 0644]
r-app-catalogue/README.md [new file with mode: 0644]
r-app-catalogue/api/rac-api.json [new file with mode: 0644]
r-app-catalogue/api/rac-api.yaml [new file with mode: 0644]
r-app-catalogue/config/application.yaml [new file with mode: 0644]
r-app-catalogue/pom.xml [new file with mode: 0644]
r-app-catalogue/src/main/java/org/oransc/rappcatalogue/api/GeneralRappCatalogueControllerAdvisor.java [new file with mode: 0644]
r-app-catalogue/src/main/java/org/oransc/rappcatalogue/api/ServicesApiDelegateImpl.java [new file with mode: 0644]
r-app-catalogue/src/main/java/org/oransc/rappcatalogue/exception/HeaderException.java [moved from policy-agent/src/main/java/org/oransc/policyagent/configuration/RicConfig.java with 56% similarity]
r-app-catalogue/src/main/java/org/oransc/rappcatalogue/exception/InvalidServiceException.java [moved from policy-agent/src/main/java/org/oransc/policyagent/exceptions/EnvironmentLoaderException.java with 63% similarity]
r-app-catalogue/src/main/java/org/oransc/rappcatalogue/exception/ServiceNotFoundException.java [moved from policy-agent/src/main/java/org/oransc/policyagent/clients/A1UriBuilder.java with 61% similarity]
r-app-catalogue/src/test/java/org/oransc/rappcatalogue/api/GeneralRappCatalogueControllerAdvisorTest.java [new file with mode: 0644]
r-app-catalogue/src/test/java/org/oransc/rappcatalogue/api/ServicesApiDelegateImplTest.java [new file with mode: 0644]
sdnc-a1-controller/northbound/README.md
sdnc-a1-controller/northbound/features/README.md [new file with mode: 0644]
sdnc-a1-controller/northbound/features/features-sdnc-a1-northbound/README.md [new file with mode: 0644]
sdnc-a1-controller/northbound/features/installer/README.md [new file with mode: 0644]
sdnc-a1-controller/northbound/features/sdnc-a1-northbound-all/README.md [new file with mode: 0644]
sdnc-a1-controller/northbound/nonrt-ric-api/README.md [new file with mode: 0644]
sdnc-a1-controller/northbound/nonrt-ric-api/features/README.md [new file with mode: 0644]
sdnc-a1-controller/northbound/nonrt-ric-api/features/features-nonrt-ric-api/README.md [new file with mode: 0644]
sdnc-a1-controller/northbound/nonrt-ric-api/features/sdnc-nonrt-ric-api/README.md [new file with mode: 0644]
sdnc-a1-controller/northbound/nonrt-ric-api/installer/README.md [new file with mode: 0644]
sdnc-a1-controller/northbound/nonrt-ric-api/model/README.md [new file with mode: 0644]
sdnc-a1-controller/northbound/nonrt-ric-api/provider/README.md [new file with mode: 0644]
sdnc-a1-controller/oam/README.md
sdnc-a1-controller/oam/installation/README.md [new file with mode: 0644]
sdnc-a1-controller/oam/installation/sdnc-a1/README.md [new file with mode: 0644]
sdnc-a1-controller/oam/platform-logic/README.md [new file with mode: 0644]
sdnc-a1-controller/oam/platform-logic/installer/README.md [new file with mode: 0644]
sdnc-a1-controller/oam/platform-logic/setup/README.md [new file with mode: 0644]
test/auto-test/.gitignore
test/auto-test/FTC1.sh
test/auto-test/FTC10.sh
test/auto-test/FTC100.sh
test/auto-test/FTC110.sh
test/auto-test/FTC1100.sh
test/auto-test/FTC150.sh
test/auto-test/FTC300.sh
test/auto-test/FTC310.sh
test/auto-test/FTC350.sh
test/auto-test/FTC800.sh
test/auto-test/FTC810.sh
test/auto-test/FTC850.sh
test/auto-test/FTC900.sh
test/auto-test/PM_DEMO.sh
test/auto-test/README.md
test/auto-test/Suite-policy-all.sh [moved from test/auto-test/Suite-all.sh with 77% similarity]
test/auto-test/Suite-policy-interfaces.sh [moved from test/auto-test/Suite-interfaces.sh with 86% similarity]
test/auto-test/demo-testdata/STD2/pi1_template.json [new file with mode: 0644]
test/auto-test/demo-testdata/STD2/qos-agent-modified.json [moved from policy-agent/src/test/resources/test_osc_get_schema_response.json with 68% similarity]
test/auto-test/demo-testdata/STD2/qos2-agent-modified.json [new file with mode: 0644]
test/auto-test/demo-testdata/STD2/sim_qos.json [new file with mode: 0644]
test/auto-test/demo-testdata/STD2/sim_qos2.json [new file with mode: 0644]
test/auto-test/testdata/STD2/pi_qos2_template.json [new file with mode: 0644]
test/auto-test/testdata/STD2/pi_qos_template.json [new file with mode: 0644]
test/auto-test/testdata/STD2/qos-agent-modified.json [new file with mode: 0644]
test/auto-test/testdata/STD2/qos2-agent-modified.json [new file with mode: 0644]
test/auto-test/testdata/STD2/sim_qos.json [new file with mode: 0644]
test/auto-test/testdata/STD2/sim_qos2.json [new file with mode: 0644]
test/auto-test/testdata/ecs/empty-type.json [new file with mode: 0644]
test/auto-test/testdata/ecs/job-template2.json [new file with mode: 0644]
test/common/README.md
test/common/agent_api_functions.sh
test/common/api_curl.sh
test/common/count_json_elements.py
test/common/cr_api_functions.sh [new file with mode: 0644]
test/common/create_policies_process.py
test/common/create_rics_json.py
test/common/delete_policies_process.py
test/common/ecs_api_functions.sh
test/common/prodstub_api_functions.sh
test/common/ricsimulator_api_functions.sh
test/common/test_env-onap-guilin.sh [new file with mode: 0644]
test/common/test_env-onap-master.sh [new file with mode: 0644]
test/common/test_env-oran-master.sh [new file with mode: 0755]
test/common/test_env.sh [changed mode: 0755->0644]
test/common/testcase_common.sh
test/cr/Dockerfile
test/cr/README.md
test/cr/app/cr.py
test/cr/basic_test.sh
test/cr/cr-build-start.sh
test/jenkins/run_test.sh
test/prodstub/.gitignore
test/prodstub/app/prodstub.py
test/prodstub/app/requirements.txt
test/prodstub/basic_test.sh
test/prodstub/prod-stub-build-start.sh
test/simulator-group/sim-monitor.js
tox.ini

index e5a2f72..26c6731 100644 (file)
@@ -6,10 +6,12 @@ docs/_build/
 
 # Eclipse
 .checkstyle
+.classpath
+target/
 .sts4-cache
 .project
 .settings
 .pydevproject
 infer-out/
 
-.vscode
\ No newline at end of file
+.vscode
diff --git a/.gitmodules b/.gitmodules
new file mode 100644 (file)
index 0000000..5056419
--- /dev/null
@@ -0,0 +1,3 @@
+[submodule "onap/oran"]
+       path = onap/oran
+       url = https://gerrit.onap.org/r/ccsdk/oran
diff --git a/docs/.project b/docs/.project
deleted file mode 100644 (file)
index e248a4f..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-       <name>docs</name>
-       <comment></comment>
-       <projects>
-       </projects>
-       <buildSpec>
-       </buildSpec>
-       <natures>
-       </natures>
-</projectDescription>
index 67f3cee..ed0cc79 100644 (file)
@@ -2,44 +2,60 @@
 .. http://creativecommons.org/licenses/by/4.0
 .. Copyright (C) 2020 Nordix
 
+.. _api_docs:
+
+.. |swagger-icon| image:: ./images/swagger.png
+                  :width: 40px
+
+.. |yaml-icon| image:: ./images/yaml_logo.png
+                  :width: 40px
+
+
 ========
 API-Docs
 ========
 
 This is the API-docs of Non-RT RIC.
 
-.. contents::
-   :depth: 3
-   :local:
-
-The Non-RT RIC consists of two parts, described in the sections below:
+The Non-RT RIC consists of three parts, described in the sections below:
  * The Policy Agent
- * The SDNC A1 Controller
+ * The Enrichment Coordinator Service
+ * The rAPP Catalogue
 
 
 Policy Agent
 ============
 
-The Policy Agent provides common functionality useful for R-Apps, for instance:
- * A repository of available Near-RT RICs, their policy types and policy instances.
- * An A1 connection to the Near-RT RICs.
+For information about the The Policy Agent that is implemented in ONAP, see `readthedocs`_ and `wiki`_.
+
+.. _readthedocs: https://docs.onap.org/projects/onap-ccsdk-oran/en/latest/index.html
+.. _wiki: https://wiki.onap.org/pages/viewpage.action?pageId=84644984
+
+Enrichment Coordinator Service
+==============================
+
+See `ECS API <./ecs-api.html>`_ for how to use the API.
+
+.. csv-table::
+   :header: "API name", "|swagger-icon|"
+   :widths: 10,5
+
+   "ECS API", ":download:`link <./offeredapis/swagger/ecs-api.json>`"
 
-See :ref:`policy-agent-api` for how to use the API.
 
-See the README.md file in the nonrtric/policy-agent repo for info about how to use it.
+rAPP Catalogue
+==============
 
-API Functions
--------------
-See the following document for the Policy Agent API: nonrtric/policy-agent/docs/api.yaml
+The Non RT-RIC Service Catalogue provides a way for services to register themselves for other services to discover.
 
-SDNC A1 Controller
-==================
+See `RAC API <./rac-api.html>`_ for how to use the API.
 
-An ONAP SDNC Controller for the A1 interface.
 
-See :ref:`sdnc-a1-controller-api` for how to use the API.
+.. csv-table::
+   :header: "API name", "|swagger-icon|", "|yaml-icon|"
+   :widths: 10,5, 5
 
-See the README.md file in the nonrtric/sdnc-a1-controller repo for info about how to use it.
+   "RAC API", ":download:`link <../r-app-catalogue/api/rac-api.json>`", ":download:`link <../r-app-catalogue/api/rac-api.yaml>`"
 
 Complementary tools
 ===================
index d620289..09eeb37 100644 (file)
@@ -7,9 +7,30 @@ branch = 'latest'
 linkcheck_ignore = [
     'http://localhost.*',
     'http://127.0.0.1.*',
-    'https://gerrit.o-ran-sc.org.*'
+    'https://gerrit.o-ran-sc.org.*',
+    './rac-api.html', #Generated file that doesn't exist at link check.
+    './ecs-api.html' #Generated file that doesn't exist at link check.
 ]
 
+extensions = ['sphinxcontrib.redoc', 'sphinx.ext.intersphinx',]
+
+redoc = [
+            {
+                'name': 'RAC API',
+                'page': 'rac-api',
+                'spec': '../r-app-catalogue/api/rac-api.json',
+                'embed': True,
+            },
+            {
+                'name': 'ECS API',
+                'page': 'ecs-api',
+                'spec': './offeredapis/swagger/ecs-api.json',
+                'embed': True,
+            }
+        ]
+
+redoc_uri = 'https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js'
+
 #intershpinx mapping with other projects
 intersphinx_mapping = {}
 
index b5fedc3..576cf2d 100644 (file)
@@ -7,123 +7,21 @@ Developer Guide
 
 This document provides a quickstart for developers of the Non-RT RIC.
 
-SDNC A1 Controller
-==================
-
-Prerequisites
--------------
-
-1. Java development kit (JDK), version 8
-2. Maven dependency-management tool, version 3.6 or later
-3. Python, version 2
-4. Docker, version 19.03.1 or latest
-5. Docker Compose, version 1.24.1 or latest
-
-Build and run
--------------
-Go to the northbound directory and run this command ::
-    mvn clean install
-
-This will build the project and create artifcats in maven repo
-
-Go to oam/installation directory and run this command ::
-    mvn clean install -P docker
-
-This will create the docker images required for A1 controller.
-
-After this step check for the docker images created by the maven build with this command ::
-    docker images | grep a1-controller
-
-Go to oam/installation/src/main/yaml and run this command ::
-    docker-compose up -d a1-controller
-
-This will create the docker containers with the A1 controller image, you can check the status of the docker container using ::
-    docker-compose logs -f a1-controller
-
-The SDNC url to access the Northbound API,
-    http://localhost:8282/apidoc/explorer/index.html
-
-Credentials: admin/Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U
-
-Configuration of certs
-----------------------
-The SDNC-A1 controller uses the default keystore and truststore that are built into the container.
-
-The paths and passwords for these stores are located in a properties file:
- nonrtric/sdnc-a1-controller/oam/installation/src/main/properties/https-props.properties
-
-The default truststore includes the a1simulator cert as a trusted cert which is located here:
- https://gerrit.o-ran-sc.org/r/gitweb?p=sim/a1-interface.git;a=tree;f=near-rt-ric-simulator/certificate;h=172c1e5aacd52d760e4416288dc5648a5817ce65;hb=HEAD
-
-The default keystore, truststore, and https-props.properties files can be overridden by mounting new files using the "volumes" field of docker-compose. Uncommment the following lines in docker-compose to do this, and provide paths to the new files:
-
-::
-
-#volumes:
-#   - <path_to_keystore>:/etc/ssl/certs/java/keystore.jks:ro
-#   - <path_to_truststore>:/etc/ssl/certs/java/truststore.jks:ro
-#   - <path_to_https-props>:/opt/onap/sdnc/data/properties/https-props.properties:ro
-
-The target paths in the container should not be modified.
-
-For example, assuming that the keystore, truststore, and https-props.properties files are located in the same directory as docker-compose:
-
-`volumes:`
-    `- ./new_keystore.jks:/etc/ssl/certs/java/keystore.jks:ro`
-
-    `- ./new_truststore.jks:/etc/ssl/certs/java/truststore.jks:ro`
-
-    `- ./new_https-props.properties:/opt/onap/sdnc/data/properties/https-props.properties:ro`
-
 Policy Agent
-============
-
-The O-RAN Non-RT RIC Policy Agent provides a REST API for management of policices. It provides support for:
-
- * Supervision of clients (R-APPs) to eliminate stray policies in case of failure
- * Consistency monitoring of the SMO view of policies and the actual situation in the RICs
- * Consistency monitoring of RIC capabilities (policy types)
- * Policy configuration. This includes:
-
-   * One REST API towards all RICs in the network
-   * Query functions that can find all policies in a RIC, all policies owned by a service (R-APP), all policies of a type etc.
-   * Maps O1 resources (ManagedElement) as defined in O1 to the controlling RIC.
-
-| The Policy Agent can be accessed over the REST API or through the DMaaP Interface. The REST API is documented in the
-| *nonrtric/policy-agent/docs/api.yaml* file. Please refer to the README file of Policy Agent to know more about the API's.
+------------
 
-Configuration of certs
-----------------------
-The Policy Agent uses the default keystore and truststore that are built into the container. The paths and passwords for these stores are located in a yaml file:
- nonrtric/policy-agent/config/application.yaml
+The Policy Management is implemented in ONAP. For documentation see `readthedocs`_ and `wiki`_.
 
-The default truststore includes a1simulator cert as a trusted cert which is located here:
- https://gerrit.o-ran-sc.org/r/gitweb?p=sim/a1-interface.git;a=tree;f=near-rt-ric-simulator/certificate;h=172c1e5aacd52d760e4416288dc5648a5817ce65;hb=HEAD
+.. _readthedocs: https://docs.onap.org/projects/onap-ccsdk-oran/en/latest/index.html
+.. _wiki: https://wiki.onap.org/pages/viewpage.action?pageId=84644984
 
-The default truststore also includes a1controller cert as a trusted cert which is located here (keystore.jks file):
- https://gerrit.o-ran-sc.org/r/gitweb?p=nonrtric.git;a=tree;f=sdnc-a1-controller/oam/installation/sdnc-a1/src/main/resources;h=17fdf6cecc7a866c5ce10a35672b742a9f0c4acf;hb=HEAD
+rAPP Catalogue
+--------------
 
-There is also Policy Agent's own cert in the default truststore for mocking purposes and unit-testing (ApplicationTest.java).
-
-The default keystore, truststore, and application.yaml files can be overridden by mounting new files using the "volumes" field of docker-compose or docker run command.
-
-Assuming that the keystore, truststore, and application.yaml files are located in the same directory as docker-compose, the volumes field should have these entries:
-
-`volumes:`
-      `- ./new_keystore.jks:/opt/app/policy-agent/etc/cert/keystore.jks:ro`
-
-      `- ./new_truststore.jks:/opt/app/policy-agent/etc/cert/truststore.jks:ro`
-
-      `- ./new_application.yaml:/opt/app/policy-agent/config/application.yaml:ro`
-
-The target paths in the container should not be modified.
-
-Example docker run command for mounting new files (assuming they are located in the current directory):
-
-`docker run -p 8081:8081 -p 8433:8433 --name=policy-agent-container --network=nonrtric-docker-net --volume "$PWD/new_keystore.jks:/opt/app/policy-agent/etc/cert/keystore.jks" --volume "$PWD/new_truststore.jks:/opt/app/policy-agent/etc/cert/truststore.jks" --volume "$PWD/new_application.yaml:/opt/app/policy-agent/config/application.yaml" o-ran-sc/nonrtric-policy-agent:2.1.0-SNAPSHOT`
+See the README.md file in the r-app-catalogue folder for how to run the component.
 
 End-to-end call
-===============
+---------------
 
 In order to make a complete end-to-end call, follow the instructions given in this `guide`_.
 
diff --git a/docs/images/NonRtRicComponents.png b/docs/images/NonRtRicComponents.png
deleted file mode 100644 (file)
index 335859b..0000000
Binary files a/docs/images/NonRtRicComponents.png and /dev/null differ
diff --git a/docs/images/swagger.png b/docs/images/swagger.png
new file mode 100644 (file)
index 0000000..f5a9e0c
Binary files /dev/null and b/docs/images/swagger.png differ
diff --git a/docs/images/yaml_logo.png b/docs/images/yaml_logo.png
new file mode 100644 (file)
index 0000000..0492eb4
Binary files /dev/null and b/docs/images/yaml_logo.png differ
index 21469e7..a32323d 100644 (file)
@@ -9,12 +9,9 @@ Non-RT RIC
    :maxdepth: 2
    :caption: Contents:
 
-   ./api-docs.rst
-   ./policy-agent-api.rst
-   ./sdnc-a1-controller-api.rst
-   ./developer-guide.rst
-   ./installation-guide.rst
    ./overview.rst
+   ./developer-guide.rst
+   ./api-docs.rst
    ./use-cases.rst
    ./release-notes.rst
 
diff --git a/docs/installation-guide.rst b/docs/installation-guide.rst
deleted file mode 100644 (file)
index 26c9133..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-.. This work is licensed under a Creative Commons Attribution 4.0 International License.
-.. http://creativecommons.org/licenses/by/4.0
-.. Copyright (C) 2020 Nordix
-
-Installation Guide
-==================
-
-.. contents::
-   :depth: 3
-   :local:
-
-Abstract
---------
-
-This document describes how to install the Non-RT RIC SDNC A1 Controller, its dependencies and required system resources.
-
-This work is in progress. Please visit the `api-docs page`_ for more information about the SDNC A1 Controller and the Policy Agent.
-
-.. _api-docs page: ./api-docs.html
-
-Installation
-------------
-
-Download the SDNC repo:
-
-   git clone "https://gerrit.o-ran-sc.org/r/nonrtric"
-
-The SDNC A1 Controller could be found in this repo.
-
-Build SDNC project:
-
-   Enter into the sdnc-a1-controller project, northbound and oam project will located there.
-
-      cd sdnc-a1-controller
-
-   Build northbound project with command:
-
-      mvn clean install -Dmaven.test.skip=true
-
-   Build oam project with command:
-
-      mvn clean install -Dmaven.test.skip=true -P docker
-
-   Enter into this directory:
-
-      cd nonrtric/sdnc-a1-controller/oam/installation/src/main/yaml
-
-   and run the command:
-
-      MTU=1500 docker-compose up a1-controller
-
-Version history
----------------
-
-+--------------------+--------------------+--------------------+--------------------+
-| **Date**           | **Ver.**           | **Author**         | **Comment**        |
-|                    |                    |                    |                    |
-+--------------------+--------------------+--------------------+--------------------+
-| 2019-11-12         | 0.1.0              | Maxime Bonneau     | First draft        |
-|                    |                    |                    |                    |
-+--------------------+--------------------+--------------------+--------------------+
-| 2020-03-24         | 0.1.1              | Maxime Bonneau     | Second draft       |
-|                    |                    |                    |                    |
-+--------------------+--------------------+--------------------+--------------------+
-|                    | 1.0                |                    |                    |
-|                    |                    |                    |                    |
-|                    |                    |                    |                    |
-+--------------------+--------------------+--------------------+--------------------+
-
-
-
similarity index 73%
rename from enrichment-coordinator-service/docs/api.json
rename to docs/offeredapis/swagger/ecs-api.json
index 65ff48d..740be9b 100644 (file)
@@ -1,11 +1,11 @@
 {
     "basePath": "/",
     "paths": {
-        "/producer_simulator/job_deleted_error": {"post": {
-            "summary": "Callback for EI job creation, returns error",
+        "/producer_simulator/ei_job": {"post": {
+            "summary": "Callback for EI job creation",
             "deprecated": false,
             "produces": ["application/json"],
-            "operationId": "jobDeletedCallbackReturnErrorUsingPOST",
+            "operationId": "jobCreatedCallbackUsingPOST",
             "responses": {
                 "200": {"description": "OK"},
                 "201": {"description": "Created"},
                 "description": "request",
                 "required": true
             }],
-            "tags": ["Producer Simulator"],
+            "tags": ["Producer Callbacks"],
             "consumes": ["application/json"]
         }},
-        "/producer_simulator/supervision": {"get": {
-            "summary": "Producer supervision",
+        "/A1-EI/v1/eitypes/{eiTypeId}": {"get": {
+            "summary": "Individual EI type",
             "deprecated": false,
             "produces": ["application/json"],
-            "operationId": "producerSupervisionUsingGET",
+            "operationId": "getEiTypeUsingGET",
             "responses": {
                 "200": {
-                    "schema": {"type": "string"},
-                    "description": "OK"
+                    "schema": {"$ref": "#/definitions/EiTypeObject"},
+                    "description": "EI type"
                 },
                 "401": {"description": "Unauthorized"},
                 "403": {"description": "Forbidden"},
-                "404": {"description": "Not Found"}
+                "404": {
+                    "schema": {"$ref": "#/definitions/ProblemDetails"},
+                    "description": "Enrichment Information type is not found"
+                }
             },
-            "tags": ["Producer Simulator"]
+            "parameters": [{
+                "in": "path",
+                "name": "eiTypeId",
+                "description": "eiTypeId",
+                "type": "string",
+                "required": true
+            }],
+            "tags": ["A1-EI (enrichment information)"]
         }},
-        "/A1-EI/v1/eitypes/{eiTypeId}/eijobs": {"get": {
-            "summary": "EI job identifiers",
+        "/consumer_simulator/eijobs/{eiJobId}/status": {"post": {
+            "summary": "Callback for EI job status",
             "deprecated": false,
             "produces": ["application/json"],
-            "operationId": "getEiJobIdsUsingGET",
+            "operationId": "jobStatusCallbackUsingPOST",
             "responses": {
-                "200": {
-                    "schema": {
-                        "type": "array",
-                        "items": {"type": "string"}
-                    },
-                    "description": "EI job identifiers"
-                },
+                "200": {"description": "OK"},
+                "201": {"description": "Created"},
                 "401": {"description": "Unauthorized"},
                 "403": {"description": "Forbidden"},
-                "404": {
-                    "schema": {"$ref": "#/definitions/error_information"},
-                    "description": "Enrichment Information type is not found"
-                }
+                "404": {"description": "Not Found"}
             },
             "parameters": [
                 {
                     "in": "path",
-                    "name": "eiTypeId",
-                    "description": "eiTypeId",
+                    "name": "eiJobId",
+                    "description": "eiJobId",
                     "type": "string",
                     "required": true
                 },
                 {
-                    "in": "query",
-                    "allowEmptyValue": false,
-                    "name": "owner",
-                    "description": "identifies the owner of the job",
-                    "type": "string",
-                    "required": false
+                    "schema": {"$ref": "#/definitions/EiJobStatusObject"},
+                    "in": "body",
+                    "name": "status",
+                    "description": "status",
+                    "required": true
                 }
             ],
-            "tags": ["A1-E Enrichment Data Consumer API"]
-        }},
-        "/A1-EI/v1/eitypes/{eiTypeId}": {"get": {
-            "summary": "Individual EI type",
-            "deprecated": false,
-            "produces": ["application/json"],
-            "operationId": "getEiTypeUsingGET",
-            "responses": {
-                "200": {
-                    "schema": {"$ref": "#/definitions/EiType"},
-                    "description": "EI type"
-                },
-                "401": {"description": "Unauthorized"},
-                "403": {"description": "Forbidden"},
-                "404": {
-                    "schema": {"$ref": "#/definitions/error_information"},
-                    "description": "Enrichment Information type is not found"
-                }
-            },
-            "parameters": [{
-                "in": "path",
-                "name": "eiTypeId",
-                "description": "eiTypeId",
-                "type": "string",
-                "required": true
-            }],
-            "tags": ["A1-E Enrichment Data Consumer API"]
+            "tags": ["Consumer Callbacks"],
+            "consumes": ["application/json"]
         }},
         "/ei-producer/v1/eitypes": {"get": {
             "summary": "EI type identifiers",
                 "403": {"description": "Forbidden"},
                 "404": {"description": "Not Found"}
             },
-            "tags": ["A1-E Enrichment Data Consumer API"]
-        }},
-        "/producer_simulator/job_deleted": {"post": {
-            "summary": "Callback for EI job deletion",
-            "deprecated": false,
-            "produces": ["application/json"],
-            "operationId": "jobDeletedCallbackUsingPOST",
-            "responses": {
-                "200": {"description": "OK"},
-                "201": {"description": "Created"},
-                "401": {"description": "Unauthorized"},
-                "403": {"description": "Forbidden"},
-                "404": {"description": "Not Found"}
-            },
-            "parameters": [{
-                "schema": {"$ref": "#/definitions/producer_ei_job_request"},
-                "in": "body",
-                "name": "request",
-                "description": "request",
-                "required": true
-            }],
-            "tags": ["Producer Simulator"],
-            "consumes": ["application/json"]
-        }},
-        "/A1-EI/v1/eitypes/{eiTypeId}/eijobs/{eiJobId}/status": {"get": {
-            "summary": "EI Job status",
-            "deprecated": false,
-            "produces": ["application/json"],
-            "operationId": "getEiJobStatusUsingGET",
-            "responses": {
-                "200": {
-                    "schema": {"$ref": "#/definitions/EiJobStatus"},
-                    "description": "EI Job status"
-                },
-                "401": {"description": "Unauthorized"},
-                "403": {"description": "Forbidden"},
-                "404": {
-                    "schema": {"$ref": "#/definitions/error_information"},
-                    "description": "Enrichment Information type or job is not found"
-                }
-            },
-            "parameters": [
-                {
-                    "in": "path",
-                    "name": "eiJobId",
-                    "description": "eiJobId",
-                    "type": "string",
-                    "required": true
-                },
-                {
-                    "in": "path",
-                    "name": "eiTypeId",
-                    "description": "eiTypeId",
-                    "type": "string",
-                    "required": true
-                }
-            ],
-            "tags": ["A1-E Enrichment Data Consumer API"]
+            "tags": ["A1-EI (enrichment information)"]
         }},
         "/ei-producer/v1/eiproducers/{eiProducerId}/status": {"get": {
             "summary": "EI producer status",
                 "401": {"description": "Unauthorized"},
                 "403": {"description": "Forbidden"},
                 "404": {
-                    "schema": {"$ref": "#/definitions/error_information"},
+                    "schema": {"$ref": "#/definitions/ProblemDetails"},
                     "description": "Enrichment Information producer is not found"
                 }
             },
             }],
             "tags": ["Enrichment Data Producer API"]
         }},
-        "/producer_simulator/supervision_error": {"get": {
-            "summary": "Producer supervision error",
+        "/producer_simulator/ei_job/{eiJobId}": {"delete": {
+            "summary": "Callback for EI job deletion",
             "deprecated": false,
             "produces": ["application/json"],
-            "operationId": "producerSupervisionErrorUsingGET",
+            "operationId": "jobDeletedCallbackUsingDELETE",
             "responses": {
-                "200": {
-                    "schema": {"type": "string"},
-                    "description": "OK"
-                },
+                "200": {"description": "OK"},
                 "401": {"description": "Unauthorized"},
-                "403": {"description": "Forbidden"},
-                "404": {"description": "Not Found"}
+                "204": {"description": "No Content"},
+                "403": {"description": "Forbidden"}
             },
-            "tags": ["Producer Simulator"]
+            "parameters": [{
+                "in": "path",
+                "name": "eiJobId",
+                "description": "eiJobId",
+                "type": "string",
+                "required": true
+            }],
+            "tags": ["Producer Callbacks"]
         }},
         "/ei-producer/v1/eiproducers": {"get": {
             "summary": "EI producer identifiers",
             "tags": ["Enrichment Data Producer API"]
         }},
         "/ei-producer/v1/eitypes/{eiTypeId}": {"get": {
-            "summary": "Individual EI Type",
+            "summary": "Individual EI type",
             "deprecated": false,
             "produces": ["application/json"],
             "operationId": "getEiTypeUsingGET_1",
                 "401": {"description": "Unauthorized"},
                 "403": {"description": "Forbidden"},
                 "404": {
-                    "schema": {"$ref": "#/definitions/error_information"},
+                    "schema": {"$ref": "#/definitions/ProblemDetails"},
                     "description": "Enrichment Information type is not found"
                 }
             },
             },
             "tags": ["Service status"]
         }},
-        "/producer_simulator/job_created_error": {"post": {
-            "summary": "Callback for EI job creation, returns error",
-            "deprecated": false,
-            "produces": ["application/json"],
-            "operationId": "jobCreatedCallbackReturnErrorUsingPOST",
-            "responses": {
-                "200": {"description": "OK"},
-                "201": {"description": "Created"},
-                "401": {"description": "Unauthorized"},
-                "403": {"description": "Forbidden"},
-                "404": {"description": "Not Found"}
-            },
-            "parameters": [{
-                "schema": {"$ref": "#/definitions/producer_ei_job_request"},
-                "in": "body",
-                "name": "request",
-                "description": "request",
-                "required": true
-            }],
-            "tags": ["Producer Simulator"],
-            "consumes": ["application/json"]
-        }},
-        "/A1-EI/v1/eitypes/{eiTypeId}/eijobs/{eiJobId}": {
+        "/A1-EI/v1/eijobs/{eiJobId}": {
             "get": {
-                "summary": "Individual EI Job",
+                "summary": "Individual EI job",
                 "deprecated": false,
                 "produces": ["application/json"],
                 "operationId": "getIndividualEiJobUsingGET",
                 "responses": {
                     "200": {
-                        "schema": {"$ref": "#/definitions/EiJob"},
-                        "description": "EI Job"
+                        "schema": {"$ref": "#/definitions/EiJobObject"},
+                        "description": "EI job"
                     },
                     "401": {"description": "Unauthorized"},
                     "403": {"description": "Forbidden"},
                     "404": {
-                        "schema": {"$ref": "#/definitions/error_information"},
-                        "description": "Enrichment Information type or job is not found"
+                        "schema": {"$ref": "#/definitions/ProblemDetails"},
+                        "description": "Enrichment Information job is not found"
                     }
                 },
-                "parameters": [
-                    {
-                        "in": "path",
-                        "name": "eiJobId",
-                        "description": "eiJobId",
-                        "type": "string",
-                        "required": true
-                    },
-                    {
-                        "in": "path",
-                        "name": "eiTypeId",
-                        "description": "eiTypeId",
-                        "type": "string",
-                        "required": true
-                    }
-                ],
-                "tags": ["A1-E Enrichment Data Consumer API"]
+                "parameters": [{
+                    "in": "path",
+                    "name": "eiJobId",
+                    "description": "eiJobId",
+                    "type": "string",
+                    "required": true
+                }],
+                "tags": ["A1-EI (enrichment information)"]
             },
             "delete": {
-                "summary": "Individual EI Job",
+                "summary": "Individual EI job",
                 "deprecated": false,
                 "produces": ["application/json"],
                 "operationId": "deleteIndividualEiJobUsingDELETE",
                     "204": {"description": "Job deleted"},
                     "403": {"description": "Forbidden"},
                     "404": {
-                        "schema": {"$ref": "#/definitions/error_information"},
-                        "description": "Enrichment Information type or job is not found"
+                        "schema": {"$ref": "#/definitions/ProblemDetails"},
+                        "description": "Enrichment Information job is not found"
                     }
                 },
-                "parameters": [
-                    {
-                        "in": "path",
-                        "name": "eiJobId",
-                        "description": "eiJobId",
-                        "type": "string",
-                        "required": true
-                    },
-                    {
-                        "in": "path",
-                        "name": "eiTypeId",
-                        "description": "eiTypeId",
-                        "type": "string",
-                        "required": true
-                    }
-                ],
-                "tags": ["A1-E Enrichment Data Consumer API"]
+                "parameters": [{
+                    "in": "path",
+                    "name": "eiJobId",
+                    "description": "eiJobId",
+                    "type": "string",
+                    "required": true
+                }],
+                "tags": ["A1-EI (enrichment information)"]
             },
             "put": {
-                "summary": "Individual EI Job",
+                "summary": "Individual EI job",
                 "deprecated": false,
                 "produces": ["application/json"],
                 "operationId": "putIndividualEiJobUsingPUT",
                     "401": {"description": "Unauthorized"},
                     "403": {"description": "Forbidden"},
                     "404": {
-                        "schema": {"$ref": "#/definitions/error_information"},
+                        "schema": {"$ref": "#/definitions/ProblemDetails"},
                         "description": "Enrichment Information type is not found"
                     }
                 },
                         "required": true
                     },
                     {
-                        "schema": {"$ref": "#/definitions/EiJob"},
+                        "schema": {"$ref": "#/definitions/EiJobObject"},
                         "in": "body",
-                        "name": "eiJobInfo",
-                        "description": "eiJobInfo",
-                        "required": true
-                    },
-                    {
-                        "in": "path",
-                        "name": "eiTypeId",
-                        "description": "eiTypeId",
-                        "type": "string",
+                        "name": "eiJobObject",
+                        "description": "eiJobObject",
                         "required": true
                     }
                 ],
-                "tags": ["A1-E Enrichment Data Consumer API"],
+                "tags": ["A1-EI (enrichment information)"],
                 "consumes": ["application/json"]
             }
         },
                 "responses": {
                     "200": {
                         "schema": {"$ref": "#/definitions/producer_registration_info"},
-                        "description": "EI Jobs"
+                        "description": "EI jobs"
                     },
                     "401": {"description": "Unauthorized"},
                     "403": {"description": "Forbidden"},
                     "404": {
-                        "schema": {"$ref": "#/definitions/error_information"},
+                        "schema": {"$ref": "#/definitions/ProblemDetails"},
                         "description": "Enrichment Information producer is not found"
                     }
                 },
                     "204": {"description": "Producer deleted"},
                     "403": {"description": "Forbidden"},
                     "404": {
-                        "schema": {"$ref": "#/definitions/error_information"},
+                        "schema": {"$ref": "#/definitions/ProblemDetails"},
                         "description": "Producer is not found"
                     }
                 },
                 "consumes": ["application/json"]
             }
         },
+        "/producer_simulator/health_check": {"get": {
+            "summary": "Producer supervision",
+            "deprecated": false,
+            "produces": ["application/json"],
+            "operationId": "producerSupervisionUsingGET",
+            "responses": {
+                "200": {
+                    "schema": {"type": "string"},
+                    "description": "OK"
+                },
+                "401": {"description": "Unauthorized"},
+                "403": {"description": "Forbidden"},
+                "404": {"description": "Not Found"}
+            },
+            "tags": ["Producer Callbacks"]
+        }},
         "/ei-producer/v1/eiproducers/{eiProducerId}/eijobs": {"get": {
             "summary": "EI job definitions",
             "deprecated": false,
                 "401": {"description": "Unauthorized"},
                 "403": {"description": "Forbidden"},
                 "404": {
-                    "schema": {"$ref": "#/definitions/error_information"},
+                    "schema": {"$ref": "#/definitions/ProblemDetails"},
                     "description": "Enrichment Information producer is not found"
                 }
             },
             }],
             "tags": ["Enrichment Data Producer API"]
         }},
-        "/producer_simulator/job_created": {"post": {
-            "summary": "Callback for EI job creation",
+        "/A1-EI/v1/eijobs": {"get": {
+            "summary": "EI job identifiers",
             "deprecated": false,
             "produces": ["application/json"],
-            "operationId": "jobCreatedCallbackUsingPOST",
+            "description": "query for EI job identifiers",
+            "operationId": "getEiJobIdsUsingGET",
             "responses": {
-                "200": {"description": "OK"},
-                "201": {"description": "Created"},
+                "200": {
+                    "schema": {
+                        "type": "array",
+                        "items": {"type": "string"}
+                    },
+                    "description": "EI job identifiers"
+                },
                 "401": {"description": "Unauthorized"},
                 "403": {"description": "Forbidden"},
-                "404": {"description": "Not Found"}
+                "404": {
+                    "schema": {"$ref": "#/definitions/ProblemDetails"},
+                    "description": "Enrichment Information type is not found"
+                }
+            },
+            "parameters": [
+                {
+                    "in": "query",
+                    "allowEmptyValue": false,
+                    "name": "eiTypeId",
+                    "description": "selects EI jobs of matching EI type",
+                    "type": "string",
+                    "required": false
+                },
+                {
+                    "in": "query",
+                    "allowEmptyValue": false,
+                    "name": "owner",
+                    "description": "selects EI jobs for one EI job owner",
+                    "type": "string",
+                    "required": false
+                }
+            ],
+            "tags": ["A1-EI (enrichment information)"]
+        }},
+        "/A1-EI/v1/eijobs/{eiJobId}/status": {"get": {
+            "summary": "EI job status",
+            "deprecated": false,
+            "produces": ["application/json"],
+            "operationId": "getEiJobStatusUsingGET",
+            "responses": {
+                "200": {
+                    "schema": {"$ref": "#/definitions/EiJobStatusObject"},
+                    "description": "EI job status"
+                },
+                "401": {"description": "Unauthorized"},
+                "403": {"description": "Forbidden"},
+                "404": {
+                    "schema": {"$ref": "#/definitions/ProblemDetails"},
+                    "description": "Enrichment Information job is not found"
+                }
             },
             "parameters": [{
-                "schema": {"$ref": "#/definitions/producer_ei_job_request"},
-                "in": "body",
-                "name": "request",
-                "description": "request",
+                "in": "path",
+                "name": "eiJobId",
+                "description": "eiJobId",
+                "type": "string",
                 "required": true
             }],
-            "tags": ["Producer Simulator"],
-            "consumes": ["application/json"]
+            "tags": ["A1-EI (enrichment information)"]
         }}
     },
-    "host": "localhost:45709",
+    "host": "localhost:38411",
     "definitions": {
-        "EiType": {
-            "description": "Information for an EI type",
-            "type": "object",
-            "title": "EiType",
-            "properties": {"eiJobParametersSchema": {
-                "description": "Json schema for the job data",
-                "type": "object"
-            }}
-        },
         "producer_ei_job_request": {
             "description": "The body of the EI producer callbacks for EI job creation and deletion",
             "type": "object",
                 }
             }
         },
-        "error_information": {
-            "description": "Problem as defined in https://tools.ietf.org/html/rfc7807",
-            "type": "object",
-            "title": "error_information",
-            "properties": {
-                "detail": {
-                    "description": "A human-readable explanation specific to this occurrence of the problem.",
-                    "type": "string",
-                    "example": "EI job type not found"
-                },
-                "status": {
-                    "format": "int32",
-                    "description": "The HTTP status code generated by the origin server for this occurrence of the problem.",
-                    "type": "integer",
-                    "example": 404
-                }
-            }
-        },
-        "void": {
-            "description": "Void/empty",
+        "EiTypeObject": {
+            "description": "Information for an EI type",
             "type": "object",
-            "title": "void"
-        },
-        "EiJob": {
-            "description": "Information for an Enrichment Information Job",
-            "type": "object",
-            "title": "EiJob",
-            "required": [
-                "jobOwner",
-                "jobParameters",
-                "targetUri"
-            ],
-            "properties": {
-                "targetUri": {
-                    "description": "The target of the EI data",
-                    "type": "string"
-                },
-                "jobOwner": {
-                    "description": "Identity of the owner of the job",
-                    "type": "string"
-                },
-                "jobParameters": {
-                    "description": "EI Type specific job data",
-                    "type": "object"
-                }
-            }
+            "title": "EiTypeObject"
         },
         "producer_ei_type_registration_info": {
             "description": "Information for an EI type",
                 }
             }
         },
-        "EiJobStatus": {
-            "description": "Status for an EI Job",
-            "type": "object",
-            "title": "EiJobStatus",
-            "required": ["operationalState"],
-            "properties": {"operationalState": {
-                "description": "Operational state, values:\nENABLED: TBD\nDISABLED: TBD.",
-                "type": "string",
-                "enum": [
-                    "ENABLED",
-                    "DISABLED"
-                ]
-            }}
-        },
         "Mono«ResponseEntity«object»»": {
             "type": "object",
             "title": "Mono«ResponseEntity«object»»"
             "type": "object",
             "title": "producer_registration_info",
             "required": [
-                "ei_job_creation_callback_url",
-                "ei_job_deletion_callback_url",
+                "ei_job_callback_url",
                 "ei_producer_supervision_callback_url",
                 "supported_ei_types"
             ],
                     "type": "array",
                     "items": {"$ref": "#/definitions/producer_ei_type_registration_info"}
                 },
-                "ei_job_creation_callback_url": {
-                    "description": "callback for job creation",
-                    "type": "string"
-                },
-                "ei_job_deletion_callback_url": {
-                    "description": "callback for job deletion",
-                    "type": "string"
-                },
                 "ei_producer_supervision_callback_url": {
                     "description": "callback for producer supervision",
                     "type": "string"
+                },
+                "ei_job_callback_url": {
+                    "description": "callback for EI job",
+                    "type": "string"
                 }
             }
         },
                     "DISABLED"
                 ]
             }}
+        },
+        "ProblemDetails": {
+            "description": "A problem detail to carry details in a HTTP response according to RFC 7807",
+            "type": "object",
+            "title": "ProblemDetails",
+            "properties": {
+                "detail": {
+                    "description": "A human-readable explanation specific to this occurrence of the problem.",
+                    "type": "string",
+                    "example": "EI job type not found"
+                },
+                "status": {
+                    "format": "int32",
+                    "description": "The HTTP status code generated by the origin server for this occurrence of the problem.",
+                    "type": "integer",
+                    "example": 404
+                }
+            }
+        },
+        "Void": {
+            "description": "Void/empty",
+            "type": "object",
+            "title": "Void"
+        },
+        "EiJobStatusObject": {
+            "description": "Status for an EI job",
+            "type": "object",
+            "title": "EiJobStatusObject",
+            "required": ["eiJobStatus"],
+            "properties": {"eiJobStatus": {
+                "description": "values:\nENABLED: the A1-EI producer is able to deliver EI result for the EI job\nDISABLED: the A1-EI producer is unable to deliver EI result for the EI job",
+                "type": "string",
+                "enum": [
+                    "ENABLED",
+                    "DISABLED"
+                ]
+            }}
+        },
+        "EiJobObject": {
+            "description": "Information for an Enrichment Information Job",
+            "type": "object",
+            "title": "EiJobObject",
+            "required": [
+                "eiTypeId",
+                "jobDefinition",
+                "jobOwner",
+                "jobResultUri"
+            ],
+            "properties": {
+                "eiTypeId": {
+                    "description": "EI type Idenitifier of the EI job",
+                    "type": "string"
+                },
+                "jobResultUri": {
+                    "description": "The target URI of the EI data",
+                    "type": "string"
+                },
+                "jobOwner": {
+                    "description": "Identity of the owner of the job",
+                    "type": "string"
+                },
+                "jobStatusNotificationUri": {
+                    "description": "The target of EI job status notifications",
+                    "type": "string"
+                },
+                "jobDefinition": {
+                    "description": "EI type specific job data",
+                    "type": "object"
+                }
+            }
         }
     },
     "swagger": "2.0",
     },
     "tags": [
         {
-            "name": "A1-E Enrichment Data Consumer API",
+            "name": "A1-EI (enrichment information)",
             "description": "Consumer Controller"
         },
+        {
+            "name": "Consumer Callbacks",
+            "description": "Consumer Simulator Controller"
+        },
         {
             "name": "Enrichment Data Producer API",
             "description": "Producer Controller"
         },
         {
-            "name": "Producer Simulator",
+            "name": "Producer Callbacks",
             "description": "Producer Simulator Controller"
         },
         {
diff --git a/docs/offeredapis/swagger/pms-api.json b/docs/offeredapis/swagger/pms-api.json
new file mode 120000 (symlink)
index 0000000..18346f5
--- /dev/null
@@ -0,0 +1 @@
+../../../onap/oran/docs/offeredapis/swagger/pms-api.json
\ No newline at end of file
index 2c51dba..7f4d582 100644 (file)
@@ -3,7 +3,7 @@
 .. Copyright (C) 2020 Nordix
 
 Requirements for the Non-RT RIC project
-==========================================
+=======================================
 
 Find detailed description of what Non-RT RIC is on this `page`_.
 
@@ -30,59 +30,3 @@ Moreover, there are functional requirements regarding the A1 interface:
 #. A1 interface shall support communication of enrichment information from Non-RT RIC to Near-RT RIC.
 #. A1 interface shall support feedback from Near-RT RIC for monitoring AI/ML model performance.
 #. A1 interface shall support the policy/intents feedback from Near-RT RIC to Non-RT RIC.
-
-A1 policy procedure
--------------------
-
-As for A-release, the methods are as follows:
-
-+---------------------+--------------------------+--------------------------+
-| A1 policy procedure | Single policy method     | Multiple policies method |
-+---------------------+--------------------------+--------------------------+
-| Create policy       | PUT                      |                          |
-+---------------------+--------------------------+--------------------------+
-| Query policy        | GET                      | GET (sequence of \*)     |
-+---------------------+--------------------------+--------------------------+
-| Update policy       | PUT                      |                          |
-+---------------------+--------------------------+--------------------------+
-| Delete policy       | DELETE                   |                          |
-+---------------------+--------------------------+--------------------------+
-| Notify policy       | POST                     | POST                     |
-+---------------------+--------------------------+--------------------------+
-
-Policy Agent Overview
-=======================
-
-The Policy Agent maintains a transient repository of the following items to support R-Apps:
-
- * All Near-RT RICs in the network. This information is configured using the ONAP CDS database (which is using the Cloudify Consul database).
- * All Policy types for all Near-RT RICs
- * All configured Policy instances in the network
-
-It provides an NBI for the R-Apps (and for the Control Panel) for policy management. This is a REST API.
-As an option, policy management can also be done via asynchronous messages through ONAP/Dmaap.
-The NBI provides support for an R-APP to locate the correct Near-RT RIC based on identifiers as defined in O1.
-
-The agent monitors all Near-RT RICs and recovers from data inconsistencies, which may happen when (for instance) an Near-RT RIC restarts.
-
-The R-Apps can be monitored so that their Policies can be automatically removed when an R-App is stopped/removed.
-
-On its southbound side the agent can connect to a number of different A1 providers:
-
- * Directly to the Non-RT RIC:
-
-      - OSC API, which is influenced by the A1 standard
-      - The Non-RT RIC simulator, which supports the A1 standard with a number of not yet CRs included.
- * To an ONAP style controller.
-
-Amber release Policy Agent architecture
------------------------------------------
-
-.. image:: ./images/NonRtRicComponents.png
-   :scale: 50 %
-
-Non-RT RIC components:
-
- #. Policy Agent
- #. SDNC A1 Controller
-
diff --git a/docs/policy-agent-api.rst b/docs/policy-agent-api.rst
deleted file mode 100644 (file)
index eaa805d..0000000
+++ /dev/null
@@ -1,1323 +0,0 @@
-.. This work is licensed under a Creative Commons Attribution 4.0 International License.
-.. http://creativecommons.org/licenses/by/4.0
-.. Copyright (C) 2020 Nordix
-
-.. |nbsp| unicode:: 0xA0
-   :trim:
-
-.. |nbh| unicode:: 0x2011
-   :trim:
-
-.. _policy-agent-api:
-
-################################
-A1 Policy Management Service API
-################################
-
-
-*******************************************
-A1 Policy Management Service - Introduction
-*******************************************
-
-The A1 Policy Management Service ("Policy Agent") is an SMO/NONRTRIC service above the NONRTRIC A1 Adapter/Controller
-that provides:
-
-* Unified REST & DMAAP APIs for managing A1 Policies in all Near |nbh| RT |nbsp| RICs
-* Synchronized view of registered "services" (e.g. R-APP, GUI, etc)
-* Synchronized view of policy instances for each "service"
-* Synchronized view of policy instances in all Near |nbh| RT |nbsp| RICs
-* Synchronized view of policy types in all Near |nbh| RT |nbsp| RICs
-* Policy Query API (e.g. per Near |nbh| RT |nbsp| RIC, per "service", per policy type)
-* An initial interface for unified Near |nbh| RT |nbsp| RIC ID to Near |nbh| RT |nbsp| RIC address mapping.
-  (Note:  may also later act as adapter to A&AI, CMDBs etc. to "find" Near |nbh| RT |nbsp| RICs - TBC)
-* An Initial "O1 ManagedElement" mapping database & interface to find appropriate Near |nbh| RT |nbsp| RIC for RAN elements.
-  (Note: may also later act as adapter to A&AI, RuntimeDB, other CMDBs etc. - TBC)
-* Monitors all Near |nbh| RT |nbsp| RICs and recovers from inconsistencies (Note: e.g. Near |nbh| RT |nbsp| RIC restarts)
-* Support for different Southbound connectors on a per Near |nbh| RT |nbsp| RIC basis. (Note: e.g. different A1
-  versions, different Near |nbh| RT |nbsp| RIC versions, different A1 adapters, different or proprietary A1
-  controllers/EMSs)
-
-***************************************
-A1 Policy Management Service - REST NBI
-***************************************
-
-This is the north bound API of the A1 Policy Management Service ("Policy Agent"). This API allows *services* to interact
-with the Policy Agent using REST.
-
-By registering with the Policy Agent, the Policy Agent takes responsibility for synchronizing the policies created by
-the service in the Near |nbh| RT |nbsp| RICs. This means that if a Near |nbh| RT |nbsp| RIC restarts, the Policy Agent
-will try to recreate all the policies residing in the Near |nbh| RT |nbsp| RIC once it is started again. If this is not
-possible, it will remove all policies belonging to the Near |nbh| RT |nbsp| RIC.
-
-The Policy Agent also keeps an updated view of the policy types available, and which Near |nbh| RT |nbsp| RICs that
-support which types. Also, the Policy Agent can tell if a Managed Element is managed by a certain
-Near |nbh| RT |nbsp| RIC.
-
-The Policy Agent NBI has five distinct parts, described in the sections below:
-
-* Service Management
-* Policy Types
-* Policy Management
-* Near-RT RIC Repository
-* Health Check
-
-******************
-Service Management
-******************
-
-A service can register itself in the Policy Agent.
-
-By providing a callback URL the service can get notifications from the Policy Agent.
-
-A service can also register a "*Keep Alive Interval*", in seconds. By doing this the service promises to call the
-Policy Agent's "*Keep Alive*" method, or else create or delete policies, more often than the "*Keep Alive Interval*"
-measured in seconds. If the service, for some reason, is not able to do this, the Policy Agent will consider that the
-service has died or vanished and will then delete all its policies, both in the internal repository and in the
-Near |nbh| RT |nbsp| RICs where they were earlier created. **Note!** |nbsp| If the service does not provide a value for
-"*Keep Alive Interval*", then the service maintains full responsibility to delete all of its policies when they are no
-longer needed.
-
-/service
-~~~~~~~~
-
-PUT
-+++
-
-Register a service.
-
-Definition
-""""""""""
-
-**URL path:**
-
-/service
-
-**Parameters:**
-
-None.
-
-**Body:**  (*Required*)
-
-A JSON object (ServiceRegistrationInfo): ::
-
-  {
-    "callbackUrl": "string",         (An empty string means the service will never get any callbacks.)
-    "keepAliveIntervalSeconds": 0,   (0 means the service will always be considered alive.)
-    "serviceName": "string"          (Required, must be unique.)
-  }
-
-**Responses:**
-
-200:
-
-Service updated.
-
-201:
-
-Service created.
-
-400:
-
-The ServiceRegistrationInfo is not accepted.
-
-Examples
-""""""""
-
-**Call**: ::
-
-  curl -X PUT "http://localhost:8081/service" -H "Content-Type: application/json" -d '{
-      "callbackUrl": "URL",
-      "keepAliveIntervalSeconds": 0,
-      "serviceName": "existing"
-    }'
-
-**Result**:
-
-201: ::
-
-   OK
-
-**Call**: ::
-
-   curl -X PUT "http://localhost:8081/service" -H  "Content-Type: application/json" -d "{}"
-
-**Result**:
-
-400: ::
-
-  Missing mandatory parameter 'serviceName'
-
-/services
-~~~~~~~~~
-
-GET
-+++
-
-Query service information.
-
-Definition
-""""""""""
-
-**URL path:**
-
-/services?name=<service-name>
-
-**Parameters:**
-
-name: (*Optional*)
-
-The name of the service.
-
-**Responses:**
-
-200:
-
-Array of JSON objects (ServiceStatus). ::
-
-  {
-    "callbackUrl": "string",             (Callback URL)
-    "keepAliveIntervalSeconds": 0,       (Policy keep alive interval)
-    "serviceName": "string",             (Identity of the service)
-    "timeSinceLastActivitySeconds": 0    (Time since last invocation by the service)
-  }
-
-404:
-
-Service is not found.
-
-Examples
-""""""""
-
-**Call**: ::
-
-  curl -X GET "http://localhost:8081/services?name=existing"
-
-**Result**:
-
-200: ::
-
-  [
-    {
-      "serviceName":"existing",
-      "keepAliveIntervalSeconds":0,
-      "timeSinceLastActivitySeconds":7224,
-      "callbackUrl":"URL"
-    }
-  ]
-
-**Call**: ::
-
-  curl -X GET "http://localhost:8081/services?name=nonexistent"
-
-Result:
-
-404: ::
-
-  Service not found
-
-DELETE
-++++++
-
-Delete a service.
-
-Definition
-""""""""""
-
-**URL path:**
-
-/services?name=<service-name>
-
-**Parameters:**
-
-name: (*Required*)
-
-The name of the service.
-
-**Responses:**
-
-204:
-  OK
-
-404:
-  Service not found.
-
-Examples
-""""""""
-
-**Call**: ::
-
-  curl -X DELETE "http://localhost:8081/services?name=existing"
-
-**Result**:
-
-204: ::
-
-  OK
-
-**Call**: ::
-
-  curl -X DELETE "http://localhost:8081/services?name=nonexistent"
-
-Result:
-
-404: ::
-
-  Could not find service: nonexistent
-
-/services/keepalive
-~~~~~~~~~~~~~~~~~~~
-
-PUT
-+++
-
-Heart beat from a service.
-
-Definition
-""""""""""
-
-**URL path:**
-
-/services/keepalive?name=<service-name>
-
-**Parameters:**
-
-name: (*Required*)
-
-The name of the service.
-
-**Responses:**
-
-200:
-
-OK
-
-404:
-
-Service is not found.
-
-Examples
-""""""""
-
-**Call**: ::
-
-  curl -X PUT "http://localhost:8081/services/keepalive?name=existing"
-
-**Result**:
-
-200: ::
-
-  OK
-
-**Call**: ::
-
-  curl -X PUT "http://localhost:8081/services/keepalive?name=nonexistent"
-
-**Result**:
-
-404: ::
-
-  Could not find service: nonexistent
-
-.. _policy-management:
-
-************
-Policy Types
-************
-
-Policies are based on types. The set of available policy types is determined by the set of policy types supported by
-Near |nbh| RT |nbsp| RICs. At startup, the Policy Agent queries all Near |nbh| RT |nbsp| RICs for their supported types
-and stores them in its internal repository. It then checks this at regular intervals to keep the repository of types up
-to date. Policy types cannot be created, updated or deleted using this interface since this must be done via the
-Near |nbh| RT |nbsp| RICs.
-
-A policy type defines a name and a JSON schema that constrains the content of a policy of that type.
-
-/policy_types
-~~~~~~~~~~~~~
-
-GET
-+++
-
-Query policy type names.
-
-Definition
-""""""""""
-
-**URL path:**
-
-/policy_types?ric=<name-of-ric>
-
-**Parameters:**
-
-ric: (*Optional*)
-
-The name of the Near |nbh| RT |nbsp| RIC to get types for.
-
-**Responses:**
-
-200:
-
-  Array of policy type names.
-
-404:
-
-  Near |nbh| RT |nbsp| RIC is not found.
-
-Examples
-""""""""
-
-**Call**: ::
-
-  curl -X GET "http://localhost:8081/policy_types"
-
-**Result**:
-
-200: ::
-
-  [
-    "STD_PolicyModelUnconstrained_0.2.0",
-    "Example_QoETarget_1.0.0",
-    "ERIC_QoSNudging_0.2.0"
-  ]
-
-**Call**: ::
-
-  curl -X GET "http://localhost:8081/policy_types?ric=nonexistent"
-
-**Result**:
-
-404: ::
-
-  org.oransc.policyagent.exceptions.ServiceException: Could not find ric: nonexistent
-
-/policy_schema
-~~~~~~~~~~~~~~
-
-GET
-+++
-
-Returns one policy type schema definition.
-
-Definition
-""""""""""
-
-**URL path:**
-
-/policy_schema?id=<name-of-type>
-
-**Parameters:**
-
-id: (*Required*)
-
-The ID of the policy type to get the definition for.
-
-**Responses:**
-
-200:
-
-Policy schema as JSON schema.
-
-404:
-
-Policy type is not found.
-
-Examples
-""""""""
-
-**Call**: ::
-
- curl -X GET "http://localhost:8081/policy_schema?id=STD_PolicyModelUnconstrained_0.2.0"
-
-**Result**:
-
-200: ::
-
-  {
-    "$schema": "http://json-schema.org/draft-07/schema#",
-    "title": "STD_PolicyModelUnconstrained_0.2.0",
-    "description": "Standard model of a policy with unconstrained scope id combinations",
-    "type": "object",
-    "properties": {
-     "scope": {
-        "type": "object",
-        "properties": {
-          "ueId": {"type": "string"},
-          "groupId": {"type": "string"}
-        },
-        "minProperties": 1,
-        "additionalProperties": false
-      },
-      "qosObjectives": {
-        "type": "object",
-        "properties": {
-          "gfbr": {"type": "number"},
-          "mfbr": {"type": "number"}
-        },
-        "additionalProperties": false
-      },
-      "resources": {
-        "type": "array",
-        "items": {
-          "type": "object",
-          "properties": {
-            "cellIdList": {
-              "type": "array",
-              "minItems": 1,
-              "uniqueItems": true,
-              "items": {
-                "type": "string"
-              }
-            },
-          "additionalProperties": false,
-          "required": ["cellIdList"]
-        }
-      }
-    },
-    "minProperties": 1,
-    "additionalProperties": false,
-    "required": ["scope"]
-  }
-
-**Call**: ::
-
-  curl -X GET "http://localhost:8081/policy_schema?id=nonexistent"
-
-**Result**:
-
-404: ::
-
-  org.oransc.policyagent.exceptions.ServiceException: Could not find type: nonexistent
-
-/policy_schemas
-~~~~~~~~~~~~~~~
-
-GET
-+++
-
-Returns policy type schema definitions.
-
-Definition
-""""""""""
-
-**URL path:**
-
-/policy_schemas?ric=<name-of-ric>
-
-**Parameters:**
-
-ric: (*Optional*)
-
-The name of the Near |nbh| RT |nbsp| RIC to get the definitions for.
-
-**Responses:**
-
-200:
-
-An array of policy schemas as JSON schemas.
-
-404:
-
-Near |nbh| RT |nbsp| RIC is not found.
-
-Examples
-""""""""
-
-**Call**: ::
-
-  curl -X GET "http://localhost:8081/policy_schemas"
-
-**Result**:
-
-200: ::
-
-  [
-    {
-      "$schema": "http://json-schema.org/draft-07/schema#",
-      "title": "STD_PolicyModelUnconstrained_0.2.0",
-      "description": "Standard model of a policy with unconstrained scope id combinations",
-      "type": "object",
-      "properties": {
-        "scope": {
-          "type": "object",
-            .
-            .
-            .
-        }
-        "additionalProperties": false,
-        "required": ["scope"]
-      },
-        .
-        .
-        .
-      {
-        "$schema": "http://json-schema.org/draft-07/schema#",
-        "title": "Example_QoETarget_1.0.0",
-        "description": "Example QoE Target policy type",
-        "type": "object",
-          "properties": {
-            "scope": {
-              "type": "object",
-                .
-                .
-                .
-            }
-            "additionalProperties": false,
-           "required": ["scope"]
-        }
-      }
-    }
-  ]
-
-**Call**: ::
-
-  curl -X GET "http://localhost:8081/policy_schemas?ric=nonexistent"
-
-**Result**:
-
-404: ::
-
-  org.oransc.policyagent.exceptions.ServiceException: Could not find ric: nonexistent
-
-*****************
-Policy Management
-*****************
-
-Policies can be queried, created, updated, and deleted. A policy is always created in a specific
-Near |nbh| RT |nbsp| RIC.
-
-A policy is defined by its policy type schema.
-
-When a policy is created, the Policy Agent stores information about it in its internal repository. At regular intervals,
-it then checks with all Near |nbh| RT |nbsp| RICs that this repository is synchronized. If, for some reason, there is an
-inconsistency, the Policy Agent will start a synchronization job and try to inconsistency, the Policy Agent will start a
-synchronization job and try to reset the Near |nbh| RT |nbsp| RIC to its last-known-good status. If this fails, the
-Policy Agent will clear all policies for the specific Near |nbh| RT |nbsp| RIC in the internal repository and set its
-state to *UNKNOWN*. This means that no interaction with the Near |nbh| RT |nbsp| RIC is possible until the Policy Agent
-has been able to contact it again and re-synchronize its state in the repository.
-
-Once a service has created a policy, it is the service's responsibility to maintain its life cycle. When a Near |nbh| RT
-|nbsp| RIC has been restarted, the Policy Agent will try to recreate policies in the Near |nbh| RT |nbsp| RIC according
-to the policies maintained in its local repository.
-This means that the service must delete any policies it has created.
-A policy may be created as a "transient policy", whereby if this policy "disappears" at any stage it will not be
-re-synchronized to the Near |nbh| RT |nbsp| RIC.
-For example, this is useful if the policy should not survive a restart of the Near |nbh| RT |nbsp| RIC.
-A non-transient policy will continue to be maintained in the Near |nbh| RT |nbsp| RIC until it is explicitly deleted
-(or the service that created it fails to update its Keep Alive status).
-
-There are some exceptions where policy instances are not re-synchronized after a Near |nbh| RT |nbsp| RIC restart or
-when some inconsistency is identified:
-
-- The service has registered a "*Keep Alive Interval*", but the service then fails to update its Keep Alive status.
-- The Policy Agent completely fails to synchronize with a Near |nbh| RT |nbsp| RIC, as described above.
-- Policies that are marked as transient policies.
-
-/policies
-~~~~~~~~~
-
-GET
-+++
-
-Query policies.
-
-Definition
-""""""""""
-
-**URL path:**
-
-/policies?ric=<name-of-ric>&service=<name-of-service>&type=<name-of-type>
-
-**Parameters:**
-
-ric: (*Optional*)
-
-The name of the Near |nbh| RT |nbsp| RIC to get policies for.
-
-service: (*Optional*)
-
-The name of the service to get policies for.
-
-type: (*Optional*)
-
-The name of the policy type to get policies for.
-
-**Responses:**
-
-200:
-
-Array of JSON objects (PolicyInfo). ::
-
-  {
-    "id": "string",              (Identity of the policy)
-    "json": "object",            (The configuration of the policy)
-    "lastModified": "string",    (Timestamp, last modification time)
-    "ric": "string",             (Identity of the target Near |nbh| RT |nbsp| RIC)
-    "service": "string",         (The name of the service owning the policy)
-    "type": "string"             (Name of the policy type)
-  }
-
-404:
-  Near |nbh| RT |nbsp| RIC or policy type not found.
-
-Examples
-""""""""
-
-**Call**: ::
-
-  curl -X GET "http://localhost:8081/policies?ric=existing"
-
-**Result**:
-
-200: ::
-
-  [
-    {
-      "id": "Policy 1",
-      "json": {
-        "scope": {
-          "ueId": "UE 1",
-          "groupId": "Group 1"
-        },
-        "qosObjectives": {
-          "gfbr": 1,
-          "mfbr": 2
-        },
-        "cellId": "Cell 1"
-      },
-      "lastModified": "Wed, 01 Apr 2020 07:45:45 GMT",
-      "ric": "existing",
-      "service": "Service 1",
-      "type": "STD_PolicyModelUnconstrained_0.2.0"
-    },
-    {
-      "id": "Policy 2",
-      "json": {
-          .
-          .
-          .
-      },
-      "lastModified": "Wed, 01 Apr 2020 07:45:45 GMT",
-      "ric": "existing",
-      "service": "Service 2",
-      "type": "Example_QoETarget_1.0.0"
-    }
-  ]
-
-**Call**: ::
-
-  curl -X GET "http://localhost:8081/policies?type=nonexistent"
-
-**Result**:
-
-404: ::
-
-  Policy type not found
-
-/policy
-~~~~~~~
-
-GET
-+++
-
-Returns a policy configuration.
-
-Definition
-""""""""""
-
-**URL path:**
-
-/policy?id=<policy-id>
-
-**Parameters:**
-
-id: (*Required*)
-
-The ID of the policy instance.
-
-**Responses:**
-
-200:
-
-JSON object containing policy information. ::
-
-  {
-    "id": "string",                  (ID of policy)
-    "json": "object",                (JSON with policy data speified by the type)
-    "ownerServiceName": "string",    (Name of the service that created the policy)
-    "ric": "string",                 (Name of the Near |nbh| RT |nbsp| RIC where the policy resides)
-    "type": "string",                (Name of the policy type of the policy)
-    "lastModified"                   (Timestamp, last modification time)
-  }
-
-404:
-
-Policy is not found.
-
-Examples
-""""""""
-
-**Call**: ::
-
-  curl -X GET "http://localhost:8081/policy?id=Policy 1"
-
-**Result**:
-
-200: ::
-
-  {
-    "id": "Policy 1",
-    "json", {
-      "scope": {
-        "ueId": "UE1 ",
-        "cellId": "Cell 1"
-      },
-      "qosObjectives": {
-        "gfbr": 319.5,
-        "mfbr": 782.75,
-        "priorityLevel": 268.5,
-        "pdb": 44.0
-      },
-      "qoeObjectives": {
-        "qoeScore": 329.0,
-        "initialBuffering": 27.75,
-        "reBuffFreq": 539.0,
-        "stallRatio": 343.0
-      },
-      "resources": []
-    },
-    "ownerServiceName": "Service 1",
-    "ric": "ric1",
-    "type": "STD_PolicyModelUnconstrained_0.2.0",
-    "lastModified": "Wed, 01 Apr 2020 07:45:45 GMT"
-  }
-
-**Call**: ::
-
-  curl -X GET "http://localhost:8081/policy?id=nonexistent"
-
-**Result**:
-
-404: ::
-
-  Policy is not found
-
-PUT
-+++
-
-Create/Update a policy. **Note!** Calls to this method will also trigger "*Keep Alive*" for a service which has a
-"*Keep Alive Interval*" registered.
-
-Definition
-""""""""""
-
-**URL path:**
-
-/policy?id=<policy-id>&ric=<name-of-ric>&service=<name-of-service>&type=<name-of-policy-type>
-
-**Parameters:**
-
-id: (*Required*)
-
-The ID of the policy instance.
-
-ric: (*Required*)
-
-The name of the Near |nbh| RT |nbsp| RIC where the policy will be created.
-
-service: (*Required*)
-
-The name of the service creating the policy.
-
-transient: (*Optional*)
-
-If the policy is transient or not (boolean defaulted to false).
-A policy is transient if it will be forgotten when the service needs to reconnect to the Near |nbh| RT |nbsp| RIC.
-
-type: (*Optional*)
-
-The name of the policy type.
-
-**Body:** (*Required*)
-
-A JSON object containing the data specified by the type.
-
-**Responses:**
-
-200:
-
-Policy updated.
-
-201:
-
-Policy created.
-
-404:
-
-Near |nbh| RT |nbsp| RIC or policy type is not found.
-
-423:
-
-Near |nbh| RT |nbsp| RIC is not operational.
-
-Examples
-""""""""
-
-**Call**: ::
-
-  curl -X PUT "http://localhost:8081/policy?id=Policy%201&ric=ric1&service=Service%201&type=STD_PolicyModelUnconstrained_0.2.0"
-    -H  "Content-Type: application/json"
-    -d '{
-          "scope": {
-            "ueId": "UE 1",
-            "cellId": "Cell 1"
-          },
-          "qosObjectives": {
-            "gfbr": 319.5,
-            "mfbr": 782.75,
-            "priorityLevel": 268.5,
-            "pdb": 44.0
-          },
-          "qoeObjectives": {
-            "qoeScore": 329.0,
-            "initialBuffering": 27.75,
-            "reBuffFreq": 539.0,
-            "stallRatio": 343.0
-          },
-          "resources": []
-        }'
-
-**Result**:
-
-200
-
-DELETE
-++++++
-
-Deletes a policy. **Note!** Calls to this method will also trigger "*Keep Alive*" for a service which has a
-"*Keep Alive Interval*" registered.
-
-Definition
-""""""""""
-
-**URL path:**
-
-/policy?id=<policy-id>
-
-**Parameters:**
-
-id: (*Required*)
-
-The ID of the policy instance.
-
-**Responses:**
-
-204:
-
-Policy deleted.
-
-404:
-
-Policy is not found.
-
-423:
-
-Near |nbh| RT |nbsp| RIC is not operational.
-
-Examples
-""""""""
-
-**Call**: ::
-
-  curl -X DELETE "http://localhost:8081/policy?id=Policy 1"
-
-**Result**:
-
-204
-
-/policy_ids
-~~~~~~~~~~~
-
-GET
-+++
-
-Query policy type IDs.
-
-Definition
-""""""""""
-
-**URL path:**
-
-/policy_ids?ric=<name-of-ric>&service=<name-of-service>&type=<name-of-policy-type>
-
-**Parameters:**
-
-ric: (*Optional*)
-
-The name of the Near |nbh| RT |nbsp| RIC to get policies for.
-
-service: (*Optional*)
-
-The name of the service to get policies for.
-
-type: (*Optional*)
-
-The name of the policy type to get policies for.
-
-**Responses:**
-
-200:
-
-Array of policy type names.
-
-404:
-
-RIC or policy type not found.
-
-Examples
-""""""""
-
-**Call**: ::
-
-  curl -X GET "http://localhost:8081/policy_ids"
-
-**Result**:
-
-200: ::
-
-  [
-    "Policy 1",
-    "Policy 2",
-    "Policy 3"
-  ]
-
-**Call**: ::
-
-  curl -X GET "http://localhost:8081/policy_ids?ric=nonexistent"
-
-**Result**:
-
-404: ::
-
-  Ric not found
-
-/policy_status
-~~~~~~~~~~~~~~
-
-GET
-+++
-
-Returns the status of a policy.
-
-Definition
-""""""""""
-
-**URL path:**
-
-/policy_status?id=<policy-id>
-
-**Parameters:**
-
-id: (*Required*)
-
-The ID of the policy.
-
-**Responses:**
-
-200:
-
-JSON object with policy status.
-
-404:
-
-Policy not found.
-
-**********************
-Near-RT RIC Repository
-**********************
-
-The Policy Agent keeps an updated view of the Near |nbh| RT |nbsp| RICs that are available in the system. A service can
-find out which Near |nbh| RT |nbsp| RIC that manages a specific element in the network or which
-Near |nbh| RT |nbsp| RICs that support a specific policy type.
-
-/ric
-~~~~
-
-GET
-+++
-
-Returns the name of a Near |nbh| RT |nbsp| RIC managing a specific Mananged Element.
-
-Definition
-""""""""""
-
-**URL path:**
-
-/ric?managedElementId=<id-of-managed-element>
-
-**Parameters:**
-
-managedElementId: (*Required*)
-
-The ID of the Managed Element.
-
-**Responses:**
-
-200:
-
-Name of the Near |nbh| RT |nbsp| RIC managing the Managed Element.
-
-404:
-
-No Near |nbh| RT |nbsp| RIC manages the given Managed Element.
-
-Examples
-""""""""
-
-**Call**: ::
-
-  curl -X GET "http://localhost:8081/ric?managedElementId=Node 1"
-
-**Result**:
-
-200: ::
-
-  Ric 1
-
-**Call**: ::
-
-  curl -X GET "http://localhost:8081/ric?managedElementId=notmanaged"
-
-**Result**:
-
-404
-
-/rics
-~~~~~
-
-GET
-+++
-
-Query Near |nbh| RT |nbsp| RIC information.
-
-Definition
-""""""""""
-
-**URL path:**
-
-/rics?policyType=<name-of-policy-type>
-
-**Parameters:**
-
-policyType: (*Optional*)
-
-The name of the policy type.
-
-**Responses:**
-
-200:
-
-Array of JSON objects containing Near |nbh| RT |nbsp| RIC information. ::
-
-  [
-    {
-      "managedElementIds": [
-        "string"
-      ],
-      "policyTypes": [
-        "string"
-      ],
-      "ricName": "string",
-      "state": "string"
-    }
-  ]
-
-404:
-
-Policy type is not found.
-
-Examples
-""""""""
-
-**Call**: ::
-
-  curl -X GET "http://localhost:8081/rics?policyType=STD_PolicyModelUnconstrained_0.2.0"
-
-**Result**:
-
-200: ::
-
-  [
-    {
-      "managedElementIds": [
-        "ME 1",
-        "ME 2"
-      ],
-      "policyTypes": [
-        "STD_PolicyModelUnconstrained_0.2.0",
-        "Example_QoETarget_1.0.0",
-        "ERIC_QoSNudging_0.2.0"
-      ],
-      "ricName": "Ric 1",
-      "state": "AVAILABLE"
-    },
-      .
-      .
-      .
-    {
-      "managedElementIds": [
-        "ME 3"
-      ],
-      "policyTypes": [
-        "STD_PolicyModelUnconstrained_0.2.0"
-      ],
-      "ricName": "Ric X",
-      "state": "UNAVAILABLE"
-    }
-  ]
-
-**Call**: ::
-
-  curl -X GET "http://localhost:8081/rics?policyType=nonexistent"
-
-**Result**:
-
-404: ::
-
-  Policy type not found
-
-************
-Health Check
-************
-
-The status of the Policy Agent.
-
-/status
-~~~~~~~
-
-GET
-+++
-
-Returns the status of the Policy Agent.
-
-Definition
-""""""""""
-
-**URL path:**
-
-/status
-
-**Parameters:**
-
-None.
-
-**Responses:**
-
-200:
-
-Service is living.
-
-Examples
-""""""""
-
-**Call**: ::
-
-  curl -X GET "http://localhost:8081/status"
-
-**Result**:
-
-200
-
-****************
-A1 through DMaaP
-****************
-
-The Policy Agent also provides the possibility to use DMaap to handle policies according to the A1 specification. The
-Policy Agent polls the DMaaP Message Router regularly and processes any messages targeted to it. The response is then
-published back to the DMaaP Message Router with the result of the call.
-
-Send Message
-~~~~~~~~~~~~
-
-The message to send is a JSON like the one below. The "*url*" is one of the URLs described under
-:ref:`policy-management`. The "*target*" must always be "*policy-agent*" for the message to be processed by the Policy
-Agent. The "*operation*" can be one of the following: "*GET | PUT | POST | DELETE*". ::
-
-  {
-    "type": "string",
-    "correlationId": "string",
-    "target": "string",
-    "timestamp": "timestamp",
-    "apiVersion": "string",
-    "originatorId": "string",
-    "requestId": "string",
-    "operation": "string",
-    "url": "string"
-  }
-
-Example
-+++++++
-
-To get all policy types for a specific Near |nbh| RT |nbsp| RIC the following message should be sent to DMaaP Message
-Router: ::
-
-  {
-    "type":"request",
-    "correlationId":"c09ac7d1-de62-0016-2000-e63701125557-201",
-    "target":"policy-agent",
-    "timestamp":"2019-05-14T11:44:51.36Z",
-    "apiVersion":"1.0",
-    "originatorId":"849e6c6b420",
-    "requestId":"23343221",
-    "operation":"GET",
-    "url":"/policy_schemas?ric=ric_ric-simulator_1"
-  }
-
-Receive Message
-~~~~~~~~~~~~~~~
-
-The message the Policy Agent sends back to the DMaaP Message Router is a JSON like the one below. The "*requestId*"
-"*correlationId*", and "*originatorId*" are the same as in the message sent to DMaaP MR. ::
-
-  {
-    "requestId": "string",
-    "correlationId": "string",
-    "originatorId": "string",
-    "type": "string",
-    "message": "string",
-    "type":  "string",
-    "timestamp": "string",
-    "status": "string"
-  }
-
-Example
-+++++++
-
-The response containing all policy types for a specific Near |nbh| RT |nbsp| RIC sent to the DMaaP Message Router from
-the Policy Agent: ::
-
-  {
-    \"requestId\":\"23343221\",
-    \"correlationId\":\"c09ac7d1-de62-0016-2000-e63701125557-201\",
-    \"originatorId\":\"849e6c6b420\",
-    \"type\":\"response\",
-    \"message\":\"[
-      {
-      \\\"$schema\\\":\\\"http://json-schema.org/draft-07/schema#\\\",
-      \\\"description\\\":\\\"QoS policy type\\\",
-      \\\"title\\\":\\\"STD_QoSNudging_0.2.0\\\",
-      \\\"type\\\":\\\"object\\\",
-      \\\"properties\\\":{\\\"scope\\\":{\\\"additionalProperties\\\":true,
-      \\\"type\\\":\\\"object\\\",
-      \\\"properties\\\":{\\\"qosId\\\":{\\\"type\\\":\\\"string\\\"},
-      \\\"ueId\\\":{\\\"type\\\":\\\"string\\\"}},
-      \\\"required\\\":[\\\"ueId\\\",
-      \\\"qosId\\\"]},
-      \\\"statement\\\":{\\\"additionalProperties\\\":false,
-      \\\"type\\\":\\\"object\\\",
-      \\\"properties\\\":{\\\"priorityLevel\\\":{\\\"type\\\":\\\"number\\\"}},
-      \\\"required\\\":[\\\"priorityLevel\\\"]}}
-      }
-    ]\",
-    \"timestamp\":\"2019-05-14T11:44:51.36Z\",
-    \"status\":\"200 OK\"
-  }
\ No newline at end of file
index 09a0c1c..78db685 100644 (file)
@@ -1,5 +1,12 @@
-sphinx
-sphinx-rtd-theme
-sphinxcontrib-httpdomain
-recommonmark
-lfdocs-conf
+tox
+Sphinx>=2,<4
+doc8
+docutils
+setuptools
+six
+sphinx_rtd_theme>=0.4.3
+sphinxcontrib-needs>=0.2.3
+sphinxcontrib-swaggerdoc
+sphinx_bootstrap_theme
+sphinxcontrib-redoc
+lfdocs-conf
\ No newline at end of file
diff --git a/docs/sdnc-a1-controller-api.rst b/docs/sdnc-a1-controller-api.rst
deleted file mode 100644 (file)
index 24f9d45..0000000
+++ /dev/null
@@ -1,530 +0,0 @@
-.. This work is licensed under a Creative Commons Attribution 4.0 International License.
-.. http://creativecommons.org/licenses/by/4.0
-.. Copyright (C) 2020 Nordix
-
-.. _sdnc-a1-controller-api:
-
-.. |nbsp| unicode:: 0xA0
-   :trim:
-
-.. |nbh| unicode:: 0x2011
-   :trim:
-
-######################
-SDNC A1 Controller API
-######################
-
-The A1 of a Near |nbh| RT |nbsp| RIC can be used through the SDNC A1 Controller.
-
-The OSC A1 Controller supports using multiple versions of A1 API southbound. By passing the full URL for each southbound
-A1 operation the problem of version-specific URL formats is avoided.
-
-Since different versions of A1 operations may use different data formats for data payloads for similar REST requests and
-responses the data formatting requirements are flexible, so version-specific encoding/decoding is handled by the service
-that requests the A1 operation.
-
-Get Policy Type
-~~~~~~~~~~~~~~~
-
-POST
-++++
-
-Gets a policy type.
-
-Definition
-""""""""""
-
-**URL path:**
-
-/restconf/operations/A1-ADAPTER-API:getA1PolicyType
-
-**Parameters:**
-
-None.
-
-**Body:** (*Required*)
-
-A JSON object. ::
-
-  {
-    "input": {
-      "near-rt-ric-url": "<url-to-near-rt-ric-to-get-type>"
-    }
-  }
-
-**Responses:**
-
-200:
-
-A JSON object where the body tag contains the JSON object of the policy type. ::
-
-  {
-    "output": {
-      "http-status": "integer",
-      "body": "{
-        <policy-type>
-      }"
-    }
-  }
-
-Examples
-""""""""
-
-Get a policy type from a Near |nbh| RT |nbsp| RIC that is using the OSC 2.1.0 version. The STD 1.1.3 version does not
-support types, so this function is not available for that version.
-
-**Call**: ::
-
-    curl -X POST "http://localhost:8282/restconf/operations/A1-ADAPTER-API:getA1PolicyType"
-    -H "Content-Type: application/json" -d '{
-      "input": {
-        "near-rt-ric-url": "http://nearRtRic-sim1:8085/a1-p/policytypes/11"
-      }
-    }'
-
-**Result**:
-
-200: ::
-
-  {
-    "output": {
-      "http-status": 200,
-      "body": "{
-        \"$schema\": \"http://json-schema.org/draft-07/schema#\",
-        \"title\": \"Example_QoETarget_1.0.0\",
-        \"description\": \"Example QoE Target policy type\",
-        \"type\": \"object\",
-        \"properties\": {
-          \"scope\": {
-            \"type\": \"object\",
-            \"properties\": {
-              \"ueId\": {
-                \"type\": \"string\"
-              },
-              \"sliceId\": {
-                \"type\": \"string\"
-              },
-              \"qosId\": {
-                \"type\": \"string\"
-              },
-              \"cellId\": {
-                \"type\": \"string\"
-              }
-            },
-            \"additionalProperties\": false,
-            \"required\": [
-              \"ueId\",
-              \"sliceId\"
-            ]
-          },
-          \"statement\": {
-            \"type\": \"object\",
-            \"properties\": {
-              \"qoeScore\": {
-                \"type\": \"number\"
-              },
-              \"initialBuffering\": {
-                \"type\": \"number\"
-              },
-              \"reBuffFreq\": {
-                \"type\": \"number\"
-              },
-              \"stallRatio\": {
-                \"type\": \"number\"
-              }
-            },
-            \"minProperties\": 1,
-            \"additionalProperties\": false
-          }
-        }
-      }"
-    }
-  }
-
-Put Policy
-~~~~~~~~~~
-
-POST
-++++
-
-Creates or updates a policy instance.
-
-Definition
-""""""""""
-
-**URL path:**
-
-/restconf/operations/A1-ADAPTER-API:putA1Policy
-
-**Parameters:**
-
-None.
-
-**Body:** (*Required*)
-
-A JSON object where the body tag contains the JSON object of the policy. ::
-
-  {
-    "input": {
-      "near-rt-ric-url": "<url-to-near-rt-ric-to-put-policy>",
-      "body": "<policy-as-json-string>"
-    }
-  }
-
-**Responses:**
-
-200:
-
-A JSON object with the response. ::
-
-  {
-    "output": {
-      "http-status": "integer"
-    }
-  }
-
-Examples
-""""""""
-
-**Call**:
-
-Create a policy in a Near |nbh| RT |nbsp| RIC that is using the OSC 2.1.0 version. ::
-
-    curl -X POST "http://localhost:8282/restconf/operations/A1-ADAPTER-API:putA1Policy"
-    -H "Content-Type: application/json" -d '{
-      "input": {
-        "near-rt-ric-url": "http://nearRtRic-sim1:8085/a1-p/policytypes/11/policies/5000",
-        "body": "{
-          "blocking_rate":20,
-          "enforce":true,
-          "trigger_threshold":10,
-          "window_length":10
-        }"
-      }
-    }'
-
-Create a policy in a Near |nbh| RT |nbsp| RIC that is using the STD 1.1.3 version. ::
-
-    curl -X POST http://localhost:8282/restconf/operations/A1-ADAPTER-API:putA1Policy
-    -H Content-Type:application/json -d '{
-      "input": {
-        "near-rt-ric-url": "http://ricsim_g2_1:8085/A1-P/v1/policies/5000",
-        "body": "{
-          "scope": {
-            "ueId": "ue5000",
-            "qosId": "qos5000"
-          },
-          "qosObjective": {
-            "priorityLevel": 5000
-          }
-        }"
-      }
-    }'
-
-**Result**:
-
-The result is the same irrespective of which API that is used.
-
-200: ::
-
-  {
-    "output": {
-      "http-status": 200
-    }
-  }
-
-Get Policy
-~~~~~~~~~~
-
-POST
-++++
-
-Gets a policy instance.
-
-Definition
-""""""""""
-
-**URL path:**
-
-/restconf/operations/A1-ADAPTER-API:getA1Policy
-
-**Parameters:**
-
-None.
-
-**Body:** (*Required*)
-
-A JSON object. ::
-
-  {
-    "input": {
-      "near-rt-ric-url": "<url-to-near-rt-ric-to-get-policy>"
-    }
-  }
-
-**Responses:**
-
-200:
-  A JSON object where the body tag contains the JSON object of the policy. ::
-
-    {
-      "output": {
-        "http-status": "integer",
-        "body": "{
-          <result>
-        }"
-      }
-    }
-
-Examples
-""""""""
-
-**Call**:
-
-Get **all** policy IDs from a Near |nbh| RT |nbsp| RIC that is using the OSC 2.1.0 version. ::
-
-    curl -X POST http://localhost:8282/restconf/operations/A1-ADAPTER-API:getA1Policy
-    -H Content-Type:application/json -d '{
-      "input": {
-        "near-rt-ric-url":"http://ricsim_g1_1:8085/a1-p/policytypes/11/policies"
-      }
-    }'
-
-Get **all** policy IDs from a Near |nbh| RT |nbsp| RIC that is using the STD 1.1.3 version. ::
-
-    curl -X POST http://localhost:8282/restconf/operations/A1-ADAPTER-API:getA1Policy
-    -H Content-Type:application/json -d '{
-      "input": {
-        "near-rt-ric-url":"http://ricsim_g2_1:8085/A1-P/v1/policies"
-      }
-    }'
-
-**Result**:
-
-The result is the same irrespective of which API that is used.
-
-200: ::
-
-  {
-    "output": {
-      "http-status":200,
-      "body":"[
-        \"5000\",
-          .
-          .
-          .
-        \"6000\"
-      ]"
-    }
-  }
-
-**Call**:
-
-Get **a specific** policy from a Near |nbh| RT |nbsp| RIC that is using the OSC 2.1.0 version. ::
-
-    curl -X POST "http://localhost:8282/restconf/operations/A1-ADAPTER-API:getA1Policy"
-    -H "Content-Type: application/json" -d '{
-      "input": {
-        "near-rt-ric-url": "http://nearRtRic-sim1:8085/a1-p/policytypes/11/policies/5000"
-      }
-    }'
-
-Get **a specific** policy from a Near |nbh| RT |nbsp| RIC that is using the STD 1.1.3 version. ::
-
-    curl -X POST http://localhost:8282/restconf/operations/A1-ADAPTER-API:getA1PolicyType
-    -H Content-Type:application/json -d '{
-      "input": {
-        "near-rt-ric-url":"http://ricsim_g2_1:8085/A1-P/v1/policies/5000"
-      }
-    }'
-
-**Result**:
-
-The result is the same irrespective of which API that is used.
-
-200: ::
-
-  {
-    "output": {
-      "http-status": 200,
-      "body": "{
-        \"blocking_rate\": 20,
-        \"enforce\": true,
-        \"trigger_threshold\": 10,
-        \"window_length\": 10
-      }"
-    }
-  }
-
-Delete Policy
-~~~~~~~~~~~~~
-
-POST
-++++
-
-Deletes a policy instance.
-
-Definition
-""""""""""
-
-**URL path:**
-
-/restconf/operations/A1-ADAPTER-API:deleteA1Policy
-
-**Parameters:**
-
-None.
-
-**Body:** (*Required*)
-
-A JSON object. ::
-
-  {
-    "input": {
-      "near-rt-ric-url": "<url-to-near-rt-ric-to-delete-policy>"
-    }
-  }
-
-**Responses:**
-
-200:
-
-A JSON object with the response. ::
-
-  {
-    "output": {
-      "http-status": "integer"
-    }
-  }
-
-Examples
-""""""""
-
-**Call**:
-
-Delete a policy from a Near |nbh| RT |nbsp| RIC that is using the OSC 2.1.0 version. ::
-
-    curl -X POST "http://localhost:8282/restconf/operations/A1-ADAPTER-API:deleteA1Policy"
-    -H "Content-Type: application/json" -d '{
-      "input": {
-        "near-rt-ric-url": "http://nearRtRic-sim1:8085/a1-p/policytypes/11/policies/5000"
-      }
-    }'
-
-Delete a policy from a Near |nbh| RT |nbsp| RIC that is using the STD 1.1.3 version. ::
-
-    curl -X POST "http://localhost:8282/restconf/operations/A1-ADAPTER-API:deleteA1Policy"
-    -H "Content-Type: application/json" -d '{
-      "input": {
-        "near-rt-ric-url": "http://ricsim_g2_1:8085/A1-P/v1/policies/5000"
-      }
-    }'
-
-**Result**:
-
-The result is the same irrespective of which API that is used.
-
-200: ::
-
-  {
-    "output": {
-      "http-status": 202
-    }
-  }
-
-Get Policy Status
-~~~~~~~~~~~~~~~~~
-
-POST
-++++
-
-Get the status of a policy instance.
-
-Definition
-""""""""""
-
-**URL path:**
-
-/restconf/operations/A1-ADAPTER-API:getA1PolicyStatus
-
-**Parameters:**
-
-None.
-
-**Body:** (*Required*)
-
-A JSON object. ::
-
-  {
-    "input": {
-      "near-rt-ric-url": "<url-to-near-rt-ric-to-get-policy-status>"
-    }
-  }
-
-**Responses:**
-
-200:
-
-A JSON object where the body tag contains the JSON object with the policy status according to the API version used. ::
-
-  {
-    "output": {
-      "http-status": "integer",
-      "body": "{
-        <policy-status-object>
-      }"
-    }
-  }
-
-Examples
-""""""""
-
-**Call**:
-
-Get the policy status for a specific policy from a Near |nbh| RT |nbsp| RIC that is using the OSC 2.1.0 version. ::
-
-    curl -X POST "http://localhost:8282/restconf/operations/A1-ADAPTER-API:getA1PolicyStatus"
-    -H "Content-Type: application/json" -d '{
-      "input": {
-        "near-rt-ric-url": "http://nearRtRic-sim1:8085/a1-p/policytypes/11/policies/5000/status"
-      }
-    }'
-
-**Result**:
-
-200: ::
-
-  {
-    "output": {
-      "http-status": 200,
-      "body": "{
-        \"instance_status\": \"IN EFFECT\",
-        \"has_been_deleted\": \"true\",
-        \"created_at\": \"Wed, 01 Apr 2020 07:45:45 GMT\"
-      }"
-    }
-  }
-
-**Call**:
-
-Get the policy status for a specific policy from a Near |nbh| RT |nbsp| RIC that is using the STD 1.1.3 version. ::
-
-    curl -X POST "http://localhost:8282/restconf/operations/A1-ADAPTER-API:getA1PolicyStatus"
-    -H "Content-Type: application/json" -d '{
-      "input": {
-        "near-rt-ric-url": "http://ricsim_g2_1:8085/A1-P/v1/policies/5000/status"
-      }
-    }'
-
-**Result**:
-
-200: ::
-
-  {
-    "output": {
-      "http-status": 200,
-      "body": "{
-        \"enforceStatus\": \"UNDEFINED\"
-      }"
-    }
-  }
diff --git a/enrichment-coordinator-service/.gitignore b/enrichment-coordinator-service/.gitignore
new file mode 100644 (file)
index 0000000..b83d222
--- /dev/null
@@ -0,0 +1 @@
+/target/
index 51d45b5..744a237 100644 (file)
@@ -24,6 +24,8 @@ ARG JAR
 WORKDIR /opt/app/enrichment-coordinator-service
 RUN mkdir -p /var/log/enrichment-coordinator-service
 RUN mkdir -p /opt/app/enrichment-coordinator-service/etc/cert/
+RUN mkdir -p /var/enrichment-coordinator-service
+RUN chmod -R 777 /var/enrichment-coordinator-service
 
 EXPOSE 8083 8434
 
index e64db0c..850dc67 100644 (file)
@@ -35,4 +35,5 @@ app:
     trust-store-used: false
     trust-store-password: policy_agent
     trust-store: /opt/app/enrichment-coordinator-service/etc/cert/truststore.jks
+  vardata-directory: /var/enrichment-coordinator-service
 
index ce41956..c5d2bec 100644 (file)
@@ -22,12 +22,15 @@ package org.oransc.enrichment;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 
+import java.lang.invoke.MethodHandles;
+
 import org.apache.catalina.connector.Connector;
-import org.oransc.enrichment.clients.ProducerCallbacks;
 import org.oransc.enrichment.configuration.ApplicationConfig;
 import org.oransc.enrichment.repository.EiJobs;
 import org.oransc.enrichment.repository.EiProducers;
 import org.oransc.enrichment.repository.EiTypes;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
 import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
@@ -41,6 +44,7 @@ class BeanFactory {
     private int httpPort = 0;
 
     private final ApplicationConfig applicationConfig = new ApplicationConfig();
+    private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
     @Bean
     public ObjectMapper mapper() {
@@ -58,7 +62,13 @@ class BeanFactory {
 
     @Bean
     public EiJobs eiJobs() {
-        return new EiJobs();
+        EiJobs jobs = new EiJobs(getApplicationConfig());
+        try {
+            jobs.restoreJobsFromDatabase();
+        } catch (Exception e) {
+            logger.error("Could not restore jobs from database: {}", e.getMessage());
+        }
+        return jobs;
     }
 
     @Bean
@@ -76,11 +86,6 @@ class BeanFactory {
         return this.applicationConfig;
     }
 
-    @Bean
-    public ProducerCallbacks getProducerCallbacks() {
-        return new ProducerCallbacks(this.applicationConfig);
-    }
-
     private static Connector getHttpConnector(int httpPort) {
         Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
         connector.setScheme("http");
diff --git a/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/clients/ProducerCallbacks.java b/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/clients/ProducerCallbacks.java
deleted file mode 100644 (file)
index 9b23865..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.enrichment.clients;
-
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-
-import java.lang.invoke.MethodHandles;
-
-import org.oransc.enrichment.configuration.ApplicationConfig;
-import org.oransc.enrichment.repository.EiJob;
-import org.oransc.enrichment.repository.EiProducer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-/**
- * Callbacks to the EiProducer
- */
-@SuppressWarnings("java:S3457") // No need to call "toString()" method as formatting and string ..
-public class ProducerCallbacks {
-
-    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-    private static Gson gson = new GsonBuilder() //
-        .serializeNulls() //
-        .create(); //
-
-    private final AsyncRestClient restClient;
-
-    public ProducerCallbacks(ApplicationConfig config) {
-        AsyncRestClientFactory restClientFactory = new AsyncRestClientFactory(config.getWebClientConfig());
-        this.restClient = restClientFactory.createRestClient("");
-    }
-
-    public void notifyProducersJobDeleted(EiJob eiJob) {
-        ProducerJobInfo request = new ProducerJobInfo(eiJob);
-        String body = gson.toJson(request);
-        for (EiProducer producer : eiJob.type().getProducers()) {
-            restClient.post(producer.getJobDeletionCallbackUrl(), body) //
-                .subscribe(notUsed -> logger.debug("Job deleted OK {}", producer.getId()), //
-                    throwable -> logger.warn("Job delete failed {}", producer.getId(), throwable.toString()), null);
-        }
-    }
-
-    /**
-     * Calls all producers for an EiJob activation.
-     * 
-     * @param eiJob an EI job
-     * @return the number of producers that returned OK
-     */
-    public Mono<Integer> notifyProducersJobStarted(EiJob eiJob) {
-        return Flux.fromIterable(eiJob.type().getProducers()) //
-            .flatMap(eiProducer -> notifyProducerJobStarted(eiProducer, eiJob)) //
-            .collectList() //
-            .flatMap(okResponses -> Mono.just(Integer.valueOf(okResponses.size()))); //
-    }
-
-    /**
-     * Calls one producer for an EiJob activation.
-     * 
-     * @param producer a producer
-     * @param eiJob an EI job
-     * @return the body of the response from the REST call
-     */
-    public Mono<String> notifyProducerJobStarted(EiProducer producer, EiJob eiJob) {
-        ProducerJobInfo request = new ProducerJobInfo(eiJob);
-        String body = gson.toJson(request);
-
-        return restClient.post(producer.getJobCreationCallbackUrl(), body)
-            .doOnNext(resp -> logger.debug("Job subscription started OK {}", producer.getId()))
-            .onErrorResume(throwable -> {
-                logger.warn("Job subscription failed {}", producer.getId(), throwable.toString());
-                return Mono.empty();
-            });
-    }
-
-}
index 2d4087f..8937464 100644 (file)
@@ -36,6 +36,10 @@ public class ApplicationConfig {
     @Value("${app.filepath}")
     private String localConfigurationFilePath;
 
+    @Getter
+    @Value("${app.vardata-directory}")
+    private String vardataDirectory;
+
     @Value("${server.ssl.key-store-type}")
     private String sslKeyStoreType = "";
 
index 28c40bf..921b807 100644 (file)
@@ -35,11 +35,12 @@ import org.springframework.http.ResponseEntity;
 import reactor.core.publisher.Mono;
 
 public class ErrorResponse {
-    private static Gson gson = new GsonBuilder() //
-        .create(); //
+    private static Gson gson = new GsonBuilder().create();
 
     // Returned as body for all failed REST calls
-    @ApiModel(value = "error_information", description = "Problem as defined in https://tools.ietf.org/html/rfc7807")
+    @ApiModel(
+        value = "ProblemDetails",
+        description = "A problem detail to carry details in a HTTP response according to RFC 7807")
     public static class ErrorInfo {
         @SerializedName("type")
         private String type = "about:blank";
index 80b6a80..b28da8d 100644 (file)
@@ -25,7 +25,7 @@ import io.swagger.annotations.ApiModel;
 import org.immutables.gson.Gson;
 
 @Gson.TypeAdapters
-@ApiModel(value = "void", description = "Void/empty")
+@ApiModel(value = "Void", description = "Void/empty")
 public class VoidResponse {
     private VoidResponse() {
     }
diff --git a/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/consumer/ConsumerCallbacks.java b/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/consumer/ConsumerCallbacks.java
new file mode 100644 (file)
index 0000000..9087355
--- /dev/null
@@ -0,0 +1,103 @@
+/*-
+ * ========================LICENSE_START=================================
+ * O-RAN-SC
+ * %%
+ * Copyright (C) 2020 Nordix Foundation
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================LICENSE_END===================================
+ */
+
+package org.oransc.enrichment.controllers.consumer;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+import java.lang.invoke.MethodHandles;
+
+import org.oransc.enrichment.clients.AsyncRestClient;
+import org.oransc.enrichment.clients.AsyncRestClientFactory;
+import org.oransc.enrichment.configuration.ApplicationConfig;
+import org.oransc.enrichment.repository.EiJob;
+import org.oransc.enrichment.repository.EiJobs;
+import org.oransc.enrichment.repository.EiProducer;
+import org.oransc.enrichment.repository.EiType;
+import org.oransc.enrichment.repository.EiTypes;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * Callbacks to the EiProducer
+ */
+@Component
+@SuppressWarnings("java:S3457") // No need to call "toString()" method as formatting and string ..
+public class ConsumerCallbacks {
+
+    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+    private static Gson gson = new GsonBuilder().create();
+
+    private final AsyncRestClient restClient;
+    private final EiTypes eiTypes;
+    private final EiJobs eiJobs;
+
+    @Autowired
+    public ConsumerCallbacks(ApplicationConfig config, EiTypes eiTypes, EiJobs eiJobs) {
+        AsyncRestClientFactory restClientFactory = new AsyncRestClientFactory(config.getWebClientConfig());
+        this.restClient = restClientFactory.createRestClient("");
+        this.eiTypes = eiTypes;
+        this.eiJobs = eiJobs;
+    }
+
+    public void notifyConsumersProducerDeleted(EiProducer eiProducer) {
+        for (EiType type : eiProducer.getEiTypes()) {
+            if (this.eiTypes.get(type.getId()) == null) {
+                // The type is removed
+                for (EiJob job : this.eiJobs.getJobsForType(type)) {
+                    if (job.isLastStatusReportedEnabled()) {
+                        noifyJobOwner(job, new ConsumerEiJobStatus(ConsumerEiJobStatus.EiJobStatusValues.DISABLED));
+                        job.setLastReportedStatus(false);
+                    }
+                }
+            }
+        }
+    }
+
+    public void notifyConsumersProducerAdded(EiProducer eiProducer) {
+        for (EiType type : eiProducer.getEiTypes()) {
+            notifyConsumersTypeAdded(type);
+        }
+    }
+
+    public void notifyConsumersTypeAdded(EiType eiType) {
+        for (EiJob job : this.eiJobs.getJobsForType(eiType)) {
+            if (!job.isLastStatusReportedEnabled()) {
+                noifyJobOwner(job, new ConsumerEiJobStatus(ConsumerEiJobStatus.EiJobStatusValues.ENABLED));
+                job.setLastReportedStatus(true);
+            }
+        }
+    }
+
+    private void noifyJobOwner(EiJob job, ConsumerEiJobStatus status) {
+        if (!job.getJobStatusUrl().isEmpty()) {
+            String body = gson.toJson(status);
+            this.restClient.post(job.getJobStatusUrl(), body) //
+                .subscribe(notUsed -> logger.debug("Consumer notified OK {}", job.getId()), //
+                    throwable -> logger.warn("Consumer notify failed {} {}", job.getJobStatusUrl(),
+                        throwable.toString()), //
+                    null);
+        }
+    }
+
+}
index a8e88d8..8603142 100644 (file)
@@ -23,9 +23,12 @@ package org.oransc.enrichment.controllers.consumer;
 public class ConsumerConsts {
 
     public static final String API_ROOT = "/A1-EI/v1";
-    public static final String CONSUMER_API_NAME = "A1-E Enrichment Data Consumer API";
+    public static final String CONSUMER_API_NAME = "A1-EI (enrichment information)";
     public static final String OWNER_PARAM = "owner";
-    public static final String OWNER_PARAM_DESCRIPTION = "identifies the owner of the job";
+    public static final String OWNER_PARAM_DESCRIPTION = "selects EI jobs for one EI job owner";
+
+    public static final String EI_TYPE_ID_PARAM = "eiTypeId";
+    public static final String EI_TYPE_ID_PARAM_DESCRIPTION = "selects EI jobs of matching EI type";
 
     private ConsumerConsts() {
     }
index 39796ee..f45ff73 100644 (file)
@@ -31,21 +31,23 @@ import io.swagger.annotations.ApiResponse;
 import io.swagger.annotations.ApiResponses;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
+import java.util.Vector;
 
 import org.everit.json.schema.Schema;
 import org.everit.json.schema.loader.SchemaLoader;
 import org.json.JSONObject;
-import org.oransc.enrichment.clients.ProducerCallbacks;
 import org.oransc.enrichment.configuration.ApplicationConfig;
 import org.oransc.enrichment.controllers.ErrorResponse;
 import org.oransc.enrichment.controllers.VoidResponse;
+import org.oransc.enrichment.controllers.producer.ProducerCallbacks;
 import org.oransc.enrichment.exceptions.ServiceException;
 import org.oransc.enrichment.repository.EiJob;
 import org.oransc.enrichment.repository.EiJobs;
+import org.oransc.enrichment.repository.EiProducer;
 import org.oransc.enrichment.repository.EiType;
 import org.oransc.enrichment.repository.EiTypes;
-import org.oransc.enrichment.repository.ImmutableEiJob;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
@@ -55,6 +57,7 @@ import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PutMapping;
 import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 import reactor.core.publisher.Mono;
@@ -62,6 +65,7 @@ import reactor.core.publisher.Mono;
 @SuppressWarnings("java:S3457") // No need to call "toString()" method as formatting and string ..
 @RestController("ConsumerController")
 @Api(tags = {ConsumerConsts.CONSUMER_API_NAME})
+@RequestMapping(path = ConsumerConsts.API_ROOT, produces = MediaType.APPLICATION_JSON_VALUE)
 public class ConsumerController {
 
     @Autowired
@@ -76,11 +80,9 @@ public class ConsumerController {
     @Autowired
     ProducerCallbacks producerCallbacks;
 
-    private static Gson gson = new GsonBuilder() //
-        .serializeNulls() //
-        .create(); //
+    private static Gson gson = new GsonBuilder().create();
 
-    @GetMapping(path = ConsumerConsts.API_ROOT + "/eitypes", produces = MediaType.APPLICATION_JSON_VALUE)
+    @GetMapping(path = "/eitypes", produces = MediaType.APPLICATION_JSON_VALUE)
     @ApiOperation(value = "EI type identifiers", notes = "")
     @ApiResponses(
         value = { //
@@ -100,7 +102,7 @@ public class ConsumerController {
         return new ResponseEntity<>(gson.toJson(result), HttpStatus.OK);
     }
 
-    @GetMapping(path = ConsumerConsts.API_ROOT + "/eitypes/{eiTypeId}", produces = MediaType.APPLICATION_JSON_VALUE)
+    @GetMapping(path = "/eitypes/{eiTypeId}", produces = MediaType.APPLICATION_JSON_VALUE)
     @ApiOperation(value = "Individual EI type", notes = "")
     @ApiResponses(
         value = { //
@@ -112,18 +114,16 @@ public class ConsumerController {
     public ResponseEntity<Object> getEiType( //
         @PathVariable("eiTypeId") String eiTypeId) {
         try {
-            EiType t = this.eiTypes.getType(eiTypeId);
-            ConsumerEiTypeInfo info = toEiTypeInfo(t);
+            this.eiTypes.getType(eiTypeId); // Make sure that the type exists
+            ConsumerEiTypeInfo info = toEiTypeInfo();
             return new ResponseEntity<>(gson.toJson(info), HttpStatus.OK);
         } catch (Exception e) {
             return ErrorResponse.create(e, HttpStatus.NOT_FOUND);
         }
     }
 
-    @GetMapping(
-        path = ConsumerConsts.API_ROOT + "/eitypes/{eiTypeId}/eijobs",
-        produces = MediaType.APPLICATION_JSON_VALUE)
-    @ApiOperation(value = "EI job identifiers", notes = "")
+    @GetMapping(path = "/eijobs", produces = MediaType.APPLICATION_JSON_VALUE)
+    @ApiOperation(value = "EI job identifiers", notes = "query for EI job identifiers")
     @ApiResponses(
         value = { //
             @ApiResponse(
@@ -136,48 +136,49 @@ public class ConsumerController {
                 message = "Enrichment Information type is not found",
                 response = ErrorResponse.ErrorInfo.class)})
     public ResponseEntity<Object> getEiJobIds( //
-        @PathVariable("eiTypeId") String eiTypeId, //
+        @ApiParam(
+            name = ConsumerConsts.EI_TYPE_ID_PARAM,
+            required = false, //
+            value = ConsumerConsts.EI_TYPE_ID_PARAM_DESCRIPTION) //
+        @RequestParam(name = ConsumerConsts.EI_TYPE_ID_PARAM, required = false) String eiTypeId,
         @ApiParam(
             name = ConsumerConsts.OWNER_PARAM,
             required = false, //
             value = ConsumerConsts.OWNER_PARAM_DESCRIPTION) //
         @RequestParam(name = ConsumerConsts.OWNER_PARAM, required = false) String owner) {
         try {
-            this.eiTypes.getType(eiTypeId); // Just to check that the type exists
             List<String> result = new ArrayList<>();
             if (owner != null) {
                 for (EiJob job : this.eiJobs.getJobsForOwner(owner)) {
-                    if (eiTypeId == null || job.type().getId().equals(eiTypeId)) {
-                        result.add(job.id());
+                    if (eiTypeId == null || job.getTypeId().equals(eiTypeId)) {
+                        result.add(job.getId());
                     }
                 }
+            } else if (eiTypeId != null) {
+                this.eiJobs.getJobsForType(eiTypeId).forEach(job -> result.add(job.getId()));
             } else {
-                for (EiJob job : this.eiJobs.getJobsForType(eiTypeId)) {
-                    result.add(job.id());
-                }
+                this.eiJobs.getJobs().forEach(job -> result.add(job.getId()));
             }
             return new ResponseEntity<>(gson.toJson(result), HttpStatus.OK);
-        } catch (Exception e) {
+        } catch (
+
+        Exception e) {
             return ErrorResponse.create(e, HttpStatus.NOT_FOUND);
         }
     }
 
-    @GetMapping(
-        path = ConsumerConsts.API_ROOT + "/eitypes/{eiTypeId}/eijobs/{eiJobId}",
-        produces = MediaType.APPLICATION_JSON_VALUE)
-    @ApiOperation(value = "Individual EI Job", notes = "")
+    @GetMapping(path = "/eijobs/{eiJobId}", produces = MediaType.APPLICATION_JSON_VALUE)
+    @ApiOperation(value = "Individual EI job", notes = "")
     @ApiResponses(
         value = { //
-            @ApiResponse(code = 200, message = "EI Job", response = ConsumerEiJobInfo.class), //
+            @ApiResponse(code = 200, message = "EI job", response = ConsumerEiJobInfo.class), //
             @ApiResponse(
                 code = 404,
-                message = "Enrichment Information type or job is not found",
+                message = "Enrichment Information job is not found",
                 response = ErrorResponse.ErrorInfo.class)})
     public ResponseEntity<Object> getIndividualEiJob( //
-        @PathVariable("eiTypeId") String eiTypeId, //
         @PathVariable("eiJobId") String eiJobId) {
         try {
-            this.eiTypes.getType(eiTypeId); // Just to check that the type exists
             EiJob job = this.eiJobs.getJob(eiJobId);
             return new ResponseEntity<>(gson.toJson(toEiJobInfo(job)), HttpStatus.OK);
         } catch (Exception e) {
@@ -185,22 +186,18 @@ public class ConsumerController {
         }
     }
 
-    @GetMapping(
-        path = ConsumerConsts.API_ROOT + "/eitypes/{eiTypeId}/eijobs/{eiJobId}/status",
-        produces = MediaType.APPLICATION_JSON_VALUE)
-    @ApiOperation(value = "EI Job status", notes = "")
+    @GetMapping(path = "/eijobs/{eiJobId}/status", produces = MediaType.APPLICATION_JSON_VALUE)
+    @ApiOperation(value = "EI job status", notes = "")
     @ApiResponses(
         value = { //
-            @ApiResponse(code = 200, message = "EI Job status", response = ConsumerEiJobStatus.class), //
+            @ApiResponse(code = 200, message = "EI job status", response = ConsumerEiJobStatus.class), //
             @ApiResponse(
                 code = 404,
-                message = "Enrichment Information type or job is not found",
+                message = "Enrichment Information job is not found",
                 response = ErrorResponse.ErrorInfo.class)})
     public ResponseEntity<Object> getEiJobStatus( //
-        @PathVariable("eiTypeId") String eiTypeId, //
         @PathVariable("eiJobId") String eiJobId) {
         try {
-            this.eiTypes.getType(eiTypeId); // Just to check that the type exists
             EiJob job = this.eiJobs.getJob(eiJobId);
             return new ResponseEntity<>(gson.toJson(toEiJobStatus(job)), HttpStatus.OK);
         } catch (Exception e) {
@@ -208,25 +205,33 @@ public class ConsumerController {
         }
     }
 
+    private Collection<EiProducer> getProducers(EiJob eiJob) {
+        try {
+            return this.eiTypes.getType(eiJob.getTypeId()).getProducers();
+        } catch (Exception e) {
+            return new Vector<>();
+        }
+    }
+
     private ConsumerEiJobStatus toEiJobStatus(EiJob job) {
-        // TODO
-        return new ConsumerEiJobStatus(ConsumerEiJobStatus.OperationalState.ENABLED);
+        if (getProducers(job).isEmpty()) {
+            return new ConsumerEiJobStatus(ConsumerEiJobStatus.EiJobStatusValues.DISABLED);
+        } else {
+            return new ConsumerEiJobStatus(ConsumerEiJobStatus.EiJobStatusValues.ENABLED);
+        }
     }
 
-    @DeleteMapping(
-        path = ConsumerConsts.API_ROOT + "/eitypes/{eiTypeId}/eijobs/{eiJobId}",
-        produces = MediaType.APPLICATION_JSON_VALUE)
-    @ApiOperation(value = "Individual EI Job", notes = "")
+    @DeleteMapping(path = "/eijobs/{eiJobId}", produces = MediaType.APPLICATION_JSON_VALUE)
+    @ApiOperation(value = "Individual EI job", notes = "")
     @ApiResponses(
         value = { //
             @ApiResponse(code = 200, message = "Not used", response = VoidResponse.class),
             @ApiResponse(code = 204, message = "Job deleted", response = VoidResponse.class),
             @ApiResponse(
                 code = 404,
-                message = "Enrichment Information type or job is not found",
+                message = "Enrichment Information job is not found",
                 response = ErrorResponse.ErrorInfo.class)})
     public ResponseEntity<Object> deleteIndividualEiJob( //
-        @PathVariable("eiTypeId") String eiTypeId, //
         @PathVariable("eiJobId") String eiJobId) {
         try {
             EiJob job = this.eiJobs.getJob(eiJobId);
@@ -239,10 +244,10 @@ public class ConsumerController {
     }
 
     @PutMapping(
-        path = ConsumerConsts.API_ROOT + "/eitypes/{eiTypeId}/eijobs/{eiJobId}", //
+        path = "/eijobs/{eiJobId}", //
         produces = MediaType.APPLICATION_JSON_VALUE, //
         consumes = MediaType.APPLICATION_JSON_VALUE)
-    @ApiOperation(value = "Individual EI Job", notes = "")
+    @ApiOperation(value = "Individual EI job", notes = "")
     @ApiResponses(
         value = { //
             @ApiResponse(code = 201, message = "Job created", response = VoidResponse.class), //
@@ -252,13 +257,12 @@ public class ConsumerController {
                 message = "Enrichment Information type is not found",
                 response = ErrorResponse.ErrorInfo.class)})
     public Mono<ResponseEntity<Object>> putIndividualEiJob( //
-        @PathVariable("eiTypeId") String eiTypeId, //
         @PathVariable("eiJobId") String eiJobId, //
-        @RequestBody ConsumerEiJobInfo eiJobInfo) {
+        @RequestBody ConsumerEiJobInfo eiJobObject) {
 
         final boolean isNewJob = this.eiJobs.get(eiJobId) == null;
 
-        return validatePutEiJob(eiTypeId, eiJobId, eiJobInfo) //
+        return validatePutEiJob(eiJobId, eiJobObject) //
             .flatMap(this::notifyProducersNewJob) //
             .doOnNext(newEiJob -> this.eiJobs.put(newEiJob)) //
             .flatMap(newEiJob -> Mono.just(new ResponseEntity<>(isNewJob ? HttpStatus.CREATED : HttpStatus.OK)))
@@ -276,13 +280,13 @@ public class ConsumerController {
             });
     }
 
-    private Mono<EiJob> validatePutEiJob(String eiTypeId, String eiJobId, ConsumerEiJobInfo eiJobInfo) {
+    private Mono<EiJob> validatePutEiJob(String eiJobId, ConsumerEiJobInfo eiJobInfo) {
         try {
-            EiType eiType = this.eiTypes.getType(eiTypeId);
+            EiType eiType = this.eiTypes.getType(eiJobInfo.eiTypeId);
             validateJsonObjectAgainstSchema(eiType.getJobDataSchema(), eiJobInfo.jobData);
             EiJob existingEiJob = this.eiJobs.get(eiJobId);
 
-            if (existingEiJob != null && !existingEiJob.type().getId().equals(eiTypeId)) {
+            if (existingEiJob != null && !existingEiJob.getTypeId().equals(eiJobInfo.eiTypeId)) {
                 throw new ServiceException("Not allowed to change type for existing EI job", HttpStatus.CONFLICT);
             }
             return Mono.just(toEiJob(eiJobInfo, eiJobId, eiType));
@@ -309,23 +313,23 @@ public class ConsumerController {
         }
     }
 
-    // Status TBD
-
     private EiJob toEiJob(ConsumerEiJobInfo info, String id, EiType type) {
-        return ImmutableEiJob.builder() //
+        return EiJob.builder() //
             .id(id) //
-            .type(type) //
+            .typeId(type.getId()) //
             .owner(info.owner) //
             .jobData(info.jobData) //
-            .targetUri(info.targetUri) //
+            .targetUrl(info.targetUri) //
+            .jobStatusUrl(info.statusNotificationUri == null ? "" : info.statusNotificationUri) //
             .build();
     }
 
-    private ConsumerEiTypeInfo toEiTypeInfo(EiType t) {
-        return new ConsumerEiTypeInfo(t.getJobDataSchema());
+    private ConsumerEiTypeInfo toEiTypeInfo() {
+        return new ConsumerEiTypeInfo();
     }
 
     private ConsumerEiJobInfo toEiJobInfo(EiJob s) {
-        return new ConsumerEiJobInfo(s.jobData(), s.owner(), s.targetUri());
+        return new ConsumerEiJobInfo(s.getTypeId(), s.getJobData(), s.getOwner(), s.getTargetUrl(),
+            s.getJobStatusUrl());
     }
 }
index 47abcbb..d88091f 100644 (file)
@@ -29,30 +29,43 @@ import io.swagger.annotations.ApiModelProperty;
 import org.immutables.gson.Gson;
 
 @Gson.TypeAdapters
-@ApiModel(value = "EiJob", description = "Information for an Enrichment Information Job")
+@ApiModel(value = "EiJobObject", description = "Information for an Enrichment Information Job")
 public class ConsumerEiJobInfo {
 
+    @ApiModelProperty(value = "EI type Idenitifier of the EI job", required = true)
+    @SerializedName("eiTypeId")
+    @JsonProperty(value = "eiTypeId", required = true)
+    public String eiTypeId;
+
     @ApiModelProperty(value = "Identity of the owner of the job", required = true)
     @SerializedName("jobOwner")
     @JsonProperty(value = "jobOwner", required = true)
     public String owner;
 
-    @ApiModelProperty(value = "EI Type specific job data", required = true)
-    @SerializedName("jobParameters")
-    @JsonProperty(value = "jobParameters", required = true)
+    @ApiModelProperty(value = "EI type specific job data", required = true)
+    @SerializedName("jobDefinition")
+    @JsonProperty(value = "jobDefinition", required = true)
     public Object jobData;
 
-    @ApiModelProperty(value = "The target of the EI data", required = true)
-    @SerializedName("targetUri")
-    @JsonProperty(value = "targetUri", required = true)
+    @ApiModelProperty(value = "The target URI of the EI data", required = true)
+    @SerializedName("jobResultUri")
+    @JsonProperty(value = "jobResultUri", required = true)
     public String targetUri;
 
+    @ApiModelProperty(value = "The target of EI job status notifications", required = false)
+    @SerializedName("jobStatusNotificationUri")
+    @JsonProperty(value = "jobStatusNotificationUri", required = false)
+    public String statusNotificationUri;
+
     public ConsumerEiJobInfo() {
     }
 
-    public ConsumerEiJobInfo(Object jobData, String owner, String targetUri) {
+    public ConsumerEiJobInfo(String eiTypeId, Object jobData, String owner, String targetUri,
+        String statusNotificationUri) {
+        this.eiTypeId = eiTypeId;
         this.jobData = jobData;
         this.owner = owner;
         this.targetUri = targetUri;
+        this.statusNotificationUri = statusNotificationUri;
     }
 }
index 43643ab..60752ec 100644 (file)
@@ -29,25 +29,28 @@ import io.swagger.annotations.ApiModelProperty;
 import org.immutables.gson.Gson;
 
 @Gson.TypeAdapters
-@ApiModel(value = "EiJobStatus", description = "Status for an EI Job")
+@ApiModel(value = "EiJobStatusObject", description = "Status for an EI job")
 public class ConsumerEiJobStatus {
 
     @Gson.TypeAdapters
-    @ApiModel(value = "OperationalState", description = "Represents the operational states for a EI Job")
-    public enum OperationalState {
+    @ApiModel(value = "EiJobStatusValues", description = "Allowed values for EI job status")
+    public enum EiJobStatusValues {
         ENABLED, DISABLED
     }
 
-    private static final String OPERATIONAL_STATE_DESCRIPTION = "Operational state, values:\n" //
-        + "ENABLED: TBD\n" //
-        + "DISABLED: TBD.";
+    private static final String OPERATIONAL_STATE_DESCRIPTION = "values:\n" //
+        + "ENABLED: the A1-EI producer is able to deliver EI result for the EI job\n" //
+        + "DISABLED: the A1-EI producer is unable to deliver EI result for the EI job";
 
-    @ApiModelProperty(value = OPERATIONAL_STATE_DESCRIPTION, name = "operational_state", required = true)
-    @SerializedName("operationalState")
-    @JsonProperty(value = "operationalState", required = true)
-    public final OperationalState state;
+    @ApiModelProperty(value = OPERATIONAL_STATE_DESCRIPTION, name = "eiJobStatus", required = true)
+    @SerializedName("eiJobStatus")
+    @JsonProperty(value = "eiJobStatus", required = true)
+    public EiJobStatusValues state;
 
-    public ConsumerEiJobStatus(OperationalState state) {
+    public ConsumerEiJobStatus() {
+    }
+
+    public ConsumerEiJobStatus(EiJobStatusValues state) {
         this.state = state;
     }
 
index 3a2ab41..b5d664b 100644 (file)
 
 package org.oransc.enrichment.controllers.consumer;
 
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.google.gson.annotations.SerializedName;
-
 import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
 
 import org.immutables.gson.Gson;
 
 @Gson.TypeAdapters
-@ApiModel(value = "EiType", description = "Information for an EI type")
+@ApiModel(value = "EiTypeObject", description = "Information for an EI type")
 public class ConsumerEiTypeInfo {
 
-    @ApiModelProperty(value = "Json schema for the job data")
-    @SerializedName("eiJobParametersSchema")
-    @JsonProperty("eiJobParametersSchema")
-    public final Object jobParametersSchema;
-
-    ConsumerEiTypeInfo(Object jobParametersSchema) {
-        this.jobParametersSchema = jobParametersSchema;
-    }
 }
diff --git a/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/producer/ProducerCallbacks.java b/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/producer/ProducerCallbacks.java
new file mode 100644 (file)
index 0000000..dc732e1
--- /dev/null
@@ -0,0 +1,133 @@
+/*-
+ * ========================LICENSE_START=================================
+ * O-RAN-SC
+ * %%
+ * Copyright (C) 2020 Nordix Foundation
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================LICENSE_END===================================
+ */
+
+package org.oransc.enrichment.controllers.producer;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+import java.lang.invoke.MethodHandles;
+import java.time.Duration;
+import java.util.Collection;
+import java.util.Vector;
+
+import org.oransc.enrichment.clients.AsyncRestClient;
+import org.oransc.enrichment.clients.AsyncRestClientFactory;
+import org.oransc.enrichment.configuration.ApplicationConfig;
+import org.oransc.enrichment.repository.EiJob;
+import org.oransc.enrichment.repository.EiJobs;
+import org.oransc.enrichment.repository.EiProducer;
+import org.oransc.enrichment.repository.EiTypes;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+import reactor.util.retry.Retry;
+
+/**
+ * Callbacks to the EiProducer
+ */
+@Component
+@SuppressWarnings("java:S3457") // No need to call "toString()" method as formatting and string ..
+public class ProducerCallbacks {
+
+    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+    private static Gson gson = new GsonBuilder().create();
+
+    private final AsyncRestClient restClient;
+    private final EiTypes eiTypes;
+
+    @Autowired
+    public ProducerCallbacks(ApplicationConfig config, EiTypes eiTypes) {
+        AsyncRestClientFactory restClientFactory = new AsyncRestClientFactory(config.getWebClientConfig());
+        this.restClient = restClientFactory.createRestClient("");
+        this.eiTypes = eiTypes;
+    }
+
+    public void notifyProducersJobDeleted(EiJob eiJob) {
+        for (EiProducer producer : getProducers(eiJob)) {
+            String url = producer.getJobCallbackUrl() + "/" + eiJob.getId();
+            restClient.delete(url) //
+                .subscribe(notUsed -> logger.debug("Producer job deleted OK {}", producer.getId()), //
+                    throwable -> logger.warn("Producer job delete failed {} {}", producer.getId(),
+                        throwable.getMessage()),
+                    null);
+        }
+    }
+
+    /**
+     * Calls all producers for an EiJob activation.
+     * 
+     * @param eiJob an EI job
+     * @return the number of producers that returned OK
+     */
+    public Mono<Integer> notifyProducersJobStarted(EiJob eiJob) {
+        Retry retrySpec = Retry.fixedDelay(1, Duration.ofSeconds(1));
+        return Flux.fromIterable(getProducers(eiJob)) //
+            .flatMap(eiProducer -> notifyProducerJobStarted(eiProducer, eiJob, retrySpec)) //
+            .collectList() //
+            .flatMap(okResponses -> Mono.just(Integer.valueOf(okResponses.size()))); //
+    }
+
+    /**
+     * Restart all jobs for one producer
+     * 
+     * @param producer
+     * @param eiJobs
+     */
+    public void restartJobs(EiProducer producer, EiJobs eiJobs) {
+        final int maxNoOfParalellRequests = 10;
+        Retry retrySpec = Retry.backoff(3, Duration.ofSeconds(1));
+
+        Flux.fromIterable(producer.getEiTypes()) //
+            .flatMap(type -> Flux.fromIterable(eiJobs.getJobsForType(type))) //
+            .flatMap(job -> notifyProducerJobStarted(producer, job, retrySpec), maxNoOfParalellRequests) //
+            .onErrorResume(t -> {
+                logger.error("Could not restart EI Job for producer: {}, reason :{}", producer.getId(), t.getMessage());
+                return Flux.empty();
+            }) //
+            .subscribe();
+    }
+
+    private Mono<String> notifyProducerJobStarted(EiProducer producer, EiJob eiJob, Retry retrySpec) {
+        ProducerJobInfo request = new ProducerJobInfo(eiJob);
+        String body = gson.toJson(request);
+
+        return restClient.post(producer.getJobCallbackUrl(), body) //
+            .retryWhen(retrySpec) //
+            .doOnNext(resp -> logger.debug("Job subscription {} started OK {}", eiJob.getId(), producer.getId())) //
+            .onErrorResume(throwable -> {
+                logger.warn("Job subscription failed {}", producer.getId(), throwable.toString());
+                return Mono.empty();
+            });
+    }
+
+    private Collection<EiProducer> getProducers(EiJob eiJob) {
+        try {
+            return this.eiTypes.getType(eiJob.getTypeId()).getProducers();
+        } catch (Exception e) {
+            return new Vector<>();
+        }
+    }
+
+}
index d67b8ed..e517b3a 100644 (file)
@@ -33,10 +33,9 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 
-import org.oransc.enrichment.clients.ProducerCallbacks;
-import org.oransc.enrichment.clients.ProducerJobInfo;
 import org.oransc.enrichment.controllers.ErrorResponse;
 import org.oransc.enrichment.controllers.VoidResponse;
+import org.oransc.enrichment.controllers.consumer.ConsumerCallbacks;
 import org.oransc.enrichment.controllers.producer.ProducerRegistrationInfo.ProducerEiTypeRegistrationInfo;
 import org.oransc.enrichment.repository.EiJob;
 import org.oransc.enrichment.repository.EiJobs;
@@ -64,9 +63,7 @@ public class ProducerController {
 
     private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-    private static Gson gson = new GsonBuilder() //
-        .serializeNulls() //
-        .create(); //
+    private static Gson gson = new GsonBuilder().create();
 
     @Autowired
     private EiJobs eiJobs;
@@ -80,6 +77,9 @@ public class ProducerController {
     @Autowired
     ProducerCallbacks producerCallbacks;
 
+    @Autowired
+    ConsumerCallbacks consumerCallbacks;
+
     @GetMapping(path = ProducerConsts.API_ROOT + "/eitypes", produces = MediaType.APPLICATION_JSON_VALUE)
     @ApiOperation(value = "EI type identifiers", notes = "")
     @ApiResponses(
@@ -101,7 +101,7 @@ public class ProducerController {
     }
 
     @GetMapping(path = ProducerConsts.API_ROOT + "/eitypes/{eiTypeId}", produces = MediaType.APPLICATION_JSON_VALUE)
-    @ApiOperation(value = "Individual EI Type", notes = "")
+    @ApiOperation(value = "Individual EI type", notes = "")
     @ApiResponses(
         value = { //
             @ApiResponse(code = 200, message = "EI type", response = ProducerEiTypeInfo.class), //
@@ -146,7 +146,7 @@ public class ProducerController {
     @ApiOperation(value = "Individual EI producer", notes = "")
     @ApiResponses(
         value = { //
-            @ApiResponse(code = 200, message = "EI Jobs", response = ProducerRegistrationInfo.class), //
+            @ApiResponse(code = 200, message = "EI jobs", response = ProducerRegistrationInfo.class), //
             @ApiResponse(
                 code = 404,
                 message = "Enrichment Information producer is not found",
@@ -239,10 +239,12 @@ public class ProducerController {
                 }
             }
 
-            registerProducer(eiProducerId, registrationInfo);
+            EiProducer producer = registerProducer(eiProducerId, registrationInfo);
             if (previousDefinition != null) {
                 purgeTypes(previousDefinition.getEiTypes());
+                this.consumerCallbacks.notifyConsumersProducerDeleted(previousDefinition);
             }
+            this.consumerCallbacks.notifyConsumersProducerAdded(producer);
 
             return new ResponseEntity<>(previousDefinition == null ? HttpStatus.CREATED : HttpStatus.OK);
         } catch (Exception e) {
@@ -253,7 +255,7 @@ public class ProducerController {
     private void purgeTypes(Collection<EiType> types) {
         for (EiType type : types) {
             if (type.getProducerIds().isEmpty()) {
-                this.eiTypes.deregisterType(type, this.eiJobs);
+                this.eiTypes.remove(type);
             }
         }
     }
@@ -271,6 +273,7 @@ public class ProducerController {
         try {
             final EiProducer producer = this.eiProducers.getProducer(eiProducerId);
             this.eiProducers.deregisterProducer(producer, this.eiTypes, this.eiJobs);
+            this.consumerCallbacks.notifyConsumersProducerDeleted(producer);
             return new ResponseEntity<>(HttpStatus.NO_CONTENT);
         } catch (Exception e) {
             return ErrorResponse.create(e, HttpStatus.NOT_FOUND);
@@ -282,30 +285,28 @@ public class ProducerController {
         if (type == null) {
             type = new EiType(typeInfo.eiTypeId, typeInfo.jobDataSchema);
             this.eiTypes.put(type);
+            this.consumerCallbacks.notifyConsumersTypeAdded(type);
         }
         return type;
     }
 
     EiProducer createProducer(Collection<EiType> types, String producerId, ProducerRegistrationInfo registrationInfo) {
-        return new EiProducer(producerId, types, registrationInfo.jobCreationCallbackUrl,
-            registrationInfo.jobDeletionCallbackUrl, registrationInfo.producerSupervisionCallbackUrl);
+        return new EiProducer(producerId, types, registrationInfo.jobCallbackUrl,
+            registrationInfo.producerSupervisionCallbackUrl);
     }
 
     private EiProducer registerProducer(String producerId, ProducerRegistrationInfo registrationInfo) {
-        ArrayList<EiType> types = new ArrayList<>();
+        ArrayList<EiType> typesForProducer = new ArrayList<>();
+        EiProducer producer = createProducer(typesForProducer, producerId, registrationInfo);
         for (ProducerEiTypeRegistrationInfo typeInfo : registrationInfo.types) {
-            types.add(registerType(typeInfo));
+            EiType type = registerType(typeInfo);
+            typesForProducer.add(type);
+            type.addProducer(producer); //
         }
-        EiProducer producer = createProducer(types, producerId, registrationInfo);
         this.eiProducers.put(producer);
 
-        for (EiType type : types) {
-            for (EiJob job : this.eiJobs.getJobsForType(type)) {
-                this.producerCallbacks.notifyProducerJobStarted(producer, job) //
-                    .subscribe();
-            }
-            type.addProducer(producer);
-        }
+        producerCallbacks.restartJobs(producer, this.eiJobs);
+
         return producer;
     }
 
@@ -314,8 +315,7 @@ public class ProducerController {
         for (EiType type : p.getEiTypes()) {
             types.add(toEiTypeRegistrationInfo(type));
         }
-        return new ProducerRegistrationInfo(types, p.getJobCreationCallbackUrl(), p.getJobDeletionCallbackUrl(),
-            p.getProducerSupervisionCallbackUrl());
+        return new ProducerRegistrationInfo(types, p.getJobCallbackUrl(), p.getProducerSupervisionCallbackUrl());
     }
 
     private ProducerEiTypeRegistrationInfo toEiTypeRegistrationInfo(EiType type) {
@@ -18,7 +18,7 @@
  * ========================LICENSE_END===================================
  */
 
-package org.oransc.enrichment.clients;
+package org.oransc.enrichment.controllers.producer;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.gson.annotations.SerializedName;
@@ -63,7 +63,7 @@ public class ProducerJobInfo {
     }
 
     public ProducerJobInfo(EiJob job) {
-        this(job.jobData(), job.id(), job.type().getId(), job.targetUri());
+        this(job.getJobData(), job.getId(), job.getTypeId(), job.getTargetUrl());
     }
 
     public ProducerJobInfo() {
index 859443d..3f78580 100644 (file)
@@ -62,26 +62,20 @@ public class ProducerRegistrationInfo {
     @JsonProperty(value = "supported_ei_types", required = true)
     public Collection<ProducerEiTypeRegistrationInfo> types;
 
-    @ApiModelProperty(value = "callback for job creation", required = true)
-    @SerializedName("ei_job_creation_callback_url")
-    @JsonProperty(value = "ei_job_creation_callback_url", required = true)
-    public String jobCreationCallbackUrl;
-
-    @ApiModelProperty(value = "callback for job deletion", required = true)
-    @SerializedName("ei_job_deletion_callback_url")
-    @JsonProperty(value = "ei_job_deletion_callback_url", required = true)
-    public String jobDeletionCallbackUrl;
+    @ApiModelProperty(value = "callback for EI job", required = true)
+    @SerializedName("ei_job_callback_url")
+    @JsonProperty(value = "ei_job_callback_url", required = true)
+    public String jobCallbackUrl;
 
     @ApiModelProperty(value = "callback for producer supervision", required = true)
     @SerializedName("ei_producer_supervision_callback_url")
     @JsonProperty(value = "ei_producer_supervision_callback_url", required = true)
     public String producerSupervisionCallbackUrl;
 
-    public ProducerRegistrationInfo(Collection<ProducerEiTypeRegistrationInfo> types, String jobCreationCallbackUrl,
-        String jobDeletionCallbackUrl, String producerSupervisionCallbackUrl) {
+    public ProducerRegistrationInfo(Collection<ProducerEiTypeRegistrationInfo> types, String jobCallbackUrl,
+        String producerSupervisionCallbackUrl) {
         this.types = types;
-        this.jobCreationCallbackUrl = jobCreationCallbackUrl;
-        this.jobDeletionCallbackUrl = jobDeletionCallbackUrl;
+        this.jobCallbackUrl = jobCallbackUrl;
         this.producerSupervisionCallbackUrl = producerSupervisionCallbackUrl;
     }
 
index bb880e7..ed0187a 100644 (file)
 
 package org.oransc.enrichment.repository;
 
-import org.immutables.gson.Gson;
-import org.immutables.value.Value;
+import java.lang.invoke.MethodHandles;
+import lombok.Builder;
+import lombok.Getter;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
- * Represents the dynamic information about a EI Job
+ * Represents the dynamic information about a EI job
  */
-@Value.Immutable
-@Gson.TypeAdapters
-public interface EiJob {
+@Builder
+public class EiJob {
+    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+    @Getter
+    private final String id;
+
+    @Getter
+    private final String typeId;
+
+    @Getter
+    private final String owner;
+
+    @Getter
+    private final Object jobData;
 
-    String id();
+    @Getter
+    private final String targetUrl;
 
-    EiType type();
+    @Getter
+    private final String jobStatusUrl;
 
-    String owner();
+    @Getter
+    @Builder.Default
+    private boolean isLastStatusReportedEnabled = true;
 
-    Object jobData();
+    public void setLastReportedStatus(boolean isEnabled) {
+        this.isLastStatusReportedEnabled = isEnabled;
+        logger.debug("Job status id: {}, enabled: {}", this.isLastStatusReportedEnabled, isEnabled);
+    }
 
-    String targetUri();
 }
index 7a0dcfd..bff5be2 100644 (file)
 
 package org.oransc.enrichment.repository;
 
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.TypeAdapterFactory;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.lang.invoke.MethodHandles;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.ServiceLoader;
 import java.util.Vector;
 
+import org.oransc.enrichment.configuration.ApplicationConfig;
 import org.oransc.enrichment.exceptions.ServiceException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.FileSystemUtils;
 
 /**
- * Dynamic representation of all EI Jobs in the system.
+ * Dynamic representation of all existing EI jobs.
  */
 public class EiJobs {
     private Map<String, EiJob> allEiJobs = new HashMap<>();
 
     private MultiMap<EiJob> jobsByType = new MultiMap<>();
     private MultiMap<EiJob> jobsByOwner = new MultiMap<>();
+    private final Gson gson;
+
+    private final ApplicationConfig config;
+    private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+    public EiJobs(ApplicationConfig config) {
+        this.config = config;
+        GsonBuilder gsonBuilder = new GsonBuilder();
+        ServiceLoader.load(TypeAdapterFactory.class).forEach(gsonBuilder::registerTypeAdapterFactory);
+        this.gson = gsonBuilder.create();
+    }
+
+    public synchronized void restoreJobsFromDatabase() throws IOException {
+        Files.createDirectories(Paths.get(getDatabaseDirectory()));
+        File dbDir = new File(getDatabaseDirectory());
+
+        for (File file : dbDir.listFiles()) {
+            String json = Files.readString(file.toPath());
+            EiJob job = gson.fromJson(json, EiJob.class);
+            this.put(job, false);
+        }
+
+    }
 
     public synchronized void put(EiJob job) {
-        allEiJobs.put(job.id(), job);
-        jobsByType.put(job.type().getId(), job.id(), job);
-        jobsByOwner.put(job.owner(), job.id(), job);
+        this.put(job, true);
     }
 
     public synchronized Collection<EiJob> getJobs() {
@@ -79,9 +117,16 @@ public class EiJobs {
     }
 
     public synchronized void remove(EiJob job) {
-        this.allEiJobs.remove(job.id());
-        jobsByType.remove(job.type().getId(), job.id());
-        jobsByOwner.remove(job.owner(), job.id());
+        this.allEiJobs.remove(job.getId());
+        jobsByType.remove(job.getTypeId(), job.getId());
+        jobsByOwner.remove(job.getOwner(), job.getId());
+
+        try {
+            Files.delete(getPath(job));
+        } catch (IOException e) {
+            logger.warn("Could not remove file: {}", e.getMessage());
+        }
+
     }
 
     public synchronized int size() {
@@ -92,6 +137,43 @@ public class EiJobs {
         this.allEiJobs.clear();
         this.jobsByType.clear();
         jobsByOwner.clear();
+        try {
+            FileSystemUtils.deleteRecursively(Path.of(getDatabaseDirectory()));
+            Files.createDirectories(Paths.get(getDatabaseDirectory()));
+        } catch (IOException e) {
+            logger.warn("Could not delete database : {}", e.getMessage());
+        }
+    }
+
+    private void put(EiJob job, boolean storePersistently) {
+        allEiJobs.put(job.getId(), job);
+        jobsByType.put(job.getTypeId(), job.getId(), job);
+        jobsByOwner.put(job.getOwner(), job.getId(), job);
+        if (storePersistently) {
+            storeJobInFile(job);
+        }
+    }
+
+    private void storeJobInFile(EiJob job) {
+        try {
+            try (PrintStream out = new PrintStream(new FileOutputStream(getFile(job)))) {
+                out.print(gson.toJson(job));
+            }
+        } catch (Exception e) {
+            logger.warn("Could not save job: {} {}", job.getId(), e.getMessage());
+        }
+    }
+
+    private File getFile(EiJob job) {
+        return getPath(job).toFile();
+    }
+
+    private Path getPath(EiJob job) {
+        return Path.of(getDatabaseDirectory(), job.getId());
+    }
+
+    private String getDatabaseDirectory() {
+        return config.getVardataDirectory() + "/database";
     }
 
 }
index 99932a7..63e5d4c 100644 (file)
@@ -32,22 +32,18 @@ public class EiProducer {
     private final Collection<EiType> eiTypes;
 
     @Getter
-    private final String jobCreationCallbackUrl;
-
-    @Getter
-    private final String jobDeletionCallbackUrl;
+    private final String jobCallbackUrl;
 
     @Getter
     private final String producerSupervisionCallbackUrl;
 
     private int unresponsiveCounter = 0;
 
-    public EiProducer(String id, Collection<EiType> eiTypes, String jobCreationCallbackUrl,
-        String jobDeletionCallbackUrl, String producerSupervisionCallbackUrl) {
+    public EiProducer(String id, Collection<EiType> eiTypes, String jobCallbackUrl,
+        String producerSupervisionCallbackUrl) {
         this.id = id;
         this.eiTypes = eiTypes;
-        this.jobCreationCallbackUrl = jobCreationCallbackUrl;
-        this.jobDeletionCallbackUrl = jobDeletionCallbackUrl;
+        this.jobCallbackUrl = jobCallbackUrl;
         this.producerSupervisionCallbackUrl = producerSupervisionCallbackUrl;
     }
 
index b3cd895..801e7fc 100644 (file)
@@ -36,11 +36,10 @@ import org.slf4j.LoggerFactory;
 @SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally
 public class EiProducers {
     private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-    private Map<String, EiProducer> allEiProducers = new HashMap<>();
+    private final Map<String, EiProducer> allEiProducers = new HashMap<>();
 
     public synchronized void put(EiProducer producer) {
         allEiProducers.put(producer.getId(), producer);
-
     }
 
     public synchronized Collection<EiProducer> getAllProducers() {
@@ -79,7 +78,7 @@ public class EiProducers {
                 this.logger.error("Bug, no producer found");
             }
             if (type.getProducerIds().isEmpty()) {
-                eiTypes.deregisterType(type, eiJobs);
+                eiTypes.remove(type);
             }
         }
     }
index 9b7b640..d0bf53a 100644 (file)
@@ -31,7 +31,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * Dynamic representation of all EI Types in the system.
+ * Dynamic representation of all EI types in the system.
  */
 @SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally
 public class EiTypes {
@@ -73,13 +73,4 @@ public class EiTypes {
     public synchronized void clear() {
         this.allEiTypes.clear();
     }
-
-    public void deregisterType(EiType type, EiJobs eiJobs) {
-        this.remove(type);
-        for (EiJob job : eiJobs.getJobsForType(type.getId())) {
-            eiJobs.remove(job);
-            this.logger.warn("Deleted job {} because no producers left", job.id());
-        }
-    }
-
 }
index f239a48..e242166 100644 (file)
@@ -23,6 +23,7 @@ package org.oransc.enrichment.tasks;
 import org.oransc.enrichment.clients.AsyncRestClient;
 import org.oransc.enrichment.clients.AsyncRestClientFactory;
 import org.oransc.enrichment.configuration.ApplicationConfig;
+import org.oransc.enrichment.controllers.consumer.ConsumerCallbacks;
 import org.oransc.enrichment.repository.EiJobs;
 import org.oransc.enrichment.repository.EiProducer;
 import org.oransc.enrichment.repository.EiProducers;
@@ -50,15 +51,17 @@ public class ProducerSupervision {
     private final EiJobs eiJobs;
     private final EiTypes eiTypes;
     private final AsyncRestClient restClient;
+    private final ConsumerCallbacks consumerCallbacks;
 
     @Autowired
     public ProducerSupervision(ApplicationConfig applicationConfig, EiProducers eiProducers, EiJobs eiJobs,
-        EiTypes eiTypes) {
+        EiTypes eiTypes, ConsumerCallbacks consumerCallbacks) {
         AsyncRestClientFactory restClientFactory = new AsyncRestClientFactory(applicationConfig.getWebClientConfig());
         this.restClient = restClientFactory.createRestClient("");
         this.eiJobs = eiJobs;
         this.eiProducers = eiProducers;
         this.eiTypes = eiTypes;
+        this.consumerCallbacks = consumerCallbacks;
     }
 
     @Scheduled(fixedRate = 1000 * 60 * 5)
@@ -87,6 +90,7 @@ public class ProducerSupervision {
         producer.setAliveStatus(false);
         if (producer.isDead()) {
             this.eiProducers.deregisterProducer(producer, this.eiTypes, this.eiJobs);
+            this.consumerCallbacks.notifyConsumersProducerDeleted(producer);
         }
     }
 
index e564fef..c5ee82a 100644 (file)
@@ -33,6 +33,7 @@ import com.google.gson.JsonParser;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.PrintStream;
+import java.lang.invoke.MethodHandles;
 import java.util.ArrayList;
 import java.util.Collection;
 
@@ -43,15 +44,17 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.oransc.enrichment.clients.AsyncRestClient;
 import org.oransc.enrichment.clients.AsyncRestClientFactory;
-import org.oransc.enrichment.clients.ProducerJobInfo;
 import org.oransc.enrichment.configuration.ApplicationConfig;
 import org.oransc.enrichment.configuration.ImmutableWebClientConfig;
 import org.oransc.enrichment.configuration.WebClientConfig;
+import org.oransc.enrichment.controller.ConsumerSimulatorController;
 import org.oransc.enrichment.controller.ProducerSimulatorController;
 import org.oransc.enrichment.controllers.consumer.ConsumerConsts;
 import org.oransc.enrichment.controllers.consumer.ConsumerEiJobInfo;
+import org.oransc.enrichment.controllers.consumer.ConsumerEiJobStatus;
 import org.oransc.enrichment.controllers.consumer.ConsumerEiTypeInfo;
 import org.oransc.enrichment.controllers.producer.ProducerConsts;
+import org.oransc.enrichment.controllers.producer.ProducerJobInfo;
 import org.oransc.enrichment.controllers.producer.ProducerRegistrationInfo;
 import org.oransc.enrichment.controllers.producer.ProducerRegistrationInfo.ProducerEiTypeRegistrationInfo;
 import org.oransc.enrichment.controllers.producer.ProducerStatusInfo;
@@ -62,6 +65,8 @@ import org.oransc.enrichment.repository.EiProducers;
 import org.oransc.enrichment.repository.EiType;
 import org.oransc.enrichment.repository.EiTypes;
 import org.oransc.enrichment.tasks.ProducerSupervision;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
@@ -86,11 +91,15 @@ import reactor.test.StepVerifier;
 @TestPropertySource(
     properties = { //
         "server.ssl.key-store=./config/keystore.jks", //
-        "app.webclient.trust-store=./config/truststore.jks"})
+        "app.webclient.trust-store=./config/truststore.jks", //
+        "app.vardata-directory=./target"})
 class ApplicationTest {
+    private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
     private final String EI_TYPE_ID = "typeId";
     private final String EI_PRODUCER_ID = "producerId";
     private final String EI_JOB_PROPERTY = "\"property1\"";
+    private final String EI_JOB_ID = "jobId";
 
     @Autowired
     ApplicationContext context;
@@ -110,12 +119,13 @@ class ApplicationTest {
     @Autowired
     ProducerSimulatorController producerSimulator;
 
+    @Autowired
+    ConsumerSimulatorController consumerSimulator;
+
     @Autowired
     ProducerSupervision producerSupervision;
 
-    private static Gson gson = new GsonBuilder() //
-        .serializeNulls() //
-        .create(); //
+    private static Gson gson = new GsonBuilder().create();
 
     /**
      * Overrides the BeanFactory.
@@ -137,6 +147,7 @@ class ApplicationTest {
         this.eiTypes.clear();
         this.eiProducers.clear();
         this.producerSimulator.getTestResults().reset();
+        this.consumerSimulator.getTestResults().reset();
     }
 
     @AfterEach
@@ -151,7 +162,7 @@ class ApplicationTest {
         assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
 
         String indented = (new JSONObject(resp.getBody())).toString(4);
-        try (PrintStream out = new PrintStream(new FileOutputStream("docs/api.json"))) {
+        try (PrintStream out = new PrintStream(new FileOutputStream("../docs/offeredapis/swagger/ecs-api.json"))) {
             out.print(indented);
         }
     }
@@ -177,7 +188,7 @@ class ApplicationTest {
         String url = ConsumerConsts.API_ROOT + "/eitypes/test";
         String rsp = restClient().get(url).block();
         ConsumerEiTypeInfo info = gson.fromJson(rsp, ConsumerEiTypeInfo.class);
-        assertThat(info.jobParametersSchema).isNotNull();
+        assertThat(info).isNotNull();
     }
 
     @Test
@@ -190,39 +201,47 @@ class ApplicationTest {
     void testGetEiJobsIds() throws Exception {
         putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
         putEiJob(EI_TYPE_ID, "jobId");
-        String url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs";
+        final String JOB_ID_JSON = "[\"jobId\"]";
+        String url = ConsumerConsts.API_ROOT + "/eijobs?eiTypeId=typeId";
         String rsp = restClient().get(url).block();
-        assertThat(rsp).isEqualTo("[\"jobId\"]");
+        assertThat(rsp).isEqualTo(JOB_ID_JSON);
 
-        url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs?owner=owner";
+        url = ConsumerConsts.API_ROOT + "/eijobs?owner=owner";
         rsp = restClient().get(url).block();
-        assertThat(rsp).isEqualTo("[\"jobId\"]");
+        assertThat(rsp).isEqualTo(JOB_ID_JSON);
 
-        url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs?owner=JUNK";
+        url = ConsumerConsts.API_ROOT + "/eijobs?owner=JUNK";
         rsp = restClient().get(url).block();
         assertThat(rsp).isEqualTo("[]");
-    }
 
-    @Test
-    void testGetEiJobTypeNotFound() throws Exception {
-        String url = ConsumerConsts.API_ROOT + "/eitypes/junk/eijobs";
-        testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND, "Could not find EI type: junk");
+        url = ConsumerConsts.API_ROOT + "/eijobs";
+        rsp = restClient().get(url).block();
+        assertThat(rsp).isEqualTo(JOB_ID_JSON);
+
+        url = ConsumerConsts.API_ROOT + "/eijobs?eiTypeId=typeId&&owner=owner";
+        rsp = restClient().get(url).block();
+        assertThat(rsp).isEqualTo(JOB_ID_JSON);
+
+        url = ConsumerConsts.API_ROOT + "/eijobs?eiTypeId=JUNK";
+        rsp = restClient().get(url).block();
+        assertThat(rsp).isEqualTo("[]");
     }
 
     @Test
     void testGetEiJob() throws Exception {
         putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
         putEiJob(EI_TYPE_ID, "jobId");
-        String url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs/jobId";
+        String url = ConsumerConsts.API_ROOT + "/eijobs/jobId";
         String rsp = restClient().get(url).block();
         ConsumerEiJobInfo info = gson.fromJson(rsp, ConsumerEiJobInfo.class);
         assertThat(info.owner).isEqualTo("owner");
+        assertThat(info.eiTypeId).isEqualTo(EI_TYPE_ID);
     }
 
     @Test
     void testGetEiJobNotFound() throws Exception {
         putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
-        String url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs/junk";
+        String url = ConsumerConsts.API_ROOT + "/eijobs/junk";
         testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND, "Could not find EI job: junk");
     }
 
@@ -230,31 +249,28 @@ class ApplicationTest {
     void testGetEiJobStatus() throws Exception {
         putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
         putEiJob(EI_TYPE_ID, "jobId");
-        String url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs/jobId/status";
-        String rsp = restClient().get(url).block();
-        assertThat(rsp).contains("ENABLED");
-    }
 
-    // Status TBD
+        verifyJobStatus("jobId", "ENABLED");
+    }
 
     @Test
     void testDeleteEiJob() throws Exception {
         putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
         putEiJob(EI_TYPE_ID, "jobId");
         assertThat(this.eiJobs.size()).isEqualTo(1);
-        String url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs/jobId";
+        String url = ConsumerConsts.API_ROOT + "/eijobs/jobId";
         restClient().delete(url).block();
         assertThat(this.eiJobs.size()).isZero();
 
         ProducerSimulatorController.TestResults simulatorResults = this.producerSimulator.getTestResults();
         await().untilAsserted(() -> assertThat(simulatorResults.jobsStopped.size()).isEqualTo(1));
-        assertThat(simulatorResults.jobsStopped.get(0).id).isEqualTo("jobId");
+        assertThat(simulatorResults.jobsStopped.get(0)).isEqualTo("jobId");
     }
 
     @Test
     void testDeleteEiJobNotFound() throws Exception {
         putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
-        String url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs/junk";
+        String url = ConsumerConsts.API_ROOT + "/eijobs/junk";
         testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND, "Could not find EI job: junk");
     }
 
@@ -264,7 +280,7 @@ class ApplicationTest {
         putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
         putEiProducerWithOneTypeRejecting("simulateProducerError", EI_TYPE_ID);
 
-        String url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs/jobId";
+        String url = ConsumerConsts.API_ROOT + "/eijobs/jobId";
         String body = gson.toJson(eiJobInfo());
         ResponseEntity<String> resp = restClient().putForEntity(url, body).block();
         assertThat(this.eiJobs.size()).isEqualTo(1);
@@ -275,33 +291,37 @@ class ApplicationTest {
         ProducerJobInfo request = simulatorResults.jobsStarted.get(0);
         assertThat(request.id).isEqualTo("jobId");
 
-        assertThat(simulatorResults.noOfRejectedCreate).isEqualTo(1);
+        // One retry --> two calls
+        await().untilAsserted(() -> assertThat(simulatorResults.noOfRejectedCreate).isEqualTo(2));
+        assertThat(simulatorResults.noOfRejectedCreate).isEqualTo(2);
 
         resp = restClient().putForEntity(url, body).block();
         assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
         EiJob job = this.eiJobs.getJob("jobId");
-        assertThat(job.owner()).isEqualTo("owner");
+        assertThat(job.getOwner()).isEqualTo("owner");
     }
 
     @Test
     void putEiProducerWithOneType_rejecting() throws JsonMappingException, JsonProcessingException, ServiceException {
         putEiProducerWithOneTypeRejecting("simulateProducerError", EI_TYPE_ID);
-        String url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs/jobId";
+        String url = ConsumerConsts.API_ROOT + "/eijobs/jobId";
         String body = gson.toJson(eiJobInfo());
         testErrorCode(restClient().put(url, body), HttpStatus.CONFLICT, "Job not accepted by any producers");
 
         ProducerSimulatorController.TestResults simulatorResults = this.producerSimulator.getTestResults();
-        assertThat(simulatorResults.noOfRejectedCreate).isEqualTo(1);
+        // There is one retry -> 2 calls
+        await().untilAsserted(() -> assertThat(simulatorResults.noOfRejectedCreate).isEqualTo(2));
+        assertThat(simulatorResults.noOfRejectedCreate).isEqualTo(2);
     }
 
     @Test
     void testPutEiJob_jsonSchemavalidationError() throws Exception {
         putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
 
-        String url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs/jobId";
+        String url = ConsumerConsts.API_ROOT + "/eijobs/jobId";
         // The element with name "property1" is mandatory in the schema
-        ConsumerEiJobInfo jobInfo =
-            new ConsumerEiJobInfo(jsonObject("{ \"XXstring\" : \"value\" }"), "owner", "targetUri");
+        ConsumerEiJobInfo jobInfo = new ConsumerEiJobInfo("typeId", jsonObject("{ \"XXstring\" : \"value\" }"), "owner",
+            "targetUri", "jobStatusUrl");
         String body = gson.toJson(jobInfo);
 
         testErrorCode(restClient().put(url, body), HttpStatus.CONFLICT, "Json validation failure");
@@ -342,8 +362,8 @@ class ApplicationTest {
         putEiProducerWithOneType("producer2", "typeId2");
         putEiJob("typeId1", "jobId");
 
-        String url = ConsumerConsts.API_ROOT + "/eitypes/typeId2/eijobs/jobId";
-        String body = gson.toJson(eiJobInfo());
+        String url = ConsumerConsts.API_ROOT + "/eijobs/jobId";
+        String body = gson.toJson(eiJobInfo("typeId2", "jobId"));
         testErrorCode(restClient().put(url, body), HttpStatus.CONFLICT,
             "Not allowed to change type for existing EI job");
     }
@@ -392,7 +412,7 @@ class ApplicationTest {
         assertThat(this.eiTypes.size()).isEqualTo(1);
         this.eiTypes.getType(EI_TYPE_ID);
 
-        url = ConsumerConsts.API_ROOT + "/eitypes/typeId/eijobs/jobId";
+        url = ConsumerConsts.API_ROOT + "/eijobs/jobId";
         body = gson.toJson(eiJobInfo());
         restClient().putForEntity(url, body).block();
 
@@ -434,17 +454,59 @@ class ApplicationTest {
         putEiJob(EI_TYPE_ID, "jobId");
         assertThat(this.eiJobs.size()).isEqualTo(1);
 
-        String url = ProducerConsts.API_ROOT + "/eiproducers/eiProducerId";
-        restClient().deleteForEntity(url).block();
+        deleteEiProducer("eiProducerId");
         assertThat(this.eiProducers.size()).isEqualTo(1);
         assertThat(this.eiTypes.getType(EI_TYPE_ID).getProducerIds()).doesNotContain("eiProducerId");
-        assertThat(this.eiJobs.size()).isEqualTo(1);
+        verifyJobStatus("jobId", "ENABLED");
 
-        String url2 = ProducerConsts.API_ROOT + "/eiproducers/eiProducerId2";
-        restClient().deleteForEntity(url2).block();
+        deleteEiProducer("eiProducerId2");
         assertThat(this.eiProducers.size()).isZero();
         assertThat(this.eiTypes.size()).isZero();
-        assertThat(this.eiJobs.size()).isZero();
+        verifyJobStatus("jobId", "DISABLED");
+    }
+
+    @Test
+    void testJobStatusNotifications() throws JsonMappingException, JsonProcessingException, ServiceException {
+        ConsumerSimulatorController.TestResults consumerCalls = this.consumerSimulator.getTestResults();
+        ProducerSimulatorController.TestResults producerCalls = this.producerSimulator.getTestResults();
+
+        putEiProducerWithOneType("eiProducerId", EI_TYPE_ID);
+        putEiJob(EI_TYPE_ID, "jobId");
+        putEiProducerWithOneType("eiProducerId2", EI_TYPE_ID);
+        await().untilAsserted(() -> assertThat(producerCalls.jobsStarted.size()).isEqualTo(2));
+
+        deleteEiProducer("eiProducerId2");
+        assertThat(this.eiTypes.size()).isEqualTo(1); // The type remains, one producer left
+        deleteEiProducer("eiProducerId");
+        assertThat(this.eiTypes.size()).isZero(); // The type is gone
+        assertThat(this.eiJobs.size()).isEqualTo(1); // The job remains
+        await().untilAsserted(() -> assertThat(consumerCalls.status.size()).isEqualTo(1));
+        assertThat(consumerCalls.status.get(0).state).isEqualTo(ConsumerEiJobStatus.EiJobStatusValues.DISABLED);
+
+        putEiProducerWithOneType("eiProducerId", EI_TYPE_ID);
+        await().untilAsserted(() -> assertThat(consumerCalls.status.size()).isEqualTo(2));
+        assertThat(consumerCalls.status.get(1).state).isEqualTo(ConsumerEiJobStatus.EiJobStatusValues.ENABLED);
+    }
+
+    @Test
+    void testJobStatusNotifications2() throws JsonMappingException, JsonProcessingException, ServiceException {
+        // Test replacing a producer with new and removed types
+
+        // Create a job
+        putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
+        putEiJob(EI_TYPE_ID, EI_JOB_ID);
+
+        // change the type for the producer, the EI_TYPE_ID is deleted
+        putEiProducerWithOneType(EI_PRODUCER_ID, "junk");
+        verifyJobStatus(EI_JOB_ID, "DISABLED");
+        ConsumerSimulatorController.TestResults consumerCalls = this.consumerSimulator.getTestResults();
+        await().untilAsserted(() -> assertThat(consumerCalls.status.size()).isEqualTo(1));
+        assertThat(consumerCalls.status.get(0).state).isEqualTo(ConsumerEiJobStatus.EiJobStatusValues.DISABLED);
+
+        putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
+        verifyJobStatus(EI_JOB_ID, "ENABLED");
+        await().untilAsserted(() -> assertThat(consumerCalls.status.size()).isEqualTo(2));
+        assertThat(consumerCalls.status.get(1).state).isEqualTo(ConsumerEiJobStatus.EiJobStatusValues.ENABLED);
     }
 
     @Test
@@ -463,31 +525,40 @@ class ApplicationTest {
         assertThat(resp.getBody()).contains(EI_PRODUCER_ID);
     }
 
-    private void assertProducerOpState(String producerId,
-        ProducerStatusInfo.OperationalState expectedOperationalState) {
-        String statusUrl = ProducerConsts.API_ROOT + "/eiproducers/" + producerId + "/status";
-        ResponseEntity<String> resp = restClient().getForEntity(statusUrl).block();
-        ProducerStatusInfo statusInfo = gson.fromJson(resp.getBody(), ProducerStatusInfo.class);
-        assertThat(statusInfo.opState).isEqualTo(expectedOperationalState);
-    }
-
     @Test
     void testProducerSupervision() throws JsonMappingException, JsonProcessingException, ServiceException {
         putEiProducerWithOneTypeRejecting("simulateProducerError", EI_TYPE_ID);
 
+        {
+            // Create a job
+            putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
+            putEiJob(EI_TYPE_ID, EI_JOB_ID);
+            deleteEiProducer(EI_PRODUCER_ID);
+        }
+
         assertThat(this.eiProducers.size()).isEqualTo(1);
         assertThat(this.eiTypes.size()).isEqualTo(1);
         assertProducerOpState("simulateProducerError", ProducerStatusInfo.OperationalState.ENABLED);
 
         this.producerSupervision.createTask().blockLast();
         this.producerSupervision.createTask().blockLast();
+
+        // Now we have one producer that is disabled, but the job will be enabled until
+        // the producer/type is removed
         assertThat(this.eiProducers.size()).isEqualTo(1);
         assertProducerOpState("simulateProducerError", ProducerStatusInfo.OperationalState.DISABLED);
+        verifyJobStatus(EI_JOB_ID, "ENABLED");
 
-        // After 3 failed checks, the producer shall be deregisterred
+        // After 3 failed checks, the producer and the type shall be deregisterred
         this.producerSupervision.createTask().blockLast();
         assertThat(this.eiProducers.size()).isEqualTo(0);
         assertThat(this.eiTypes.size()).isEqualTo(0);
+        verifyJobStatus(EI_JOB_ID, "DISABLED");
+
+        // Job disabled status notification shall be received
+        ConsumerSimulatorController.TestResults consumerResults = this.consumerSimulator.getTestResults();
+        await().untilAsserted(() -> assertThat(consumerResults.status.size()).isEqualTo(1));
+        assertThat(consumerResults.status.get(0).state).isEqualTo(ConsumerEiJobStatus.EiJobStatusValues.DISABLED);
     }
 
     @Test
@@ -500,6 +571,52 @@ class ApplicationTest {
         assertThat(resp.getBody()).contains("hunky dory");
     }
 
+    @Test
+    void testEiJobDatabase() throws Exception {
+        putEiProducerWithOneType(EI_PRODUCER_ID, EI_TYPE_ID);
+        putEiJob(EI_TYPE_ID, "jobId1");
+        putEiJob(EI_TYPE_ID, "jobId2");
+
+        assertThat(this.eiJobs.size()).isEqualTo(2);
+
+        {
+            // Restore the jobs
+            EiJobs jobs = new EiJobs(this.applicationConfig);
+            jobs.restoreJobsFromDatabase();
+            assertThat(jobs.size()).isEqualTo(2);
+            jobs.remove("jobId1");
+            jobs.remove("jobId2");
+        }
+        {
+            // Restore the jobs, no jobs in database
+            EiJobs jobs = new EiJobs(this.applicationConfig);
+            jobs.restoreJobsFromDatabase();
+            assertThat(jobs.size()).isEqualTo(0);
+        }
+        logger.warn("Test removing a job when the db file is gone");
+        this.eiJobs.remove("jobId1");
+        assertThat(this.eiJobs.size()).isEqualTo(1);
+    }
+
+    private void deleteEiProducer(String eiProducerId) {
+        String url = ProducerConsts.API_ROOT + "/eiproducers/" + eiProducerId;
+        restClient().deleteForEntity(url).block();
+    }
+
+    private void verifyJobStatus(String jobId, String expStatus) {
+        String url = ConsumerConsts.API_ROOT + "/eijobs/" + jobId + "/status";
+        String rsp = restClient().get(url).block();
+        assertThat(rsp).contains(expStatus);
+    }
+
+    private void assertProducerOpState(String producerId,
+        ProducerStatusInfo.OperationalState expectedOperationalState) {
+        String statusUrl = ProducerConsts.API_ROOT + "/eiproducers/" + producerId + "/status";
+        ResponseEntity<String> resp = restClient().getForEntity(statusUrl).block();
+        ProducerStatusInfo statusInfo = gson.fromJson(resp.getBody(), ProducerStatusInfo.class);
+        assertThat(statusInfo.opState).isEqualTo(expectedOperationalState);
+    }
+
     ProducerEiTypeRegistrationInfo producerEiTypeRegistrationInfo(String typeId)
         throws JsonMappingException, JsonProcessingException {
         return new ProducerEiTypeRegistrationInfo(jsonSchemaObject(), typeId);
@@ -510,8 +627,7 @@ class ApplicationTest {
         Collection<ProducerEiTypeRegistrationInfo> types = new ArrayList<>();
         types.add(producerEiTypeRegistrationInfo(typeId));
         return new ProducerRegistrationInfo(types, //
-            baseUrl() + ProducerSimulatorController.JOB_CREATED_ERROR_URL,
-            baseUrl() + ProducerSimulatorController.JOB_DELETED_ERROR_URL,
+            baseUrl() + ProducerSimulatorController.JOB_ERROR_URL,
             baseUrl() + ProducerSimulatorController.SUPERVISION_ERROR_URL);
     }
 
@@ -520,16 +636,19 @@ class ApplicationTest {
         Collection<ProducerEiTypeRegistrationInfo> types = new ArrayList<>();
         types.add(producerEiTypeRegistrationInfo(typeId));
         return new ProducerRegistrationInfo(types, //
-            baseUrl() + ProducerSimulatorController.JOB_CREATED_URL,
-            baseUrl() + ProducerSimulatorController.JOB_DELETED_URL,
-            baseUrl() + ProducerSimulatorController.SUPERVISION_URL);
+            baseUrl() + ProducerSimulatorController.JOB_URL, baseUrl() + ProducerSimulatorController.SUPERVISION_URL);
+    }
+
+    private ConsumerEiJobInfo eiJobInfo() throws JsonMappingException, JsonProcessingException {
+        return eiJobInfo(EI_TYPE_ID, EI_JOB_ID);
     }
 
-    ConsumerEiJobInfo eiJobInfo() throws JsonMappingException, JsonProcessingException {
-        return new ConsumerEiJobInfo(jsonObject(), "owner", "targetUri");
+    ConsumerEiJobInfo eiJobInfo(String typeId, String eiJobId) throws JsonMappingException, JsonProcessingException {
+        return new ConsumerEiJobInfo(typeId, jsonObject(), "owner", "targetUri",
+            baseUrl() + ConsumerSimulatorController.getJobStatusUrl(eiJobId));
     }
 
-    Object jsonObject(String json) {
+    private Object jsonObject(String json) {
         try {
             return JsonParser.parseString(json).getAsJsonObject();
         } catch (Exception e) {
@@ -537,7 +656,7 @@ class ApplicationTest {
         }
     }
 
-    Object jsonSchemaObject() {
+    private Object jsonSchemaObject() {
         // a json schema with one mandatory property named "string"
         String schemaStr = "{" //
             + "\"$schema\": \"http://json-schema.org/draft-04/schema#\"," //
@@ -554,15 +673,15 @@ class ApplicationTest {
         return jsonObject(schemaStr);
     }
 
-    Object jsonObject() {
+    private Object jsonObject() {
         return jsonObject("{ " + EI_JOB_PROPERTY + " : \"value\" }");
     }
 
     private EiJob putEiJob(String eiTypeId, String jobId)
         throws JsonMappingException, JsonProcessingException, ServiceException {
 
-        String url = ConsumerConsts.API_ROOT + "/eitypes/" + eiTypeId + "/eijobs/" + jobId;
-        String body = gson.toJson(eiJobInfo());
+        String url = ConsumerConsts.API_ROOT + "/eijobs/" + jobId;
+        String body = gson.toJson(eiJobInfo(eiTypeId, jobId));
         restClient().putForEntity(url, body).block();
 
         return this.eiJobs.getJob(jobId);
diff --git a/enrichment-coordinator-service/src/test/java/org/oransc/enrichment/controller/ConsumerSimulatorController.java b/enrichment-coordinator-service/src/test/java/org/oransc/enrichment/controller/ConsumerSimulatorController.java
new file mode 100644 (file)
index 0000000..562f286
--- /dev/null
@@ -0,0 +1,83 @@
+/*-
+ * ========================LICENSE_START=================================
+ * O-RAN-SC
+ * %%
+ * Copyright (C) 2020 Nordix Foundation
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================LICENSE_END===================================
+ */
+
+package org.oransc.enrichment.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+
+import java.lang.invoke.MethodHandles;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import lombok.Getter;
+
+import org.oransc.enrichment.controllers.VoidResponse;
+import org.oransc.enrichment.controllers.consumer.ConsumerEiJobStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController("ConsumerSimulatorController")
+@Api(tags = {"Consumer Callbacks"})
+public class ConsumerSimulatorController {
+
+    private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+    public static class TestResults {
+
+        public List<ConsumerEiJobStatus> status = Collections.synchronizedList(new ArrayList<ConsumerEiJobStatus>());
+
+        public void reset() {
+            status.clear();
+        }
+    }
+
+    @Getter
+    private TestResults testResults = new TestResults();
+
+    public static String getJobStatusUrl(String eiJobId) {
+        return "/consumer_simulator/eijobs/" + eiJobId + "/status";
+    }
+
+    @PostMapping(path = "/consumer_simulator/eijobs/{eiJobId}/status", produces = MediaType.APPLICATION_JSON_VALUE)
+    @ApiOperation(value = "Callback for EI job status", notes = "")
+    @ApiResponses(
+        value = { //
+            @ApiResponse(code = 200, message = "OK", response = VoidResponse.class)} //
+    )
+    public ResponseEntity<Object> jobStatusCallback( //
+        @PathVariable("eiJobId") String eiJobId, //
+        @RequestBody ConsumerEiJobStatus status) {
+        logger.info("Job status callback status: {} eiJobId: {}", status.state, eiJobId);
+        this.testResults.status.add(status);
+        return new ResponseEntity<>(HttpStatus.OK);
+    }
+
+}
index c465196..2a3688c 100644 (file)
@@ -32,37 +32,37 @@ import java.util.List;
 
 import lombok.Getter;
 
-import org.oransc.enrichment.clients.ProducerJobInfo;
 import org.oransc.enrichment.controllers.ErrorResponse;
 import org.oransc.enrichment.controllers.VoidResponse;
+import org.oransc.enrichment.controllers.producer.ProducerJobInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.DeleteMapping;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RestController;
 
 @RestController("ProducerSimulatorController")
-@Api(tags = {"Producer Simulator"})
+@Api(tags = {"Producer Callbacks"})
 public class ProducerSimulatorController {
 
     private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-    public static final String JOB_CREATED_URL = "/producer_simulator/job_created";
-    public static final String JOB_DELETED_URL = "/producer_simulator/job_deleted";
-    public static final String JOB_CREATED_ERROR_URL = "/producer_simulator/job_created_error";
-    public static final String JOB_DELETED_ERROR_URL = "/producer_simulator/job_deleted_error";
+    public static final String JOB_URL = "/producer_simulator/ei_job";
+    public static final String JOB_ERROR_URL = "/producer_simulator/ei_job_error";
 
-    public static final String SUPERVISION_URL = "/producer_simulator/supervision";
-    public static final String SUPERVISION_ERROR_URL = "/producer_simulator/supervision_error";
+    public static final String SUPERVISION_URL = "/producer_simulator/health_check";
+    public static final String SUPERVISION_ERROR_URL = "/producer_simulator/health_check_error";
 
     public static class TestResults {
 
         public List<ProducerJobInfo> jobsStarted = Collections.synchronizedList(new ArrayList<ProducerJobInfo>());
-        public List<ProducerJobInfo> jobsStopped = Collections.synchronizedList(new ArrayList<ProducerJobInfo>());
+        public List<String> jobsStopped = Collections.synchronizedList(new ArrayList<String>());
         public int noOfRejectedCreate = 0;
         public int noOfRejectedDelete = 0;
         public boolean errorFound = false;
@@ -82,7 +82,7 @@ public class ProducerSimulatorController {
     @Getter
     private TestResults testResults = new TestResults();
 
-    @PostMapping(path = JOB_CREATED_URL, produces = MediaType.APPLICATION_JSON_VALUE)
+    @PostMapping(path = JOB_URL, produces = MediaType.APPLICATION_JSON_VALUE)
     @ApiOperation(value = "Callback for EI job creation", notes = "")
     @ApiResponses(
         value = { //
@@ -103,25 +103,25 @@ public class ProducerSimulatorController {
         }
     }
 
-    @PostMapping(path = JOB_DELETED_URL, produces = MediaType.APPLICATION_JSON_VALUE)
+    @DeleteMapping(path = "/producer_simulator/ei_job/{eiJobId}", produces = MediaType.APPLICATION_JSON_VALUE)
     @ApiOperation(value = "Callback for EI job deletion", notes = "")
     @ApiResponses(
         value = { //
             @ApiResponse(code = 200, message = "OK", response = VoidResponse.class)}//
     )
     public ResponseEntity<Object> jobDeletedCallback( //
-        @RequestBody ProducerJobInfo request) {
+        @PathVariable("eiJobId") String eiJobId) {
         try {
-            logger.info("Job deleted callback {}", request.id);
-            this.testResults.jobsStopped.add(request);
+            logger.info("Job deleted callback {}", eiJobId);
+            this.testResults.jobsStopped.add(eiJobId);
             return new ResponseEntity<>(HttpStatus.OK);
         } catch (Exception e) {
             return ErrorResponse.create(e, HttpStatus.NOT_FOUND);
         }
     }
 
-    @PostMapping(path = JOB_CREATED_ERROR_URL, produces = MediaType.APPLICATION_JSON_VALUE)
-    @ApiOperation(value = "Callback for EI job creation, returns error", notes = "")
+    @PostMapping(path = JOB_ERROR_URL, produces = MediaType.APPLICATION_JSON_VALUE)
+    @ApiOperation(value = "Callback for EI job creation, returns error", notes = "", hidden = true)
     @ApiResponses(
         value = { //
             @ApiResponse(code = 200, message = "OK", response = VoidResponse.class)}//
@@ -133,8 +133,8 @@ public class ProducerSimulatorController {
         return ErrorResponse.create("Producer returns error on create job", HttpStatus.NOT_FOUND);
     }
 
-    @PostMapping(path = JOB_DELETED_ERROR_URL, produces = MediaType.APPLICATION_JSON_VALUE)
-    @ApiOperation(value = "Callback for EI job creation, returns error", notes = "")
+    @DeleteMapping(path = JOB_ERROR_URL + "/{eiJobId}", produces = MediaType.APPLICATION_JSON_VALUE)
+    @ApiOperation(value = "Callback for EI job creation, returns error", notes = "", hidden = true)
     @ApiResponses(
         value = { //
             @ApiResponse(code = 200, message = "OK", response = VoidResponse.class)}//
@@ -158,7 +158,7 @@ public class ProducerSimulatorController {
     }
 
     @GetMapping(path = SUPERVISION_ERROR_URL, produces = MediaType.APPLICATION_JSON_VALUE)
-    @ApiOperation(value = "Producer supervision error", notes = "")
+    @ApiOperation(value = "Producer supervision error", notes = "", hidden = true)
     @ApiResponses(
         value = { //
             @ApiResponse(code = 200, message = "OK", response = String.class)}//
diff --git a/onap/oran b/onap/oran
new file mode 160000 (submodule)
index 0000000..50fe65e
--- /dev/null
+++ b/onap/oran
@@ -0,0 +1 @@
+Subproject commit 50fe65ea5daca6935cdbc1155adbfb53f5a28c40
index a02ed34..602050b 100644 (file)
@@ -5,3 +5,4 @@
 target
 .checkstyle
 policy-agent.iml
+config
index 7c722e1..f64eebb 100644 (file)
@@ -21,23 +21,22 @@ FROM openjdk:11-jre-slim
 
 ARG JAR
 
+EXPOSE 8081 8433
+
+
 WORKDIR /opt/app/policy-agent
 RUN mkdir -p /var/log/policy-agent
 RUN mkdir -p /opt/app/policy-agent/etc/cert/
-
 EXPOSE 8081 8433
 
 ADD /config/application.yaml /opt/app/policy-agent/config/application.yaml
 ADD /config/application_configuration.json /opt/app/policy-agent/data/application_configuration.json_example
-ADD target/${JAR} /opt/app/policy-agent/policy-agent.jar
 ADD /config/keystore.jks /opt/app/policy-agent/etc/cert/keystore.jks
 ADD /config/truststore.jks /opt/app/policy-agent/etc/cert/truststore.jks
 
-
 RUN chmod -R 777 /opt/app/policy-agent/config/
+RUN chmod -R 777 /opt/app/policy-agent/data/
 
+ADD target/${JAR} /opt/app/policy-agent/policy-agent.jar
 CMD ["java", "-jar", "/opt/app/policy-agent/policy-agent.jar"]
 
-
-
-
diff --git a/policy-agent/config/README b/policy-agent/config/README
deleted file mode 100644 (file)
index 6e50749..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-The keystore.jks and truststore.jks files are created by using the following commands (note that this is an example):
-
-1) Create a CA certificate and a private key:
-
-openssl genrsa -des3 -out CA-key.pem 2048
-openssl req -new -key CA-key.pem -x509 -days 1000 -out CA-cert.pem 
-
-2) Create a keystore with a private key entry that is signed by the CA:
-
-keytool -genkeypair -alias policy_agent -keyalg RSA -keysize 2048 -keystore keystore.jks -validity 3650 -storepass policy_agent
-keytool -certreq -alias policy_agent -file request.csr -keystore keystore.jks -ext san=dns:your.domain.com -storepass policy_agent
-openssl x509 -req -days 365 -in request.csr -CA CA-cert.pem -CAkey CA-key.pem -CAcreateserial -out ca_signed-cert.pem
-keytool -importcert -alias ca_cert -file CA-cert.pem -keystore keystore.jks -trustcacerts -storepass policy_agent
-keytool -importcert -alias policy_agent -file ca_signed-cert.pem -keystore keystore.jks -trustcacerts -storepass policy_agent
-
-
-3) Create a trust store containing the CA cert (to trust all certs signed by the CA):
-
-keytool -genkeypair -alias not_used -keyalg RSA -keysize 2048 -keystore truststore.jks -validity 3650 -storepass policy_agent
-keytool -importcert -alias ca_cert -file CA-cert.pem -keystore truststore.jks -trustcacerts -storepass policy_agent
-
-
-4) Command for listing of the contents of jks files, examples:
-keytool -list -v -keystore keystore.jks -storepass policy_agent
-keytool -list -v -keystore truststore.jks -storepass policy_agent
-
-## License
-
-Copyright (C) 2020 Nordix Foundation. All rights reserved.
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
diff --git a/policy-agent/config/application.yaml b/policy-agent/config/application.yaml
deleted file mode 100644 (file)
index 4f5e242..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-spring:
-  profiles:
-    active: prod
-  main:
-    allow-bean-definition-overriding: true
-  aop:
-    auto: false
-management:
-  endpoints:
-    web:
-      exposure:
-        include: "loggers,logfile,health,info,metrics,threaddump,heapdump"
-
-logging:
-  level:
-    ROOT: ERROR
-    org.springframework: ERROR
-    org.springframework.data: ERROR
-    org.springframework.web.reactive.function.client.ExchangeFunctions: ERROR
-    org.oransc.policyagent: INFO
-  file:
-    name: /var/log/policy-agent/application.log
-server:
-   port : 8433
-   http-port: 8081
-   ssl:
-      key-store-type: JKS
-      key-store-password: policy_agent
-      key-store: /opt/app/policy-agent/etc/cert/keystore.jks
-      key-password: policy_agent
-      key-alias: policy_agent
-app:
-  filepath: /opt/app/policy-agent/data/application_configuration.json
-  webclient:
-    trust-store-used: false
-    trust-store-password: policy_agent
-    trust-store: /opt/app/policy-agent/etc/cert/truststore.jks
-
diff --git a/policy-agent/config/application_configuration.json b/policy-agent/config/application_configuration.json
deleted file mode 100644 (file)
index 6c21b16..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-{
-   "config": {
-      "//description": "Application configuration",
-      "controller": [
-         {
-            "name": "controller1",
-            "baseUrl": "http://a1controller:8282",
-            "userName": "admin",
-            "password": "Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U"
-         }
-      ],
-      "ric": [
-         {
-            "name": "ric1",
-            "baseUrl": "http://ric1:8085/",
-            "controller": "controller1",
-            "managedElementIds": [
-               "kista_1",
-               "kista_2"
-            ]
-         }
-      ]
-   }
-}
\ No newline at end of file
diff --git a/policy-agent/config/keystore.jks b/policy-agent/config/keystore.jks
deleted file mode 100644 (file)
index 122997a..0000000
Binary files a/policy-agent/config/keystore.jks and /dev/null differ
diff --git a/policy-agent/config/truststore.jks b/policy-agent/config/truststore.jks
deleted file mode 100644 (file)
index 60d6288..0000000
Binary files a/policy-agent/config/truststore.jks and /dev/null differ
diff --git a/policy-agent/docs/api.yaml b/policy-agent/docs/api.yaml
deleted file mode 100644 (file)
index ec9bbce..0000000
+++ /dev/null
@@ -1,650 +0,0 @@
-swagger: '2.0'
-info:
-  description: This page lists all the rest apis for the service.
-  version: '1.0'
-  title: A1 Policy management service
-host: 'localhost:8081'
-basePath: /
-tags:
-  - name: A1 Policy Management
-    description: Policy Controller
-  - name: Health check
-    description: Status Controller
-  - name: RIC Repository
-    description: Ric Repository Controller
-  - name: Service registry and supervision
-    description: Service Controller
-paths:
-  /policies:
-    get:
-      tags:
-        - A1 Policy Management
-      summary: Query policies
-      operationId: getPoliciesUsingGET
-      produces:
-        - '*/*'
-      parameters:
-        - name: ric
-          in: query
-          description: The name of the Near-RT RIC to get policies for.
-          required: false
-          type: string
-          allowEmptyValue: false
-        - name: service
-          in: query
-          description: The name of the service to get policies for.
-          required: false
-          type: string
-          allowEmptyValue: false
-        - name: type
-          in: query
-          description: The name of the policy type to get policies for.
-          required: false
-          type: string
-          allowEmptyValue: false
-      responses:
-        '200':
-          description: Policies
-          schema:
-            type: array
-            items:
-              $ref: '#/definitions/PolicyInfo'
-        '401':
-          description: Unauthorized
-        '403':
-          description: Forbidden
-        '404':
-          description: RIC or type not found
-          schema:
-            type: string
-      deprecated: false
-  /policy:
-    get:
-      tags:
-        - A1 Policy Management
-      summary: Returns a policy configuration
-      operationId: getPolicyUsingGET
-      produces:
-        - '*/*'
-      parameters:
-        - name: id
-          in: query
-          description: The ID of the policy instance.
-          required: true
-          type: string
-          allowEmptyValue: false
-      responses:
-        '200':
-          description: Policy found
-          schema:
-            type: object
-        '401':
-          description: Unauthorized
-        '403':
-          description: Forbidden
-        '404':
-          description: Policy is not found
-      deprecated: false
-    put:
-      tags:
-        - A1 Policy Management
-      summary: Put a policy
-      operationId: putPolicyUsingPUT
-      consumes:
-        - application/json
-      produces:
-        - '*/*'
-      parameters:
-        - name: id
-          in: query
-          description: The ID of the policy instance.
-          required: true
-          type: string
-          allowEmptyValue: false
-        - in: body
-          name: jsonBody
-          description: jsonBody
-          required: true
-          schema:
-            type: object
-        - name: ric
-          in: query
-          description: The name of the Near-RT RIC where the policy will be created.
-          required: true
-          type: string
-          allowEmptyValue: false
-        - name: service
-          in: query
-          description: The name of the service creating the policy.
-          required: true
-          type: string
-          allowEmptyValue: false
-        - name: transient
-          in: query
-          description: If the policy is transient or not (boolean defaulted to false). A policy is transient if it will be forgotten when the service needs to reconnect to the Near-RT RIC.
-          required: false
-          type: boolean
-          default: false
-          allowEmptyValue: false
-          x-example: false
-        - name: type
-          in: query
-          description: The name of the policy type.
-          required: false
-          type: string
-          allowEmptyValue: false
-      responses:
-        '200':
-          description: Policy updated
-          schema:
-            type: object
-        '201':
-          description: Policy created
-          schema:
-            type: object
-        '401':
-          description: Unauthorized
-        '403':
-          description: Forbidden
-        '404':
-          description: RIC or policy type is not found
-          schema:
-            type: string
-        '423':
-          description: RIC is not operational
-          schema:
-            type: string
-      deprecated: false
-    delete:
-      tags:
-        - A1 Policy Management
-      summary: Delete a policy
-      operationId: deletePolicyUsingDELETE
-      produces:
-        - '*/*'
-      parameters:
-        - name: id
-          in: query
-          description: The ID of the policy instance.
-          required: true
-          type: string
-          allowEmptyValue: false
-      responses:
-        '200':
-          description: OK
-          schema:
-            type: object
-        '204':
-          description: Policy deleted
-          schema:
-            type: object
-        '401':
-          description: Unauthorized
-        '403':
-          description: Forbidden
-        '404':
-          description: Policy is not found
-          schema:
-            type: string
-        '423':
-          description: RIC is not operational
-          schema:
-            type: string
-      deprecated: false
-  /policy_ids:
-    get:
-      tags:
-        - A1 Policy Management
-      summary: 'Query policies, only IDs returned'
-      operationId: getPolicyIdsUsingGET
-      produces:
-        - '*/*'
-      parameters:
-        - name: ric
-          in: query
-          description: The name of the Near-RT RIC to get policies for.
-          required: false
-          type: string
-          allowEmptyValue: false
-        - name: service
-          in: query
-          description: The name of the service to get policies for.
-          required: false
-          type: string
-          allowEmptyValue: false
-        - name: type
-          in: query
-          description: The name of the policy type to get policies for.
-          required: false
-          type: string
-          allowEmptyValue: false
-      responses:
-        '200':
-          description: Policy ids
-          schema:
-            type: array
-            items:
-              type: string
-        '401':
-          description: Unauthorized
-        '403':
-          description: Forbidden
-        '404':
-          description: RIC or type not found
-          schema:
-            type: string
-      deprecated: false
-  /policy_schema:
-    get:
-      tags:
-        - A1 Policy Management
-      summary: Returns one policy type schema definition
-      operationId: getPolicySchemaUsingGET
-      produces:
-        - '*/*'
-      parameters:
-        - name: id
-          in: query
-          description: The ID of the policy type to get the definition for.
-          required: true
-          type: string
-          allowEmptyValue: false
-      responses:
-        '200':
-          description: Policy schema
-          schema:
-            type: object
-        '401':
-          description: Unauthorized
-        '403':
-          description: Forbidden
-        '404':
-          description: RIC is not found
-          schema:
-            type: string
-      deprecated: false
-  /policy_schemas:
-    get:
-      tags:
-        - A1 Policy Management
-      summary: Returns policy type schema definitions
-      operationId: getPolicySchemasUsingGET
-      produces:
-        - '*/*'
-      parameters:
-        - name: ric
-          in: query
-          description: The name of the Near-RT RIC to get the definitions for.
-          required: false
-          type: string
-          allowEmptyValue: false
-      responses:
-        '200':
-          description: Policy schemas
-          schema:
-            type: array
-            items:
-              type: object
-        '401':
-          description: Unauthorized
-        '403':
-          description: Forbidden
-        '404':
-          description: RIC is not found
-          schema:
-            type: string
-      deprecated: false
-  /policy_status:
-    get:
-      tags:
-        - A1 Policy Management
-      summary: Returns a policy status
-      operationId: getPolicyStatusUsingGET
-      produces:
-        - '*/*'
-      parameters:
-        - name: id
-          in: query
-          description: The ID of the policy.
-          required: true
-          type: string
-          allowEmptyValue: false
-      responses:
-        '200':
-          description: Policy status
-          schema:
-            type: object
-        '401':
-          description: Unauthorized
-        '403':
-          description: Forbidden
-        '404':
-          description: Policy is not found
-          schema:
-            type: string
-      deprecated: false
-  /policy_types:
-    get:
-      tags:
-        - A1 Policy Management
-      summary: Query policy type names
-      operationId: getPolicyTypesUsingGET
-      produces:
-        - '*/*'
-      parameters:
-        - name: ric
-          in: query
-          description: The name of the Near-RT RIC to get types for.
-          required: false
-          type: string
-          allowEmptyValue: false
-      responses:
-        '200':
-          description: Policy type names
-          schema:
-            type: array
-            items:
-              type: string
-        '401':
-          description: Unauthorized
-        '403':
-          description: Forbidden
-        '404':
-          description: RIC is not found
-          schema:
-            type: string
-      deprecated: false
-  /ric:
-    get:
-      tags:
-        - RIC Repository
-      summary: Returns the name of a RIC managing one Mananged Element
-      operationId: getRicUsingGET
-      produces:
-        - '*/*'
-      parameters:
-        - name: managedElementId
-          in: query
-          description: The ID of the Managed Element
-          required: true
-          type: string
-          allowEmptyValue: false
-      responses:
-        '200':
-          description: RIC is found
-          schema:
-            type: string
-        '401':
-          description: Unauthorized
-        '403':
-          description: Forbidden
-        '404':
-          description: RIC is not found
-          schema:
-            type: string
-      deprecated: false
-  /rics:
-    get:
-      tags:
-        - RIC Repository
-      summary: Query Near-RT RIC information
-      operationId: getRicsUsingGET
-      produces:
-        - '*/*'
-      parameters:
-        - name: policyType
-          in: query
-          description: The name of the policy type
-          required: false
-          type: string
-          allowEmptyValue: false
-      responses:
-        '200':
-          description: OK
-          schema:
-            type: array
-            items:
-              $ref: '#/definitions/RicInfo'
-        '401':
-          description: Unauthorized
-        '403':
-          description: Forbidden
-        '404':
-          description: Policy type is not found
-          schema:
-            type: string
-      deprecated: false
-  /service:
-    put:
-      tags:
-        - Service registry and supervision
-      summary: Register a service
-      operationId: putServiceUsingPUT
-      consumes:
-        - application/json
-      produces:
-        - '*/*'
-      parameters:
-        - in: body
-          name: registrationInfo
-          description: registrationInfo
-          required: true
-          schema:
-            $ref: '#/definitions/ServiceRegistrationInfo'
-      responses:
-        '200':
-          description: Service updated
-          schema:
-            type: string
-        '201':
-          description: Service created
-          schema:
-            type: string
-        '400':
-          description: The ServiceRegistrationInfo is not accepted
-          schema:
-            type: string
-        '401':
-          description: Unauthorized
-        '403':
-          description: Forbidden
-        '404':
-          description: Not Found
-      deprecated: false
-  /services:
-    get:
-      tags:
-        - Service registry and supervision
-      summary: Returns service information
-      operationId: getServicesUsingGET
-      produces:
-        - '*/*'
-      parameters:
-        - name: name
-          in: query
-          description: The name of the service
-          required: false
-          type: string
-          allowEmptyValue: false
-      responses:
-        '200':
-          description: OK
-          schema:
-            type: array
-            items:
-              $ref: '#/definitions/ServiceStatus'
-        '401':
-          description: Unauthorized
-        '403':
-          description: Forbidden
-        '404':
-          description: Service is not found
-          schema:
-            type: string
-      deprecated: false
-    delete:
-      tags:
-        - Service registry and supervision
-      summary: Delete a service
-      operationId: deleteServiceUsingDELETE
-      produces:
-        - '*/*'
-      parameters:
-        - name: name
-          in: query
-          description: The name of the service
-          required: true
-          type: string
-          allowEmptyValue: false
-      responses:
-        '200':
-          description: OK
-          schema:
-            type: string
-        '204':
-          description: OK
-          schema:
-            type: string
-        '401':
-          description: Unauthorized
-        '403':
-          description: Forbidden
-        '404':
-          description: Service not found
-          schema:
-            type: string
-      deprecated: false
-  /services/keepalive:
-    put:
-      tags:
-        - Service registry and supervision
-      summary: Heartbeat from a serice
-      operationId: keepAliveServiceUsingPUT
-      consumes:
-        - application/json
-      produces:
-        - '*/*'
-      parameters:
-        - name: name
-          in: query
-          description: The name of the service
-          required: true
-          type: string
-          allowEmptyValue: false
-      responses:
-        '200':
-          description: 'Service supervision timer refreshed, OK'
-          schema:
-            type: string
-        '201':
-          description: Created
-        '401':
-          description: Unauthorized
-        '403':
-          description: Forbidden
-        '404':
-          description: 'The service is not found, needs re-registration'
-      deprecated: false
-  /status:
-    get:
-      tags:
-        - Health check
-      summary: Returns status and statistics of this service
-      operationId: getStatusUsingGET
-      produces:
-        - '*/*'
-      responses:
-        '200':
-          description: Service is living
-          schema:
-            type: string
-        '401':
-          description: Unauthorized
-        '403':
-          description: Forbidden
-        '404':
-          description: Not Found
-      deprecated: false
-definitions:
-  Mono«ResponseEntity«object»»:
-    type: object
-    title: Mono«ResponseEntity«object»»
-  Mono«ResponseEntity«string»»:
-    type: object
-    title: Mono«ResponseEntity«string»»
-  PolicyInfo:
-    type: object
-    properties:
-      id:
-        type: string
-        description: identity of the policy
-      json:
-        type: object
-        description: the configuration of the policy
-      lastModified:
-        type: string
-        description: 'timestamp, last modification time'
-      ric:
-        type: string
-        description: identity of the target Near-RT RIC
-      service:
-        type: string
-        description: the name of the service owning the policy
-      type:
-        type: string
-        description: name of the policy type
-    title: PolicyInfo
-  RicInfo:
-    type: object
-    properties:
-      managedElementIds:
-        type: array
-        description: O1 identities for managed entities
-        items:
-          type: string
-      policyTypes:
-        type: array
-        description: supported policy types
-        items:
-          type: string
-      ricName:
-        type: string
-        description: identity of the ric
-      state:
-        type: string
-        description: state info
-    title: RicInfo
-  ServiceRegistrationInfo:
-    type: object
-    required:
-      - serviceName
-    properties:
-      callbackUrl:
-        type: string
-        description: callback for notifying of RIC synchronization
-      keepAliveIntervalSeconds:
-        type: integer
-        format: int64
-        description: 'keep alive interval for the service. This is a heartbeat supervision of the service, which in regular intevals must invoke a ''keepAlive'' REST call. When a service does not invoke this call within the given time, it is considered unavailble. An unavailable service will be automatically deregistered and its policies will be deleted. Value 0 means no timeout supervision.'
-      serviceName:
-        type: string
-        description: identity of the service
-    title: ServiceRegistrationInfo
-  ServiceStatus:
-    type: object
-    properties:
-      callbackUrl:
-        type: string
-        description: callback for notifying of RIC synchronization
-      keepAliveIntervalSeconds:
-        type: integer
-        format: int64
-        description: policy keep alive timeout
-      serviceName:
-        type: string
-        description: identity of the service
-      timeSinceLastActivitySeconds:
-        type: integer
-        format: int64
-        description: time since last invocation by the service
-    title: ServiceStatus
index aedb516..41df80e 100644 (file)
@@ -61,7 +61,6 @@
         <javax.ws.rs-api.version>2.1.1</javax.ws.rs-api.version>
         <sonar-maven-plugin.version>3.7.0.1746</sonar-maven-plugin.version>
         <jacoco-maven-plugin.version>0.8.5</jacoco-maven-plugin.version>
-        <exec.skip>true</exec.skip>
     </properties>
     <dependencies>
         <dependency>
                 <artifactId>exec-maven-plugin</artifactId>
                 <executions>
                     <execution>
-                        <id>run-test-script</id>
-                        <phase>verify</phase>
+                        <id>git submodule update</id>
+                        <phase>initialize</phase>
+                        <configuration>
+                            <executable>git</executable>
+                            <arguments>
+                                <argument>submodule</argument>
+                                <argument>update</argument>
+                                <argument>--init</argument>
+                                <argument>--recursive</argument>
+                            </arguments>
+                        </configuration>
+                        <goals>
+                            <goal>exec</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>copy configuration</id>
+                        <phase>initialize</phase>
+                        <configuration>
+                            <executable>cp</executable>
+                            <arguments>
+                                <argument>-r</argument>
+                                <argument>../onap/oran/a1-policy-management/config</argument>
+                                <argument>.</argument>
+                            </arguments>
+                        </configuration>
                         <goals>
                             <goal>exec</goal>
                         </goals>
                     </execution>
                 </executions>
-                <configuration>
-                    <executable>bash</executable>
-                    <arguments>
-                        <argument>run_test.sh</argument>
-                    </arguments>
-                    <workingDirectory>../test/jenkins/</workingDirectory>
-                </configuration>
             </plugin>
         </plugins>
     </build>
         <system>JIRA</system>
         <url>https://jira.o-ran-sc.org/</url>
     </issueManagement>
-</project>
+</project>
\ No newline at end of file
diff --git a/policy-agent/src b/policy-agent/src
new file mode 120000 (symlink)
index 0000000..a737975
--- /dev/null
@@ -0,0 +1 @@
+../onap/oran/a1-policy-management/src
\ No newline at end of file
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/Application.java b/policy-agent/src/main/java/org/oransc/policyagent/Application.java
deleted file mode 100644 (file)
index 3bc7326..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent;
-
-import org.oransc.policyagent.dmaap.DmaapMessageConsumer;
-import org.oransc.policyagent.tasks.RefreshConfigTask;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.CommandLineRunner;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.annotation.Bean;
-
-@SpringBootApplication
-public class Application {
-
-    @Autowired
-    private RefreshConfigTask configRefresh;
-
-    @Autowired
-    private DmaapMessageConsumer dmaapMessageConsumer;
-
-    public static void main(String[] args) {
-        SpringApplication.run(Application.class);
-    }
-
-    /**
-     * Starts the configuration refresh task and reads the configuration.
-     *
-     * @param ctx the application context.
-     *
-     * @return the command line runner for the configuration refresh task.
-     */
-    @Bean
-    public CommandLineRunner configRefreshRunner(ApplicationContext ctx) {
-        return args -> configRefresh.start();
-    }
-
-    /**
-     * Starts the DMaaP message consumer service.
-     *
-     * @param ctx the application context.
-     *
-     * @return the command line runner for the DMaaP message consumer service.
-     */
-    @Bean
-    public CommandLineRunner dmaapMessageConsumerRunner(ApplicationContext ctx) {
-        return args -> dmaapMessageConsumer.start();
-    }
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/BeanFactory.java b/policy-agent/src/main/java/org/oransc/policyagent/BeanFactory.java
deleted file mode 100644 (file)
index 1e01247..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import org.apache.catalina.connector.Connector;
-import org.oransc.policyagent.clients.A1ClientFactory;
-import org.oransc.policyagent.configuration.ApplicationConfig;
-import org.oransc.policyagent.repository.Policies;
-import org.oransc.policyagent.repository.PolicyTypes;
-import org.oransc.policyagent.repository.Rics;
-import org.oransc.policyagent.repository.Services;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
-import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-@Configuration
-class BeanFactory {
-    private final ApplicationConfig applicationConfig = new ApplicationConfig();
-
-    @Value("${server.http-port}")
-    private int httpPort = 0;
-
-    @Bean
-    public Policies getPolicies() {
-        return new Policies();
-    }
-
-    @Bean
-    public PolicyTypes getPolicyTypes() {
-        return new PolicyTypes();
-    }
-
-    @Bean
-    public Rics getRics() {
-        return new Rics();
-    }
-
-    @Bean
-    public ApplicationConfig getApplicationConfig() {
-        return this.applicationConfig;
-    }
-
-    @Bean
-    Services getServices() {
-        return new Services();
-    }
-
-    @Bean
-    A1ClientFactory getA1ClientFactory() {
-        return new A1ClientFactory(this.applicationConfig);
-    }
-
-    @Bean
-    public ObjectMapper mapper() {
-        return new ObjectMapper();
-    }
-
-    @Bean
-    public ServletWebServerFactory servletContainer() {
-        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
-        if (httpPort > 0) {
-            tomcat.addAdditionalTomcatConnectors(getHttpConnector(httpPort));
-        }
-        return tomcat;
-    }
-
-    private static Connector getHttpConnector(int httpPort) {
-        Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
-        connector.setScheme("http");
-        connector.setPort(httpPort);
-        connector.setSecure(false);
-        return connector;
-    }
-
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/SwaggerConfig.java b/policy-agent/src/main/java/org/oransc/policyagent/SwaggerConfig.java
deleted file mode 100644 (file)
index ddcf0d3..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent;
-
-import com.google.common.base.Predicates;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
-
-import springfox.documentation.builders.ApiInfoBuilder;
-import springfox.documentation.builders.PathSelectors;
-import springfox.documentation.builders.RequestHandlerSelectors;
-import springfox.documentation.service.ApiInfo;
-import springfox.documentation.spi.DocumentationType;
-import springfox.documentation.spring.web.plugins.Docket;
-import springfox.documentation.swagger2.annotations.EnableSwagger2;
-
-/**
- * Swagger configuration class that uses swagger2 documentation type and scans
- * all the controllers under org.oransc.policyagent.controllers package. To
- * access the swagger gui go to http://ip:port/swagger-ui.html
- *
- */
-@Configuration
-@EnableSwagger2
-public class SwaggerConfig extends WebMvcConfigurationSupport {
-
-    static final String API_TITLE = "A1 Policy management service";
-    static final String DESCRIPTION = "This page lists all the rest apis for the service.";
-    static final String VERSION = "1.0";
-    @SuppressWarnings("squid:S1075") // Refactor your code to get this URI from a customizable parameter.
-    static final String RESOURCES_PATH = "classpath:/META-INF/resources/";
-    static final String WEBJARS_PATH = RESOURCES_PATH + "webjars/";
-    static final String SWAGGER_UI = "swagger-ui.html";
-    static final String WEBJARS = "/webjars/**";
-
-    /**
-     * Gets the API info.
-     *
-     * @return the API info.
-     */
-    @Bean
-    public Docket api() {
-        return new Docket(DocumentationType.SWAGGER_2) //
-            .apiInfo(apiInfo()) //
-            .select() //
-            .apis(RequestHandlerSelectors.any()) //
-            .paths(PathSelectors.any()) //
-            .paths(Predicates.not(PathSelectors.regex("/error"))) //
-            // this endpoint is not implemented, but was visible for Swagger
-            .paths(Predicates.not(PathSelectors.regex("/actuator.*"))) //
-            // this endpoint is implemented by spring framework, exclude for now
-            .build();
-    }
-
-    private static ApiInfo apiInfo() {
-        return new ApiInfoBuilder() //
-            .title(API_TITLE) //
-            .description(DESCRIPTION) //
-            .version(VERSION) //
-            .build();
-    }
-
-    @Override
-    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
-        registry.addResourceHandler(SWAGGER_UI) //
-            .addResourceLocations(RESOURCES_PATH);
-
-        registry.addResourceHandler(WEBJARS) //
-            .addResourceLocations(WEBJARS_PATH);
-    }
-
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/aspect/LogAspect.java b/policy-agent/src/main/java/org/oransc/policyagent/aspect/LogAspect.java
deleted file mode 100644 (file)
index 93b2ec0..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.aspect;
-
-import org.aspectj.lang.JoinPoint;
-import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.annotation.After;
-import org.aspectj.lang.annotation.Around;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Before;
-import org.aspectj.lang.reflect.MethodSignature;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
-import org.springframework.util.StopWatch;
-
-@Aspect
-@Component
-public class LogAspect {
-
-    private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);
-
-    @Around("execution(* org.oransc.policyagent..*(..)))")
-    public void executimeTime(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
-        final StopWatch stopWatch = new StopWatch();
-        stopWatch.start();
-        proceedingJoinPoint.proceed();
-        stopWatch.stop();
-        MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
-        String className = methodSignature.getDeclaringType().getSimpleName();
-        String methodName = methodSignature.getName();
-        logger.trace("Execution time of {}.{}: {} ms", className, methodName, stopWatch.getTotalTimeMillis());
-    }
-
-    @Before("execution(* org.oransc.policyagent..*(..)))")
-    public void entryLog(final JoinPoint joinPoint) {
-        logger.trace("Entering method: {}", joinPoint.getSignature().getName());
-    }
-
-    @After("execution(* org.oransc.policyagent..*(..)))")
-    public void exitLog(final JoinPoint joinPoint) {
-        logger.trace("Exiting method: {}", joinPoint.getSignature().getName());
-    }
-
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/A1Client.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/A1Client.java
deleted file mode 100644 (file)
index f94c2c1..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.clients;
-
-import java.util.List;
-
-import org.oransc.policyagent.repository.Policy;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-/**
- * Common interface for 'A1' Policy access. Implementations of this interface
- * adapts to the different southbound REST APIs supported.
- */
-public interface A1Client {
-
-    public enum A1ProtocolType {
-        UNKNOWN, //
-        STD_V1_1, // STD A1 version 1.1
-        OSC_V1, // OSC 'A1'
-        SDNC_OSC_STD_V1_1, // SDNC_OSC with STD A1 version 1.1 southbound
-        SDNC_OSC_OSC_V1, // SDNC_OSC with OSC 'A1' southbound
-        SDNC_ONAP
-    }
-
-    public Mono<A1ProtocolType> getProtocolVersion();
-
-    public Mono<List<String>> getPolicyTypeIdentities();
-
-    public Mono<List<String>> getPolicyIdentities();
-
-    public Mono<String> getPolicyTypeSchema(String policyTypeId);
-
-    public Mono<String> putPolicy(Policy policy);
-
-    public Mono<String> deletePolicy(Policy policy);
-
-    public Flux<String> deleteAllPolicies();
-
-    public Mono<String> getPolicyStatus(Policy policy);
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/A1ClientFactory.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/A1ClientFactory.java
deleted file mode 100644 (file)
index 0860f77..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.clients;
-
-import lombok.Getter;
-
-import org.oransc.policyagent.clients.A1Client.A1ProtocolType;
-import org.oransc.policyagent.configuration.ApplicationConfig;
-import org.oransc.policyagent.configuration.ControllerConfig;
-import org.oransc.policyagent.exceptions.ServiceException;
-import org.oransc.policyagent.repository.Ric;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import reactor.core.publisher.Mono;
-
-/**
- * Factory for A1 clients that supports four different protocol versions of the
- * A1 api.
- */
-public class A1ClientFactory {
-
-    private static final Logger logger = LoggerFactory.getLogger(A1ClientFactory.class);
-
-    @Getter
-    private final ApplicationConfig appConfig;
-
-    @Autowired
-    public A1ClientFactory(ApplicationConfig appConfig) {
-        this.appConfig = appConfig;
-    }
-
-    /**
-     * Creates an A1 client with the correct A1 protocol for the provided Ric.
-     *
-     * <p>
-     * It detects the protocol version by trial and error, since there is no
-     * getVersion method specified in the A1 api yet.
-     *
-     * <p>
-     * As a side effect it also sets the protocol version in the provided Ric. This
-     * means that after the first successful creation it won't have to try which
-     * protocol to use, but can create the client directly.
-     *
-     * @param ric The RIC to get a client for.
-     * @return a client with the correct protocol, or a ServiceException if none of
-     *         the protocols are supported by the Ric.
-     */
-    public Mono<A1Client> createA1Client(Ric ric) {
-        return getProtocolVersion(ric) //
-            .flatMap(version -> createA1ClientMono(ric, version));
-    }
-
-    A1Client createClient(Ric ric, A1ProtocolType version) throws ServiceException {
-        if (version == A1ProtocolType.STD_V1_1) {
-            assertNoControllerConfig(ric, version);
-            return new StdA1ClientVersion1(ric.getConfig(), this.appConfig.getWebClientConfig());
-        } else if (version == A1ProtocolType.OSC_V1) {
-            assertNoControllerConfig(ric, version);
-            return new OscA1Client(ric.getConfig(), this.appConfig.getWebClientConfig());
-        } else if (version == A1ProtocolType.SDNC_OSC_STD_V1_1 || version == A1ProtocolType.SDNC_OSC_OSC_V1) {
-            return new SdncOscA1Client(version, ric.getConfig(), getControllerConfig(ric),
-                this.appConfig.getWebClientConfig());
-        } else if (version == A1ProtocolType.SDNC_ONAP) {
-            return new SdncOnapA1Client(ric.getConfig(), getControllerConfig(ric), this.appConfig.getWebClientConfig());
-        } else {
-            logger.error("Unhandled protocol: {}", version);
-            throw new ServiceException("Unhandled protocol");
-        }
-    }
-
-    private ControllerConfig getControllerConfig(Ric ric) throws ServiceException {
-        String controllerName = ric.getConfig().controllerName();
-        if (controllerName.isEmpty()) {
-            ric.setProtocolVersion(A1ProtocolType.UNKNOWN);
-            throw new ServiceException("No controller configured for RIC: " + ric.name());
-        }
-        try {
-            return this.appConfig.getControllerConfig(controllerName);
-        } catch (ServiceException e) {
-            ric.setProtocolVersion(A1ProtocolType.UNKNOWN);
-            throw e;
-        }
-    }
-
-    private void assertNoControllerConfig(Ric ric, A1ProtocolType version) throws ServiceException {
-        if (!ric.getConfig().controllerName().isEmpty()) {
-            ric.setProtocolVersion(A1ProtocolType.UNKNOWN);
-            throw new ServiceException(
-                "Controller config should be empty, ric: " + ric.name() + " when using protocol version: " + version);
-        }
-    }
-
-    private Mono<A1Client> createA1ClientMono(Ric ric, A1ProtocolType version) {
-        try {
-            return Mono.just(createClient(ric, version));
-        } catch (ServiceException e) {
-            return Mono.error(e);
-        }
-    }
-
-    private Mono<A1Client.A1ProtocolType> getProtocolVersion(Ric ric) {
-        if (ric.getProtocolVersion() == A1ProtocolType.UNKNOWN) {
-            return fetchVersion(ric, A1ProtocolType.STD_V1_1) //
-                .onErrorResume(notUsed -> fetchVersion(ric, A1ProtocolType.OSC_V1)) //
-                .onErrorResume(notUsed -> fetchVersion(ric, A1ProtocolType.SDNC_OSC_STD_V1_1)) //
-                .onErrorResume(notUsed -> fetchVersion(ric, A1ProtocolType.SDNC_ONAP)) //
-                .doOnNext(ric::setProtocolVersion)
-                .doOnNext(version -> logger.debug("Established protocol version:{} for Ric: {}", version, ric.name())) //
-                .doOnError(notUsed -> logger.warn("Could not get protocol version from RIC: {}", ric.name())) //
-                .onErrorResume(
-                    notUsed -> Mono.error(new ServiceException("Protocol negotiation failed for " + ric.name())));
-        } else {
-            return Mono.just(ric.getProtocolVersion());
-        }
-    }
-
-    private Mono<A1ProtocolType> fetchVersion(Ric ric, A1ProtocolType protocolType) {
-        return createA1ClientMono(ric, protocolType) //
-            .flatMap(A1Client::getProtocolVersion);
-    }
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/AsyncRestClient.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/AsyncRestClient.java
deleted file mode 100644 (file)
index 4bc29ee..0000000
+++ /dev/null
@@ -1,334 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.clients;
-
-import io.netty.channel.ChannelOption;
-import io.netty.handler.ssl.SslContext;
-import io.netty.handler.ssl.SslContextBuilder;
-import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
-import io.netty.handler.timeout.ReadTimeoutHandler;
-import io.netty.handler.timeout.WriteTimeoutHandler;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.invoke.MethodHandles;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.Collectors;
-
-import javax.net.ssl.KeyManagerFactory;
-
-import org.oransc.policyagent.configuration.WebClientConfig;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.http.MediaType;
-import org.springframework.http.ResponseEntity;
-import org.springframework.http.client.reactive.ReactorClientHttpConnector;
-import org.springframework.lang.Nullable;
-import org.springframework.util.ResourceUtils;
-import org.springframework.web.reactive.function.client.ExchangeStrategies;
-import org.springframework.web.reactive.function.client.WebClient;
-import org.springframework.web.reactive.function.client.WebClient.RequestHeadersSpec;
-import org.springframework.web.reactive.function.client.WebClientResponseException;
-
-import reactor.core.publisher.Mono;
-import reactor.netty.http.client.HttpClient;
-import reactor.netty.resources.ConnectionProvider;
-import reactor.netty.tcp.TcpClient;
-
-/**
- * Generic reactive REST client.
- */
-public class AsyncRestClient {
-    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-    private WebClient webClient = null;
-    private final String baseUrl;
-    private static final AtomicInteger sequenceNumber = new AtomicInteger();
-    private final WebClientConfig clientConfig;
-    static KeyStore clientTrustStore = null;
-    private boolean sslEnabled = true;
-
-    public AsyncRestClient(String baseUrl) {
-        this(baseUrl, null);
-        this.sslEnabled = false;
-    }
-
-    public AsyncRestClient(String baseUrl, WebClientConfig config) {
-        this.baseUrl = baseUrl;
-        this.clientConfig = config;
-    }
-
-    public Mono<ResponseEntity<String>> postForEntity(String uri, @Nullable String body) {
-        Object traceTag = createTraceTag();
-        logger.debug("{} POST uri = '{}{}''", traceTag, baseUrl, uri);
-        logger.trace("{} POST body: {}", traceTag, body);
-        Mono<String> bodyProducer = body != null ? Mono.just(body) : Mono.empty();
-        return getWebClient() //
-            .flatMap(client -> {
-                RequestHeadersSpec<?> request = client.post() //
-                    .uri(uri) //
-                    .contentType(MediaType.APPLICATION_JSON) //
-                    .body(bodyProducer, String.class);
-                return retrieve(traceTag, request);
-            });
-    }
-
-    public Mono<String> post(String uri, @Nullable String body) {
-        return postForEntity(uri, body) //
-            .flatMap(this::toBody);
-    }
-
-    public Mono<String> postWithAuthHeader(String uri, String body, String username, String password) {
-        Object traceTag = createTraceTag();
-        logger.debug("{} POST (auth) uri = '{}{}''", traceTag, baseUrl, uri);
-        logger.trace("{} POST body: {}", traceTag, body);
-        return getWebClient() //
-            .flatMap(client -> {
-                RequestHeadersSpec<?> request = client.post() //
-                    .uri(uri) //
-                    .headers(headers -> headers.setBasicAuth(username, password)) //
-                    .contentType(MediaType.APPLICATION_JSON) //
-                    .bodyValue(body);
-                return retrieve(traceTag, request) //
-                    .flatMap(this::toBody);
-            });
-    }
-
-    public Mono<ResponseEntity<String>> putForEntity(String uri, String body) {
-        Object traceTag = createTraceTag();
-        logger.debug("{} PUT uri = '{}{}''", traceTag, baseUrl, uri);
-        logger.trace("{} PUT body: {}", traceTag, body);
-        return getWebClient() //
-            .flatMap(client -> {
-                RequestHeadersSpec<?> request = client.put() //
-                    .uri(uri) //
-                    .contentType(MediaType.APPLICATION_JSON) //
-                    .bodyValue(body);
-                return retrieve(traceTag, request);
-            });
-    }
-
-    public Mono<ResponseEntity<String>> putForEntity(String uri) {
-        Object traceTag = createTraceTag();
-        logger.debug("{} PUT uri = '{}{}''", traceTag, baseUrl, uri);
-        logger.trace("{} PUT body: <empty>", traceTag);
-        return getWebClient() //
-            .flatMap(client -> {
-                RequestHeadersSpec<?> request = client.put() //
-                    .uri(uri);
-                return retrieve(traceTag, request);
-            });
-    }
-
-    public Mono<String> put(String uri, String body) {
-        return putForEntity(uri, body) //
-            .flatMap(this::toBody);
-    }
-
-    public Mono<ResponseEntity<String>> getForEntity(String uri) {
-        Object traceTag = createTraceTag();
-        logger.debug("{} GET uri = '{}{}''", traceTag, baseUrl, uri);
-        return getWebClient() //
-            .flatMap(client -> {
-                RequestHeadersSpec<?> request = client.get().uri(uri);
-                return retrieve(traceTag, request);
-            });
-    }
-
-    public Mono<String> get(String uri) {
-        return getForEntity(uri) //
-            .flatMap(this::toBody);
-    }
-
-    public Mono<ResponseEntity<String>> deleteForEntity(String uri) {
-        Object traceTag = createTraceTag();
-        logger.debug("{} DELETE uri = '{}{}''", traceTag, baseUrl, uri);
-        return getWebClient() //
-            .flatMap(client -> {
-                RequestHeadersSpec<?> request = client.delete().uri(uri);
-                return retrieve(traceTag, request);
-            });
-    }
-
-    public Mono<String> delete(String uri) {
-        return deleteForEntity(uri) //
-            .flatMap(this::toBody);
-    }
-
-    private Mono<ResponseEntity<String>> retrieve(Object traceTag, RequestHeadersSpec<?> request) {
-        final Class<String> clazz = String.class;
-        return request.retrieve() //
-            .toEntity(clazz) //
-            .doOnNext(entity -> logger.trace("{} Received: {}", traceTag, entity.getBody())) //
-            .doOnError(throwable -> onHttpError(traceTag, throwable));
-    }
-
-    private static Object createTraceTag() {
-        return sequenceNumber.incrementAndGet();
-    }
-
-    private void onHttpError(Object traceTag, Throwable t) {
-        if (t instanceof WebClientResponseException) {
-            WebClientResponseException exception = (WebClientResponseException) t;
-            logger.debug("{} HTTP error status = '{}', body '{}'", traceTag, exception.getStatusCode(),
-                exception.getResponseBodyAsString());
-        } else {
-            logger.debug("{} HTTP error", traceTag, t);
-        }
-    }
-
-    private Mono<String> toBody(ResponseEntity<String> entity) {
-        if (entity.getBody() == null) {
-            return Mono.just("");
-        } else {
-            return Mono.just(entity.getBody());
-        }
-    }
-
-    private boolean isCertificateEntry(KeyStore trustStore, String alias) {
-        try {
-            return trustStore.isCertificateEntry(alias);
-        } catch (KeyStoreException e) {
-            logger.error("Error reading truststore {}", e.getMessage());
-            return false;
-        }
-    }
-
-    private Certificate getCertificate(KeyStore trustStore, String alias) {
-        try {
-            return trustStore.getCertificate(alias);
-        } catch (KeyStoreException e) {
-            logger.error("Error reading truststore {}", e.getMessage());
-            return null;
-        }
-    }
-
-    private static synchronized KeyStore getTrustStore(String trustStorePath, String trustStorePass)
-        throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException {
-        if (clientTrustStore == null) {
-            KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType());
-            store.load(new FileInputStream(ResourceUtils.getFile(trustStorePath)), trustStorePass.toCharArray());
-            clientTrustStore = store;
-        }
-        return clientTrustStore;
-    }
-
-    private SslContext createSslContextRejectingUntrustedPeers(String trustStorePath, String trustStorePass,
-        KeyManagerFactory keyManager)
-        throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException {
-
-        final KeyStore trustStore = getTrustStore(trustStorePath, trustStorePass);
-        List<Certificate> certificateList = Collections.list(trustStore.aliases()).stream() //
-            .filter(alias -> isCertificateEntry(trustStore, alias)) //
-            .map(alias -> getCertificate(trustStore, alias)) //
-            .collect(Collectors.toList());
-        final X509Certificate[] certificates = certificateList.toArray(new X509Certificate[certificateList.size()]);
-
-        return SslContextBuilder.forClient() //
-            .keyManager(keyManager) //
-            .trustManager(certificates) //
-            .build();
-    }
-
-    private SslContext createSslContext(KeyManagerFactory keyManager)
-        throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException {
-        if (this.clientConfig.isTrustStoreUsed()) {
-            return createSslContextRejectingUntrustedPeers(this.clientConfig.trustStore(),
-                this.clientConfig.trustStorePassword(), keyManager);
-        } else {
-            // Trust anyone
-            return SslContextBuilder.forClient() //
-                .keyManager(keyManager) //
-                .trustManager(InsecureTrustManagerFactory.INSTANCE) //
-                .build();
-        }
-    }
-
-    private TcpClient createTcpClientSecure(SslContext sslContext) {
-        return TcpClient.create(ConnectionProvider.newConnection()) //
-            .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10_000) //
-            .secure(c -> c.sslContext(sslContext)) //
-            .doOnConnected(connection -> {
-                connection.addHandlerLast(new ReadTimeoutHandler(30));
-                connection.addHandlerLast(new WriteTimeoutHandler(30));
-            });
-    }
-
-    private TcpClient createTcpClientInsecure() {
-        return TcpClient.create(ConnectionProvider.newConnection()) //
-            .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10_000) //
-            .doOnConnected(connection -> {
-                connection.addHandlerLast(new ReadTimeoutHandler(30));
-                connection.addHandlerLast(new WriteTimeoutHandler(30));
-            });
-    }
-
-    private WebClient createWebClient(String baseUrl, TcpClient tcpClient) {
-        HttpClient httpClient = HttpClient.from(tcpClient);
-        ReactorClientHttpConnector connector = new ReactorClientHttpConnector(httpClient);
-        ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder() //
-            .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(-1)) //
-            .build();
-        return WebClient.builder() //
-            .clientConnector(connector) //
-            .baseUrl(baseUrl) //
-            .exchangeStrategies(exchangeStrategies) //
-            .build();
-    }
-
-    private Mono<WebClient> getWebClient() {
-        if (this.webClient == null) {
-            try {
-                if (this.sslEnabled) {
-                    final KeyManagerFactory keyManager =
-                        KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
-                    final KeyStore keyStore = KeyStore.getInstance(this.clientConfig.keyStoreType());
-                    final String keyStoreFile = this.clientConfig.keyStore();
-                    final String keyStorePassword = this.clientConfig.keyStorePassword();
-                    final String keyPassword = this.clientConfig.keyPassword();
-                    try (final InputStream inputStream = new FileInputStream(keyStoreFile)) {
-                        keyStore.load(inputStream, keyStorePassword.toCharArray());
-                    }
-                    keyManager.init(keyStore, keyPassword.toCharArray());
-                    SslContext sslContext = createSslContext(keyManager);
-                    TcpClient tcpClient = createTcpClientSecure(sslContext);
-                    this.webClient = createWebClient(this.baseUrl, tcpClient);
-                } else {
-                    TcpClient tcpClient = createTcpClientInsecure();
-                    this.webClient = createWebClient(this.baseUrl, tcpClient);
-                }
-            } catch (Exception e) {
-                logger.error("Could not create WebClient {}", e.getMessage());
-                return Mono.error(e);
-            }
-        }
-        return Mono.just(this.webClient);
-    }
-
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/OscA1Client.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/OscA1Client.java
deleted file mode 100644 (file)
index a388267..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.clients;
-
-import java.lang.invoke.MethodHandles;
-import java.util.List;
-
-import org.json.JSONObject;
-import org.oransc.policyagent.configuration.RicConfig;
-import org.oransc.policyagent.configuration.WebClientConfig;
-import org.oransc.policyagent.repository.Policy;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-/**
- * Client for accessing OSC A1 REST API
- */
-@SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally
-public class OscA1Client implements A1Client {
-    static final int CONCURRENCY_RIC = 1; // How may paralell requests that is sent to one NearRT RIC
-
-    public static class UriBuilder implements A1UriBuilder {
-        private final RicConfig ricConfig;
-
-        public UriBuilder(RicConfig ricConfig) {
-            this.ricConfig = ricConfig;
-        }
-
-        @Override
-        public String createPutPolicyUri(String type, String policyId) {
-            return createPolicyUri(type, policyId);
-        }
-
-        /**
-         * /a1-p/policytypes/{policy_type_id}/policies
-         */
-        public String createGetPolicyIdsUri(String type) {
-            return createPolicyTypeUri(type) + "/policies";
-        }
-
-        @Override
-        public String createDeleteUri(String type, String policyId) {
-            return createPolicyUri(type, policyId);
-        }
-
-        /**
-         * â€‹/a1-p​/policytypes​/{policy_type_id}​/policies​/{policy_instance_id}​/status
-         */
-        @Override
-        public String createGetPolicyStatusUri(String type, String policyId) {
-            return createPolicyUri(type, policyId) + "/status";
-        }
-
-        /**
-         * â€‹/a1-p​/healthcheck
-         */
-        public String createHealtcheckUri() {
-            return baseUri() + "/healthcheck";
-        }
-
-        /**
-         * /a1-p/policytypes/{policy_type_id}
-         */
-        public String createGetSchemaUri(String type) {
-            return this.createPolicyTypeUri(type);
-        }
-
-        /**
-         * â€‹/a1-p​/policytypes​/{policy_type_id}
-         */
-        public String createPolicyTypesUri() {
-            return baseUri() + "/policytypes";
-        }
-
-        /**
-         * â€‹/a1-p​/policytypes​/{policy_type_id}​/policies​/{policy_instance_id}
-         */
-        private String createPolicyUri(String type, String id) {
-            return createPolicyTypeUri(type) + "/policies/" + id;
-        }
-
-        /**
-         * /a1-p/policytypes/{policy_type_id}
-         */
-        private String createPolicyTypeUri(String type) {
-            return createPolicyTypesUri() + "/" + type;
-        }
-
-        private String baseUri() {
-            return ricConfig.baseUrl() + "/a1-p";
-        }
-    }
-
-    private static final String TITLE = "title";
-    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-    private final AsyncRestClient restClient;
-    private final UriBuilder uri;
-
-    public OscA1Client(RicConfig ricConfig, WebClientConfig clientConfig) {
-        this(ricConfig, new AsyncRestClient("", clientConfig));
-    }
-
-    public OscA1Client(RicConfig ricConfig, AsyncRestClient restClient) {
-        this.restClient = restClient;
-        logger.debug("OscA1Client for ric: {}", ricConfig.name());
-
-        uri = new UriBuilder(ricConfig);
-    }
-
-    public static Mono<String> extractCreateSchema(String policyTypeResponse, String policyTypeId) {
-        try {
-            JSONObject obj = new JSONObject(policyTypeResponse);
-            JSONObject schemaObj = obj.getJSONObject("create_schema");
-            schemaObj.put(TITLE, policyTypeId);
-            return Mono.just(schemaObj.toString());
-        } catch (Exception e) {
-            String exceptionString = e.toString();
-            logger.error("Unexpected response for policy type: {}, exception: {}", policyTypeResponse, exceptionString);
-            return Mono.error(e);
-        }
-    }
-
-    @Override
-    public Mono<List<String>> getPolicyTypeIdentities() {
-        return getPolicyTypeIds() //
-            .collectList();
-    }
-
-    @Override
-    public Mono<List<String>> getPolicyIdentities() {
-        return getPolicyTypeIds() //
-            .flatMap(this::getPolicyIdentitiesByType) //
-            .collectList();
-    }
-
-    @Override
-    public Mono<String> getPolicyTypeSchema(String policyTypeId) {
-        String schemaUri = uri.createGetSchemaUri(policyTypeId);
-        return restClient.get(schemaUri) //
-            .flatMap(response -> extractCreateSchema(response, policyTypeId));
-    }
-
-    @Override
-    public Mono<String> putPolicy(Policy policy) {
-        String policyUri = this.uri.createPutPolicyUri(policy.type().name(), policy.id());
-        return restClient.put(policyUri, policy.json());
-    }
-
-    @Override
-    public Mono<String> deletePolicy(Policy policy) {
-        return deletePolicyById(policy.type().name(), policy.id());
-    }
-
-    @Override
-    public Mono<A1ProtocolType> getProtocolVersion() {
-        return restClient.get(uri.createHealtcheckUri()) //
-            .flatMap(notUsed -> Mono.just(A1ProtocolType.OSC_V1));
-    }
-
-    @Override
-    public Flux<String> deleteAllPolicies() {
-        return getPolicyTypeIds() //
-            .flatMap(this::deletePoliciesForType, CONCURRENCY_RIC);
-    }
-
-    @Override
-    public Mono<String> getPolicyStatus(Policy policy) {
-        String statusUri = uri.createGetPolicyStatusUri(policy.type().name(), policy.id());
-        return restClient.get(statusUri);
-
-    }
-
-    private Flux<String> getPolicyTypeIds() {
-        return restClient.get(uri.createPolicyTypesUri()) //
-            .flatMapMany(SdncJsonHelper::parseJsonArrayOfString);
-    }
-
-    private Flux<String> getPolicyIdentitiesByType(String typeId) {
-        return restClient.get(uri.createGetPolicyIdsUri(typeId)) //
-            .flatMapMany(SdncJsonHelper::parseJsonArrayOfString);
-    }
-
-    private Mono<String> deletePolicyById(String typeId, String policyId) {
-        String policyUri = uri.createDeleteUri(typeId, policyId);
-        return restClient.delete(policyUri);
-    }
-
-    private Flux<String> deletePoliciesForType(String typeId) {
-        return getPolicyIdentitiesByType(typeId) //
-            .flatMap(policyId -> deletePolicyById(typeId, policyId), CONCURRENCY_RIC);
-    }
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/SdncJsonHelper.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/SdncJsonHelper.java
deleted file mode 100644 (file)
index ab0d3fa..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.clients;
-
-import com.google.gson.FieldNamingPolicy;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-
-import java.lang.invoke.MethodHandles;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-/**
- * Common json functionality used by the SDNC clients
- */
-@SuppressWarnings("java:S1192") // Same text in several traces
-class SdncJsonHelper {
-    private static Gson gson = new GsonBuilder() //
-        .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES) //
-        .create();
-    private static final String OUTPUT = "output";
-    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-    private SdncJsonHelper() {
-    }
-
-    public static Flux<String> parseJsonArrayOfString(String inputString) {
-        try {
-            List<String> arrayList = new ArrayList<>();
-            if (!inputString.isEmpty()) {
-                JSONArray jsonArray = new JSONArray(inputString);
-                for (int i = 0; i < jsonArray.length(); i++) {
-                    Object value = jsonArray.get(i);
-                    arrayList.add(value.toString());
-                }
-            }
-            return Flux.fromIterable(arrayList);
-        } catch (JSONException ex) { // invalid json
-            logger.debug("Invalid json {}", ex.getMessage());
-            return Flux.error(ex);
-        }
-    }
-
-    public static <T> String createInputJsonString(T params) {
-        JsonElement paramsJson = gson.toJsonTree(params);
-        JsonObject jsonObj = new JsonObject();
-        jsonObj.add("input", paramsJson);
-        return gson.toJson(jsonObj);
-    }
-
-    public static <T> String createOutputJsonString(T params) {
-        JsonElement paramsJson = gson.toJsonTree(params);
-        JsonObject jsonObj = new JsonObject();
-        jsonObj.add(OUTPUT, paramsJson);
-        return gson.toJson(jsonObj);
-    }
-
-    public static Mono<JSONObject> getOutput(String response) {
-        try {
-            JSONObject outputJson = new JSONObject(response);
-            JSONObject responseParams = outputJson.getJSONObject(OUTPUT);
-            return Mono.just(responseParams);
-        } catch (JSONException ex) { // invalid json
-            logger.debug("Invalid json {}", ex.getMessage());
-            return Mono.error(ex);
-        }
-    }
-
-    public static Mono<String> getValueFromResponse(String response, String key) {
-        return getOutput(response) //
-            .flatMap(responseParams -> {
-                if (!responseParams.has(key)) {
-                    return Mono.just("");
-                }
-                String value = responseParams.get(key).toString();
-                return Mono.just(value);
-            });
-    }
-
-    public static Mono<String> extractPolicySchema(String inputString) {
-        try {
-            JSONObject jsonObject = new JSONObject(inputString);
-            JSONObject schemaObject = jsonObject.getJSONObject("policySchema");
-            String schemaString = schemaObject.toString();
-            return Mono.just(schemaString);
-        } catch (JSONException ex) { // invalid json
-            logger.debug("Invalid json {}", ex.getMessage());
-            return Mono.error(ex);
-        }
-    }
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/SdncOnapA1Client.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/SdncOnapA1Client.java
deleted file mode 100644 (file)
index 37e0303..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.clients;
-
-import java.lang.invoke.MethodHandles;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-import org.immutables.gson.Gson;
-import org.immutables.value.Value;
-import org.oransc.policyagent.configuration.ControllerConfig;
-import org.oransc.policyagent.configuration.RicConfig;
-import org.oransc.policyagent.configuration.WebClientConfig;
-import org.oransc.policyagent.repository.Policy;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-/**
- * Client for accessing the A1 adapter in the SDNC controller in ONAP
- */
-@SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally
-public class SdncOnapA1Client implements A1Client {
-    @Value.Immutable
-    @Gson.TypeAdapters
-    interface SdncOnapAdapterInput {
-        public String nearRtRicId();
-
-        public Optional<String> policyTypeId();
-
-        public Optional<String> policyInstanceId();
-
-        public Optional<String> policyInstance();
-
-        public Optional<List<String>> properties();
-    }
-
-    private static final String URL_PREFIX = "/A1-ADAPTER-API:";
-
-    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-    private final ControllerConfig controllerConfig;
-    private final RicConfig ricConfig;
-    private final AsyncRestClient restClient;
-
-    public SdncOnapA1Client(RicConfig ricConfig, ControllerConfig controllerConfig, WebClientConfig clientConfig) {
-        this(ricConfig, controllerConfig,
-            new AsyncRestClient(controllerConfig.baseUrl() + "/restconf/operations", clientConfig));
-        logger.debug("SdncOnapA1Client for ric: {}, a1ControllerBaseUrl: {}", ricConfig.name(),
-            controllerConfig.baseUrl());
-    }
-
-    public SdncOnapA1Client(RicConfig ricConfig, ControllerConfig controllerConfig, AsyncRestClient restClient) {
-        this.ricConfig = ricConfig;
-        this.controllerConfig = controllerConfig;
-        this.restClient = restClient;
-    }
-
-    @Override
-    public Mono<List<String>> getPolicyTypeIdentities() {
-        return getPolicyTypeIds() //
-            .collectList();
-    }
-
-    @Override
-    public Mono<List<String>> getPolicyIdentities() {
-        return getPolicyTypeIds() //
-            .flatMap(this::getPolicyIdentitiesByType) //
-            .collectList();
-    }
-
-    @Override
-    public Mono<String> getPolicyTypeSchema(String policyTypeId) {
-        SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() //
-            .nearRtRicId(ricConfig.baseUrl()) //
-            .policyTypeId(policyTypeId) //
-            .build();
-        String inputJsonString = SdncJsonHelper.createInputJsonString(inputParams);
-        logger.debug("POST getPolicyType inputJsonString = {}", inputJsonString);
-
-        return restClient
-            .postWithAuthHeader(URL_PREFIX + "getPolicyType", inputJsonString, controllerConfig.userName(),
-                controllerConfig.password()) //
-            .flatMap(response -> SdncJsonHelper.getValueFromResponse(response, "policy-type")) //
-            .flatMap(SdncJsonHelper::extractPolicySchema);
-    }
-
-    @Override
-    public Mono<String> putPolicy(Policy policy) {
-        SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() //
-            .nearRtRicId(ricConfig.baseUrl()) //
-            .policyTypeId(policy.type().name()) //
-            .policyInstanceId(policy.id()) //
-            .policyInstance(policy.json()) //
-            .properties(new ArrayList<>()) //
-            .build();
-
-        String inputJsonString = SdncJsonHelper.createInputJsonString(inputParams);
-        logger.debug("POST putPolicy inputJsonString = {}", inputJsonString);
-
-        return restClient.postWithAuthHeader(URL_PREFIX + "createPolicyInstance", inputJsonString,
-            controllerConfig.userName(), controllerConfig.password());
-    }
-
-    @Override
-    public Mono<String> deletePolicy(Policy policy) {
-        return deletePolicyByTypeId(policy.type().name(), policy.id());
-    }
-
-    @Override
-    public Flux<String> deleteAllPolicies() {
-        return getPolicyTypeIds() //
-            .flatMap(this::deletePoliciesForType); //
-    }
-
-    @Override
-    public Mono<A1ProtocolType> getProtocolVersion() {
-        return getPolicyTypeIdentities() //
-            .flatMap(notUsed -> Mono.just(A1ProtocolType.SDNC_ONAP));
-    }
-
-    @Override
-    public Mono<String> getPolicyStatus(Policy policy) {
-        return Mono.error(new Exception("Status not implemented in the controller"));
-    }
-
-    private Flux<String> getPolicyTypeIds() {
-        SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() //
-            .nearRtRicId(ricConfig.baseUrl()) //
-            .build();
-        String inputJsonString = SdncJsonHelper.createInputJsonString(inputParams);
-        logger.debug("POST getPolicyTypeIdentities inputJsonString = {}", inputJsonString);
-
-        return restClient
-            .postWithAuthHeader(URL_PREFIX + "getPolicyTypes", inputJsonString, controllerConfig.userName(),
-                controllerConfig.password()) //
-            .flatMap(response -> SdncJsonHelper.getValueFromResponse(response, "policy-type-id-list")) //
-            .flatMapMany(SdncJsonHelper::parseJsonArrayOfString);
-    }
-
-    private Flux<String> getPolicyIdentitiesByType(String policyTypeId) {
-        SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() //
-            .nearRtRicId(ricConfig.baseUrl()) //
-            .policyTypeId(policyTypeId) //
-            .build();
-        String inputJsonString = SdncJsonHelper.createInputJsonString(inputParams);
-        logger.debug("POST getPolicyIdentities inputJsonString = {}", inputJsonString);
-
-        return restClient
-            .postWithAuthHeader(URL_PREFIX + "getPolicyInstances", inputJsonString, controllerConfig.userName(),
-                controllerConfig.password()) //
-            .flatMap(response -> SdncJsonHelper.getValueFromResponse(response, "policy-instance-id-list")) //
-            .flatMapMany(SdncJsonHelper::parseJsonArrayOfString);
-    }
-
-    private Flux<String> deletePoliciesForType(String typeId) {
-        return getPolicyIdentitiesByType(typeId) //
-            .flatMap(policyId -> deletePolicyByTypeId(typeId, policyId)); //
-    }
-
-    private Mono<String> deletePolicyByTypeId(String policyTypeId, String policyId) {
-        SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() //
-            .nearRtRicId(ricConfig.baseUrl()) //
-            .policyTypeId(policyTypeId) //
-            .policyInstanceId(policyId) //
-            .build();
-        String inputJsonString = SdncJsonHelper.createInputJsonString(inputParams);
-        logger.debug("POST deletePolicy inputJsonString = {}", inputJsonString);
-
-        return restClient.postWithAuthHeader(URL_PREFIX + "deletePolicyInstance", inputJsonString,
-            controllerConfig.userName(), controllerConfig.password());
-    }
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/SdncOscA1Client.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/SdncOscA1Client.java
deleted file mode 100644 (file)
index 79a2a5e..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.clients;
-
-import com.google.gson.FieldNamingPolicy;
-import com.google.gson.GsonBuilder;
-
-import java.lang.invoke.MethodHandles;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Optional;
-
-import org.immutables.value.Value;
-import org.json.JSONObject;
-import org.oransc.policyagent.configuration.ControllerConfig;
-import org.oransc.policyagent.configuration.RicConfig;
-import org.oransc.policyagent.configuration.WebClientConfig;
-import org.oransc.policyagent.repository.Policy;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.http.HttpStatus;
-import org.springframework.web.reactive.function.client.WebClientResponseException;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-/**
- * Client for accessing the A1 adapter in the SDNC controller in OSC.
- */
-@SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally
-public class SdncOscA1Client implements A1Client {
-
-    static final int CONCURRENCY_RIC = 1; // How may paralell requests that is sent to one NearRT RIC
-
-    @Value.Immutable
-    @org.immutables.gson.Gson.TypeAdapters
-    public interface AdapterRequest {
-        public String nearRtRicUrl();
-
-        public Optional<String> body();
-    }
-
-    @Value.Immutable
-    @org.immutables.gson.Gson.TypeAdapters
-    public interface AdapterOutput {
-        public Optional<String> body();
-
-        public int httpStatus();
-    }
-
-    static com.google.gson.Gson gson = new GsonBuilder() //
-        .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES) //
-        .create(); //
-
-    private static final String GET_POLICY_RPC = "getA1Policy";
-    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-    private final ControllerConfig controllerConfig;
-    private final AsyncRestClient restClient;
-    private final RicConfig ricConfig;
-    private final A1ProtocolType protocolType;
-
-    /**
-     * Constructor that creates the REST client to use.
-     *
-     * @param protocolType the southbound protocol of the controller. Supported protocols are SDNC_OSC_STD_V1_1 and
-     *        SDNC_OSC_OSC_V1
-     * @param ricConfig the configuration of the Ric to communicate with
-     * @param controllerConfig the configuration of the SDNC controller to use
-     *
-     * @throws IllegalArgumentException when the protocolType is wrong.
-     */
-    public SdncOscA1Client(A1ProtocolType protocolType, RicConfig ricConfig, ControllerConfig controllerConfig,
-        WebClientConfig clientConfig) {
-        this(protocolType, ricConfig, controllerConfig,
-            new AsyncRestClient(controllerConfig.baseUrl() + "/restconf/operations", clientConfig));
-        logger.debug("SdncOscA1Client for ric: {}, a1Controller: {}", ricConfig.name(), controllerConfig);
-    }
-
-    /**
-     * Constructor where the REST client to use is provided.
-     *
-     * @param protocolType the southbound protocol of the controller. Supported protocols are SDNC_OSC_STD_V1_1 and
-     *        SDNC_OSC_OSC_V1
-     * @param ricConfig the configuration of the Ric to communicate with
-     * @param controllerConfig the configuration of the SDNC controller to use
-     * @param restClient the REST client to use
-     *
-     * @throws IllegalArgumentException when the protocolType is wrong.
-     */
-    public SdncOscA1Client(A1ProtocolType protocolType, RicConfig ricConfig, ControllerConfig controllerConfig,
-        AsyncRestClient restClient) {
-        if (!(A1ProtocolType.SDNC_OSC_STD_V1_1.equals(protocolType)
-            || A1ProtocolType.SDNC_OSC_OSC_V1.equals(protocolType))) {
-            throw new IllegalArgumentException("Protocol type must be " + A1ProtocolType.SDNC_OSC_STD_V1_1 + " or "
-                + A1ProtocolType.SDNC_OSC_OSC_V1 + ", was: " + protocolType);
-        }
-        this.restClient = restClient;
-        this.ricConfig = ricConfig;
-        this.protocolType = protocolType;
-        this.controllerConfig = controllerConfig;
-    }
-
-    @Override
-    public Mono<List<String>> getPolicyTypeIdentities() {
-        if (this.protocolType == A1ProtocolType.SDNC_OSC_STD_V1_1) {
-            return Mono.just(Arrays.asList(""));
-        } else {
-            OscA1Client.UriBuilder uri = new OscA1Client.UriBuilder(ricConfig);
-            final String ricUrl = uri.createPolicyTypesUri();
-            return post(GET_POLICY_RPC, ricUrl, Optional.empty()) //
-                .flatMapMany(SdncJsonHelper::parseJsonArrayOfString) //
-                .collectList();
-        }
-
-    }
-
-    @Override
-    public Mono<List<String>> getPolicyIdentities() {
-        return getPolicyIds() //
-            .collectList();
-    }
-
-    @Override
-    public Mono<String> getPolicyTypeSchema(String policyTypeId) {
-        if (this.protocolType == A1ProtocolType.SDNC_OSC_STD_V1_1) {
-            return Mono.just("{}");
-        } else {
-            OscA1Client.UriBuilder uri = new OscA1Client.UriBuilder(ricConfig);
-            final String ricUrl = uri.createGetSchemaUri(policyTypeId);
-            return post(GET_POLICY_RPC, ricUrl, Optional.empty()) //
-                .flatMap(response -> OscA1Client.extractCreateSchema(response, policyTypeId));
-        }
-    }
-
-    @Override
-    public Mono<String> putPolicy(Policy policy) {
-        return getUriBuilder() //
-            .flatMap(builder -> {
-                String ricUrl = builder.createPutPolicyUri(policy.type().name(), policy.id());
-                return post("putA1Policy", ricUrl, Optional.of(policy.json()));
-            });
-    }
-
-    @Override
-    public Mono<String> deletePolicy(Policy policy) {
-        return deletePolicyById(policy.type().name(), policy.id());
-    }
-
-    @Override
-    public Flux<String> deleteAllPolicies() {
-        if (this.protocolType == A1ProtocolType.SDNC_OSC_STD_V1_1) {
-            return getPolicyIds() //
-                .flatMap(policyId -> deletePolicyById("", policyId), CONCURRENCY_RIC); //
-        } else {
-            OscA1Client.UriBuilder uriBuilder = new OscA1Client.UriBuilder(ricConfig);
-            return getPolicyTypeIdentities() //
-                .flatMapMany(Flux::fromIterable) //
-                .flatMap(type -> oscDeleteInstancesForType(uriBuilder, type), CONCURRENCY_RIC);
-        }
-    }
-
-    private Flux<String> oscGetInstancesForType(OscA1Client.UriBuilder uriBuilder, String type) {
-        return post(GET_POLICY_RPC, uriBuilder.createGetPolicyIdsUri(type), Optional.empty()) //
-            .flatMapMany(SdncJsonHelper::parseJsonArrayOfString);
-    }
-
-    private Flux<String> oscDeleteInstancesForType(OscA1Client.UriBuilder uriBuilder, String type) {
-        return oscGetInstancesForType(uriBuilder, type) //
-            .flatMap(instance -> deletePolicyById(type, instance), CONCURRENCY_RIC);
-    }
-
-    @Override
-    public Mono<A1ProtocolType> getProtocolVersion() {
-        return tryStdProtocolVersion() //
-            .onErrorResume(t -> tryOscProtocolVersion());
-    }
-
-    @Override
-    public Mono<String> getPolicyStatus(Policy policy) {
-        return getUriBuilder() //
-            .flatMap(builder -> {
-                String ricUrl = builder.createGetPolicyStatusUri(policy.type().name(), policy.id());
-                return post("getA1PolicyStatus", ricUrl, Optional.empty());
-            });
-    }
-
-    private Mono<A1UriBuilder> getUriBuilder() {
-        if (protocolType == A1ProtocolType.SDNC_OSC_STD_V1_1) {
-            return Mono.just(new StdA1ClientVersion1.UriBuilder(ricConfig));
-        } else {
-            return Mono.just(new OscA1Client.UriBuilder(ricConfig));
-        }
-    }
-
-    private Mono<A1ProtocolType> tryOscProtocolVersion() {
-        OscA1Client.UriBuilder oscApiuriBuilder = new OscA1Client.UriBuilder(ricConfig);
-        return post(GET_POLICY_RPC, oscApiuriBuilder.createHealtcheckUri(), Optional.empty()) //
-            .flatMap(x -> Mono.just(A1ProtocolType.SDNC_OSC_OSC_V1));
-    }
-
-    private Mono<A1ProtocolType> tryStdProtocolVersion() {
-        StdA1ClientVersion1.UriBuilder uriBuilder = new StdA1ClientVersion1.UriBuilder(ricConfig);
-        return post(GET_POLICY_RPC, uriBuilder.createGetPolicyIdsUri(), Optional.empty()) //
-            .flatMap(x -> Mono.just(A1ProtocolType.SDNC_OSC_STD_V1_1));
-    }
-
-    private Flux<String> getPolicyIds() {
-        if (this.protocolType == A1ProtocolType.SDNC_OSC_STD_V1_1) {
-            StdA1ClientVersion1.UriBuilder uri = new StdA1ClientVersion1.UriBuilder(ricConfig);
-            final String ricUrl = uri.createGetPolicyIdsUri();
-            return post(GET_POLICY_RPC, ricUrl, Optional.empty()) //
-                .flatMapMany(SdncJsonHelper::parseJsonArrayOfString);
-        } else {
-            OscA1Client.UriBuilder uri = new OscA1Client.UriBuilder(ricConfig);
-            return getPolicyTypeIdentities() //
-                .flatMapMany(Flux::fromIterable)
-                .flatMap(type -> post(GET_POLICY_RPC, uri.createGetPolicyIdsUri(type), Optional.empty())) //
-                .flatMap(SdncJsonHelper::parseJsonArrayOfString);
-        }
-    }
-
-    private Mono<String> deletePolicyById(String type, String policyId) {
-        return getUriBuilder() //
-            .flatMap(builder -> {
-                String ricUrl = builder.createDeleteUri(type, policyId);
-                return post("deleteA1Policy", ricUrl, Optional.empty());
-            });
-    }
-
-    private Mono<String> post(String rpcName, String ricUrl, Optional<String> body) {
-        AdapterRequest inputParams = ImmutableAdapterRequest.builder() //
-            .nearRtRicUrl(ricUrl) //
-            .body(body) //
-            .build();
-        final String inputJsonString = SdncJsonHelper.createInputJsonString(inputParams);
-        logger.debug("POST inputJsonString = {}", inputJsonString);
-
-        return restClient
-            .postWithAuthHeader(controllerUrl(rpcName), inputJsonString, this.controllerConfig.userName(),
-                this.controllerConfig.password()) //
-            .flatMap(this::extractResponseBody);
-    }
-
-    private Mono<String> extractResponse(JSONObject responseOutput) {
-        AdapterOutput output = gson.fromJson(responseOutput.toString(), ImmutableAdapterOutput.class);
-        Optional<String> optionalBody = output.body();
-        String body = optionalBody.isPresent() ? optionalBody.get() : "";
-        if (HttpStatus.valueOf(output.httpStatus()).is2xxSuccessful()) {
-            return Mono.just(body);
-        } else {
-            logger.debug("Error response: {} {}", output.httpStatus(), body);
-            byte[] responseBodyBytes = body.getBytes(StandardCharsets.UTF_8);
-            WebClientResponseException responseException = new WebClientResponseException(output.httpStatus(),
-                "statusText", null, responseBodyBytes, StandardCharsets.UTF_8, null);
-
-            return Mono.error(responseException);
-        }
-    }
-
-    private Mono<String> extractResponseBody(String responseStr) {
-        return SdncJsonHelper.getOutput(responseStr) //
-            .flatMap(this::extractResponse);
-    }
-
-    private String controllerUrl(String rpcName) {
-        return "/A1-ADAPTER-API:" + rpcName;
-    }
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/StdA1ClientVersion1.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/StdA1ClientVersion1.java
deleted file mode 100644 (file)
index 4ebc25c..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.clients;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.oransc.policyagent.configuration.RicConfig;
-import org.oransc.policyagent.configuration.WebClientConfig;
-import org.oransc.policyagent.repository.Policy;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-/**
- * Client for accessing standard A1 REST API version 1.1
- */
-public class StdA1ClientVersion1 implements A1Client {
-
-    public static class UriBuilder implements A1UriBuilder {
-
-        private final RicConfig ricConfig;
-
-        public UriBuilder(RicConfig ricConfig) {
-            this.ricConfig = ricConfig;
-        }
-
-        /**
-         * /A1-P/v1/policies/{policyId}
-         */
-        @Override
-        public String createPutPolicyUri(String type, String policyId) {
-            return policiesBaseUri() + policyId;
-        }
-
-        /**
-         * /A1-P/v1/policies
-         */
-        public String createGetPolicyIdsUri() {
-            return baseUri() + "/policies";
-        }
-
-        /**
-         * /A1-P/v1/policies/{policyId}
-         */
-        @Override
-        public String createDeleteUri(String type, String policyId) {
-            return policiesBaseUri() + policyId;
-        }
-
-        /**
-         * /A1-P/v1/policies/{policyId}/status
-         */
-        public String createGetPolicyStatusUri(String type, String policyId) {
-            return policiesBaseUri() + policyId + "/status";
-        }
-
-        private String baseUri() {
-            return ricConfig.baseUrl() + "/A1-P/v1";
-        }
-
-        private String policiesBaseUri() {
-            return createGetPolicyIdsUri() + "/";
-        }
-    }
-
-    private final AsyncRestClient restClient;
-    private final UriBuilder uri;
-
-    public StdA1ClientVersion1(RicConfig ricConfig, WebClientConfig webClientConfig) {
-        this(new AsyncRestClient("", webClientConfig), ricConfig);
-    }
-
-    public StdA1ClientVersion1(AsyncRestClient restClient, RicConfig ricConfig) {
-        this.restClient = restClient;
-        this.uri = new UriBuilder(ricConfig);
-    }
-
-    @Override
-    public Mono<List<String>> getPolicyIdentities() {
-        return getPolicyIds() //
-            .collectList();
-    }
-
-    @Override
-    public Mono<String> putPolicy(Policy policy) {
-        return restClient.put(uri.createPutPolicyUri(policy.type().name(), policy.id()), policy.json());
-    }
-
-    @Override
-    public Mono<List<String>> getPolicyTypeIdentities() {
-        return Mono.just(Arrays.asList(""));
-    }
-
-    @Override
-    public Mono<String> getPolicyTypeSchema(String policyTypeId) {
-        return Mono.just("{}");
-    }
-
-    @Override
-    public Mono<String> deletePolicy(Policy policy) {
-        return deletePolicyById(policy.id());
-    }
-
-    @Override
-    public Flux<String> deleteAllPolicies() {
-        return getPolicyIds() //
-            .flatMap(this::deletePolicyById); //
-    }
-
-    @Override
-    public Mono<A1ProtocolType> getProtocolVersion() {
-        return getPolicyIdentities() //
-            .flatMap(x -> Mono.just(A1ProtocolType.STD_V1_1));
-    }
-
-    @Override
-    public Mono<String> getPolicyStatus(Policy policy) {
-        return restClient.get(uri.createGetPolicyStatusUri(policy.type().name(), policy.id()));
-    }
-
-    private Flux<String> getPolicyIds() {
-        return restClient.get(uri.createGetPolicyIdsUri()) //
-            .flatMapMany(SdncJsonHelper::parseJsonArrayOfString);
-    }
-
-    private Mono<String> deletePolicyById(String policyId) {
-        return restClient.delete(uri.createDeleteUri("", policyId));
-    }
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfig.java b/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfig.java
deleted file mode 100644 (file)
index 5e02098..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.configuration;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.validation.constraints.NotEmpty;
-
-import lombok.Getter;
-
-import org.oransc.policyagent.exceptions.ServiceException;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import reactor.core.publisher.Flux;
-
-@EnableConfigurationProperties
-@ConfigurationProperties()
-public class ApplicationConfig {
-    @NotEmpty
-    @Getter
-    @Value("${app.filepath}")
-    private String localConfigurationFilePath;
-
-    @Value("${server.ssl.key-store-type}")
-    private String sslKeyStoreType = "";
-
-    @Value("${server.ssl.key-store-password}")
-    private String sslKeyStorePassword = "";
-
-    @Value("${server.ssl.key-store}")
-    private String sslKeyStore = "";
-
-    @Value("${server.ssl.key-password}")
-    private String sslKeyPassword = "";
-
-    @Value("${app.webclient.trust-store-used}")
-    private boolean sslTrustStoreUsed = false;
-
-    @Value("${app.webclient.trust-store-password}")
-    private String sslTrustStorePassword = "";
-
-    @Value("${app.webclient.trust-store}")
-    private String sslTrustStore = "";
-
-    private Map<String, RicConfig> ricConfigs = new HashMap<>();
-
-    @Getter
-    private String dmaapConsumerTopicUrl;
-
-    @Getter
-    private String dmaapProducerTopicUrl;
-
-    private Map<String, ControllerConfig> controllerConfigs = new HashMap<>();
-
-    public synchronized Collection<RicConfig> getRicConfigs() {
-        return this.ricConfigs.values();
-    }
-
-    public WebClientConfig getWebClientConfig() {
-        return ImmutableWebClientConfig.builder() //
-            .keyStoreType(this.sslKeyStoreType) //
-            .keyStorePassword(this.sslKeyStorePassword) //
-            .keyStore(this.sslKeyStore) //
-            .keyPassword(this.sslKeyPassword) //
-            .isTrustStoreUsed(this.sslTrustStoreUsed) //
-            .trustStore(this.sslTrustStore) //
-            .trustStorePassword(this.sslTrustStorePassword) //
-            .build();
-    }
-
-    public synchronized ControllerConfig getControllerConfig(String name) throws ServiceException {
-        ControllerConfig controllerConfig = this.controllerConfigs.get(name);
-        if (controllerConfig == null) {
-            throw new ServiceException("Could not find controller config: " + name);
-        }
-        return controllerConfig;
-    }
-
-    public synchronized RicConfig getRic(String ricName) throws ServiceException {
-        RicConfig ricConfig = this.ricConfigs.get(ricName);
-        if (ricConfig == null) {
-            throw new ServiceException("Could not find ric configuration: " + ricName);
-        }
-        return ricConfig;
-    }
-
-    public static class RicConfigUpdate {
-        public enum Type {
-            ADDED, CHANGED, REMOVED
-        }
-
-        @Getter
-        private final RicConfig ricConfig;
-        @Getter
-        private final Type type;
-
-        RicConfigUpdate(RicConfig ric, Type event) {
-            this.ricConfig = ric;
-            this.type = event;
-        }
-    }
-
-    public synchronized Flux<RicConfigUpdate> setConfiguration(
-        ApplicationConfigParser.ConfigParserResult parserResult) {
-
-        Collection<RicConfigUpdate> modifications = new ArrayList<>();
-        this.controllerConfigs = parserResult.controllerConfigs();
-
-        this.dmaapConsumerTopicUrl = parserResult.dmaapConsumerTopicUrl();
-        this.dmaapProducerTopicUrl = parserResult.dmaapProducerTopicUrl();
-
-        Map<String, RicConfig> newRicConfigs = new HashMap<>();
-        for (RicConfig newConfig : parserResult.ricConfigs()) {
-            RicConfig oldConfig = this.ricConfigs.get(newConfig.name());
-            this.ricConfigs.remove(newConfig.name());
-            if (oldConfig == null) {
-                newRicConfigs.put(newConfig.name(), newConfig);
-                modifications.add(new RicConfigUpdate(newConfig, RicConfigUpdate.Type.ADDED));
-            } else if (!newConfig.equals(oldConfig)) {
-                modifications.add(new RicConfigUpdate(newConfig, RicConfigUpdate.Type.CHANGED));
-                newRicConfigs.put(newConfig.name(), newConfig);
-            } else {
-                newRicConfigs.put(oldConfig.name(), oldConfig);
-            }
-        }
-        for (RicConfig deletedConfig : this.ricConfigs.values()) {
-            modifications.add(new RicConfigUpdate(deletedConfig, RicConfigUpdate.Type.REMOVED));
-        }
-        this.ricConfigs = newRicConfigs;
-
-        return Flux.fromIterable(modifications);
-    }
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfigParser.java b/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfigParser.java
deleted file mode 100644 (file)
index 14e836b..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.configuration;
-
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import javax.validation.constraints.NotNull;
-
-import org.immutables.gson.Gson;
-import org.immutables.value.Value;
-import org.oransc.policyagent.exceptions.ServiceException;
-
-/**
- * Parser for the Json representing of the component configuration.
- */
-public class ApplicationConfigParser {
-
-    private static final String CONFIG = "config";
-    private static final String CONTROLLER = "controller";
-
-    @Value.Immutable
-    @Gson.TypeAdapters
-    public interface ConfigParserResult {
-        List<RicConfig> ricConfigs();
-
-        Map<String, ControllerConfig> controllerConfigs();
-
-        String dmaapConsumerTopicUrl();
-
-        String dmaapProducerTopicUrl();
-
-    }
-
-    public ConfigParserResult parse(JsonObject root) throws ServiceException {
-
-        String dmaapProducerTopicUrl = "";
-        String dmaapConsumerTopicUrl = "";
-
-        JsonObject agentConfigJson = root.getAsJsonObject(CONFIG);
-
-        if (agentConfigJson == null) {
-            throw new ServiceException("Missing root configuration \"" + CONFIG + "\" in JSON: " + root);
-        }
-
-        JsonObject json = agentConfigJson.getAsJsonObject("streams_publishes");
-        if (json != null) {
-            dmaapProducerTopicUrl = parseDmaapConfig(json);
-        }
-
-        json = agentConfigJson.getAsJsonObject("streams_subscribes");
-        if (json != null) {
-            dmaapConsumerTopicUrl = parseDmaapConfig(json);
-        }
-
-        List<RicConfig> ricConfigs = parseRics(agentConfigJson);
-        Map<String, ControllerConfig> controllerConfigs = parseControllerConfigs(agentConfigJson);
-        checkConfigurationConsistency(ricConfigs, controllerConfigs);
-
-        return ImmutableConfigParserResult.builder() //
-            .dmaapConsumerTopicUrl(dmaapConsumerTopicUrl) //
-            .dmaapProducerTopicUrl(dmaapProducerTopicUrl) //
-            .ricConfigs(ricConfigs) //
-            .controllerConfigs(controllerConfigs) //
-            .build();
-    }
-
-    private void checkConfigurationConsistency(List<RicConfig> ricConfigs,
-        Map<String, ControllerConfig> controllerConfigs) throws ServiceException {
-        Set<String> ricUrls = new HashSet<>();
-        Set<String> ricNames = new HashSet<>();
-        for (RicConfig ric : ricConfigs) {
-            if (!ricUrls.add(ric.baseUrl())) {
-                throw new ServiceException("Configuration error, more than one RIC URL: " + ric.baseUrl());
-            }
-            if (!ricNames.add(ric.name())) {
-                throw new ServiceException("Configuration error, more than one RIC with name: " + ric.name());
-            }
-            if (!ric.controllerName().isEmpty() && controllerConfigs.get(ric.controllerName()) == null) {
-                throw new ServiceException(
-                    "Configuration error, controller configuration not found: " + ric.controllerName());
-            }
-
-        }
-    }
-
-    private List<RicConfig> parseRics(JsonObject config) throws ServiceException {
-        List<RicConfig> result = new ArrayList<>();
-        for (JsonElement ricElem : getAsJsonArray(config, "ric")) {
-            JsonObject ricAsJson = ricElem.getAsJsonObject();
-            JsonElement controllerNameElement = ricAsJson.get(CONTROLLER);
-            ImmutableRicConfig ricConfig = ImmutableRicConfig.builder() //
-                .name(get(ricAsJson, "name").getAsString()) //
-                .baseUrl(get(ricAsJson, "baseUrl").getAsString()) //
-                .managedElementIds(parseManagedElementIds(get(ricAsJson, "managedElementIds").getAsJsonArray())) //
-                .controllerName(controllerNameElement != null ? controllerNameElement.getAsString() : "") //
-                .build();
-            result.add(ricConfig);
-        }
-        return result;
-    }
-
-    Map<String, ControllerConfig> parseControllerConfigs(JsonObject config) throws ServiceException {
-        if (config.get(CONTROLLER) == null) {
-            return new HashMap<>();
-        }
-        Map<String, ControllerConfig> result = new HashMap<>();
-        for (JsonElement element : getAsJsonArray(config, CONTROLLER)) {
-            JsonObject controllerAsJson = element.getAsJsonObject();
-            ImmutableControllerConfig controllerConfig = ImmutableControllerConfig.builder() //
-                .name(get(controllerAsJson, "name").getAsString()) //
-                .baseUrl(get(controllerAsJson, "baseUrl").getAsString()) //
-                .password(get(controllerAsJson, "password").getAsString()) //
-                .userName(get(controllerAsJson, "userName").getAsString()) // )
-                .build();
-
-            if (result.put(controllerConfig.name(), controllerConfig) != null) {
-                throw new ServiceException(
-                    "Configuration error, more than one controller with name: " + controllerConfig.name());
-            }
-        }
-        return result;
-    }
-
-    private List<String> parseManagedElementIds(JsonArray asJsonObject) {
-        Iterator<JsonElement> iterator = asJsonObject.iterator();
-        List<String> managedElementIds = new ArrayList<>();
-        while (iterator.hasNext()) {
-            managedElementIds.add(iterator.next().getAsString());
-
-        }
-        return managedElementIds;
-    }
-
-    private static JsonElement get(JsonObject obj, String memberName) throws ServiceException {
-        JsonElement elem = obj.get(memberName);
-        if (elem == null) {
-            throw new ServiceException("Could not find member: '" + memberName + "' in: " + obj);
-        }
-        return elem;
-    }
-
-    private JsonArray getAsJsonArray(JsonObject obj, String memberName) throws ServiceException {
-        return get(obj, memberName).getAsJsonArray();
-    }
-
-    private String parseDmaapConfig(JsonObject streamCfg) throws ServiceException {
-        Set<Entry<String, JsonElement>> streamConfigEntries = streamCfg.entrySet();
-        if (streamConfigEntries.size() != 1) {
-            throw new ServiceException(
-                "Invalid configuration. Number of streams must be one, config: " + streamConfigEntries);
-        }
-        JsonObject streamConfigEntry = streamConfigEntries.iterator().next().getValue().getAsJsonObject();
-        JsonObject dmaapInfo = get(streamConfigEntry, "dmaap_info").getAsJsonObject();
-        return getAsString(dmaapInfo, "topic_url");
-    }
-
-    private static @NotNull String getAsString(JsonObject obj, String memberName) throws ServiceException {
-        return get(obj, memberName).getAsString();
-    }
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/configuration/AsyncConfiguration.java b/policy-agent/src/main/java/org/oransc/policyagent/configuration/AsyncConfiguration.java
deleted file mode 100644 (file)
index 882f30c..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.configuration;
-
-import java.util.concurrent.Executor;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.scheduling.annotation.AsyncConfigurer;
-import org.springframework.scheduling.annotation.EnableAsync;
-import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
-
-@Configuration
-@EnableAsync
-public class AsyncConfiguration implements AsyncConfigurer {
-
-    @Override
-    @Bean(name = "threadPoolTaskExecutor")
-    public Executor getAsyncExecutor() {
-        // Set this configuration value from common properties file
-        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
-        executor.setCorePoolSize(5);
-        executor.setMaxPoolSize(10);
-        executor.setQueueCapacity(25);
-        return executor;
-    }
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/configuration/ControllerConfig.java b/policy-agent/src/main/java/org/oransc/policyagent/configuration/ControllerConfig.java
deleted file mode 100644 (file)
index fa88d14..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.configuration;
-
-import org.immutables.value.Value;
-
-@Value.Immutable
-@Value.Style(redactedMask = "####")
-
-public interface ControllerConfig {
-    public String name();
-
-    public String baseUrl();
-
-    public String userName();
-
-    @Value.Redacted
-    public String password();
-
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/configuration/WebClientConfig.java b/policy-agent/src/main/java/org/oransc/policyagent/configuration/WebClientConfig.java
deleted file mode 100644 (file)
index 7f0b233..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.configuration;
-
-import org.immutables.value.Value;
-
-@Value.Immutable
-@Value.Style(redactedMask = "####")
-public interface WebClientConfig {
-    public String keyStoreType();
-
-    @Value.Redacted
-    public String keyStorePassword();
-
-    public String keyStore();
-
-    @Value.Redacted
-    public String keyPassword();
-
-    public boolean isTrustStoreUsed();
-
-    @Value.Redacted
-    public String trustStorePassword();
-
-    public String trustStore();
-
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyController.java b/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyController.java
deleted file mode 100644 (file)
index d2ae0e0..0000000
+++ /dev/null
@@ -1,482 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.controllers;
-
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
-import io.swagger.annotations.ApiResponse;
-import io.swagger.annotations.ApiResponses;
-
-import java.lang.invoke.MethodHandles;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import lombok.Getter;
-
-import org.oransc.policyagent.clients.A1ClientFactory;
-import org.oransc.policyagent.exceptions.ServiceException;
-import org.oransc.policyagent.repository.ImmutablePolicy;
-import org.oransc.policyagent.repository.Lock.LockType;
-import org.oransc.policyagent.repository.Policies;
-import org.oransc.policyagent.repository.Policy;
-import org.oransc.policyagent.repository.PolicyType;
-import org.oransc.policyagent.repository.PolicyTypes;
-import org.oransc.policyagent.repository.Ric;
-import org.oransc.policyagent.repository.Rics;
-import org.oransc.policyagent.repository.Service;
-import org.oransc.policyagent.repository.Services;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.reactive.function.client.WebClientResponseException;
-import reactor.core.publisher.Mono;
-
-@RestController
-@Api(tags = "A1 Policy Management")
-public class PolicyController {
-
-    public static class RejectionException extends Exception {
-        private static final long serialVersionUID = 1L;
-        @Getter
-        private final HttpStatus status;
-
-        public RejectionException(String message, HttpStatus status) {
-            super(message);
-            this.status = status;
-        }
-    }
-
-    @Autowired
-    private Rics rics;
-    @Autowired
-    private PolicyTypes policyTypes;
-    @Autowired
-    private Policies policies;
-    @Autowired
-    private A1ClientFactory a1ClientFactory;
-    @Autowired
-    private Services services;
-
-    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-    private static Gson gson = new GsonBuilder() //
-        .serializeNulls() //
-        .create(); //
-
-    @GetMapping("/policy_schemas")
-    @ApiOperation(value = "Returns policy type schema definitions")
-    @ApiResponses(
-        value = {
-            @ApiResponse(code = 200, message = "Policy schemas", response = Object.class, responseContainer = "List"), //
-            @ApiResponse(code = 404, message = "RIC is not found", response = String.class)})
-    public ResponseEntity<String> getPolicySchemas( //
-        @ApiParam(name = "ric", required = false, value = "The name of the Near-RT RIC to get the definitions for.") //
-        @RequestParam(name = "ric", required = false) String ricName) {
-        if (ricName == null) {
-            Collection<PolicyType> types = this.policyTypes.getAll();
-            return new ResponseEntity<>(toPolicyTypeSchemasJson(types), HttpStatus.OK);
-        } else {
-            try {
-                Collection<PolicyType> types = rics.getRic(ricName).getSupportedPolicyTypes();
-                return new ResponseEntity<>(toPolicyTypeSchemasJson(types), HttpStatus.OK);
-            } catch (ServiceException e) {
-                return new ResponseEntity<>(e.toString(), HttpStatus.NOT_FOUND);
-            }
-        }
-    }
-
-    @GetMapping("/policy_schema")
-    @ApiOperation(value = "Returns one policy type schema definition")
-    @ApiResponses(
-        value = { //
-            @ApiResponse(code = 200, message = "Policy schema", response = Object.class),
-            @ApiResponse(code = 404, message = "RIC is not found", response = String.class)})
-    public ResponseEntity<String> getPolicySchema( //
-        @ApiParam(name = "id", required = true, value = "The ID of the policy type to get the definition for.") //
-        @RequestParam(name = "id", required = true) String id) {
-        try {
-            PolicyType type = policyTypes.getType(id);
-            return new ResponseEntity<>(type.schema(), HttpStatus.OK);
-        } catch (ServiceException e) {
-            return new ResponseEntity<>(e.toString(), HttpStatus.NOT_FOUND);
-        }
-    }
-
-    @GetMapping("/policy_types")
-    @ApiOperation(value = "Query policy type names")
-    @ApiResponses(
-        value = {
-            @ApiResponse(
-                code = 200,
-                message = "Policy type names",
-                response = String.class,
-                responseContainer = "List"),
-            @ApiResponse(code = 404, message = "RIC is not found", response = String.class)})
-    public ResponseEntity<String> getPolicyTypes( //
-        @ApiParam(name = "ric", required = false, value = "The name of the Near-RT RIC to get types for.") //
-        @RequestParam(name = "ric", required = false) String ricName) {
-        if (ricName == null) {
-            Collection<PolicyType> types = this.policyTypes.getAll();
-            return new ResponseEntity<>(toPolicyTypeIdsJson(types), HttpStatus.OK);
-        } else {
-            try {
-                Collection<PolicyType> types = rics.getRic(ricName).getSupportedPolicyTypes();
-                return new ResponseEntity<>(toPolicyTypeIdsJson(types), HttpStatus.OK);
-            } catch (ServiceException e) {
-                return new ResponseEntity<>(e.toString(), HttpStatus.NOT_FOUND);
-            }
-        }
-    }
-
-    @GetMapping("/policy")
-    @ApiOperation(value = "Returns a policy configuration") //
-    @ApiResponses(
-        value = { //
-            @ApiResponse(code = 200, message = "Policy found", response = Object.class), //
-            @ApiResponse(code = 404, message = "Policy is not found")} //
-    )
-    public ResponseEntity<String> getPolicy( //
-        @ApiParam(name = "id", required = true, value = "The ID of the policy instance.") //
-        @RequestParam(name = "id", required = true) String id) {
-        try {
-            Policy p = policies.getPolicy(id);
-            return new ResponseEntity<>(p.json(), HttpStatus.OK);
-        } catch (ServiceException e) {
-            return new ResponseEntity<>(e.getMessage(), HttpStatus.NOT_FOUND);
-        }
-    }
-
-    @DeleteMapping("/policy")
-    @ApiOperation(value = "Delete a policy", response = Object.class)
-    @ApiResponses(
-        value = { //
-            @ApiResponse(code = 204, message = "Policy deleted", response = Object.class),
-            @ApiResponse(code = 404, message = "Policy is not found", response = String.class),
-            @ApiResponse(code = 423, message = "RIC is not operational", response = String.class)})
-    public Mono<ResponseEntity<Object>> deletePolicy( //
-        @ApiParam(name = "id", required = true, value = "The ID of the policy instance.") //
-        @RequestParam(name = "id", required = true) String id) {
-        try {
-            Policy policy = policies.getPolicy(id);
-            keepServiceAlive(policy.ownerServiceName());
-            Ric ric = policy.ric();
-            return ric.getLock().lock(LockType.SHARED) //
-                .flatMap(notUsed -> assertRicStateIdle(ric)) //
-                .flatMap(notUsed -> a1ClientFactory.createA1Client(policy.ric())) //
-                .doOnNext(notUsed -> policies.remove(policy)) //
-                .flatMap(client -> client.deletePolicy(policy)) //
-                .doOnNext(notUsed -> ric.getLock().unlockBlocking()) //
-                .doOnError(notUsed -> ric.getLock().unlockBlocking()) //
-                .flatMap(notUsed -> Mono.just(new ResponseEntity<>(HttpStatus.NO_CONTENT)))
-                .onErrorResume(this::handleException);
-        } catch (ServiceException e) {
-            return Mono.just(new ResponseEntity<>(HttpStatus.NOT_FOUND));
-        }
-    }
-
-    @PutMapping(path = "/policy")
-    @ApiOperation(value = "Put a policy", response = String.class)
-    @ApiResponses(
-        value = { //
-            @ApiResponse(code = 201, message = "Policy created", response = Object.class), //
-            @ApiResponse(code = 200, message = "Policy updated", response = Object.class), //
-            @ApiResponse(code = 423, message = "RIC is not operational", response = String.class), //
-            @ApiResponse(code = 404, message = "RIC or policy type is not found", response = String.class) //
-        })
-    public Mono<ResponseEntity<Object>> putPolicy( //
-        @ApiParam(name = "type", required = false, value = "The name of the policy type.") //
-        @RequestParam(name = "type", required = false, defaultValue = "") String typeName, //
-        @ApiParam(name = "id", required = true, value = "The ID of the policy instance.") //
-        @RequestParam(name = "id", required = true) String instanceId, //
-        @ApiParam(name = "ric", required = true, value = "The name of the Near-RT RIC where the policy will be " + //
-            "created.") //
-        @RequestParam(name = "ric", required = true) String ricName, //
-        @ApiParam(name = "service", required = true, value = "The name of the service creating the policy.") //
-        @RequestParam(name = "service", required = true) String service, //
-        @ApiParam(name = "transient", required = false, value = "If the policy is transient or not (boolean " + //
-            "defaulted to false). A policy is transient if it will be forgotten when the service needs to " + //
-            "reconnect to the Near-RT RIC.") //
-        @RequestParam(name = "transient", required = false, defaultValue = "false") boolean isTransient, //
-        @RequestBody Object jsonBody) {
-
-        String jsonString = gson.toJson(jsonBody);
-        Ric ric = rics.get(ricName);
-        PolicyType type = policyTypes.get(typeName);
-        keepServiceAlive(service);
-        if (ric == null || type == null) {
-            return Mono.just(new ResponseEntity<>(HttpStatus.NOT_FOUND));
-        }
-        Policy policy = ImmutablePolicy.builder() //
-            .id(instanceId) //
-            .json(jsonString) //
-            .type(type) //
-            .ric(ric) //
-            .ownerServiceName(service) //
-            .lastModified(getTimeStampUtc()) //
-            .isTransient(isTransient) //
-            .build();
-
-        final boolean isCreate = this.policies.get(policy.id()) == null;
-
-        return ric.getLock().lock(LockType.SHARED) //
-            .flatMap(notUsed -> assertRicStateIdle(ric)) //
-            .flatMap(notUsed -> checkSupportedType(ric, type)) //
-            .flatMap(notUsed -> validateModifiedPolicy(policy)) //
-            .flatMap(notUsed -> a1ClientFactory.createA1Client(ric)) //
-            .flatMap(client -> client.putPolicy(policy)) //
-            .doOnNext(notUsed -> policies.put(policy)) //
-            .doOnNext(notUsed -> ric.getLock().unlockBlocking()) //
-            .doOnError(trowable -> ric.getLock().unlockBlocking()) //
-            .flatMap(notUsed -> Mono.just(new ResponseEntity<>(isCreate ? HttpStatus.CREATED : HttpStatus.OK))) //
-            .onErrorResume(this::handleException);
-    }
-
-    @SuppressWarnings({"unchecked"})
-    private <T> Mono<ResponseEntity<T>> createResponseEntity(String message, HttpStatus status) {
-        ResponseEntity<T> re = new ResponseEntity<>((T) message, status);
-        return Mono.just(re);
-    }
-
-    private <T> Mono<ResponseEntity<T>> handleException(Throwable throwable) {
-        if (throwable instanceof WebClientResponseException) {
-            WebClientResponseException e = (WebClientResponseException) throwable;
-            return createResponseEntity(e.getResponseBodyAsString(), e.getStatusCode());
-        } else if (throwable instanceof RejectionException) {
-            RejectionException e = (RejectionException) throwable;
-            return createResponseEntity(e.getMessage(), e.getStatus());
-        } else {
-            return createResponseEntity(throwable.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
-        }
-    }
-
-    private Mono<Object> validateModifiedPolicy(Policy policy) {
-        // Check that ric is not updated
-        Policy current = this.policies.get(policy.id());
-        if (current != null && !current.ric().name().equals(policy.ric().name())) {
-            RejectionException e = new RejectionException("Policy cannot change RIC, policyId: " + current.id() + //
-                ", RIC name: " + current.ric().name() + //
-                ", new name: " + policy.ric().name(), HttpStatus.CONFLICT);
-            logger.debug("Request rejected, {}", e.getMessage());
-            return Mono.error(e);
-        }
-        return Mono.just("OK");
-    }
-
-    private Mono<Object> checkSupportedType(Ric ric, PolicyType type) {
-        if (!ric.isSupportingType(type.name())) {
-            logger.debug("Request rejected, type not supported, RIC: {}", ric);
-            RejectionException e = new RejectionException(
-                "Type: " + type.name() + " not supported by RIC: " + ric.name(), HttpStatus.NOT_FOUND);
-            return Mono.error(e);
-        }
-        return Mono.just("OK");
-    }
-
-    private Mono<Object> assertRicStateIdle(Ric ric) {
-        if (ric.getState() == Ric.RicState.AVAILABLE) {
-            return Mono.just("OK");
-        } else {
-            logger.debug("Request rejected RIC not IDLE, ric: {}", ric);
-            RejectionException e = new RejectionException(
-                "Ric is not operational, RIC name: " + ric.name() + ", state: " + ric.getState(), HttpStatus.LOCKED);
-            return Mono.error(e);
-        }
-    }
-
-    @GetMapping("/policies")
-    @ApiOperation(value = "Query policies")
-    @ApiResponses(
-        value = {
-            @ApiResponse(code = 200, message = "Policies", response = PolicyInfo.class, responseContainer = "List"),
-            @ApiResponse(code = 404, message = "RIC or type not found", response = String.class)})
-    public ResponseEntity<String> getPolicies( //
-        @ApiParam(name = "type", required = false, value = "The name of the policy type to get policies for.") //
-        @RequestParam(name = "type", required = false) String type, //
-        @ApiParam(name = "ric", required = false, value = "The name of the Near-RT RIC to get policies for.") //
-        @RequestParam(name = "ric", required = false) String ric, //
-        @ApiParam(name = "service", required = false, value = "The name of the service to get policies for.") //
-        @RequestParam(name = "service", required = false) String service) //
-    {
-        if ((type != null && this.policyTypes.get(type) == null)) {
-            return new ResponseEntity<>("Policy type not found", HttpStatus.NOT_FOUND);
-        }
-        if ((ric != null && this.rics.get(ric) == null)) {
-            return new ResponseEntity<>("RIC not found", HttpStatus.NOT_FOUND);
-        }
-
-        String filteredPolicies = policiesToJson(filter(type, ric, service));
-        return new ResponseEntity<>(filteredPolicies, HttpStatus.OK);
-    }
-
-    @GetMapping("/policy_ids")
-    @ApiOperation(value = "Query policies, only IDs returned")
-    @ApiResponses(
-        value = {@ApiResponse(code = 200, message = "Policy ids", response = String.class, responseContainer = "List"),
-            @ApiResponse(code = 404, message = "RIC or type not found", response = String.class)})
-    public ResponseEntity<String> getPolicyIds( //
-        @ApiParam(name = "type", required = false, value = "The name of the policy type to get policies for.") //
-        @RequestParam(name = "type", required = false) String type, //
-        @ApiParam(name = "ric", required = false, value = "The name of the Near-RT RIC to get policies for.") //
-        @RequestParam(name = "ric", required = false) String ric, //
-        @ApiParam(name = "service", required = false, value = "The name of the service to get policies for.") //
-        @RequestParam(name = "service", required = false) String service) //
-    {
-        if ((type != null && this.policyTypes.get(type) == null)) {
-            return new ResponseEntity<>("Policy type not found", HttpStatus.NOT_FOUND);
-        }
-        if ((ric != null && this.rics.get(ric) == null)) {
-            return new ResponseEntity<>("RIC not found", HttpStatus.NOT_FOUND);
-        }
-
-        String policyIdsJson = toPolicyIdsJson(filter(type, ric, service));
-        return new ResponseEntity<>(policyIdsJson, HttpStatus.OK);
-    }
-
-    @GetMapping("/policy_status")
-    @ApiOperation(value = "Returns a policy status") //
-    @ApiResponses(
-        value = { //
-            @ApiResponse(code = 200, message = "Policy status", response = Object.class), //
-            @ApiResponse(code = 404, message = "Policy is not found", response = String.class)} //
-    )
-    public Mono<ResponseEntity<String>> getPolicyStatus( //
-        @ApiParam(name = "id", required = true, value = "The ID of the policy.") @RequestParam(
-            name = "id", //
-            required = true) String id) {
-        try {
-            Policy policy = policies.getPolicy(id);
-
-            return a1ClientFactory.createA1Client(policy.ric()) //
-                .flatMap(client -> client.getPolicyStatus(policy)) //
-                .flatMap(status -> Mono.just(new ResponseEntity<>(status, HttpStatus.OK)))
-                .onErrorResume(this::handleException);
-        } catch (ServiceException e) {
-            return Mono.just(new ResponseEntity<>(e.getMessage(), HttpStatus.NOT_FOUND));
-        }
-    }
-
-    private void keepServiceAlive(String name) {
-        Service s = this.services.get(name);
-        if (s != null) {
-            s.keepAlive();
-        }
-    }
-
-    private boolean include(String filter, String value) {
-        return filter == null || value.equals(filter);
-    }
-
-    private Collection<Policy> filter(Collection<Policy> collection, String type, String ric, String service) {
-        if (type == null && ric == null && service == null) {
-            return collection;
-        }
-        List<Policy> filtered = new ArrayList<>();
-        for (Policy p : collection) {
-            if (include(type, p.type().name()) && include(ric, p.ric().name())
-                && include(service, p.ownerServiceName())) {
-                filtered.add(p);
-            }
-        }
-        return filtered;
-    }
-
-    private Collection<Policy> filter(String type, String ric, String service) {
-        if (type != null) {
-            return filter(policies.getForType(type), null, ric, service);
-        } else if (service != null) {
-            return filter(policies.getForService(service), type, ric, null);
-        } else if (ric != null) {
-            return filter(policies.getForRic(ric), type, null, service);
-        } else {
-            return policies.getAll();
-        }
-    }
-
-    private String policiesToJson(Collection<Policy> policies) {
-        List<PolicyInfo> v = new ArrayList<>(policies.size());
-        for (Policy p : policies) {
-            PolicyInfo policyInfo = new PolicyInfo();
-            policyInfo.id = p.id();
-            policyInfo.json = fromJson(p.json());
-            policyInfo.ric = p.ric().name();
-            policyInfo.type = p.type().name();
-            policyInfo.service = p.ownerServiceName();
-            policyInfo.lastModified = p.lastModified();
-            if (!policyInfo.validate()) {
-                logger.error("BUG, all fields must be set");
-            }
-            v.add(policyInfo);
-        }
-        return gson.toJson(v);
-    }
-
-    private Object fromJson(String jsonStr) {
-        return gson.fromJson(jsonStr, Object.class);
-    }
-
-    private String toPolicyTypeSchemasJson(Collection<PolicyType> types) {
-        StringBuilder result = new StringBuilder();
-        result.append("[");
-        boolean first = true;
-        for (PolicyType t : types) {
-            if (!first) {
-                result.append(",");
-            }
-            first = false;
-            result.append(t.schema());
-        }
-        result.append("]");
-        return result.toString();
-    }
-
-    private String toPolicyTypeIdsJson(Collection<PolicyType> types) {
-        List<String> v = new ArrayList<>(types.size());
-        for (PolicyType t : types) {
-            v.add(t.name());
-        }
-        return gson.toJson(v);
-    }
-
-    private String toPolicyIdsJson(Collection<Policy> policies) {
-        List<String> v = new ArrayList<>(policies.size());
-        for (Policy p : policies) {
-            v.add(p.id());
-        }
-        return gson.toJson(v);
-    }
-
-    private String getTimeStampUtc() {
-        return java.time.Instant.now().toString();
-    }
-
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyInfo.java b/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyInfo.java
deleted file mode 100644 (file)
index d28ce02..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.controllers;
-
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-
-import org.immutables.gson.Gson;
-
-@Gson.TypeAdapters
-@ApiModel(value = "PolicyInfo")
-public class PolicyInfo {
-
-    @ApiModelProperty(value = "identity of the policy")
-    public String id;
-
-    @ApiModelProperty(value = "name of the policy type")
-    public String type;
-
-    @ApiModelProperty(value = "identity of the target Near-RT RIC")
-    public String ric;
-
-    @ApiModelProperty(value = "the configuration of the policy")
-    public Object json;
-
-    @ApiModelProperty(value = "the name of the service owning the policy")
-    public String service;
-
-    @ApiModelProperty(value = "timestamp, last modification time")
-    public String lastModified;
-
-    PolicyInfo() {
-    }
-
-    public boolean validate() {
-        return id != null && type != null && ric != null && json != null && service != null && lastModified != null;
-    }
-
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/controllers/RicInfo.java b/policy-agent/src/main/java/org/oransc/policyagent/controllers/RicInfo.java
deleted file mode 100644 (file)
index c75270e..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.controllers;
-
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-
-import java.util.Collection;
-
-import org.immutables.gson.Gson;
-
-@Gson.TypeAdapters
-@ApiModel(value = "RicInfo")
-class RicInfo {
-    @ApiModelProperty(value = "identity of the ric")
-    public final String ricName;
-
-    @ApiModelProperty(value = "O1 identities for managed entities")
-    public final Collection<String> managedElementIds;
-
-    @ApiModelProperty(value = "supported policy types")
-    public final Collection<String> policyTypes;
-
-    @ApiModelProperty(value = "state info")
-    public final String state;
-
-    RicInfo(String name, Collection<String> managedElementIds, Collection<String> policyTypes, String state) {
-        this.ricName = name;
-        this.managedElementIds = managedElementIds;
-        this.policyTypes = policyTypes;
-        this.state = state;
-    }
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/controllers/RicRepositoryController.java b/policy-agent/src/main/java/org/oransc/policyagent/controllers/RicRepositoryController.java
deleted file mode 100644 (file)
index c3e5800..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.controllers;
-
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
-import io.swagger.annotations.ApiResponse;
-import io.swagger.annotations.ApiResponses;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-import org.oransc.policyagent.repository.PolicyTypes;
-import org.oransc.policyagent.repository.Ric;
-import org.oransc.policyagent.repository.Rics;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
-@RestController
-@Api(tags = "RIC Repository")
-public class RicRepositoryController {
-
-    @Autowired
-    private Rics rics;
-
-    @Autowired
-    PolicyTypes types;
-
-    private static Gson gson = new GsonBuilder() //
-        .serializeNulls() //
-        .create(); //
-
-    /**
-     * Example: http://localhost:8081/rics?managedElementId=kista_1
-     */
-    @GetMapping("/ric")
-    @ApiOperation(value = "Returns the name of a RIC managing one Mananged Element")
-    @ApiResponses(
-        value = { //
-            @ApiResponse(code = 200, message = "RIC is found", response = String.class), //
-            @ApiResponse(code = 404, message = "RIC is not found", response = String.class) //
-        })
-    public ResponseEntity<String> getRic( //
-        @ApiParam(name = "managedElementId", required = true, value = "The ID of the Managed Element") //
-        @RequestParam(name = "managedElementId", required = true) String managedElementId) {
-        Optional<Ric> ric = this.rics.lookupRicForManagedElement(managedElementId);
-
-        if (ric.isPresent()) {
-            return new ResponseEntity<>(ric.get().name(), HttpStatus.OK);
-        } else {
-            return new ResponseEntity<>("No RIC found", HttpStatus.NOT_FOUND);
-        }
-    }
-
-    /**
-     * @return a Json array of all RIC data Example: http://localhost:8081/ric
-     */
-    @GetMapping("/rics")
-    @ApiOperation(value = "Query Near-RT RIC information")
-    @ApiResponses(
-        value = { //
-            @ApiResponse(code = 200, message = "OK", response = RicInfo.class, responseContainer = "List"), //
-            @ApiResponse(code = 404, message = "Policy type is not found", response = String.class)})
-    public ResponseEntity<String> getRics( //
-        @ApiParam(name = "policyType", required = false, value = "The name of the policy type") //
-        @RequestParam(name = "policyType", required = false) String supportingPolicyType) {
-        if ((supportingPolicyType != null) && (this.types.get(supportingPolicyType) == null)) {
-            return new ResponseEntity<>("Policy type not found", HttpStatus.NOT_FOUND);
-        }
-
-        List<RicInfo> result = new ArrayList<>();
-        for (Ric ric : rics.getRics()) {
-            if (supportingPolicyType == null || ric.isSupportingType(supportingPolicyType)) {
-                result.add(new RicInfo(ric.name(), ric.getManagedElementIds(), ric.getSupportedPolicyTypeNames(),
-                    ric.getState().toString()));
-            }
-        }
-
-        return new ResponseEntity<>(gson.toJson(result), HttpStatus.OK);
-    }
-
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceController.java b/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceController.java
deleted file mode 100644 (file)
index 8481830..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.controllers;
-
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
-import io.swagger.annotations.ApiResponse;
-import io.swagger.annotations.ApiResponses;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.time.Duration;
-import java.util.ArrayList;
-import java.util.Collection;
-
-import org.oransc.policyagent.exceptions.ServiceException;
-import org.oransc.policyagent.repository.Policies;
-import org.oransc.policyagent.repository.Policy;
-import org.oransc.policyagent.repository.Service;
-import org.oransc.policyagent.repository.Services;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
-@RestController
-@Api(tags = "Service registry and supervision")
-public class ServiceController {
-
-    private final Services services;
-    private final Policies policies;
-
-    private static Gson gson = new GsonBuilder() //
-        .create(); //
-
-    @Autowired
-    ServiceController(Services services, Policies policies) {
-        this.services = services;
-        this.policies = policies;
-    }
-
-    @GetMapping("/services")
-    @ApiOperation(value = "Returns service information")
-    @ApiResponses(
-        value = { //
-            @ApiResponse(code = 200, message = "OK", response = ServiceStatus.class, responseContainer = "List"), //
-            @ApiResponse(code = 404, message = "Service is not found", response = String.class)})
-    public ResponseEntity<String> getServices(//
-        @ApiParam(name = "name", required = false, value = "The name of the service") //
-        @RequestParam(name = "name", required = false) String name) {
-        if (name != null && this.services.get(name) == null) {
-            return new ResponseEntity<>("Service not found", HttpStatus.NOT_FOUND);
-        }
-
-        Collection<ServiceStatus> servicesStatus = new ArrayList<>();
-        for (Service s : this.services.getAll()) {
-            if (name == null || name.equals(s.getName())) {
-                servicesStatus.add(toServiceStatus(s));
-            }
-        }
-
-        String res = gson.toJson(servicesStatus);
-        return new ResponseEntity<>(res, HttpStatus.OK);
-    }
-
-    private ServiceStatus toServiceStatus(Service s) {
-        return new ServiceStatus(s.getName(), s.getKeepAliveInterval().toSeconds(), s.timeSinceLastPing().toSeconds(),
-            s.getCallbackUrl());
-    }
-
-    private void validateRegistrationInfo(ServiceRegistrationInfo registrationInfo)
-        throws ServiceException, MalformedURLException {
-        if (registrationInfo.serviceName.isEmpty()) {
-            throw new ServiceException("Missing mandatory parameter 'serviceName'");
-        }
-        if (registrationInfo.keepAliveIntervalSeconds < 0) {
-            throw new ServiceException("Keepalive interval shoul be greater or equal to 0");
-        }
-        if (!registrationInfo.callbackUrl.isEmpty()) {
-            new URL(registrationInfo.callbackUrl);
-        }
-    }
-
-    @ApiOperation(value = "Register a service")
-    @ApiResponses(
-        value = { //
-            @ApiResponse(code = 200, message = "Service updated", response = String.class),
-            @ApiResponse(code = 201, message = "Service created", response = String.class), //
-            @ApiResponse(code = 400, message = "The ServiceRegistrationInfo is not accepted", response = String.class)})
-    @PutMapping("/service")
-    public ResponseEntity<String> putService(//
-        @RequestBody ServiceRegistrationInfo registrationInfo) {
-        try {
-            validateRegistrationInfo(registrationInfo);
-            final boolean isCreate = this.services.get(registrationInfo.serviceName) == null;
-            this.services.put(toService(registrationInfo));
-            return new ResponseEntity<>("OK", isCreate ? HttpStatus.CREATED : HttpStatus.OK);
-        } catch (Exception e) {
-            return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
-        }
-    }
-
-    @ApiOperation(value = "Delete a service")
-    @ApiResponses(
-        value = { //
-            @ApiResponse(code = 204, message = "OK"),
-            @ApiResponse(code = 404, message = "Service not found", response = String.class)})
-    @DeleteMapping("/services")
-    public ResponseEntity<String> deleteService(//
-        @ApiParam(name = "name", required = true, value = "The name of the service") //
-        @RequestParam(name = "name", required = true) String serviceName) {
-        try {
-            Service service = removeService(serviceName);
-            // Remove the policies from the repo and let the consistency monitoring
-            // do the rest.
-            removePolicies(service);
-            return new ResponseEntity<>("OK", HttpStatus.NO_CONTENT);
-        } catch (Exception e) {
-            return new ResponseEntity<>(e.getMessage(), HttpStatus.NOT_FOUND);
-        }
-    }
-
-    @ApiOperation(value = "Heartbeat from a serice")
-    @ApiResponses(
-        value = { //
-            @ApiResponse(code = 200, message = "Service supervision timer refreshed, OK"),
-            @ApiResponse(code = 404, message = "The service is not found, needs re-registration")})
-    @PutMapping("/services/keepalive")
-    public ResponseEntity<String> keepAliveService(//
-        @ApiParam(name = "name", required = true, value = "The name of the service") //
-        @RequestParam(name = "name", required = true) String serviceName) {
-        try {
-            services.getService(serviceName).keepAlive();
-            return new ResponseEntity<>("OK", HttpStatus.OK);
-        } catch (ServiceException e) {
-            return new ResponseEntity<>(e.getMessage(), HttpStatus.NOT_FOUND);
-        }
-    }
-
-    private Service removeService(String name) throws ServiceException {
-        Service service = this.services.getService(name); // Just to verify that it exists
-        this.services.remove(service.getName());
-        return service;
-    }
-
-    private void removePolicies(Service service) {
-        Collection<Policy> policyList = this.policies.getForService(service.getName());
-        for (Policy policy : policyList) {
-            this.policies.remove(policy);
-        }
-    }
-
-    private Service toService(ServiceRegistrationInfo s) {
-        return new Service(s.serviceName, Duration.ofSeconds(s.keepAliveIntervalSeconds), s.callbackUrl);
-    }
-
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceRegistrationInfo.java b/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceRegistrationInfo.java
deleted file mode 100644 (file)
index 1194e25..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.controllers;
-
-import com.google.gson.annotations.SerializedName;
-
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-
-import org.immutables.gson.Gson;
-
-@Gson.TypeAdapters
-@ApiModel(value = "ServiceRegistrationInfo")
-public class ServiceRegistrationInfo {
-
-    @ApiModelProperty(value = "identity of the service", required = true, allowEmptyValue = false)
-    @SerializedName(value = "serviceName", alternate = {"name"})
-
-    public String serviceName = "";
-
-    @ApiModelProperty(
-        value = "keep alive interval for the service. This is a heartbeat supervision of the service, "
-            + "which in regular intevals must invoke a 'keepAlive' REST call. "
-            + "When a service does not invoke this call within the given time, it is considered unavailble. "
-            + "An unavailable service will be automatically deregistered and its policies will be deleted. "
-            + "Value 0 means no timeout supervision.")
-    @SerializedName("keepAliveIntervalSeconds")
-    public long keepAliveIntervalSeconds = 0;
-
-    @ApiModelProperty(value = "callback for notifying of RIC synchronization", required = false, allowEmptyValue = true)
-    @SerializedName("callbackUrl")
-    public String callbackUrl = "";
-
-    public ServiceRegistrationInfo() {
-    }
-
-    public ServiceRegistrationInfo(String name, long keepAliveIntervalSeconds, String callbackUrl) {
-        this.serviceName = name;
-        this.keepAliveIntervalSeconds = keepAliveIntervalSeconds;
-        this.callbackUrl = callbackUrl;
-    }
-
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceStatus.java b/policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceStatus.java
deleted file mode 100644 (file)
index 42be574..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.controllers;
-
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-
-import org.immutables.gson.Gson;
-
-@Gson.TypeAdapters
-@ApiModel(value = "ServiceStatus")
-public class ServiceStatus {
-
-    @ApiModelProperty(value = "identity of the service")
-    public final String serviceName;
-
-    @ApiModelProperty(value = "policy keep alive timeout")
-    public final long keepAliveIntervalSeconds;
-
-    @ApiModelProperty(value = "time since last invocation by the service")
-    public final long timeSinceLastActivitySeconds;
-
-    @ApiModelProperty(value = "callback for notifying of RIC synchronization")
-    public String callbackUrl;
-
-    ServiceStatus(String name, long keepAliveIntervalSeconds, long timeSincePingSeconds, String callbackUrl) {
-        this.serviceName = name;
-        this.keepAliveIntervalSeconds = keepAliveIntervalSeconds;
-        this.timeSinceLastActivitySeconds = timeSincePingSeconds;
-        this.callbackUrl = callbackUrl;
-    }
-
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/controllers/StatusController.java b/policy-agent/src/main/java/org/oransc/policyagent/controllers/StatusController.java
deleted file mode 100644 (file)
index c55d5be..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.controllers;
-
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiResponse;
-import io.swagger.annotations.ApiResponses;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RestController;
-import reactor.core.publisher.Mono;
-
-@RestController
-@Api(tags = "Health check")
-public class StatusController {
-
-    @GetMapping("/status")
-    @ApiOperation(value = "Returns status and statistics of this service")
-    @ApiResponses(
-        value = { //
-            @ApiResponse(code = 200, message = "Service is living", response = String.class) //
-        })
-    public Mono<ResponseEntity<String>> getStatus() {
-        return Mono.just(new ResponseEntity<>("hunky dory", HttpStatus.OK));
-    }
-
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapMessageConsumer.java b/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapMessageConsumer.java
deleted file mode 100644 (file)
index 0ee6213..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.dmaap;
-
-import com.google.common.collect.Iterables;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonParser;
-
-import java.time.Duration;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.oransc.policyagent.clients.AsyncRestClient;
-import org.oransc.policyagent.configuration.ApplicationConfig;
-import org.oransc.policyagent.exceptions.ServiceException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Component;
-
-/**
- * The class fetches incoming requests from DMAAP. It uses the timeout parameter
- * that lets the MessageRouter keep the connection with the Kafka open until
- * requests are sent in.
- *
- * <p>
- * this service will regularly check the configuration and start polling DMaaP
- * if the configuration is added. If the DMaaP configuration is removed, then
- * the service will stop polling and resume checking for configuration.
- *
- * <p>
- * Each received request is processed by {@link DmaapMessageHandler}.
- */
-@Component
-public class DmaapMessageConsumer {
-
-    protected static final Duration TIME_BETWEEN_DMAAP_RETRIES = Duration.ofSeconds(10);
-
-    private static final Logger logger = LoggerFactory.getLogger(DmaapMessageConsumer.class);
-
-    private final ApplicationConfig applicationConfig;
-
-    private DmaapMessageHandler dmaapMessageHandler = null;
-
-    @Value("${server.http-port}")
-    private int localServerHttpPort;
-
-    @Autowired
-    public DmaapMessageConsumer(ApplicationConfig applicationConfig) {
-        this.applicationConfig = applicationConfig;
-    }
-
-    /**
-     * Starts the consumer. If there is a DMaaP configuration, it will start polling
-     * for messages. Otherwise it will check regularly for the configuration.
-     *
-     * @return the running thread, for test purposes.
-     */
-    public Thread start() {
-        Thread thread = new Thread(this::messageHandlingLoop);
-        thread.start();
-        return thread;
-    }
-
-    private void messageHandlingLoop() {
-        while (!isStopped()) {
-            try {
-                if (isDmaapConfigured()) {
-                    Iterable<String> dmaapMsgs = fetchAllMessages();
-                    if (dmaapMsgs != null && Iterables.size(dmaapMsgs) > 0) {
-                        logger.debug("Fetched all the messages from DMAAP and will start to process the messages");
-                        for (String msg : dmaapMsgs) {
-                            processMsg(msg);
-                        }
-                    }
-                } else {
-                    sleep(TIME_BETWEEN_DMAAP_RETRIES); // wait for configuration
-                }
-            } catch (Exception e) {
-                logger.warn("{}", e.getMessage());
-                sleep(TIME_BETWEEN_DMAAP_RETRIES);
-            }
-        }
-    }
-
-    protected boolean isStopped() {
-        return false;
-    }
-
-    protected boolean isDmaapConfigured() {
-        String producerTopicUrl = applicationConfig.getDmaapProducerTopicUrl();
-        String consumerTopicUrl = applicationConfig.getDmaapConsumerTopicUrl();
-        return (!producerTopicUrl.isEmpty() && !consumerTopicUrl.isEmpty());
-    }
-
-    private static List<String> parseMessages(String jsonString) {
-        JsonArray arrayOfMessages = JsonParser.parseString(jsonString).getAsJsonArray();
-        List<String> result = new ArrayList<>();
-        for (JsonElement element : arrayOfMessages) {
-            if (element.isJsonPrimitive()) {
-                result.add(element.getAsString());
-            } else {
-                String messageAsString = element.toString();
-                result.add(messageAsString);
-            }
-        }
-        return result;
-    }
-
-    protected Iterable<String> fetchAllMessages() throws ServiceException {
-        String topicUrl = this.applicationConfig.getDmaapConsumerTopicUrl();
-        AsyncRestClient consumer = getMessageRouterConsumer();
-        ResponseEntity<String> response = consumer.getForEntity(topicUrl).block();
-        logger.debug("DMaaP consumer received {} : {}", response.getStatusCode(), response.getBody());
-        if (response.getStatusCode().is2xxSuccessful()) {
-            return parseMessages(response.getBody());
-        } else {
-            throw new ServiceException("Cannot fetch because of Error respons: " + response.getStatusCode().toString()
-                + " " + response.getBody());
-        }
-    }
-
-    private void processMsg(String msg) {
-        logger.debug("Message Reveived from DMAAP : {}", msg);
-        getDmaapMessageHandler().handleDmaapMsg(msg);
-    }
-
-    protected DmaapMessageHandler getDmaapMessageHandler() {
-        if (this.dmaapMessageHandler == null) {
-            String agentBaseUrl = "http://localhost:" + this.localServerHttpPort;
-            AsyncRestClient agentClient =
-                new AsyncRestClient(agentBaseUrl, this.applicationConfig.getWebClientConfig());
-            AsyncRestClient producer = new AsyncRestClient(this.applicationConfig.getDmaapProducerTopicUrl(),
-                this.applicationConfig.getWebClientConfig());
-            this.dmaapMessageHandler = new DmaapMessageHandler(producer, agentClient);
-        }
-        return this.dmaapMessageHandler;
-    }
-
-    protected void sleep(Duration duration) {
-        try {
-            Thread.sleep(duration.toMillis());
-        } catch (Exception e) {
-            logger.error("Failed to put the thread to sleep", e);
-        }
-    }
-
-    protected AsyncRestClient getMessageRouterConsumer() {
-        return new AsyncRestClient("", this.applicationConfig.getWebClientConfig());
-    }
-
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapMessageHandler.java b/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapMessageHandler.java
deleted file mode 100644 (file)
index 226b54e..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.dmaap;
-
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonObject;
-
-import java.util.Optional;
-
-import org.oransc.policyagent.clients.AsyncRestClient;
-import org.oransc.policyagent.dmaap.DmaapRequestMessage.Operation;
-import org.oransc.policyagent.exceptions.ServiceException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.reactive.function.client.WebClientException;
-import org.springframework.web.reactive.function.client.WebClientResponseException;
-import reactor.core.publisher.Mono;
-
-/**
- * The class handles incoming requests from DMAAP.
- * <p>
- * That means: invoke a REST call towards this services and to send back a response though DMAAP
- */
-public class DmaapMessageHandler {
-    private static final Logger logger = LoggerFactory.getLogger(DmaapMessageHandler.class);
-    private static Gson gson = new GsonBuilder() //
-        .create(); //
-    private final AsyncRestClient dmaapClient;
-    private final AsyncRestClient agentClient;
-
-    public DmaapMessageHandler(AsyncRestClient dmaapClient, AsyncRestClient agentClient) {
-        this.agentClient = agentClient;
-        this.dmaapClient = dmaapClient;
-    }
-
-    public void handleDmaapMsg(String msg) {
-        try {
-            String result = this.createTask(msg).block();
-            logger.debug("handleDmaapMsg: {}", result);
-        } catch (Exception throwable) {
-            logger.warn("handleDmaapMsg failure {}", throwable.getMessage());
-        }
-    }
-
-    Mono<String> createTask(String msg) {
-        try {
-            DmaapRequestMessage dmaapRequestMessage = gson.fromJson(msg, ImmutableDmaapRequestMessage.class);
-            return this.invokePolicyAgent(dmaapRequestMessage) //
-                .onErrorResume(t -> handleAgentCallError(t, dmaapRequestMessage)) //
-                .flatMap(
-                    response -> sendDmaapResponse(response.getBody(), dmaapRequestMessage, response.getStatusCode()));
-        } catch (Exception e) {
-            String errorMsg = "Received unparsable message from DMAAP: \"" + msg + "\", reason: " + e.getMessage();
-            return Mono.error(new ServiceException(errorMsg)); // Cannot make any response
-        }
-    }
-
-    private Mono<ResponseEntity<String>> handleAgentCallError(Throwable error,
-        DmaapRequestMessage dmaapRequestMessage) {
-        logger.debug("Agent call failed: {}", error.getMessage());
-        HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;
-        String errorMessage = error.getMessage();
-        if (error instanceof WebClientResponseException) {
-            WebClientResponseException exception = (WebClientResponseException) error;
-            status = exception.getStatusCode();
-            errorMessage = exception.getResponseBodyAsString();
-        } else if (error instanceof ServiceException) {
-            status = HttpStatus.BAD_REQUEST;
-            errorMessage = error.getMessage();
-        } else if (!(error instanceof WebClientException)) {
-            logger.warn("Unexpected exception ", error);
-        }
-        return sendDmaapResponse(errorMessage, dmaapRequestMessage, status) //
-            .flatMap(notUsed -> Mono.empty());
-    }
-
-    private Mono<ResponseEntity<String>> invokePolicyAgent(DmaapRequestMessage dmaapRequestMessage) {
-        DmaapRequestMessage.Operation operation = dmaapRequestMessage.operation();
-        String uri = dmaapRequestMessage.url();
-
-        if (operation == Operation.DELETE) {
-            return agentClient.deleteForEntity(uri);
-        } else if (operation == Operation.GET) {
-            return agentClient.getForEntity(uri);
-        } else if (operation == Operation.PUT) {
-            return agentClient.putForEntity(uri, payload(dmaapRequestMessage));
-        } else if (operation == Operation.POST) {
-            return agentClient.postForEntity(uri, payload(dmaapRequestMessage));
-        } else {
-            return Mono.error(new ServiceException("Not implemented operation: " + operation));
-        }
-    }
-
-    private String payload(DmaapRequestMessage message) {
-        Optional<JsonObject> payload = message.payload();
-        if (payload.isPresent()) {
-            return gson.toJson(payload.get());
-        } else {
-            logger.warn("Expected payload in message from DMAAP: {}", message);
-            return "";
-        }
-    }
-
-    private Mono<String> sendDmaapResponse(String response, DmaapRequestMessage dmaapRequestMessage,
-        HttpStatus status) {
-        return createDmaapResponseMessage(dmaapRequestMessage, response, status) //
-            .flatMap(this::sendToDmaap) //
-            .onErrorResume(this::handleResponseCallError);
-    }
-
-    private Mono<String> sendToDmaap(String body) {
-        logger.debug("sendToDmaap: {} ", body);
-        return dmaapClient.post("", "[" + body + "]");
-    }
-
-    private Mono<String> handleResponseCallError(Throwable t) {
-        logger.debug("Failed to send response to DMaaP: {}", t.getMessage());
-        return Mono.empty();
-    }
-
-    private Mono<String> createDmaapResponseMessage(DmaapRequestMessage dmaapRequestMessage, String response,
-        HttpStatus status) {
-        DmaapResponseMessage dmaapResponseMessage = ImmutableDmaapResponseMessage.builder() //
-            .status(status.toString()) //
-            .message(response == null ? "" : response) //
-            .type("response") //
-            .correlationId(dmaapRequestMessage.correlationId() == null ? "" : dmaapRequestMessage.correlationId()) //
-            .originatorId(dmaapRequestMessage.originatorId() == null ? "" : dmaapRequestMessage.originatorId()) //
-            .requestId(dmaapRequestMessage.requestId() == null ? "" : dmaapRequestMessage.requestId()) //
-            .timestamp(dmaapRequestMessage.timestamp() == null ? "" : dmaapRequestMessage.timestamp()) //
-            .build();
-        String str = gson.toJson(dmaapResponseMessage);
-        return Mono.just(str);
-
-    }
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapRequestMessage.java b/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapRequestMessage.java
deleted file mode 100644 (file)
index c2d0d4c..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.dmaap;
-
-import com.google.gson.JsonObject;
-
-import java.util.Optional;
-
-import org.immutables.gson.Gson;
-import org.immutables.value.Value;
-
-@Value.Immutable
-@Gson.TypeAdapters
-public interface DmaapRequestMessage {
-
-    public enum Operation {
-        PUT, GET, DELETE, POST
-    }
-
-    String correlationId();
-
-    String target();
-
-    String timestamp();
-
-    String apiVersion();
-
-    String originatorId();
-
-    String requestId();
-
-    Operation operation();
-
-    String url();
-
-    Optional<JsonObject> payload();
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapResponseMessage.java b/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapResponseMessage.java
deleted file mode 100644 (file)
index 35d67ff..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.dmaap;
-
-import org.immutables.gson.Gson;
-import org.immutables.value.Value;
-
-@Value.Immutable
-@Gson.TypeAdapters
-public interface DmaapResponseMessage {
-
-    String type();
-
-    String correlationId();
-
-    String timestamp();
-
-    String originatorId();
-
-    String requestId();
-
-    String status();
-
-    String message();
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/exceptions/ServiceException.java b/policy-agent/src/main/java/org/oransc/policyagent/exceptions/ServiceException.java
deleted file mode 100644 (file)
index c5b604e..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*-
- * ============LICENSE_START======================================================================
- * Copyright (C) 2019 Nordix Foundation. All rights reserved.
- * ===============================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END========================================================================
- */
-
-package org.oransc.policyagent.exceptions;
-
-public class ServiceException extends Exception {
-
-    private static final long serialVersionUID = 1L;
-
-    public ServiceException(String message) {
-        super(message);
-    }
-
-    public ServiceException(String message, Exception originalException) {
-        super(message, originalException);
-    }
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/repository/Lock.java b/policy-agent/src/main/java/org/oransc/policyagent/repository/Lock.java
deleted file mode 100644 (file)
index 716148f..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.repository;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import reactor.core.publisher.Mono;
-import reactor.core.publisher.MonoSink;
-
-/**
- * A resource lock. Exclusive means that the caller takes exclusive ownership of
- * the resurce. Non exclusive lock means that several users can lock the
- * resource (for shared usage).
- */
-public class Lock {
-    private static final Logger logger = LoggerFactory.getLogger(Lock.class);
-
-    private boolean isExclusive = false;
-    private int lockCounter = 0;
-    private final List<LockRequest> lockRequestQueue = new LinkedList<>();
-    private static AsynchCallbackExecutor callbackProcessor = new AsynchCallbackExecutor();
-
-    public enum LockType {
-        EXCLUSIVE, SHARED
-    }
-
-    /** The caller thread will be blocked util the lock is granted. */
-    public synchronized void lockBlocking(LockType locktype) {
-        while (!tryLock(locktype)) {
-            this.waitForUnlock();
-        }
-    }
-
-    /** Reactive version. The Lock will be emitted when the lock is granted */
-    public synchronized Mono<Lock> lock(LockType lockType) {
-        if (tryLock(lockType)) {
-            return Mono.just(this);
-        } else {
-            return Mono.create(monoSink -> addToQueue(monoSink, lockType));
-        }
-    }
-
-    public Mono<Lock> unlock() {
-        return Mono.create(monoSink -> {
-            unlockBlocking();
-            monoSink.success(this);
-        });
-    }
-
-    public synchronized void unlockBlocking() {
-        if (lockCounter <= 0) {
-            lockCounter = -1; // Might as well stop, to make it easier to find the problem
-            logger.error("Number of unlocks must match the number of locks");
-        }
-        this.lockCounter--;
-        if (lockCounter == 0) {
-            isExclusive = false;
-        }
-        this.notifyAll();
-        this.processQueuedEntries();
-    }
-
-    @Override
-    public synchronized String toString() {
-        return "Lock cnt: " + this.lockCounter + " exclusive: " + this.isExclusive + " queued: "
-            + this.lockRequestQueue.size();
-    }
-
-    /** returns the current number of granted locks */
-    public synchronized int getLockCounter() {
-        return this.lockCounter;
-    }
-
-    private void processQueuedEntries() {
-        List<LockRequest> granted = new ArrayList<>();
-        for (Iterator<LockRequest> i = lockRequestQueue.iterator(); i.hasNext();) {
-            LockRequest request = i.next();
-            if (tryLock(request.lockType)) {
-                i.remove();
-                granted.add(request);
-            }
-        }
-        callbackProcessor.addAll(granted);
-    }
-
-    private synchronized void addToQueue(MonoSink<Lock> callback, LockType lockType) {
-        lockRequestQueue.add(new LockRequest(callback, lockType, this));
-        processQueuedEntries();
-    }
-
-    @SuppressWarnings("java:S2274") // Always invoke wait() and await() methods inside a loop
-    private synchronized void waitForUnlock() {
-        try {
-            this.wait();
-        } catch (InterruptedException e) {
-            logger.warn("waitForUnlock interrupted", e);
-            Thread.currentThread().interrupt();
-        }
-    }
-
-    private boolean tryLock(LockType lockType) {
-        if (this.isExclusive) {
-            return false;
-        }
-        if (lockType == LockType.EXCLUSIVE && lockCounter > 0) {
-            return false;
-        }
-        lockCounter++;
-        this.isExclusive = lockType == LockType.EXCLUSIVE;
-        return true;
-    }
-
-    /**
-     * Represents a queued lock request
-     */
-    private static class LockRequest {
-        final MonoSink<Lock> callback;
-        final LockType lockType;
-        final Lock lock;
-
-        LockRequest(MonoSink<Lock> callback, LockType lockType, Lock lock) {
-            this.callback = callback;
-            this.lockType = lockType;
-            this.lock = lock;
-        }
-    }
-
-    /**
-     * A separate thread that calls a MonoSink to continue. This is done after a
-     * queued lock is granted.
-     */
-    private static class AsynchCallbackExecutor implements Runnable {
-        private List<LockRequest> lockRequestQueue = new LinkedList<>();
-
-        public AsynchCallbackExecutor() {
-            Thread thread = new Thread(this);
-            thread.start();
-        }
-
-        public synchronized void addAll(List<LockRequest> requests) {
-            this.lockRequestQueue.addAll(requests);
-            this.notifyAll();
-        }
-
-        @Override
-        public void run() {
-            try {
-                while (true) {
-                    for (LockRequest request : consume()) {
-                        request.callback.success(request.lock);
-                    }
-                    waitForNewEntries();
-                }
-            } catch (InterruptedException e) {
-                Thread.currentThread().interrupt();
-                logger.error("Interrupted {}", e.getMessage());
-            }
-        }
-
-        private synchronized List<LockRequest> consume() {
-            List<LockRequest> q = this.lockRequestQueue;
-            this.lockRequestQueue = new LinkedList<>();
-            return q;
-        }
-
-        @SuppressWarnings("java:S2274")
-        private synchronized void waitForNewEntries() throws InterruptedException {
-            if (this.lockRequestQueue.isEmpty()) {
-                this.wait();
-            }
-        }
-    }
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/repository/Policies.java b/policy-agent/src/main/java/org/oransc/policyagent/repository/Policies.java
deleted file mode 100644 (file)
index 4e2ebfa..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.repository;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.Vector;
-
-import org.oransc.policyagent.exceptions.ServiceException;
-
-public class Policies {
-    private Map<String, Policy> policiesId = new HashMap<>();
-    private Map<String, Map<String, Policy>> policiesRic = new HashMap<>();
-    private Map<String, Map<String, Policy>> policiesService = new HashMap<>();
-    private Map<String, Map<String, Policy>> policiesType = new HashMap<>();
-
-    public synchronized void put(Policy policy) {
-        policiesId.put(policy.id(), policy);
-        multiMapPut(policiesRic, policy.ric().name(), policy);
-        multiMapPut(policiesService, policy.ownerServiceName(), policy);
-        multiMapPut(policiesType, policy.type().name(), policy);
-    }
-
-    private void multiMapPut(Map<String, Map<String, Policy>> multiMap, String key, Policy value) {
-        multiMap.computeIfAbsent(key, k -> new HashMap<>()).put(value.id(), value);
-    }
-
-    private void multiMapRemove(Map<String, Map<String, Policy>> multiMap, String key, Policy value) {
-        Map<String, Policy> map = multiMap.get(key);
-        if (map != null) {
-            map.remove(value.id());
-            if (map.isEmpty()) {
-                multiMap.remove(key);
-            }
-        }
-    }
-
-    private Collection<Policy> multiMapGet(Map<String, Map<String, Policy>> multiMap, String key) {
-        Map<String, Policy> map = multiMap.get(key);
-        if (map == null) {
-            return Collections.emptyList();
-        }
-        return new Vector<>(map.values());
-    }
-
-    public synchronized boolean containsPolicy(String id) {
-        return policiesId.containsKey(id);
-    }
-
-    public synchronized Policy get(String id) {
-        return policiesId.get(id);
-    }
-
-    public synchronized Policy getPolicy(String id) throws ServiceException {
-        Policy p = policiesId.get(id);
-        if (p == null) {
-            throw new ServiceException("Could not find policy: " + id);
-        }
-        return p;
-    }
-
-    public synchronized Collection<Policy> getAll() {
-        return new Vector<>(policiesId.values());
-    }
-
-    public synchronized Collection<Policy> getForService(String service) {
-        return multiMapGet(policiesService, service);
-    }
-
-    public synchronized Collection<Policy> getForRic(String ric) {
-        return multiMapGet(policiesRic, ric);
-    }
-
-    public synchronized Collection<Policy> getForType(String type) {
-        return multiMapGet(policiesType, type);
-    }
-
-    public synchronized Policy removeId(String id) {
-        Policy p = policiesId.get(id);
-        if (p != null) {
-            remove(p);
-        }
-        return p;
-    }
-
-    public synchronized void remove(Policy policy) {
-        policiesId.remove(policy.id());
-        multiMapRemove(policiesRic, policy.ric().name(), policy);
-        multiMapRemove(policiesService, policy.ownerServiceName(), policy);
-        multiMapRemove(policiesType, policy.type().name(), policy);
-    }
-
-    public synchronized void removePoliciesForRic(String ricName) {
-        Collection<Policy> policiesForRic = getForRic(ricName);
-        for (Policy policy : policiesForRic) {
-            remove(policy);
-        }
-    }
-
-    public synchronized int size() {
-        return policiesId.size();
-    }
-
-    public synchronized void clear() {
-        while (policiesId.size() > 0) {
-            Set<String> keys = policiesId.keySet();
-            removeId(keys.iterator().next());
-        }
-    }
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/repository/Policy.java b/policy-agent/src/main/java/org/oransc/policyagent/repository/Policy.java
deleted file mode 100644 (file)
index e96d250..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.repository;
-
-import org.immutables.gson.Gson;
-import org.immutables.value.Value;
-
-@Value.Immutable
-@Gson.TypeAdapters
-public interface Policy {
-    public String id();
-
-    public String json();
-
-    public String ownerServiceName();
-
-    public Ric ric();
-
-    public PolicyType type();
-
-    public String lastModified();
-
-    public boolean isTransient();
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/repository/PolicyType.java b/policy-agent/src/main/java/org/oransc/policyagent/repository/PolicyType.java
deleted file mode 100644 (file)
index 41b9498..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.repository;
-
-import org.immutables.gson.Gson;
-import org.immutables.value.Value;
-
-@Value.Immutable
-@Gson.TypeAdapters
-public interface PolicyType {
-    public String name();
-
-    public String schema();
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/repository/PolicyTypes.java b/policy-agent/src/main/java/org/oransc/policyagent/repository/PolicyTypes.java
deleted file mode 100644 (file)
index 2897a50..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.repository;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Vector;
-
-import org.oransc.policyagent.exceptions.ServiceException;
-
-public class PolicyTypes {
-    private Map<String, PolicyType> types = new HashMap<>();
-
-    public synchronized PolicyType getType(String name) throws ServiceException {
-        PolicyType t = types.get(name);
-        if (t == null) {
-            throw new ServiceException("Could not find type: " + name);
-        }
-        return t;
-    }
-
-    public synchronized PolicyType get(String name) {
-        return types.get(name);
-    }
-
-    public synchronized void put(PolicyType type) {
-        types.put(type.name(), type);
-    }
-
-    public synchronized boolean contains(String policyType) {
-        return types.containsKey(policyType);
-    }
-
-    public synchronized Collection<PolicyType> getAll() {
-        return new Vector<>(types.values());
-    }
-
-    public synchronized int size() {
-        return types.size();
-    }
-
-    public synchronized void clear() {
-        this.types.clear();
-    }
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/repository/Ric.java b/policy-agent/src/main/java/org/oransc/policyagent/repository/Ric.java
deleted file mode 100644 (file)
index fb2e4b9..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.repository;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Vector;
-
-import lombok.Getter;
-import lombok.Setter;
-
-import org.oransc.policyagent.clients.A1Client.A1ProtocolType;
-import org.oransc.policyagent.configuration.RicConfig;
-
-/**
- * Represents the dynamic information about a Near-RT RIC.
- */
-public class Ric {
-
-    @Setter
-    private RicConfig ricConfig;
-    private RicState state = RicState.UNAVAILABLE;
-    private Map<String, PolicyType> supportedPolicyTypes = new HashMap<>();
-    @Getter
-    @Setter
-    private A1ProtocolType protocolVersion = A1ProtocolType.UNKNOWN;
-
-    @Getter
-    private final Lock lock = new Lock();
-
-    /**
-     * Creates the Ric. Initial state is {@link RicState.UNDEFINED}.
-     *
-     * @param ricConfig The {@link RicConfig} for this Ric.
-     */
-    public Ric(RicConfig ricConfig) {
-        this.ricConfig = ricConfig;
-    }
-
-    public String name() {
-        return ricConfig.name();
-    }
-
-    public RicConfig getConfig() {
-        return this.ricConfig;
-    }
-
-    public synchronized RicState getState() {
-        return this.state;
-    }
-
-    public synchronized void setState(RicState state) {
-        this.state = state;
-    }
-
-    /**
-     * Gets the nodes managed by this Ric.
-     *
-     * @return a vector containing the nodes managed by this Ric.
-     */
-    public synchronized Collection<String> getManagedElementIds() {
-        return ricConfig.managedElementIds();
-    }
-
-    /**
-     * Determines if the given node is managed by this Ric.
-     *
-     * @param managedElementId the node name to check.
-     * @return true if the given node is managed by this Ric.
-     */
-    public synchronized boolean isManaging(String managedElementId) {
-        return ricConfig.managedElementIds().contains(managedElementId);
-    }
-
-    /**
-     * Gets the policy types supported by this Ric.
-     *
-     * @return the policy types supported by this Ric in an unmodifiable list.
-     */
-    public synchronized Collection<PolicyType> getSupportedPolicyTypes() {
-        return new Vector<>(supportedPolicyTypes.values());
-    }
-
-    public synchronized Collection<String> getSupportedPolicyTypeNames() {
-        return new Vector<>(supportedPolicyTypes.keySet());
-    }
-
-    /**
-     * Adds a policy type as supported by this Ric.
-     *
-     * @param type the policy type to support.
-     */
-    public synchronized void addSupportedPolicyType(PolicyType type) {
-        supportedPolicyTypes.put(type.name(), type);
-    }
-
-    /**
-     * Removes all policy type as supported by this Ric.
-     */
-    public synchronized void clearSupportedPolicyTypes() {
-        supportedPolicyTypes.clear();
-    }
-
-    /**
-     * Checks if a type is supported by this Ric.
-     *
-     * @param typeName the name of the type to check if it is supported.
-     *
-     * @return true if the given type is supported by this Ric, false otherwise.
-     */
-    public synchronized boolean isSupportingType(String typeName) {
-        return supportedPolicyTypes.containsKey(typeName);
-    }
-
-    @Override
-    public synchronized String toString() {
-        return Ric.class.getSimpleName() + ": " + "name: " + name() + ", state: " + state + ", baseUrl: "
-            + ricConfig.baseUrl() + ", managedNodes: " + ricConfig.managedElementIds();
-    }
-
-    /**
-     * Represents the states possible for a Ric.
-     */
-    public enum RicState {
-        /**
-         * The agent view of the Ric may be inconsistent.
-         */
-        UNAVAILABLE,
-        /**
-         * The normal state. Policies can be configured.
-         */
-        AVAILABLE,
-        /**
-         * The agent is synchronizing the view of the Ric.
-         */
-        SYNCHRONIZING,
-
-        /**
-         * A consistency check between the agent and the Ric is done
-         */
-        CONSISTENCY_CHECK
-    }
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/repository/Rics.java b/policy-agent/src/main/java/org/oransc/policyagent/repository/Rics.java
deleted file mode 100644 (file)
index 7faa376..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.repository;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Vector;
-
-import org.oransc.policyagent.exceptions.ServiceException;
-
-/**
- * Dynamic representation of all Rics in the system.
- */
-public class Rics {
-    Map<String, Ric> registeredRics = new HashMap<>();
-
-    public synchronized void put(Ric ric) {
-        registeredRics.put(ric.name(), ric);
-    }
-
-    public synchronized Collection<Ric> getRics() {
-        return new Vector<>(registeredRics.values());
-    }
-
-    public synchronized Ric getRic(String name) throws ServiceException {
-        Ric ric = registeredRics.get(name);
-        if (ric == null) {
-            throw new ServiceException("Could not find ric: " + name);
-        }
-        return ric;
-    }
-
-    public synchronized Ric get(String name) {
-        return registeredRics.get(name);
-    }
-
-    public synchronized void remove(String name) {
-        registeredRics.remove(name);
-    }
-
-    public synchronized int size() {
-        return registeredRics.size();
-    }
-
-    public synchronized void clear() {
-        this.registeredRics.clear();
-    }
-
-    public synchronized Optional<Ric> lookupRicForManagedElement(String managedElementId) {
-        for (Ric ric : this.registeredRics.values()) {
-            if (ric.getManagedElementIds().contains(managedElementId)) {
-                return Optional.of(ric);
-            }
-        }
-        return Optional.empty();
-    }
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/repository/Service.java b/policy-agent/src/main/java/org/oransc/policyagent/repository/Service.java
deleted file mode 100644 (file)
index 7b2c9bd..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.repository;
-
-import java.time.Duration;
-import java.time.Instant;
-
-import lombok.Getter;
-
-public class Service {
-    @Getter
-    private final String name;
-    private final Duration keepAliveInterval;
-    private Instant lastPing;
-    private final String callbackUrl;
-
-    public Service(String name, Duration keepAliveInterval, String callbackUrl) {
-        this.name = name;
-        this.keepAliveInterval = keepAliveInterval;
-        this.callbackUrl = callbackUrl;
-        keepAlive();
-    }
-
-    public synchronized Duration getKeepAliveInterval() {
-        return this.keepAliveInterval;
-    }
-
-    public synchronized void keepAlive() {
-        this.lastPing = Instant.now();
-    }
-
-    public synchronized boolean isExpired() {
-        return this.keepAliveInterval.getSeconds() > 0 && timeSinceLastPing().compareTo(this.keepAliveInterval) > 0;
-    }
-
-    public synchronized Duration timeSinceLastPing() {
-        return Duration.between(this.lastPing, Instant.now());
-    }
-
-    public synchronized String getCallbackUrl() {
-        return this.callbackUrl;
-    }
-
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/repository/Services.java b/policy-agent/src/main/java/org/oransc/policyagent/repository/Services.java
deleted file mode 100644 (file)
index 1c0e15a..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.repository;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Vector;
-
-import org.oransc.policyagent.exceptions.ServiceException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class Services {
-    private static final Logger logger = LoggerFactory.getLogger(Services.class);
-
-    private Map<String, Service> registeredServices = new HashMap<>();
-
-    public synchronized Service getService(String name) throws ServiceException {
-        Service s = registeredServices.get(name);
-        if (s == null) {
-            throw new ServiceException("Could not find service: " + name);
-        }
-        return s;
-    }
-
-    public synchronized Service get(String name) {
-        return registeredServices.get(name);
-    }
-
-    public synchronized void put(Service service) {
-        logger.debug("Put service: {}", service.getName());
-        service.keepAlive();
-        registeredServices.put(service.getName(), service);
-    }
-
-    public synchronized Iterable<Service> getAll() {
-        return new Vector<>(registeredServices.values());
-    }
-
-    public synchronized void remove(String name) {
-        registeredServices.remove(name);
-    }
-
-    public synchronized int size() {
-        return registeredServices.size();
-    }
-
-    public synchronized void clear() {
-        registeredServices.clear();
-    }
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/tasks/EnvironmentProcessor.java b/policy-agent/src/main/java/org/oransc/policyagent/tasks/EnvironmentProcessor.java
deleted file mode 100644 (file)
index afb273d..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.tasks;
-
-import java.util.Optional;
-import java.util.Properties;
-
-import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.EnvProperties;
-import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.ImmutableEnvProperties;
-import org.oransc.policyagent.exceptions.EnvironmentLoaderException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import reactor.core.publisher.Mono;
-
-/**
- * This class reads a few environment variables used for locating the Consul
- * (Config Binding Service).
- */
-class EnvironmentProcessor {
-
-    private static final int DEFAULT_CONSUL_PORT = 8500;
-    private static final Logger logger = LoggerFactory.getLogger(EnvironmentProcessor.class);
-
-    private EnvironmentProcessor() {
-    }
-
-    static Mono<EnvProperties> readEnvironmentVariables(Properties systemEnvironment) {
-
-        EnvProperties envProperties;
-        try {
-            envProperties = ImmutableEnvProperties.builder() //
-                .consulHost(getConsulHost(systemEnvironment)) //
-                .consulPort(getConsultPort(systemEnvironment)) //
-                .cbsName(getConfigBindingService(systemEnvironment)) //
-                .appName(getService(systemEnvironment)) //
-                .build();
-        } catch (EnvironmentLoaderException e) {
-            return Mono.error(e);
-        }
-        logger.trace("Evaluated environment system variables {}", envProperties);
-        return Mono.just(envProperties);
-    }
-
-    private static String getConsulHost(Properties systemEnvironments) throws EnvironmentLoaderException {
-        return Optional.ofNullable(systemEnvironments.getProperty("CONSUL_HOST"))
-            .orElseThrow(() -> new EnvironmentLoaderException("$CONSUL_HOST environment has not been defined"));
-    }
-
-    private static Integer getConsultPort(Properties systemEnvironments) {
-        return Optional.ofNullable(systemEnvironments.getProperty("CONSUL_PORT")) //
-            .map(Integer::valueOf) //
-            .orElseGet(EnvironmentProcessor::getDefaultPortOfConsul);
-    }
-
-    private static String getConfigBindingService(Properties systemEnvironments) throws EnvironmentLoaderException {
-        return Optional.ofNullable(systemEnvironments.getProperty("CONFIG_BINDING_SERVICE")) //
-            .orElseThrow(
-                () -> new EnvironmentLoaderException("$CONFIG_BINDING_SERVICE environment has not been defined"));
-    }
-
-    private static String getService(Properties systemEnvironments) throws EnvironmentLoaderException {
-        return Optional
-            .ofNullable(Optional.ofNullable(systemEnvironments.getProperty("HOSTNAME"))
-                .orElse(systemEnvironments.getProperty("SERVICE_NAME")))
-            .orElseThrow(() -> new EnvironmentLoaderException(
-                "Neither $HOSTNAME/$SERVICE_NAME have not been defined as system environment"));
-    }
-
-    private static Integer getDefaultPortOfConsul() {
-        logger.warn("$CONSUL_PORT variable will be set to default port {}", DEFAULT_CONSUL_PORT);
-        return DEFAULT_CONSUL_PORT;
-    }
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/tasks/RefreshConfigTask.java b/policy-agent/src/main/java/org/oransc/policyagent/tasks/RefreshConfigTask.java
deleted file mode 100644 (file)
index b99a230..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.tasks;
-
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import com.google.gson.TypeAdapterFactory;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.time.Duration;
-import java.util.Properties;
-import java.util.ServiceLoader;
-
-import javax.validation.constraints.NotNull;
-
-import lombok.AccessLevel;
-import lombok.Getter;
-
-import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.CbsClient;
-import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.CbsClientFactory;
-import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.CbsRequests;
-import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.CbsRequest;
-import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.EnvProperties;
-import org.onap.dcaegen2.services.sdk.rest.services.model.logging.RequestDiagnosticContext;
-import org.oransc.policyagent.clients.A1ClientFactory;
-import org.oransc.policyagent.configuration.ApplicationConfig;
-import org.oransc.policyagent.configuration.ApplicationConfig.RicConfigUpdate;
-import org.oransc.policyagent.configuration.ApplicationConfigParser;
-import org.oransc.policyagent.configuration.RicConfig;
-import org.oransc.policyagent.repository.Policies;
-import org.oransc.policyagent.repository.PolicyTypes;
-import org.oransc.policyagent.repository.Ric;
-import org.oransc.policyagent.repository.Rics;
-import org.oransc.policyagent.repository.Services;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-import reactor.core.Disposable;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-/**
- * Regularly refreshes the configuration from Consul or from a local configuration file.
- */
-@Component
-public class RefreshConfigTask {
-
-    private static final Logger logger = LoggerFactory.getLogger(RefreshConfigTask.class);
-
-    @Value("#{systemEnvironment}")
-    public Properties systemEnvironment;
-
-    /**
-     * The time between refreshes of the configuration.
-     */
-    static final Duration CONFIG_REFRESH_INTERVAL = Duration.ofMinutes(1);
-
-    final ApplicationConfig appConfig;
-    @Getter(AccessLevel.PROTECTED)
-    private Disposable refreshTask = null;
-    private boolean isConsulUsed = false;
-
-    private final Rics rics;
-    private final A1ClientFactory a1ClientFactory;
-    private final Policies policies;
-    private final Services services;
-    private final PolicyTypes policyTypes;
-
-    @Autowired
-    public RefreshConfigTask(ApplicationConfig appConfig, Rics rics, Policies policies, Services services,
-        PolicyTypes policyTypes, A1ClientFactory a1ClientFactory) {
-        this.appConfig = appConfig;
-        this.rics = rics;
-        this.policies = policies;
-        this.services = services;
-        this.policyTypes = policyTypes;
-        this.a1ClientFactory = a1ClientFactory;
-    }
-
-    public void start() {
-        logger.debug("Starting refreshConfigTask");
-        stop();
-        refreshTask = createRefreshTask() //
-            .subscribe(notUsed -> logger.debug("Refreshed configuration data"),
-                throwable -> logger.error("Configuration refresh terminated due to exception {}", throwable.toString()),
-                () -> logger.error("Configuration refresh terminated"));
-    }
-
-    public void stop() {
-        if (refreshTask != null) {
-            refreshTask.dispose();
-        }
-    }
-
-    Flux<RicConfigUpdate.Type> createRefreshTask() {
-        Flux<JsonObject> loadFromFile = Flux.interval(Duration.ZERO, CONFIG_REFRESH_INTERVAL) //
-            .filter(notUsed -> !this.isConsulUsed) //
-            .flatMap(notUsed -> loadConfigurationFromFile()) //
-            .onErrorResume(this::ignoreErrorFlux) //
-            .doOnNext(json -> logger.debug("loadFromFile succeeded")) //
-            .doOnTerminate(() -> logger.error("loadFromFile Terminate"));
-
-        Flux<JsonObject> loadFromConsul = Flux.interval(Duration.ZERO, CONFIG_REFRESH_INTERVAL) //
-            .flatMap(i -> getEnvironment(systemEnvironment)) //
-            .flatMap(this::createCbsClient) //
-            .flatMap(this::getFromCbs) //
-            .onErrorResume(this::ignoreErrorMono) //
-            .doOnNext(json -> logger.debug("loadFromConsul succeeded")) //
-            .doOnNext(json -> this.isConsulUsed = true) //
-            .doOnTerminate(() -> logger.error("loadFromConsul Terminated"));
-
-        return Flux.merge(loadFromFile, loadFromConsul) //
-            .flatMap(this::parseConfiguration) //
-            .flatMap(this::updateConfig) //
-            .doOnNext(this::handleUpdatedRicConfig) //
-            .flatMap(configUpdate -> Flux.just(configUpdate.getType())) //
-            .doOnTerminate(() -> logger.error("Configuration refresh task is terminated"));
-    }
-
-    Mono<EnvProperties> getEnvironment(Properties systemEnvironment) {
-        return EnvironmentProcessor.readEnvironmentVariables(systemEnvironment) //
-            .onErrorResume(t -> Mono.empty());
-    }
-
-    Mono<CbsClient> createCbsClient(EnvProperties env) {
-        return CbsClientFactory.createCbsClient(env) //
-            .onErrorResume(this::ignoreErrorMono);
-    }
-
-    private Mono<JsonObject> getFromCbs(CbsClient cbsClient) {
-        try {
-            final CbsRequest getConfigRequest = CbsRequests.getAll(RequestDiagnosticContext.create());
-            return cbsClient.get(getConfigRequest) //
-                .onErrorResume(this::ignoreErrorMono);
-        } catch (Exception e) {
-            return ignoreErrorMono(e);
-        }
-    }
-
-    private <R> Flux<R> ignoreErrorFlux(Throwable throwable) {
-        String errMsg = throwable.toString();
-        logger.warn("Could not refresh application configuration. {}", errMsg);
-        return Flux.empty();
-    }
-
-    private <R> Mono<R> ignoreErrorMono(Throwable throwable) {
-        String errMsg = throwable.toString();
-        logger.warn("Could not refresh application configuration. {}", errMsg);
-        return Mono.empty();
-    }
-
-    private Mono<ApplicationConfigParser.ConfigParserResult> parseConfiguration(JsonObject jsonObject) {
-        try {
-            ApplicationConfigParser parser = new ApplicationConfigParser();
-            return Mono.just(parser.parse(jsonObject));
-        } catch (Exception e) {
-            String str = e.toString();
-            logger.error("Could not parse configuration {}", str);
-            return Mono.empty();
-        }
-    }
-
-    private Flux<RicConfigUpdate> updateConfig(ApplicationConfigParser.ConfigParserResult config) {
-        return this.appConfig.setConfiguration(config);
-    }
-
-    boolean fileExists(String filepath) {
-        return (filepath != null && (new File(filepath).exists()));
-    }
-
-    private void handleUpdatedRicConfig(RicConfigUpdate updatedInfo) {
-        synchronized (this.rics) {
-            String ricName = updatedInfo.getRicConfig().name();
-            RicConfigUpdate.Type event = updatedInfo.getType();
-            if (event == RicConfigUpdate.Type.ADDED) {
-                addRic(updatedInfo.getRicConfig());
-            } else if (event == RicConfigUpdate.Type.REMOVED) {
-                rics.remove(ricName);
-                this.policies.removePoliciesForRic(ricName);
-            } else if (event == RicConfigUpdate.Type.CHANGED) {
-                Ric ric = this.rics.get(ricName);
-                if (ric == null) {
-                    // Should not happen,just for robustness
-                    addRic(updatedInfo.getRicConfig());
-                } else {
-                    ric.setRicConfig(updatedInfo.getRicConfig());
-                }
-            }
-        }
-    }
-
-    private void addRic(RicConfig config) {
-        Ric ric = new Ric(config);
-        this.rics.put(ric);
-        runRicSynchronization(ric);
-    }
-
-    void runRicSynchronization(Ric ric) {
-        RicSynchronizationTask synchronizationTask =
-            new RicSynchronizationTask(a1ClientFactory, policyTypes, policies, services);
-        synchronizationTask.run(ric);
-    }
-
-    /**
-     * Reads the configuration from file.
-     */
-    Flux<JsonObject> loadConfigurationFromFile() {
-        String filepath = appConfig.getLocalConfigurationFilePath();
-        if (!fileExists(filepath)) {
-            return Flux.empty();
-        }
-
-        GsonBuilder gsonBuilder = new GsonBuilder();
-        ServiceLoader.load(TypeAdapterFactory.class).forEach(gsonBuilder::registerTypeAdapterFactory);
-
-        try (InputStream inputStream = createInputStream(filepath)) {
-            JsonObject rootObject = getJsonElement(inputStream).getAsJsonObject();
-            ApplicationConfigParser appParser = new ApplicationConfigParser();
-            appParser.parse(rootObject);
-            logger.debug("Local configuration file loaded: {}", filepath);
-            return Flux.just(rootObject);
-        } catch (Exception e) {
-            logger.error("Local configuration file not loaded: {}, {}", filepath, e.getMessage());
-            return Flux.empty();
-        }
-    }
-
-    JsonElement getJsonElement(InputStream inputStream) {
-        return JsonParser.parseReader(new InputStreamReader(inputStream));
-    }
-
-    InputStream createInputStream(@NotNull String filepath) throws IOException {
-        return new BufferedInputStream(new FileInputStream(filepath));
-    }
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/tasks/RicSupervision.java b/policy-agent/src/main/java/org/oransc/policyagent/tasks/RicSupervision.java
deleted file mode 100644 (file)
index 228038a..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.tasks;
-
-import java.util.Collection;
-
-import org.oransc.policyagent.clients.A1Client;
-import org.oransc.policyagent.clients.A1ClientFactory;
-import org.oransc.policyagent.exceptions.ServiceException;
-import org.oransc.policyagent.repository.Lock.LockType;
-import org.oransc.policyagent.repository.Policies;
-import org.oransc.policyagent.repository.PolicyTypes;
-import org.oransc.policyagent.repository.Ric;
-import org.oransc.policyagent.repository.Ric.RicState;
-import org.oransc.policyagent.repository.Rics;
-import org.oransc.policyagent.repository.Services;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.annotation.EnableScheduling;
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.stereotype.Component;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-/**
- * Regularly checks the existing rics towards the local repository to keep it
- * consistent. When the policy types or instances in the Near-RT RIC is not
- * consistent, a synchronization is performed.
- */
-@Component
-@EnableScheduling
-@SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally
-public class RicSupervision {
-    private static final Logger logger = LoggerFactory.getLogger(RicSupervision.class);
-
-    private final Rics rics;
-    private final Policies policies;
-    private final PolicyTypes policyTypes;
-    private final A1ClientFactory a1ClientFactory;
-    private final Services services;
-
-    private static class SynchStartedException extends ServiceException {
-        private static final long serialVersionUID = 1L;
-
-        public SynchStartedException(String message) {
-            super(message);
-        }
-    }
-
-    private static class RicData {
-        RicData(Ric ric, A1Client a1Client) {
-            this.ric = ric;
-            this.a1Client = a1Client;
-        }
-
-        A1Client getClient() {
-            return a1Client;
-        }
-
-        final Ric ric;
-        private final A1Client a1Client;
-    }
-
-    @Autowired
-    public RicSupervision(Rics rics, Policies policies, A1ClientFactory a1ClientFactory, PolicyTypes policyTypes,
-        Services services) {
-        this.rics = rics;
-        this.policies = policies;
-        this.a1ClientFactory = a1ClientFactory;
-        this.policyTypes = policyTypes;
-        this.services = services;
-    }
-
-    /**
-     * Regularly contacts all Rics to check if they are alive and synchronized.
-     */
-    @Scheduled(fixedRate = 1000 * 60)
-    public void checkAllRics() {
-        logger.debug("Checking Rics starting");
-        createTask().subscribe(null, null, () -> logger.debug("Checking all RICs completed"));
-    }
-
-    private Flux<RicData> createTask() {
-        return Flux.fromIterable(rics.getRics()) //
-            .flatMap(this::createRicData) //
-            .flatMap(this::checkOneRic);
-    }
-
-    private Mono<RicData> checkOneRic(RicData ricData) {
-        return checkRicState(ricData) //
-            .flatMap(x -> ricData.ric.getLock().lock(LockType.EXCLUSIVE)) //
-            .flatMap(notUsed -> setRicState(ricData)) //
-            .flatMap(x -> checkRicPolicies(ricData)) //
-            .flatMap(x -> checkRicPolicyTypes(ricData)) //
-            .doOnNext(x -> onRicCheckedOk(ricData)) //
-            .doOnError(t -> onRicCheckedError(t, ricData)) //
-            .onErrorResume(throwable -> Mono.empty());
-    }
-
-    private void onRicCheckedError(Throwable t, RicData ricData) {
-        logger.debug("Ric: {} check stopped, exception: {}", ricData.ric.name(), t.getMessage());
-        if (t instanceof SynchStartedException) {
-            // this is just a temporary state,
-            ricData.ric.setState(RicState.AVAILABLE);
-        } else {
-            ricData.ric.setState(RicState.UNAVAILABLE);
-        }
-        ricData.ric.getLock().unlockBlocking();
-    }
-
-    private void onRicCheckedOk(RicData ricData) {
-        logger.debug("Ric: {} checked OK", ricData.ric.name());
-        ricData.ric.setState(RicState.AVAILABLE);
-        ricData.ric.getLock().unlockBlocking();
-    }
-
-    @SuppressWarnings("squid:S2445") // Blocks should be synchronized on "private final" fields
-    private Mono<RicData> setRicState(RicData ric) {
-        synchronized (ric) {
-            if (ric.ric.getState() == RicState.CONSISTENCY_CHECK) {
-                logger.debug("Ric: {} is already being checked", ric.ric.getConfig().name());
-                return Mono.empty();
-            }
-            ric.ric.setState(RicState.CONSISTENCY_CHECK);
-            return Mono.just(ric);
-        }
-    }
-
-    private Mono<RicData> createRicData(Ric ric) {
-        return Mono.just(ric) //
-            .flatMap(aRic -> this.a1ClientFactory.createA1Client(ric)) //
-            .flatMap(a1Client -> Mono.just(new RicData(ric, a1Client)));
-    }
-
-    private Mono<RicData> checkRicState(RicData ric) {
-        if (ric.ric.getState() == RicState.UNAVAILABLE) {
-            return startSynchronization(ric) //
-                .onErrorResume(t -> Mono.empty());
-        } else if (ric.ric.getState() == RicState.SYNCHRONIZING || ric.ric.getState() == RicState.CONSISTENCY_CHECK) {
-            return Mono.empty();
-        } else {
-            return Mono.just(ric);
-        }
-    }
-
-    private Mono<RicData> checkRicPolicies(RicData ric) {
-        return ric.getClient().getPolicyIdentities() //
-            .flatMap(ricP -> validateInstances(ricP, ric));
-    }
-
-    private Mono<RicData> validateInstances(Collection<String> ricPolicies, RicData ric) {
-        synchronized (this.policies) {
-            if (ricPolicies.size() != policies.getForRic(ric.ric.name()).size()) {
-                return startSynchronization(ric);
-            }
-
-            for (String policyId : ricPolicies) {
-                if (!policies.containsPolicy(policyId)) {
-                    return startSynchronization(ric);
-                }
-            }
-            return Mono.just(ric);
-        }
-    }
-
-    private Mono<RicData> checkRicPolicyTypes(RicData ric) {
-        return ric.getClient().getPolicyTypeIdentities() //
-            .flatMap(ricTypes -> validateTypes(ricTypes, ric));
-    }
-
-    private Mono<RicData> validateTypes(Collection<String> ricTypes, RicData ric) {
-        if (ricTypes.size() != ric.ric.getSupportedPolicyTypes().size()) {
-            return startSynchronization(ric);
-        }
-        for (String typeName : ricTypes) {
-            if (!ric.ric.isSupportingType(typeName)) {
-                return startSynchronization(ric);
-            }
-        }
-        return Mono.just(ric);
-    }
-
-    private Mono<RicData> startSynchronization(RicData ric) {
-        RicSynchronizationTask synchronizationTask = createSynchronizationTask();
-        synchronizationTask.run(ric.ric);
-        return Mono.error(new SynchStartedException("Syncronization started"));
-    }
-
-    RicSynchronizationTask createSynchronizationTask() {
-        return new RicSynchronizationTask(a1ClientFactory, policyTypes, policies, services);
-    }
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/tasks/RicSynchronizationTask.java b/policy-agent/src/main/java/org/oransc/policyagent/tasks/RicSynchronizationTask.java
deleted file mode 100644 (file)
index 6ae55c4..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.tasks;
-
-import static org.oransc.policyagent.repository.Ric.RicState;
-
-import org.oransc.policyagent.clients.A1Client;
-import org.oransc.policyagent.clients.A1ClientFactory;
-import org.oransc.policyagent.clients.AsyncRestClient;
-import org.oransc.policyagent.repository.ImmutablePolicyType;
-import org.oransc.policyagent.repository.Lock.LockType;
-import org.oransc.policyagent.repository.Policies;
-import org.oransc.policyagent.repository.Policy;
-import org.oransc.policyagent.repository.PolicyType;
-import org.oransc.policyagent.repository.PolicyTypes;
-import org.oransc.policyagent.repository.Ric;
-import org.oransc.policyagent.repository.Service;
-import org.oransc.policyagent.repository.Services;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import reactor.core.publisher.BaseSubscriber;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-import reactor.core.publisher.SignalType;
-
-/**
- * Synchronizes the content of a RIC with the content in the repository. This
- * means:
- * <p>
- * load all policy types
- * <p>
- * send all policy instances to the RIC
- * <p>
- * if that fails remove all policy instances
- * <p>
- * Notify subscribing services
- */
-@SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally
-public class RicSynchronizationTask {
-
-    private static final Logger logger = LoggerFactory.getLogger(RicSynchronizationTask.class);
-    static final int CONCURRENCY_RIC = 1; // How may paralell requests that is sent to one NearRT RIC
-
-    private final A1ClientFactory a1ClientFactory;
-    private final PolicyTypes policyTypes;
-    private final Policies policies;
-    private final Services services;
-
-    public RicSynchronizationTask(A1ClientFactory a1ClientFactory, PolicyTypes policyTypes, Policies policies,
-        Services services) {
-        this.a1ClientFactory = a1ClientFactory;
-        this.policyTypes = policyTypes;
-        this.policies = policies;
-        this.services = services;
-    }
-
-    public void run(Ric ric) {
-        logger.debug("Handling ric: {}", ric.getConfig().name());
-
-        if (ric.getState() == RicState.SYNCHRONIZING) {
-            logger.debug("Ric: {} is already being synchronized", ric.getConfig().name());
-            return;
-        }
-
-        ric.getLock().lock(LockType.EXCLUSIVE) //
-            .flatMap(notUsed -> setRicState(ric)) //
-            .flatMap(lock -> this.a1ClientFactory.createA1Client(ric)) //
-            .flatMapMany(client -> runSynchronization(ric, client)) //
-            .onErrorResume(throwable -> deleteAllPolicyInstances(ric, throwable))
-            .subscribe(new BaseSubscriber<Object>() {
-                @Override
-                protected void hookOnError(Throwable throwable) {
-                    logger.warn("Synchronization failure for ric: {}, reason: {}", ric.name(), throwable.getMessage());
-                    ric.setState(RicState.UNAVAILABLE);
-                }
-
-                @Override
-                protected void hookOnComplete() {
-                    onSynchronizationComplete(ric);
-                }
-
-                @Override
-                protected void hookFinally(SignalType type) {
-                    ric.getLock().unlockBlocking();
-                }
-            });
-    }
-
-    @SuppressWarnings("squid:S2445") // Blocks should be synchronized on "private final" fields
-    private Mono<Ric> setRicState(Ric ric) {
-        synchronized (ric) {
-            if (ric.getState() == RicState.SYNCHRONIZING) {
-                logger.debug("Ric: {} is already being synchronized", ric.getConfig().name());
-                return Mono.empty();
-            }
-            ric.setState(RicState.SYNCHRONIZING);
-            return Mono.just(ric);
-        }
-    }
-
-    private Flux<Object> runSynchronization(Ric ric, A1Client a1Client) {
-        Flux<PolicyType> synchronizedTypes = synchronizePolicyTypes(ric, a1Client);
-        Flux<?> policiesDeletedInRic = a1Client.deleteAllPolicies();
-        Flux<Policy> policiesRecreatedInRic = recreateAllPoliciesInRic(ric, a1Client);
-
-        return Flux.concat(synchronizedTypes, policiesDeletedInRic, policiesRecreatedInRic);
-    }
-
-    private void onSynchronizationComplete(Ric ric) {
-        logger.debug("Synchronization completed for: {}", ric.name());
-        ric.setState(RicState.AVAILABLE);
-        notifyAllServices("Synchronization completed for:" + ric.name());
-    }
-
-    private void notifyAllServices(String body) {
-        for (Service service : services.getAll()) {
-            String url = service.getCallbackUrl();
-            if (url.length() > 0) {
-                createNotificationClient(url) //
-                    .put("", body) //
-                    .subscribe( //
-                        notUsed -> logger.debug("Service {} notified", service.getName()),
-                        throwable -> logger.warn("Service notification failed for service: {}. Cause: {}",
-                            service.getName(), throwable.getMessage()),
-                        () -> logger.debug("All services notified"));
-            }
-        }
-    }
-
-    private Flux<Object> deleteAllPolicyInstances(Ric ric, Throwable t) {
-        logger.debug("Recreation of policies failed for ric: {}, reason: {}", ric.name(), t.getMessage());
-        deleteAllPoliciesInRepository(ric);
-
-        Flux<PolicyType> synchronizedTypes = this.a1ClientFactory.createA1Client(ric) //
-            .flatMapMany(a1Client -> synchronizePolicyTypes(ric, a1Client));
-        Flux<?> deletePoliciesInRic = this.a1ClientFactory.createA1Client(ric) //
-            .flatMapMany(A1Client::deleteAllPolicies) //
-            .doOnComplete(() -> deleteAllPoliciesInRepository(ric));
-
-        return Flux.concat(synchronizedTypes, deletePoliciesInRic);
-    }
-
-    AsyncRestClient createNotificationClient(final String url) {
-        return new AsyncRestClient(url, this.a1ClientFactory.getAppConfig().getWebClientConfig());
-    }
-
-    private Flux<PolicyType> synchronizePolicyTypes(Ric ric, A1Client a1Client) {
-        return a1Client.getPolicyTypeIdentities() //
-            .doOnNext(x -> ric.clearSupportedPolicyTypes()) //
-            .flatMapMany(Flux::fromIterable) //
-            .doOnNext(typeId -> logger.debug("For ric: {}, handling type: {}", ric.getConfig().name(), typeId)) //
-            .flatMap(policyTypeId -> getPolicyType(policyTypeId, a1Client), CONCURRENCY_RIC) //
-            .doOnNext(ric::addSupportedPolicyType); //
-    }
-
-    private Mono<PolicyType> getPolicyType(String policyTypeId, A1Client a1Client) {
-        if (policyTypes.contains(policyTypeId)) {
-            return Mono.just(policyTypes.get(policyTypeId));
-        }
-        return a1Client.getPolicyTypeSchema(policyTypeId) //
-            .flatMap(schema -> createPolicyType(policyTypeId, schema));
-    }
-
-    private Mono<PolicyType> createPolicyType(String policyTypeId, String schema) {
-        PolicyType pt = ImmutablePolicyType.builder().name(policyTypeId).schema(schema).build();
-        policyTypes.put(pt);
-        return Mono.just(pt);
-    }
-
-    private void deleteAllPoliciesInRepository(Ric ric) {
-        for (Policy policy : policies.getForRic(ric.name())) {
-            this.policies.remove(policy);
-        }
-    }
-
-    private Flux<Policy> putPolicy(Policy policy, Ric ric, A1Client a1Client) {
-        logger.debug("Recreating policy: {}, for ric: {}", policy.id(), ric.getConfig().name());
-        return a1Client.putPolicy(policy) //
-            .flatMapMany(notUsed -> Flux.just(policy));
-    }
-
-    private boolean checkTransient(Policy policy) {
-        if (policy.isTransient()) {
-            this.policies.remove(policy);
-        }
-        return policy.isTransient();
-    }
-
-    private Flux<Policy> recreateAllPoliciesInRic(Ric ric, A1Client a1Client) {
-        return Flux.fromIterable(policies.getForRic(ric.name())) //
-            .filter(policy -> !checkTransient(policy)) //
-            .flatMap(policy -> putPolicy(policy, ric, a1Client), CONCURRENCY_RIC);
-    }
-
-}
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/tasks/ServiceSupervision.java b/policy-agent/src/main/java/org/oransc/policyagent/tasks/ServiceSupervision.java
deleted file mode 100644 (file)
index 9c55532..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.tasks;
-
-import java.time.Duration;
-
-import org.oransc.policyagent.clients.A1ClientFactory;
-import org.oransc.policyagent.repository.Lock;
-import org.oransc.policyagent.repository.Lock.LockType;
-import org.oransc.policyagent.repository.Policies;
-import org.oransc.policyagent.repository.Policy;
-import org.oransc.policyagent.repository.Service;
-import org.oransc.policyagent.repository.Services;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.annotation.EnableScheduling;
-import org.springframework.stereotype.Component;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-/**
- * Periodically checks that services with a keepAliveInterval set are alive. If
- * a service is deemed not alive, all the service's policies are deleted, both
- * in the repository and in the affected Rics, and the service is removed from
- * the repository. This means that the service needs to register again after
- * this.
- */
-@Component
-@EnableScheduling
-@SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally
-public class ServiceSupervision {
-    private static final Logger logger = LoggerFactory.getLogger(ServiceSupervision.class);
-    static final int CONCURRENCY_RIC = 1; // How may paralell requests that is sent
-    private final Services services;
-    private final Policies policies;
-    private A1ClientFactory a1ClientFactory;
-    private final Duration checkInterval;
-
-    @Autowired
-    public ServiceSupervision(Services services, Policies policies, A1ClientFactory a1ClientFactory) {
-        this(services, policies, a1ClientFactory, Duration.ofMinutes(1));
-    }
-
-    public ServiceSupervision(Services services, Policies policies, A1ClientFactory a1ClientFactory,
-        Duration checkInterval) {
-        this.services = services;
-        this.policies = policies;
-        this.a1ClientFactory = a1ClientFactory;
-        this.checkInterval = checkInterval;
-        start();
-    }
-
-    private void start() {
-        logger.debug("Checking services starting");
-        createTask().subscribe(null, null, () -> logger.error("Checking services unexpectedly terminated"));
-    }
-
-    private Flux<?> createTask() {
-        return Flux.interval(this.checkInterval) //
-            .flatMap(notUsed -> checkAllServices());
-    }
-
-    Flux<Policy> checkAllServices() {
-        return Flux.fromIterable(services.getAll()) //
-            .filter(Service::isExpired) //
-            .doOnNext(service -> logger.info("Service is expired: {}", service.getName())) //
-            .doOnNext(service -> services.remove(service.getName())) //
-            .flatMap(this::getAllPoliciesForService) //
-            .flatMap(this::deletePolicy, CONCURRENCY_RIC);
-    }
-
-    @SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally
-    private Flux<Policy> deletePolicy(Policy policy) {
-        Lock lock = policy.ric().getLock();
-        return lock.lock(LockType.SHARED) //
-            .doOnNext(notUsed -> policies.remove(policy)) //
-            .flatMap(notUsed -> deletePolicyInRic(policy))
-            .doOnNext(notUsed -> logger.debug("Policy deleted due to service inactivity: {}, service: {}", policy.id(),
-                policy.ownerServiceName())) //
-            .doOnNext(notUsed -> lock.unlockBlocking()) //
-            .doOnError(throwable -> lock.unlockBlocking()) //
-            .doOnError(throwable -> logger.debug("Failed to delete inactive policy: {}, reason: {}", policy.id(),
-                throwable.getMessage())) //
-            .flatMapMany(notUsed -> Flux.just(policy)) //
-            .onErrorResume(throwable -> Flux.empty());
-    }
-
-    private Flux<Policy> getAllPoliciesForService(Service service) {
-        return Flux.fromIterable(policies.getForService(service.getName()));
-    }
-
-    private Mono<Policy> deletePolicyInRic(Policy policy) {
-        return a1ClientFactory.createA1Client(policy.ric()) //
-            .flatMap(client -> client.deletePolicy(policy) //
-                .onErrorResume(exception -> handleDeleteFromRicFailure(policy, exception)) //
-                .map(nothing -> policy));
-    }
-
-    private Mono<String> handleDeleteFromRicFailure(Policy policy, Throwable e) {
-        logger.warn("Could not delete policy: {} from ric: {}. Cause: {}", policy.id(), policy.ric().name(),
-            e.getMessage());
-        return Mono.empty();
-    }
-}
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java b/policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java
deleted file mode 100644 (file)
index 4de5c71..0000000
+++ /dev/null
@@ -1,843 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.awaitility.Awaitility.await;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doReturn;
-
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonParser;
-
-import java.nio.charset.StandardCharsets;
-import java.time.Duration;
-import java.time.Instant;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.oransc.policyagent.clients.AsyncRestClient;
-import org.oransc.policyagent.configuration.ApplicationConfig;
-import org.oransc.policyagent.configuration.ImmutableRicConfig;
-import org.oransc.policyagent.configuration.ImmutableWebClientConfig;
-import org.oransc.policyagent.configuration.RicConfig;
-import org.oransc.policyagent.configuration.WebClientConfig;
-import org.oransc.policyagent.controllers.PolicyInfo;
-import org.oransc.policyagent.controllers.ServiceRegistrationInfo;
-import org.oransc.policyagent.controllers.ServiceStatus;
-import org.oransc.policyagent.exceptions.ServiceException;
-import org.oransc.policyagent.repository.ImmutablePolicy;
-import org.oransc.policyagent.repository.ImmutablePolicyType;
-import org.oransc.policyagent.repository.Lock.LockType;
-import org.oransc.policyagent.repository.Policies;
-import org.oransc.policyagent.repository.Policy;
-import org.oransc.policyagent.repository.PolicyType;
-import org.oransc.policyagent.repository.PolicyTypes;
-import org.oransc.policyagent.repository.Ric;
-import org.oransc.policyagent.repository.Ric.RicState;
-import org.oransc.policyagent.repository.Rics;
-import org.oransc.policyagent.repository.Services;
-import org.oransc.policyagent.tasks.RicSupervision;
-import org.oransc.policyagent.tasks.ServiceSupervision;
-import org.oransc.policyagent.utils.MockA1Client;
-import org.oransc.policyagent.utils.MockA1ClientFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
-import org.springframework.boot.test.context.TestConfiguration;
-import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
-import org.springframework.boot.web.server.LocalServerPort;
-import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.test.context.TestPropertySource;
-import org.springframework.test.context.junit.jupiter.SpringExtension;
-import org.springframework.web.reactive.function.client.WebClientResponseException;
-
-import reactor.core.publisher.Mono;
-import reactor.test.StepVerifier;
-import reactor.util.annotation.Nullable;
-
-@ExtendWith(SpringExtension.class)
-@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
-@TestPropertySource(
-    properties = { //
-        "server.ssl.key-store=./config/keystore.jks", //
-        "app.webclient.trust-store=./config/truststore.jks"})
-class ApplicationTest {
-    private static final Logger logger = LoggerFactory.getLogger(ApplicationTest.class);
-
-    @Autowired
-    ApplicationContext context;
-
-    @Autowired
-    private Rics rics;
-
-    @Autowired
-    private Policies policies;
-
-    @Autowired
-    private PolicyTypes policyTypes;
-
-    @Autowired
-    MockA1ClientFactory a1ClientFactory;
-
-    @Autowired
-    RicSupervision supervision;
-
-    @Autowired
-    ApplicationConfig applicationConfig;
-
-    @Autowired
-    Services services;
-
-    private static Gson gson = new GsonBuilder() //
-        .serializeNulls() //
-        .create(); //
-
-    public static class MockApplicationConfig extends ApplicationConfig {
-        @Override
-        public String getLocalConfigurationFilePath() {
-            return ""; // No config file loaded for the test
-        }
-    }
-
-    /**
-     * Overrides the BeanFactory.
-     */
-    @TestConfiguration
-    static class TestBeanFactory {
-        private final PolicyTypes policyTypes = new PolicyTypes();
-        private final Services services = new Services();
-        private final Policies policies = new Policies();
-        MockA1ClientFactory a1ClientFactory = null;
-
-        @Bean
-        public ApplicationConfig getApplicationConfig() {
-            return new MockApplicationConfig();
-        }
-
-        @Bean
-        MockA1ClientFactory getA1ClientFactory() {
-            if (a1ClientFactory == null) {
-                this.a1ClientFactory = new MockA1ClientFactory(this.policyTypes);
-            }
-            return this.a1ClientFactory;
-        }
-
-        @Bean
-        public PolicyTypes getPolicyTypes() {
-            return this.policyTypes;
-        }
-
-        @Bean
-        Policies getPolicies() {
-            return this.policies;
-        }
-
-        @Bean
-        Services getServices() {
-            return this.services;
-        }
-
-        @Bean
-        public ServiceSupervision getServiceSupervision() {
-            Duration checkInterval = Duration.ofMillis(1);
-            return new ServiceSupervision(this.services, this.policies, this.getA1ClientFactory(), checkInterval);
-        }
-
-        @Bean
-        public ServletWebServerFactory servletContainer() {
-            return new TomcatServletWebServerFactory();
-        }
-
-    }
-
-    @LocalServerPort
-    private int port;
-
-    @BeforeEach
-    void reset() {
-        rics.clear();
-        policies.clear();
-        policyTypes.clear();
-        services.clear();
-        a1ClientFactory.reset();
-    }
-
-    @AfterEach
-    void verifyNoRicLocks() {
-        for (Ric ric : this.rics.getRics()) {
-            ric.getLock().lockBlocking(LockType.EXCLUSIVE);
-            ric.getLock().unlockBlocking();
-            assertThat(ric.getLock().getLockCounter()).isZero();
-            assertThat(ric.getState()).isEqualTo(Ric.RicState.AVAILABLE);
-        }
-    }
-
-    @Test
-    void testGetRics() throws Exception {
-        addRic("ric1");
-        this.addPolicyType("type1", "ric1");
-        String url = "/rics?policyType=type1";
-        String rsp = restClient().get(url).block();
-        assertThat(rsp).contains("ric1");
-
-        // nameless type for ORAN A1 1.1
-        addRic("ric2");
-        this.addPolicyType("", "ric2");
-        url = "/rics?policyType=";
-
-        // This tests also validation of trusted certs restClient(true)
-        rsp = restClient(true).get(url).block();
-        assertThat(rsp).contains("ric2") //
-            .doesNotContain("ric1") //
-            .contains("AVAILABLE");
-
-        // All RICs
-        rsp = restClient().get("/rics").block();
-        assertThat(rsp).contains("ric2") //
-            .contains("ric1");
-
-        // Non existing policy type
-        url = "/rics?policyType=XXXX";
-        testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND);
-    }
-
-    @Test
-    void testSynchronization() throws Exception {
-        // Two polictypes will be put in the NearRT RICs
-        PolicyTypes nearRtRicPolicyTypes = new PolicyTypes();
-        nearRtRicPolicyTypes.put(createPolicyType("typeName"));
-        nearRtRicPolicyTypes.put(createPolicyType("typeName2"));
-        this.a1ClientFactory.setPolicyTypes(nearRtRicPolicyTypes);
-
-        // One type and one instance added to the agent storage
-        final String ric1Name = "ric1";
-        Ric ric1 = addRic(ric1Name);
-        Policy policy2 = addPolicy("policyId2", "typeName", "service", ric1Name);
-        Ric ric2 = addRic("ric2");
-
-        getA1Client(ric1Name).putPolicy(policy2); // put it in the RIC
-        policies.remove(policy2); // Remove it from the repo -> should be deleted in the RIC
-
-        String policyId = "policyId";
-        Policy policy = addPolicy(policyId, "typeName", "service", ric1Name); // This should be created in the RIC
-        supervision.checkAllRics(); // The created policy should be put in the RIC
-
-        // Wait until synch is completed
-        await().untilAsserted(() -> RicState.SYNCHRONIZING.equals(rics.getRic(ric1Name).getState()));
-        await().untilAsserted(() -> RicState.AVAILABLE.equals(rics.getRic(ric1Name).getState()));
-        await().untilAsserted(() -> RicState.AVAILABLE.equals(rics.getRic("ric2").getState()));
-
-        Policies ricPolicies = getA1Client(ric1Name).getPolicies();
-        assertThat(ricPolicies.size()).isEqualTo(1);
-        Policy ricPolicy = ricPolicies.get(policyId);
-        assertThat(ricPolicy.json()).isEqualTo(policy.json());
-
-        // Both types should be in the agent storage after the synch
-        assertThat(ric1.getSupportedPolicyTypes()).hasSize(2);
-        assertThat(ric2.getSupportedPolicyTypes()).hasSize(2);
-    }
-
-    @Test
-    void testGetRicForManagedElement_thenReturnCorrectRic() throws Exception {
-        String ricName = "ric1";
-        String managedElementId = "kista_1";
-        addRic(ricName, managedElementId);
-
-        String url = "/ric?managedElementId=" + managedElementId;
-        String rsp = restClient().get(url).block();
-        assertThat(rsp).isEqualTo(ricName);
-
-        // test GET RIC for ManagedElement that does not exist
-        url = "/ric?managedElementId=" + "junk";
-        testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND);
-    }
-
-    private String putPolicyUrl(String serviceName, String ricName, String policyTypeName, String policyInstanceId,
-        boolean isTransient) {
-        String url;
-        if (policyTypeName.isEmpty()) {
-            url = "/policy?id=" + policyInstanceId + "&ric=" + ricName + "&service=" + serviceName;
-        } else {
-            url = "/policy?id=" + policyInstanceId + "&ric=" + ricName + "&service=" + serviceName + "&type="
-                + policyTypeName;
-        }
-        if (isTransient) {
-            url += "&transient=true";
-        }
-        return url;
-    }
-
-    private String putPolicyUrl(String serviceName, String ricName, String policyTypeName, String policyInstanceId) {
-        return putPolicyUrl(serviceName, ricName, policyTypeName, policyInstanceId, false);
-    }
-
-    @Test
-    void testPutPolicy() throws Exception {
-        String serviceName = "service1";
-        String ricName = "ric1";
-        String policyTypeName = "type1";
-        String policyInstanceId = "instance1";
-
-        putService(serviceName);
-        addPolicyType(policyTypeName, ricName);
-
-        // PUT a transient policy
-        String url = putPolicyUrl(serviceName, ricName, policyTypeName, policyInstanceId, true);
-        final String policyBody = jsonString();
-        this.rics.getRic(ricName).setState(Ric.RicState.AVAILABLE);
-
-        restClient().put(url, policyBody).block();
-
-        Policy policy = policies.getPolicy(policyInstanceId);
-        assertThat(policy).isNotNull();
-        assertThat(policy.id()).isEqualTo(policyInstanceId);
-        assertThat(policy.ownerServiceName()).isEqualTo(serviceName);
-        assertThat(policy.ric().name()).isEqualTo("ric1");
-        assertThat(policy.isTransient()).isTrue();
-
-        // Put a non transient policy
-        url = putPolicyUrl(serviceName, ricName, policyTypeName, policyInstanceId);
-        restClient().put(url, policyBody).block();
-        policy = policies.getPolicy(policyInstanceId);
-        assertThat(policy.isTransient()).isFalse();
-
-        url = "/policies";
-        String rsp = restClient().get(url).block();
-        assertThat(rsp).as("Response contains policy instance ID.").contains(policyInstanceId);
-
-        url = "/policy?id=" + policyInstanceId;
-        rsp = restClient().get(url).block();
-        assertThat(rsp).isEqualTo(policyBody);
-
-        // Test of error codes
-        url = putPolicyUrl(serviceName, ricName + "XX", policyTypeName, policyInstanceId);
-        testErrorCode(restClient().put(url, policyBody), HttpStatus.NOT_FOUND);
-
-        url = putPolicyUrl(serviceName, ricName, policyTypeName + "XX", policyInstanceId);
-        addPolicyType(policyTypeName + "XX", "otherRic");
-        testErrorCode(restClient().put(url, policyBody), HttpStatus.NOT_FOUND);
-
-        url = putPolicyUrl(serviceName, ricName, policyTypeName, policyInstanceId);
-        this.rics.getRic(ricName).setState(Ric.RicState.SYNCHRONIZING);
-        testErrorCode(restClient().put(url, policyBody), HttpStatus.LOCKED);
-        this.rics.getRic(ricName).setState(Ric.RicState.AVAILABLE);
-    }
-
-    @Test
-    /**
-     * Test that HttpStatus and body from failing REST call to A1 is passed on to
-     * the caller.
-     *
-     * @throws ServiceException
-     */
-    void testErrorFromRic() throws ServiceException {
-        putService("service1");
-        addPolicyType("type1", "ric1");
-
-        String url = putPolicyUrl("service1", "ric1", "type1", "id1");
-        MockA1Client a1Client = a1ClientFactory.getOrCreateA1Client("ric1");
-        HttpStatus httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;
-        String responseBody = "Refused";
-        byte[] responseBodyBytes = responseBody.getBytes(StandardCharsets.UTF_8);
-
-        WebClientResponseException a1Exception = new WebClientResponseException(httpStatus.value(), "statusText", null,
-            responseBodyBytes, StandardCharsets.UTF_8, null);
-        doReturn(Mono.error(a1Exception)).when(a1Client).putPolicy(any());
-
-        // PUT Policy
-        testErrorCode(restClient().put(url, "{}"), httpStatus, responseBody);
-
-        // DELETE POLICY
-        this.addPolicy("instance1", "type1", "service1", "ric1");
-        doReturn(Mono.error(a1Exception)).when(a1Client).deletePolicy(any());
-        testErrorCode(restClient().delete("/policy?id=instance1"), httpStatus, responseBody);
-
-        // GET STATUS
-        this.addPolicy("instance1", "type1", "service1", "ric1");
-        doReturn(Mono.error(a1Exception)).when(a1Client).getPolicyStatus(any());
-        testErrorCode(restClient().get("/policy_status?id=instance1"), httpStatus, responseBody);
-
-        // Check that empty response body is OK
-        a1Exception = new WebClientResponseException(httpStatus.value(), "", null, null, null, null);
-        doReturn(Mono.error(a1Exception)).when(a1Client).getPolicyStatus(any());
-        testErrorCode(restClient().get("/policy_status?id=instance1"), httpStatus);
-    }
-
-    @Test
-    void testPutTypelessPolicy() throws Exception {
-        putService("service1");
-        addPolicyType("", "ric1");
-        String url = putPolicyUrl("service1", "ric1", "", "id1");
-        restClient().put(url, jsonString()).block();
-
-        String rsp = restClient().get("/policies").block();
-        List<PolicyInfo> info = parseList(rsp, PolicyInfo.class);
-        assertThat(info).hasSize(1);
-        PolicyInfo policyInfo = info.get(0);
-        assertThat(policyInfo.id).isEqualTo("id1");
-        assertThat(policyInfo.type).isEmpty();
-    }
-
-    @Test
-    void testRefuseToUpdatePolicy() throws Exception {
-        // Test that only the json can be changed for a already created policy
-        // In this case service is attempted to be changed
-        this.addRic("ric1");
-        this.addRic("ricXXX");
-        this.addPolicy("instance1", "type1", "service1", "ric1");
-        this.addPolicy("instance2", "type1", "service1", "ricXXX");
-
-        // Try change ric1 -> ricXXX
-        String urlWrongRic = putPolicyUrl("service1", "ricXXX", "type1", "instance1");
-        testErrorCode(restClient().put(urlWrongRic, jsonString()), HttpStatus.CONFLICT);
-    }
-
-    @Test
-    void testGetPolicy() throws Exception {
-        String url = "/policy?id=id";
-        Policy policy = addPolicy("id", "typeName", "service1", "ric1");
-        {
-            String rsp = restClient().get(url).block();
-            assertThat(rsp).isEqualTo(policy.json());
-        }
-        {
-            policies.remove(policy);
-            testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND);
-        }
-    }
-
-    @Test
-    void testDeletePolicy() throws Exception {
-        addPolicy("id", "typeName", "service1", "ric1");
-        assertThat(policies.size()).isEqualTo(1);
-
-        String url = "/policy?id=id";
-        ResponseEntity<String> entity = restClient().deleteForEntity(url).block();
-
-        assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT);
-        assertThat(policies.size()).isZero();
-
-        // Delete a non existing policy
-        testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND);
-    }
-
-    @Test
-    void testGetPolicySchemas() throws Exception {
-        addPolicyType("type1", "ric1");
-        addPolicyType("type2", "ric2");
-
-        String url = "/policy_schemas";
-        String rsp = this.restClient().get(url).block();
-        assertThat(rsp).contains("type1") //
-            .contains("[{\"title\":\"type2\"}");
-
-        List<String> info = parseSchemas(rsp);
-        assertThat(info).hasSize(2);
-
-        url = "/policy_schemas?ric=ric1";
-        rsp = restClient().get(url).block();
-        assertThat(rsp).contains("type1");
-        info = parseSchemas(rsp);
-        assertThat(info).hasSize(1);
-
-        // Get schema for non existing RIC
-        url = "/policy_schemas?ric=ric1XXX";
-        testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND);
-    }
-
-    @Test
-    void testGetPolicySchema() throws Exception {
-        addPolicyType("type1", "ric1");
-        addPolicyType("type2", "ric2");
-
-        String url = "/policy_schema?id=type1";
-        String rsp = restClient().get(url).block();
-        logger.info(rsp);
-        assertThat(rsp).contains("type1") //
-            .contains("title");
-
-        // Get non existing schema
-        url = "/policy_schema?id=type1XX";
-        testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND);
-    }
-
-    @Test
-    void testGetPolicyTypes() throws Exception {
-        addPolicyType("type1", "ric1");
-        addPolicyType("type2", "ric2");
-
-        String url = "/policy_types";
-        String rsp = restClient().get(url).block();
-        assertThat(rsp).isEqualTo("[\"type2\",\"type1\"]");
-
-        url = "/policy_types?ric=ric1";
-        rsp = restClient().get(url).block();
-        assertThat(rsp).isEqualTo("[\"type1\"]");
-
-        // Get policy types for non existing RIC
-        url = "/policy_types?ric=ric1XXX";
-        testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND);
-    }
-
-    @Test
-    void testGetPolicies() throws Exception {
-        addPolicy("id1", "type1", "service1");
-
-        String url = "/policies";
-        String rsp = restClient().get(url).block();
-        logger.info(rsp);
-        List<PolicyInfo> info = parseList(rsp, PolicyInfo.class);
-        assertThat(info).hasSize(1);
-        PolicyInfo policyInfo = info.get(0);
-        assert (policyInfo.validate());
-        assertThat(policyInfo.id).isEqualTo("id1");
-        assertThat(policyInfo.type).isEqualTo("type1");
-        assertThat(policyInfo.service).isEqualTo("service1");
-    }
-
-    @Test
-    void testGetPoliciesFilter() throws Exception {
-        addPolicy("id1", "type1", "service1");
-        addPolicy("id2", "type1", "service2");
-        addPolicy("id3", "type2", "service1");
-
-        String url = "/policies?type=type1";
-        String rsp = restClient().get(url).block();
-        logger.info(rsp);
-        assertThat(rsp).contains("id1") //
-            .contains("id2") //
-            .doesNotContain("id3");
-
-        url = "/policies?type=type1&service=service2";
-        rsp = restClient().get(url).block();
-        logger.info(rsp);
-        assertThat(rsp).doesNotContain("id1") //
-            .contains("id2") //
-            .doesNotContain("id3");
-
-        // Test get policies for non existing type
-        url = "/policies?type=type1XXX";
-        testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND);
-
-        // Test get policies for non existing RIC
-        url = "/policies?ric=XXX";
-        testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND);
-    }
-
-    @Test
-    void testGetPolicyIdsFilter() throws Exception {
-        addPolicy("id1", "type1", "service1", "ric1");
-        addPolicy("id2", "type1", "service2", "ric1");
-        addPolicy("id3", "type2", "service1", "ric1");
-
-        String url = "/policy_ids?type=type1";
-        String rsp = restClient().get(url).block();
-        logger.info(rsp);
-        assertThat(rsp).contains("id1") //
-            .contains("id2") //
-            .doesNotContain("id3");
-
-        url = "/policy_ids?type=type1&service=service1&ric=ric1";
-        rsp = restClient().get(url).block();
-        assertThat(rsp).isEqualTo("[\"id1\"]");
-
-        // Test get policy ids for non existing type
-        url = "/policy_ids?type=type1XXX";
-        testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND);
-
-        // Test get policy ids for non existing RIC
-        url = "/policy_ids?ric=XXX";
-        testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND);
-    }
-
-    @Test
-    void testPutAndGetService() throws Exception {
-        // PUT
-        String serviceName = "name";
-        putService(serviceName, 0, HttpStatus.CREATED);
-        putService(serviceName, 0, HttpStatus.OK);
-
-        // GET one service
-        String url = "/services?name=name";
-        String rsp = restClient().get(url).block();
-        List<ServiceStatus> info = parseList(rsp, ServiceStatus.class);
-        assertThat(info).hasSize(1);
-        ServiceStatus status = info.iterator().next();
-        assertThat(status.keepAliveIntervalSeconds).isZero();
-        assertThat(status.serviceName).isEqualTo(serviceName);
-
-        // GET (all)
-        url = "/services";
-        rsp = restClient().get(url).block();
-        assertThat(rsp).as("Response contains service name").contains(serviceName);
-        logger.info(rsp);
-
-        // Keep alive
-        url = "/services/keepalive?name=name";
-        ResponseEntity<String> entity = restClient().putForEntity(url).block();
-        assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
-
-        // DELETE service
-        assertThat(services.size()).isEqualTo(1);
-        url = "/services?name=name";
-        restClient().delete(url).block();
-        assertThat(services.size()).isZero();
-
-        // Keep alive, no registered service
-        testErrorCode(restClient().put("/services/keepalive?name=name", ""), HttpStatus.NOT_FOUND);
-
-        // PUT servive with bad payload
-        testErrorCode(restClient().put("/service", "crap"), HttpStatus.BAD_REQUEST);
-        testErrorCode(restClient().put("/service", "{}"), HttpStatus.BAD_REQUEST);
-        testErrorCode(restClient().put("/service", createServiceJson(serviceName, -123)), HttpStatus.BAD_REQUEST);
-        testErrorCode(restClient().put("/service", createServiceJson(serviceName, 0, "missing.portandprotocol.com")),
-            HttpStatus.BAD_REQUEST);
-
-        // GET non existing service
-        testErrorCode(restClient().get("/services?name=XXX"), HttpStatus.NOT_FOUND);
-    }
-
-    @Test
-    void testServiceSupervision() throws Exception {
-        putService("service1", 1, HttpStatus.CREATED);
-        addPolicyType("type1", "ric1");
-
-        String url = putPolicyUrl("service1", "ric1", "type1", "instance1");
-        final String policyBody = jsonString();
-        restClient().put(url, policyBody).block();
-
-        assertThat(policies.size()).isEqualTo(1);
-        assertThat(services.size()).isEqualTo(1);
-
-        // Timeout after ~1 second
-        await().untilAsserted(() -> assertThat(policies.size()).isZero());
-        assertThat(services.size()).isZero();
-    }
-
-    @Test
-    void testGetPolicyStatus() throws Exception {
-        addPolicy("id", "typeName", "service1", "ric1");
-        assertThat(policies.size()).isEqualTo(1);
-
-        String url = "/policy_status?id=id";
-        String rsp = restClient().get(url).block();
-        assertThat(rsp).isEqualTo("OK");
-
-        // GET non existing policy status
-        url = "/policy_status?id=XXX";
-        testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND);
-    }
-
-    private Policy addPolicy(String id, String typeName, String service, String ric) throws ServiceException {
-        addRic(ric);
-        Policy policy = ImmutablePolicy.builder() //
-            .id(id) //
-            .json(jsonString()) //
-            .ownerServiceName(service) //
-            .ric(rics.getRic(ric)) //
-            .type(addPolicyType(typeName, ric)) //
-            .lastModified("lastModified") //
-            .isTransient(false) //
-            .build();
-        policies.put(policy);
-        return policy;
-    }
-
-    private Policy addPolicy(String id, String typeName, String service) throws ServiceException {
-        return addPolicy(id, typeName, service, "ric");
-    }
-
-    private String createServiceJson(String name, long keepAliveIntervalSeconds) {
-        return createServiceJson(name, keepAliveIntervalSeconds, "https://examples.javacodegeeks.com/core-java/");
-    }
-
-    private String createServiceJson(String name, long keepAliveIntervalSeconds, String url) {
-        ServiceRegistrationInfo service = new ServiceRegistrationInfo(name, keepAliveIntervalSeconds, url);
-
-        String json = gson.toJson(service);
-        return json;
-    }
-
-    private void putService(String name) {
-        putService(name, 0, null);
-    }
-
-    private void putService(String name, long keepAliveIntervalSeconds, @Nullable HttpStatus expectedStatus) {
-        String url = "/service";
-        String body = createServiceJson(name, keepAliveIntervalSeconds);
-        ResponseEntity<String> resp = restClient().putForEntity(url, body).block();
-        if (expectedStatus != null) {
-            assertEquals(expectedStatus, resp.getStatusCode(), "");
-        }
-    }
-
-    private String baseUrl() {
-        return "https://localhost:" + port;
-    }
-
-    private String jsonString() {
-        return "{\"servingCellNrcgi\":\"1\"}";
-    }
-
-    @Test
-    void testConcurrency() throws Exception {
-        final Instant startTime = Instant.now();
-        List<Thread> threads = new ArrayList<>();
-        a1ClientFactory.setResponseDelay(Duration.ofMillis(1));
-        addRic("ric");
-        addPolicyType("type1", "ric");
-        addPolicyType("type2", "ric");
-        List<ConcurrencyTestRunnable> tests = new ArrayList<>();
-
-        for (int i = 0; i < 10; ++i) {
-            ConcurrencyTestRunnable test =
-                new ConcurrencyTestRunnable(restClient(), supervision, a1ClientFactory, rics, policyTypes);
-            Thread thread = new Thread(test, "TestThread_" + i);
-            thread.start();
-            threads.add(thread);
-            tests.add(test);
-        }
-        for (Thread t : threads) {
-            t.join();
-        }
-        for (ConcurrencyTestRunnable test : tests) {
-            assertThat(test.isFailed()).isFalse();
-        }
-
-        assertThat(policies.size()).isZero();
-        logger.info("Concurrency test took " + Duration.between(startTime, Instant.now()));
-    }
-
-    private AsyncRestClient restClient(boolean useTrustValidation) {
-        WebClientConfig config = this.applicationConfig.getWebClientConfig();
-        config = ImmutableWebClientConfig.builder() //
-            .keyStoreType(config.keyStoreType()) //
-            .keyStorePassword(config.keyStorePassword()) //
-            .keyStore(config.keyStore()) //
-            .keyPassword(config.keyPassword()) //
-            .isTrustStoreUsed(useTrustValidation) //
-            .trustStore(config.trustStore()) //
-            .trustStorePassword(config.trustStorePassword()) //
-            .build();
-
-        return new AsyncRestClient(baseUrl(), config);
-    }
-
-    private AsyncRestClient restClient() {
-        return restClient(false);
-    }
-
-    private void testErrorCode(Mono<?> request, HttpStatus expStatus) {
-        testErrorCode(request, expStatus, "");
-    }
-
-    private void testErrorCode(Mono<?> request, HttpStatus expStatus, String responseContains) {
-        StepVerifier.create(request) //
-            .expectSubscription() //
-            .expectErrorMatches(t -> checkWebClientError(t, expStatus, responseContains)) //
-            .verify();
-    }
-
-    private boolean checkWebClientError(Throwable throwable, HttpStatus expStatus, String responseContains) {
-        assertTrue(throwable instanceof WebClientResponseException);
-        WebClientResponseException responseException = (WebClientResponseException) throwable;
-        assertThat(responseException.getStatusCode()).isEqualTo(expStatus);
-        assertThat(responseException.getResponseBodyAsString()).contains(responseContains);
-        return true;
-    }
-
-    private MockA1Client getA1Client(String ricName) throws ServiceException {
-        return a1ClientFactory.getOrCreateA1Client(ricName);
-    }
-
-    private PolicyType createPolicyType(String policyTypeName) {
-        return ImmutablePolicyType.builder() //
-            .name(policyTypeName) //
-            .schema("{\"title\":\"" + policyTypeName + "\"}") //
-            .build();
-    }
-
-    private PolicyType addPolicyType(String policyTypeName, String ricName) {
-        PolicyType type = createPolicyType(policyTypeName);
-        policyTypes.put(type);
-        addRic(ricName).addSupportedPolicyType(type);
-        return type;
-    }
-
-    private Ric addRic(String ricName) {
-        return addRic(ricName, null);
-    }
-
-    private Ric addRic(String ricName, String managedElement) {
-        if (rics.get(ricName) != null) {
-            return rics.get(ricName);
-        }
-        List<String> mes = new ArrayList<>();
-        if (managedElement != null) {
-            mes.add(managedElement);
-        }
-        RicConfig conf = ImmutableRicConfig.builder() //
-            .name(ricName) //
-            .baseUrl(ricName) //
-            .managedElementIds(mes) //
-            .controllerName("") //
-            .build();
-        Ric ric = new Ric(conf);
-        ric.setState(Ric.RicState.AVAILABLE);
-        this.rics.put(ric);
-        return ric;
-    }
-
-    private static <T> List<T> parseList(String jsonString, Class<T> clazz) {
-        List<T> result = new ArrayList<>();
-        JsonArray jsonArr = JsonParser.parseString(jsonString).getAsJsonArray();
-        for (JsonElement jsonElement : jsonArr) {
-            T json = gson.fromJson(jsonElement.toString(), clazz);
-            result.add(json);
-        }
-        return result;
-    }
-
-    private static List<String> parseSchemas(String jsonString) {
-        JsonArray arrayOfSchema = JsonParser.parseString(jsonString).getAsJsonArray();
-        List<String> result = new ArrayList<>();
-        for (JsonElement schemaObject : arrayOfSchema) {
-            result.add(schemaObject.toString());
-        }
-        return result;
-    }
-}
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/ConcurrencyTestRunnable.java b/policy-agent/src/test/java/org/oransc/policyagent/ConcurrencyTestRunnable.java
deleted file mode 100644 (file)
index 0ca5534..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent;
-
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.oransc.policyagent.clients.AsyncRestClient;
-import org.oransc.policyagent.repository.ImmutablePolicy;
-import org.oransc.policyagent.repository.Policy;
-import org.oransc.policyagent.repository.PolicyType;
-import org.oransc.policyagent.repository.PolicyTypes;
-import org.oransc.policyagent.repository.Ric;
-import org.oransc.policyagent.repository.Rics;
-import org.oransc.policyagent.tasks.RicSupervision;
-import org.oransc.policyagent.utils.MockA1Client;
-import org.oransc.policyagent.utils.MockA1ClientFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.http.ResponseEntity;
-
-/**
- * Invoke operations over the NBI and start synchronizations in a separate
- * thread. For test of robustness using concurrent clients.
- */
-class ConcurrencyTestRunnable implements Runnable {
-    private static final Logger logger = LoggerFactory.getLogger(ConcurrencyTestRunnable.class);
-    private final AsyncRestClient webClient;
-    static AtomicInteger nextCount = new AtomicInteger(0);
-    private final int count;
-    private final RicSupervision supervision;
-    private final MockA1ClientFactory a1ClientFactory;
-    private final Rics rics;
-    private final PolicyTypes types;
-    private boolean failed = false;
-
-    ConcurrencyTestRunnable(AsyncRestClient webClient, RicSupervision supervision, MockA1ClientFactory a1ClientFactory,
-        Rics rics, PolicyTypes types) {
-        this.count = nextCount.incrementAndGet();
-        this.supervision = supervision;
-        this.a1ClientFactory = a1ClientFactory;
-        this.rics = rics;
-        this.types = types;
-        this.webClient = webClient;
-    }
-
-    private void printStatusInfo() {
-        try {
-            String url = "/actuator/metrics/jvm.threads.live";
-            ResponseEntity<String> result = webClient.getForEntity(url).block();
-            System.out.println(Thread.currentThread() + result.getBody());
-
-            url = "/rics";
-            result = webClient.getForEntity(url).block();
-            System.out.println(Thread.currentThread() + result.getBody());
-
-        } catch (Exception e) {
-            logger.error(Thread.currentThread() + "Concurrency test printStatusInfo exception " + e.toString());
-        }
-    }
-
-    @Override
-    public void run() {
-        try {
-            for (int i = 0; i < 500; ++i) {
-                if (i % 100 == 0) {
-                    createInconsistency();
-                    this.supervision.checkAllRics();
-                }
-                String name = "policy:" + count + ":" + i;
-                putPolicy(name);
-                putPolicy(name + "-");
-                listPolicies();
-                listTypes();
-                deletePolicy(name);
-                deletePolicy(name + "-");
-            }
-        } catch (Exception e) {
-            logger.error("Concurrency test exception " + e.toString());
-            printStatusInfo();
-            failed = true;
-        }
-    }
-
-    public boolean isFailed() {
-        return this.failed;
-    }
-
-    private Policy createPolicyObject(String id) {
-        Ric ric = this.rics.get("ric");
-        PolicyType type = this.types.get("type1");
-        return ImmutablePolicy.builder() //
-            .id(id) //
-            .json("{}") //
-            .type(type) //
-            .ric(ric) //
-            .ownerServiceName("") //
-            .lastModified("") //
-            .isTransient(false) //
-            .build();
-    }
-
-    private void createInconsistency() {
-        MockA1Client client = a1ClientFactory.getOrCreateA1Client("ric");
-        Policy policy = createPolicyObject("junk");
-        client.putPolicy(policy).block();
-
-    }
-
-    private void listPolicies() {
-        String uri = "/policies";
-        webClient.getForEntity(uri).block();
-    }
-
-    private void listTypes() {
-        String uri = "/policy_types";
-        webClient.getForEntity(uri).block();
-    }
-
-    private void putPolicy(String name) {
-        String putUrl = "/policy?type=type1&id=" + name + "&ric=ric&service=service1";
-        webClient.putForEntity(putUrl, "{}").block();
-    }
-
-    private void deletePolicy(String name) {
-        String deleteUrl = "/policy?id=" + name;
-        webClient.delete(deleteUrl).block();
-    }
-}
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/MockPolicyAgent.java b/policy-agent/src/test/java/org/oransc/policyagent/MockPolicyAgent.java
deleted file mode 100644 (file)
index f42a631..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent;
-
-import static org.awaitility.Awaitility.await;
-
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.nio.file.Files;
-
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.oransc.policyagent.configuration.ApplicationConfig;
-import org.oransc.policyagent.repository.ImmutablePolicy;
-import org.oransc.policyagent.repository.ImmutablePolicyType;
-import org.oransc.policyagent.repository.Policies;
-import org.oransc.policyagent.repository.Policy;
-import org.oransc.policyagent.repository.PolicyType;
-import org.oransc.policyagent.repository.PolicyTypes;
-import org.oransc.policyagent.repository.Ric;
-import org.oransc.policyagent.repository.Rics;
-import org.oransc.policyagent.utils.MockA1ClientFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
-import org.springframework.boot.test.context.TestConfiguration;
-import org.springframework.boot.web.server.LocalServerPort;
-import org.springframework.context.annotation.Bean;
-import org.springframework.test.context.TestPropertySource;
-import org.springframework.test.context.junit.jupiter.SpringExtension;
-import org.springframework.util.StringUtils;
-
-@ExtendWith(SpringExtension.class)
-@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT)
-@TestPropertySource(
-    properties = { //
-        "server.ssl.key-store=./config/keystore.jks", //
-        "app.webclient.trust-store=./config/truststore.jks"})
-class MockPolicyAgent {
-    private static final Logger logger = LoggerFactory.getLogger(MockPolicyAgent.class);
-
-    @Autowired
-    Rics rics;
-
-    @Autowired
-    Policies policies;
-
-    @Autowired
-    PolicyTypes policyTypes;
-
-    @Autowired
-    ApplicationConfig applicationConfig;
-
-    static class MockApplicationConfig extends ApplicationConfig {
-        @Override
-        public String getLocalConfigurationFilePath() {
-            URL url = MockApplicationConfig.class.getClassLoader().getResource("test_application_configuration.json");
-            return url.getFile();
-        }
-    }
-
-    /**
-     * Overrides the BeanFactory.
-     */
-    @TestConfiguration
-    static class TestBeanFactory {
-
-        private final Rics rics = new Rics();
-        private final Policies policies = new Policies();
-        private final PolicyTypes policyTypes = new PolicyTypes();
-
-        @Bean
-        public ApplicationConfig getApplicationConfig() {
-            return new MockApplicationConfig();
-        }
-
-        @Bean
-        public MockA1ClientFactory getA1ClientFactory() {
-            PolicyTypes ricTypes = new PolicyTypes();
-            loadTypes(ricTypes);
-            return new MockA1ClientFactory(ricTypes);
-        }
-
-        @Bean
-        public Policies getPolicies() {
-            return this.policies;
-        }
-
-        @Bean
-        public PolicyTypes getPolicyTypes() {
-            return this.policyTypes;
-        }
-
-        @Bean
-        public Rics getRics() {
-            return this.rics;
-        }
-
-        private static File[] getResourceFolderFiles(String folder) {
-            return getFile(folder).listFiles();
-        }
-
-        private static String readFile(File file) throws IOException {
-            return new String(Files.readAllBytes(file.toPath()));
-        }
-
-        private void loadTypes(PolicyTypes policyTypes) {
-            File[] files = getResourceFolderFiles("policy_types/");
-            for (File file : files) {
-                try {
-                    String schema = readFile(file);
-                    String typeName = title(schema);
-                    PolicyType type = ImmutablePolicyType.builder().name(typeName).schema(schema).build();
-                    policyTypes.put(type);
-                } catch (Exception e) {
-                    logger.error("Could not load json schema ", e);
-                }
-            }
-            policyTypes.put(ImmutablePolicyType.builder().name("").schema("{}").build());
-        }
-    }
-
-    private static File getFile(String path) {
-        ClassLoader loader = Thread.currentThread().getContextClassLoader();
-        URL url = loader.getResource(path);
-        return new File(url.getPath());
-    }
-
-    @LocalServerPort
-    private int port;
-
-    private void keepServerAlive() throws InterruptedException, IOException {
-        waitForConfigurationToBeLoaded();
-        loadInstances();
-        logger.info("Keeping server alive!");
-        synchronized (this) {
-            this.wait();
-        }
-    }
-
-    private void waitForConfigurationToBeLoaded() throws IOException {
-        String json = getConfigJsonFromFile();
-        try {
-            int noOfRicsInConfigFile = StringUtils.countOccurrencesOf(json, "baseUrl");
-            await().until(() -> rics.size() == noOfRicsInConfigFile);
-        } catch (Exception e) {
-            logger.info("Loaded rics: {}, and no of rics in config file: {} never matched!", rics.size(),
-                StringUtils.countOccurrencesOf(json, "baseUrl"));
-        }
-    }
-
-    private static String title(String jsonSchema) {
-        JsonObject parsedSchema = (JsonObject) JsonParser.parseString(jsonSchema);
-        String title = parsedSchema.get("title").getAsString();
-        return title;
-    }
-
-    private void loadInstances() throws IOException {
-        PolicyType unnamedPolicyType = policyTypes.get("");
-        Ric ric = rics.get("ric1");
-        String json = getConfigJsonFromFile();
-
-        Policy policy = ImmutablePolicy.builder() //
-            .id("typelessPolicy") //
-            .json(json) //
-            .ownerServiceName("MockPolicyAgent") //
-            .ric(ric) //
-            .type(unnamedPolicyType) //
-            .lastModified("now") //
-            .isTransient(false) //
-            .build();
-        this.policies.put(policy);
-    }
-
-    private String getConfigJsonFromFile() throws IOException {
-        File jsonFile = getFile("test_application_configuration.json");
-        String json = new String(Files.readAllBytes(jsonFile.toPath()));
-        return json;
-    }
-
-    @Test
-    @SuppressWarnings("squid:S2699") // Tests should include assertions. This test is only for keeping the server
-                                     // alive, so it will only be confusing to add an assertion.
-    void runMock() throws Exception {
-        keepServerAlive();
-    }
-
-}
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/aspect/LogAspectTest.java b/policy-agent/src/test/java/org/oransc/policyagent/aspect/LogAspectTest.java
deleted file mode 100644 (file)
index ae8ed2c..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.aspect;
-
-import static ch.qos.logback.classic.Level.TRACE;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.read.ListAppender;
-
-import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.reflect.MethodSignature;
-import org.junit.Rule;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.oransc.policyagent.utils.LoggingUtils;
-
-@ExtendWith(MockitoExtension.class)
-class LogAspectTest {
-    @Rule
-    MockitoRule mockitoRule = MockitoJUnit.rule();
-
-    @Mock
-    private ProceedingJoinPoint proceedingJoinPoint;
-
-    @Mock
-    private MethodSignature methodSignature;
-
-    private LogAspect sampleAspect = new LogAspect();
-
-    @Test
-    void testExecutetimeTime_shouldLogTime() throws Throwable {
-        when(proceedingJoinPoint.getSignature()).thenReturn(methodSignature);
-        when(methodSignature.getDeclaringType()).thenReturn(this.getClass());
-
-        final ListAppender<ILoggingEvent> logAppender = LoggingUtils.getLogListAppender(LogAspect.class, TRACE);
-
-        sampleAspect.executimeTime(proceedingJoinPoint);
-        // 'proceed()' is called exactly once
-        verify(proceedingJoinPoint, times(1)).proceed();
-        // 'proceed(Object[])' is never called
-        verify(proceedingJoinPoint, never()).proceed(null);
-
-        assertThat(logAppender.list.get(0).getFormattedMessage()).startsWith("Execution time of");
-    }
-
-    @Test
-    void testEntryLog_shouldLogEntry() throws Throwable {
-        when(proceedingJoinPoint.getSignature()).thenReturn(methodSignature);
-        String signature = "signature";
-        when(methodSignature.getName()).thenReturn(signature);
-
-        final ListAppender<ILoggingEvent> logAppender = LoggingUtils.getLogListAppender(LogAspect.class, TRACE);
-
-        sampleAspect.entryLog(proceedingJoinPoint);
-
-        assertThat(logAppender.list.get(0).getFormattedMessage()).isEqualTo("Entering method: " + signature);
-    }
-
-    @Test
-    void testExitLog_shouldLogExit() throws Throwable {
-        when(proceedingJoinPoint.getSignature()).thenReturn(methodSignature);
-        String signature = "signature";
-        when(methodSignature.getName()).thenReturn(signature);
-
-        final ListAppender<ILoggingEvent> logAppender = LoggingUtils.getLogListAppender(LogAspect.class, TRACE);
-
-        sampleAspect.exitLog(proceedingJoinPoint);
-
-        assertThat(logAppender.list.get(0).getFormattedMessage()).isEqualTo("Exiting method: " + signature);
-    }
-}
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/clients/A1ClientFactoryTest.java b/policy-agent/src/test/java/org/oransc/policyagent/clients/A1ClientFactoryTest.java
deleted file mode 100644 (file)
index 74cebb0..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.clients;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
-import java.util.Vector;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.oransc.policyagent.clients.A1Client.A1ProtocolType;
-import org.oransc.policyagent.configuration.ApplicationConfig;
-import org.oransc.policyagent.configuration.ControllerConfig;
-import org.oransc.policyagent.configuration.ImmutableControllerConfig;
-import org.oransc.policyagent.configuration.ImmutableRicConfig;
-import org.oransc.policyagent.exceptions.ServiceException;
-import org.oransc.policyagent.repository.Ric;
-
-import reactor.core.publisher.Mono;
-import reactor.test.StepVerifier;
-
-@ExtendWith(MockitoExtension.class)
-class A1ClientFactoryTest {
-    private static final String RIC_NAME = "Name";
-    private static final String EXCEPTION_MESSAGE = "Error";
-
-    @Mock
-    private ApplicationConfig applicationConfigMock;
-
-    @Mock
-    A1Client clientMock1;
-
-    @Mock
-    A1Client clientMock2;
-
-    @Mock
-    A1Client clientMock3;
-
-    @Mock
-    A1Client clientMock4;
-
-    private Ric ric;
-    private A1ClientFactory factoryUnderTest;
-
-    private static ImmutableRicConfig ricConfig(String controllerName) {
-        return ImmutableRicConfig.builder() //
-            .name(RIC_NAME) //
-            .baseUrl("baseUrl") //
-            .managedElementIds(new Vector<>()) //
-            .controllerName(controllerName) //
-            .build();
-    }
-
-    @BeforeEach
-    void createFactoryUnderTest() {
-        factoryUnderTest = spy(new A1ClientFactory(applicationConfigMock));
-        this.ric = new Ric(ricConfig(""));
-
-    }
-
-    @Test
-    void getProtocolVersion_ok() throws ServiceException {
-        whenGetProtocolVersionThrowException(clientMock1);
-        whenGetProtocolVersionReturn(clientMock2, A1ProtocolType.STD_V1_1);
-        doReturn(clientMock1, clientMock2).when(factoryUnderTest).createClient(any(), any());
-
-        A1Client client = factoryUnderTest.createA1Client(ric).block();
-
-        assertEquals(clientMock2, client, "Not correct client returned");
-        assertEquals(A1ProtocolType.STD_V1_1, ric.getProtocolVersion(), "Not correct protocol");
-    }
-
-    @Test
-    void getProtocolVersion_ok_Last() throws ServiceException {
-        whenGetProtocolVersionThrowException(clientMock1, clientMock2, clientMock3);
-        whenGetProtocolVersionReturn(clientMock4, A1ProtocolType.STD_V1_1);
-        doReturn(clientMock1, clientMock2, clientMock3, clientMock4).when(factoryUnderTest).createClient(any(), any());
-
-        A1Client client = factoryUnderTest.createA1Client(ric).block();
-
-        assertEquals(clientMock4, client, "Not correct client returned");
-        assertEquals(A1ProtocolType.STD_V1_1, ric.getProtocolVersion(), "Not correct protocol");
-    }
-
-    @Test
-    void getProtocolVersion_error() throws ServiceException {
-        whenGetProtocolVersionThrowException(clientMock1, clientMock2, clientMock3, clientMock4);
-        doReturn(clientMock1, clientMock2, clientMock3, clientMock4).when(factoryUnderTest).createClient(any(), any());
-
-        StepVerifier.create(factoryUnderTest.createA1Client(ric)) //
-            .expectSubscription() //
-            .expectError() //
-            .verify();
-
-        assertEquals(A1ProtocolType.UNKNOWN, ric.getProtocolVersion(), "Protocol negotiation failed for " + ric.name());
-    }
-
-    private A1Client createClient(A1ProtocolType version) throws ServiceException {
-        return factoryUnderTest.createClient(ric, version);
-    }
-
-    @Test
-    void create_check_types() throws ServiceException {
-        assertTrue(createClient(A1ProtocolType.STD_V1_1) instanceof StdA1ClientVersion1);
-        assertTrue(createClient(A1ProtocolType.OSC_V1) instanceof OscA1Client);
-    }
-
-    @Test
-    void create_check_types_controllers() throws ServiceException {
-        this.ric = new Ric(ricConfig("anythingButEmpty"));
-        whenGetGetControllerConfigReturn();
-        assertTrue(createClient(A1ProtocolType.SDNC_ONAP) instanceof SdncOnapA1Client);
-
-        whenGetGetControllerConfigReturn();
-        assertTrue(createClient(A1ProtocolType.SDNC_OSC_STD_V1_1) instanceof SdncOscA1Client);
-
-        whenGetGetControllerConfigReturn();
-        assertTrue(createClient(A1ProtocolType.SDNC_OSC_OSC_V1) instanceof SdncOscA1Client);
-    }
-
-    private void whenGetProtocolVersionThrowException(A1Client... clientMocks) {
-        for (A1Client clientMock : clientMocks) {
-            when(clientMock.getProtocolVersion()).thenReturn(Mono.error(new Exception(EXCEPTION_MESSAGE)));
-        }
-    }
-
-    private void whenGetProtocolVersionReturn(A1Client clientMock, A1ProtocolType protocol) {
-        when(clientMock.getProtocolVersion()).thenReturn(Mono.just(protocol));
-    }
-
-    private void whenGetGetControllerConfigReturn() throws ServiceException {
-        ControllerConfig controllerCfg = ImmutableControllerConfig.builder() //
-            .name("name") //
-            .baseUrl("baseUrl") //
-            .password("pass") //
-            .userName("user") //
-            .build();
-        when(applicationConfigMock.getControllerConfig(any())).thenReturn(controllerCfg);
-    }
-
-}
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/clients/A1ClientHelper.java b/policy-agent/src/test/java/org/oransc/policyagent/clients/A1ClientHelper.java
deleted file mode 100644 (file)
index 722fea7..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.clients;
-
-import java.util.Arrays;
-import java.util.Vector;
-
-import org.json.JSONObject;
-import org.oransc.policyagent.configuration.ImmutableRicConfig;
-import org.oransc.policyagent.configuration.RicConfig;
-import org.oransc.policyagent.repository.ImmutablePolicy;
-import org.oransc.policyagent.repository.ImmutablePolicyType;
-import org.oransc.policyagent.repository.Policy;
-import org.oransc.policyagent.repository.PolicyType;
-import org.oransc.policyagent.repository.Ric;
-import reactor.core.publisher.Mono;
-
-public class A1ClientHelper {
-
-    private A1ClientHelper() {
-    }
-
-    protected static Mono<String> createOutputJsonResponse(String key, String value) {
-        JSONObject paramsJson = new JSONObject();
-        paramsJson.put(key, value);
-        JSONObject responseJson = new JSONObject();
-        responseJson.put("output", paramsJson);
-        return Mono.just(responseJson.toString());
-    }
-
-    protected static Ric createRic(String url) {
-        RicConfig cfg = ImmutableRicConfig.builder().name("ric") //
-            .baseUrl(url) //
-            .managedElementIds(new Vector<String>(Arrays.asList("kista_1", "kista_2"))) //
-            .controllerName("") //
-            .build();
-        return new Ric(cfg);
-    }
-
-    protected static Policy createPolicy(String nearRtRicUrl, String policyId, String json, String type) {
-        return ImmutablePolicy.builder() //
-            .id(policyId) //
-            .json(json) //
-            .ownerServiceName("service") //
-            .ric(createRic(nearRtRicUrl)) //
-            .type(createPolicyType(type)) //
-            .lastModified("now") //
-            .isTransient(false) //
-            .build();
-    }
-
-    protected static PolicyType createPolicyType(String name) {
-        return ImmutablePolicyType.builder().name(name).schema("schema").build();
-    }
-
-    protected static String getCreateSchema(String policyType, String policyTypeId) {
-        JSONObject obj = new JSONObject(policyType);
-        JSONObject schemaObj = obj.getJSONObject("create_schema");
-        schemaObj.put("title", policyTypeId);
-        return schemaObj.toString();
-    }
-}
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/clients/AsyncRestClientTest.java b/policy-agent/src/test/java/org/oransc/policyagent/clients/AsyncRestClientTest.java
deleted file mode 100644 (file)
index f3b9482..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.clients;
-
-import io.netty.util.internal.logging.InternalLoggerFactory;
-import io.netty.util.internal.logging.JdkLoggerFactory;
-
-import java.io.IOException;
-
-import okhttp3.mockwebserver.MockResponse;
-import okhttp3.mockwebserver.MockWebServer;
-
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.MediaType;
-import org.springframework.web.reactive.function.client.WebClientResponseException;
-
-import reactor.core.publisher.Mono;
-import reactor.test.StepVerifier;
-import reactor.util.Loggers;
-
-class AsyncRestClientTest {
-    private static final String BASE_URL = "BaseUrl";
-    private static final String REQUEST_URL = "/test";
-    private static final String USERNAME = "username";
-    private static final String PASSWORD = "password";
-    private static final String TEST_JSON = "{\"type\":\"type1\"}";
-    private static final int SUCCESS_CODE = 200;
-    private static final int ERROR_CODE = 500;
-
-    private static MockWebServer mockWebServer;
-
-    private static AsyncRestClient clientUnderTest;
-
-    @BeforeAll
-    static void init() {
-        // skip a lot of unnecessary logs from MockWebServer
-        InternalLoggerFactory.setDefaultFactory(JdkLoggerFactory.INSTANCE);
-        Loggers.useJdkLoggers();
-        mockWebServer = new MockWebServer();
-        clientUnderTest = new AsyncRestClient(mockWebServer.url(BASE_URL).toString());
-    }
-
-    @AfterAll
-    static void tearDown() throws IOException {
-        mockWebServer.shutdown();
-    }
-
-    @Test
-    void testGetNoError() {
-        mockWebServer.enqueue(new MockResponse().setResponseCode(SUCCESS_CODE) //
-            .setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) //
-            .setBody(TEST_JSON));
-
-        Mono<String> returnedMono = clientUnderTest.get(REQUEST_URL);
-        StepVerifier.create(returnedMono).expectNext(TEST_JSON).expectComplete().verify();
-    }
-
-    @Test
-    void testGetError() {
-        mockWebServer.enqueue(new MockResponse().setResponseCode(ERROR_CODE));
-
-        Mono<String> returnedMono = clientUnderTest.get(REQUEST_URL);
-        StepVerifier.create(returnedMono)
-            .expectErrorMatches(throwable -> throwable instanceof WebClientResponseException).verify();
-    }
-
-    @Test
-    void testPutNoError() {
-        mockWebServer.enqueue(new MockResponse().setResponseCode(SUCCESS_CODE) //
-            .setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) //
-            .setBody(TEST_JSON));
-
-        Mono<String> returnedMono = clientUnderTest.put(REQUEST_URL, TEST_JSON);
-        StepVerifier.create(returnedMono).expectNext(TEST_JSON).expectComplete().verify();
-    }
-
-    @Test
-    void testPutError() {
-        mockWebServer.enqueue(new MockResponse().setResponseCode(ERROR_CODE));
-
-        Mono<String> returnedMono = clientUnderTest.put(REQUEST_URL, TEST_JSON);
-        StepVerifier.create(returnedMono)
-            .expectErrorMatches(throwable -> throwable instanceof WebClientResponseException).verify();
-    }
-
-    @Test
-    void testDeleteNoError() {
-        mockWebServer.enqueue(new MockResponse().setResponseCode(SUCCESS_CODE));
-
-        Mono<String> returnedMono = clientUnderTest.delete(REQUEST_URL);
-        StepVerifier.create(returnedMono).expectNext("").expectComplete().verify();
-    }
-
-    @Test
-    void testDeleteError() {
-        mockWebServer.enqueue(new MockResponse().setResponseCode(ERROR_CODE));
-
-        Mono<String> returnedMono = clientUnderTest.delete(REQUEST_URL);
-        StepVerifier.create(returnedMono)
-            .expectErrorMatches(throwable -> throwable instanceof WebClientResponseException).verify();
-    }
-
-    @Test
-    void testPostNoError() {
-        mockWebServer.enqueue(new MockResponse().setResponseCode(SUCCESS_CODE) //
-            .setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) //
-            .setBody(TEST_JSON));
-
-        Mono<String> returnedMono = clientUnderTest.post(REQUEST_URL, TEST_JSON);
-        StepVerifier.create(returnedMono).expectNext(TEST_JSON).expectComplete().verify();
-    }
-
-    @Test
-    void testPostError() {
-        mockWebServer.enqueue(new MockResponse().setResponseCode(ERROR_CODE));
-
-        Mono<String> returnedMono = clientUnderTest.post(REQUEST_URL, TEST_JSON);
-        StepVerifier.create(returnedMono)
-            .expectErrorMatches(throwable -> throwable instanceof WebClientResponseException).verify();
-    }
-
-    @Test
-    void testPostWithAuthHeaderNoError() {
-        mockWebServer.enqueue(new MockResponse().setResponseCode(SUCCESS_CODE) //
-            .setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) //
-            .setBody(TEST_JSON));
-
-        Mono<String> returnedMono = clientUnderTest.postWithAuthHeader(REQUEST_URL, TEST_JSON, USERNAME, PASSWORD);
-        StepVerifier.create(returnedMono).expectNext(TEST_JSON).expectComplete().verify();
-    }
-
-    @Test
-    void testPostWithAuthHeaderError() {
-        mockWebServer.enqueue(new MockResponse().setResponseCode(ERROR_CODE));
-
-        Mono<String> returnedMono = clientUnderTest.postWithAuthHeader(REQUEST_URL, TEST_JSON, USERNAME, PASSWORD);
-        StepVerifier.create(returnedMono)
-            .expectErrorMatches(throwable -> throwable instanceof WebClientResponseException).verify();
-    }
-}
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/clients/OscA1ClientTest.java b/policy-agent/src/test/java/org/oransc/policyagent/clients/OscA1ClientTest.java
deleted file mode 100644 (file)
index d23276d..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.clients;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.json.JSONException;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.oransc.policyagent.configuration.ImmutableRicConfig;
-import org.oransc.policyagent.configuration.RicConfig;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-import reactor.test.StepVerifier;
-
-@ExtendWith(MockitoExtension.class)
-class OscA1ClientTest {
-
-    private static final String RIC_URL = "RicUrl";
-
-    private static final String RIC_BASE_URL = "RicBaseUrl/a1-p";
-
-    private static final String POLICYTYPES_IDENTITIES_URL = RIC_BASE_URL + "/policytypes";
-    private static final String POLICIES = "/policies";
-    private static final String POLICYTYPES_URL = RIC_BASE_URL + "/policytypes/";
-    private static final String POLICY_TYPE_1_ID = "type1";
-    private static final String POLICY_TYPE_2_ID = "type2";
-    private static final String POLICY_TYPE_SCHEMA_VALID = "{\"type\":\"type1\"}";
-    private static final String POLICY_TYPE_SCHEMA_INVALID = "\"type\":\"type1\"}";
-    private static final String POLICY_1_ID = "policy1";
-    private static final String POLICY_2_ID = "policy2";
-    private static final String POLICY_JSON_VALID = "{\"policyId\":\"policy1\"}";
-
-    OscA1Client clientUnderTest;
-
-    AsyncRestClient asyncRestClientMock;
-
-    @BeforeEach
-    void init() {
-        RicConfig ricConfig = ImmutableRicConfig.builder() //
-            .name("name") //
-            .baseUrl("RicBaseUrl") //
-            .managedElementIds(new ArrayList<>()) //
-            .controllerName("") //
-            .build();
-        asyncRestClientMock = mock(AsyncRestClient.class);
-        clientUnderTest = new OscA1Client(ricConfig, asyncRestClientMock);
-    }
-
-    @Test
-    void testGetPolicyTypeIdentities() {
-        List<String> policyTypeIds = Arrays.asList(POLICY_TYPE_1_ID, POLICY_TYPE_2_ID);
-        Mono<String> policyTypeIdsResp = Mono.just(policyTypeIds.toString());
-        when(asyncRestClientMock.get(anyString())).thenReturn(policyTypeIdsResp);
-
-        Mono<List<String>> returnedMono = clientUnderTest.getPolicyTypeIdentities();
-        verify(asyncRestClientMock).get(POLICYTYPES_IDENTITIES_URL);
-        StepVerifier.create(returnedMono).expectNext(policyTypeIds).expectComplete().verify();
-    }
-
-    @Test
-    void testGetPolicyIdentities() {
-        Mono<String> policyTypeIdsResp = Mono.just(Arrays.asList(POLICY_TYPE_1_ID, POLICY_TYPE_2_ID).toString());
-        Mono<String> policyIdsType1Resp = Mono.just(Arrays.asList(POLICY_1_ID).toString());
-        Mono<String> policyIdsType2Resp = Mono.just(Arrays.asList(POLICY_2_ID).toString());
-        when(asyncRestClientMock.get(anyString())).thenReturn(policyTypeIdsResp).thenReturn(policyIdsType1Resp)
-            .thenReturn(policyIdsType2Resp);
-
-        List<String> returned = clientUnderTest.getPolicyIdentities().block();
-
-        assertEquals(2, returned.size(), "");
-        verify(asyncRestClientMock).get(POLICYTYPES_IDENTITIES_URL);
-        verify(asyncRestClientMock).get(POLICYTYPES_URL + POLICY_TYPE_1_ID + POLICIES);
-        verify(asyncRestClientMock).get(POLICYTYPES_URL + POLICY_TYPE_2_ID + POLICIES);
-    }
-
-    @Test
-    void testGetValidPolicyType() {
-        String policyType = "{\"create_schema\": " + POLICY_TYPE_SCHEMA_VALID + "}";
-        Mono<String> policyTypeResp = Mono.just(policyType);
-
-        when(asyncRestClientMock.get(anyString())).thenReturn(policyTypeResp);
-
-        Mono<String> returnedMono = clientUnderTest.getPolicyTypeSchema(POLICY_TYPE_1_ID);
-        verify(asyncRestClientMock).get(POLICYTYPES_URL + POLICY_TYPE_1_ID);
-        StepVerifier.create(returnedMono).expectNext(A1ClientHelper.getCreateSchema(policyType, POLICY_TYPE_1_ID))
-            .expectComplete().verify();
-    }
-
-    @Test
-    void testGetInValidPolicyTypeJson() {
-        String policyType = "{\"create_schema\": " + POLICY_TYPE_SCHEMA_INVALID + "}";
-        Mono<String> policyTypeResp = Mono.just(policyType);
-
-        when(asyncRestClientMock.get(anyString())).thenReturn(policyTypeResp);
-
-        Mono<String> returnedMono = clientUnderTest.getPolicyTypeSchema(POLICY_TYPE_1_ID);
-        verify(asyncRestClientMock).get(POLICYTYPES_URL + POLICY_TYPE_1_ID);
-        StepVerifier.create(returnedMono).expectErrorMatches(throwable -> throwable instanceof JSONException).verify();
-    }
-
-    @Test
-    void testGetPolicyTypeWithoutCreateSchema() {
-        Mono<String> policyTypeResp = Mono.just(POLICY_TYPE_SCHEMA_VALID);
-
-        when(asyncRestClientMock.get(anyString())).thenReturn(policyTypeResp);
-
-        Mono<String> returnedMono = clientUnderTest.getPolicyTypeSchema(POLICY_TYPE_1_ID);
-        verify(asyncRestClientMock).get(POLICYTYPES_URL + POLICY_TYPE_1_ID);
-        StepVerifier.create(returnedMono).expectErrorMatches(throwable -> throwable instanceof Exception).verify();
-    }
-
-    @Test
-    void testPutPolicy() {
-        when(asyncRestClientMock.put(anyString(), anyString())).thenReturn(Mono.empty());
-
-        clientUnderTest
-            .putPolicy(A1ClientHelper.createPolicy(RIC_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE_1_ID)).block();
-        verify(asyncRestClientMock).put(POLICYTYPES_URL + POLICY_TYPE_1_ID + POLICIES + "/" + POLICY_1_ID,
-            POLICY_JSON_VALID);
-    }
-
-    @Test
-    void testDeletePolicy() {
-        when(asyncRestClientMock.delete(anyString())).thenReturn(Mono.empty());
-
-        Mono<String> returnedMono = clientUnderTest
-            .deletePolicy(A1ClientHelper.createPolicy(RIC_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE_1_ID));
-        verify(asyncRestClientMock).delete(POLICYTYPES_URL + POLICY_TYPE_1_ID + POLICIES + "/" + POLICY_1_ID);
-        StepVerifier.create(returnedMono).expectComplete().verify();
-    }
-
-    @Test
-    void testDeleteAllPolicies() {
-        Mono<String> policyTypeIdsResp = Mono.just(Arrays.asList(POLICY_TYPE_1_ID, POLICY_TYPE_2_ID).toString());
-        Mono<String> policyIdsType1Resp = Mono.just(Arrays.asList(POLICY_1_ID).toString());
-        Mono<String> policyIdsType2Resp = Mono.just(Arrays.asList(POLICY_2_ID).toString());
-        when(asyncRestClientMock.get(anyString())).thenReturn(policyTypeIdsResp).thenReturn(policyIdsType1Resp)
-            .thenReturn(policyIdsType2Resp);
-        when(asyncRestClientMock.delete(anyString())).thenReturn(Mono.empty());
-
-        Flux<String> returnedFlux = clientUnderTest.deleteAllPolicies();
-        StepVerifier.create(returnedFlux).expectComplete().verify();
-        verify(asyncRestClientMock).get(POLICYTYPES_IDENTITIES_URL);
-        verify(asyncRestClientMock).get(POLICYTYPES_URL + POLICY_TYPE_1_ID + POLICIES);
-        verify(asyncRestClientMock).delete(POLICYTYPES_URL + POLICY_TYPE_1_ID + POLICIES + "/" + POLICY_1_ID);
-        verify(asyncRestClientMock).get(POLICYTYPES_URL + POLICY_TYPE_2_ID + POLICIES);
-        verify(asyncRestClientMock).delete(POLICYTYPES_URL + POLICY_TYPE_2_ID + POLICIES + "/" + POLICY_2_ID);
-    }
-}
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/clients/SdncOnapA1ClientTest.java b/policy-agent/src/test/java/org/oransc/policyagent/clients/SdncOnapA1ClientTest.java
deleted file mode 100644 (file)
index 6b4ebd6..0000000
+++ /dev/null
@@ -1,271 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.clients;
-
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.json.JSONException;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.mockito.stubbing.OngoingStubbing;
-import org.oransc.policyagent.configuration.ControllerConfig;
-import org.oransc.policyagent.configuration.ImmutableControllerConfig;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-import reactor.test.StepVerifier;
-
-@ExtendWith(MockitoExtension.class)
-class SdncOnapA1ClientTest {
-    private static final String CONTROLLER_USERNAME = "username";
-    private static final String CONTROLLER_PASSWORD = "password";
-    private static final String RIC_1_URL = "RicUrl";
-    private static final String POLICYTYPES_IDENTITIES_URL = "/A1-ADAPTER-API:getPolicyTypes";
-    private static final String POLICIES_IDENTITIES_URL = "/A1-ADAPTER-API:getPolicyInstances";
-    private static final String POLICYTYPES_URL = "/A1-ADAPTER-API:getPolicyType";
-    private static final String PUT_POLICY_URL = "/A1-ADAPTER-API:createPolicyInstance";
-    private static final String DELETE_POLICY_URL = "/A1-ADAPTER-API:deletePolicyInstance";
-
-    private static final String POLICY_TYPE_1_ID = "type1";
-    private static final String POLICY_TYPE_2_ID = "type2";
-    private static final String POLICY_TYPE_SCHEMA_VALID = "{\"type\":\"type1\"}";
-    private static final String POLICY_TYPE_SCHEMA_INVALID = "\"type\":\"type1\"}";
-    private static final String POLICY_1_ID = "policy1";
-    private static final String POLICY_2_ID = "policy2";
-    private static final String POLICY_JSON_VALID = "{\"scope\":{\"ueId\":\"ue1\"}}";
-
-    SdncOnapA1Client clientUnderTest;
-
-    AsyncRestClient asyncRestClientMock;
-
-    @BeforeEach
-    void init() {
-        asyncRestClientMock = mock(AsyncRestClient.class);
-        ControllerConfig controllerCfg = ImmutableControllerConfig.builder() //
-            .name("name") //
-            .baseUrl("baseUrl") //
-            .password(CONTROLLER_PASSWORD) //
-            .userName(CONTROLLER_USERNAME) //
-            .build();
-
-        clientUnderTest =
-            new SdncOnapA1Client(A1ClientHelper.createRic(RIC_1_URL).getConfig(), controllerCfg, asyncRestClientMock);
-    }
-
-    @Test
-    void testGetPolicyTypeIdentities() {
-        SdncOnapA1Client.SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() //
-            .nearRtRicId(RIC_1_URL) //
-            .build();
-        String inputJsonString = SdncJsonHelper.createInputJsonString(inputParams);
-
-        List<String> policyTypeIds = Arrays.asList(POLICY_TYPE_1_ID, POLICY_TYPE_2_ID);
-        Mono<String> policyTypeIdsResp =
-            A1ClientHelper.createOutputJsonResponse("policy-type-id-list", policyTypeIds.toString());
-        whenAsyncPostThenReturn(policyTypeIdsResp);
-
-        Mono<List<String>> returnedMono = clientUnderTest.getPolicyTypeIdentities();
-        verify(asyncRestClientMock).postWithAuthHeader(POLICYTYPES_IDENTITIES_URL, inputJsonString, CONTROLLER_USERNAME,
-            CONTROLLER_PASSWORD);
-        StepVerifier.create(returnedMono).expectNext(policyTypeIds).expectComplete().verify();
-    }
-
-    @Test
-    void testGetPolicyIdentities() {
-        SdncOnapA1Client.SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() //
-            .nearRtRicId(RIC_1_URL) //
-            .build();
-        String inputJsonStringGetTypeIds = SdncJsonHelper.createInputJsonString(inputParams);
-        inputParams = ImmutableSdncOnapAdapterInput.builder() //
-            .nearRtRicId(RIC_1_URL) //
-            .policyTypeId(POLICY_TYPE_1_ID) //
-            .build();
-        String inputJsonStringGetPolicyIdsType1 = SdncJsonHelper.createInputJsonString(inputParams);
-        inputParams = ImmutableSdncOnapAdapterInput.builder() //
-            .nearRtRicId(RIC_1_URL) //
-            .policyTypeId(POLICY_TYPE_2_ID) //
-            .build();
-        String inputJsonStringGetPolicyIdsType2 = SdncJsonHelper.createInputJsonString(inputParams);
-
-        List<String> policyTypeIds = Arrays.asList(POLICY_TYPE_1_ID, POLICY_TYPE_2_ID);
-        Mono<String> policyTypeIdsResp =
-            A1ClientHelper.createOutputJsonResponse("policy-type-id-list", policyTypeIds.toString());
-        List<String> policyIdsType1 = Arrays.asList(POLICY_1_ID);
-        Mono<String> policyIdsType1Resp =
-            A1ClientHelper.createOutputJsonResponse("policy-instance-id-list", policyIdsType1.toString());
-        List<String> policyIdsType2 = Arrays.asList(POLICY_2_ID);
-        Mono<String> policyIdsType2Resp =
-            A1ClientHelper.createOutputJsonResponse("policy-instance-id-list", policyIdsType2.toString());
-        whenAsyncPostThenReturn(policyTypeIdsResp).thenReturn(policyIdsType1Resp).thenReturn(policyIdsType2Resp);
-
-        Mono<List<String>> returnedMono = clientUnderTest.getPolicyIdentities();
-        StepVerifier.create(returnedMono).expectNext(Arrays.asList(POLICY_1_ID, POLICY_2_ID)).expectComplete().verify();
-        verify(asyncRestClientMock).postWithAuthHeader(POLICYTYPES_IDENTITIES_URL, inputJsonStringGetTypeIds,
-            CONTROLLER_USERNAME, CONTROLLER_PASSWORD);
-        verify(asyncRestClientMock).postWithAuthHeader(POLICIES_IDENTITIES_URL, inputJsonStringGetPolicyIdsType1,
-            CONTROLLER_USERNAME, CONTROLLER_PASSWORD);
-        verify(asyncRestClientMock).postWithAuthHeader(POLICIES_IDENTITIES_URL, inputJsonStringGetPolicyIdsType2,
-            CONTROLLER_USERNAME, CONTROLLER_PASSWORD);
-    }
-
-    @Test
-    void testGetValidPolicyType() {
-        SdncOnapA1Client.SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() //
-            .nearRtRicId(RIC_1_URL) //
-            .policyTypeId(POLICY_TYPE_1_ID) //
-            .build();
-        String inputJsonString = SdncJsonHelper.createInputJsonString(inputParams);
-
-        String policyType = "{\"policySchema\": " + POLICY_TYPE_SCHEMA_VALID + ", \"statusSchema\": {} }";
-        Mono<String> policyTypeResp = A1ClientHelper.createOutputJsonResponse("policy-type", policyType);
-        whenAsyncPostThenReturn(policyTypeResp);
-
-        Mono<String> returnedMono = clientUnderTest.getPolicyTypeSchema(POLICY_TYPE_1_ID);
-        verify(asyncRestClientMock).postWithAuthHeader(POLICYTYPES_URL, inputJsonString, CONTROLLER_USERNAME,
-            CONTROLLER_PASSWORD);
-        StepVerifier.create(returnedMono).expectNext(POLICY_TYPE_SCHEMA_VALID).expectComplete().verify();
-    }
-
-    @Test
-    void testGetInvalidPolicyType() {
-        SdncOnapA1Client.SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() //
-            .nearRtRicId(RIC_1_URL) //
-            .policyTypeId(POLICY_TYPE_1_ID) //
-            .build();
-        String inputJsonString = SdncJsonHelper.createInputJsonString(inputParams);
-
-        String policyType = "{\"policySchema\": " + POLICY_TYPE_SCHEMA_INVALID + ", \"statusSchema\": {} }";
-        Mono<String> policyTypeResp = A1ClientHelper.createOutputJsonResponse("policy-type", policyType);
-        whenAsyncPostThenReturn(policyTypeResp);
-
-        Mono<String> returnedMono = clientUnderTest.getPolicyTypeSchema(POLICY_TYPE_1_ID);
-        verify(asyncRestClientMock).postWithAuthHeader(POLICYTYPES_URL, inputJsonString, CONTROLLER_USERNAME,
-            CONTROLLER_PASSWORD);
-        StepVerifier.create(returnedMono).expectErrorMatches(throwable -> throwable instanceof JSONException).verify();
-    }
-
-    @Test
-    void testPutPolicy() {
-        SdncOnapA1Client.SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() //
-            .nearRtRicId(RIC_1_URL) //
-            .policyTypeId(POLICY_TYPE_1_ID) //
-            .policyInstanceId(POLICY_1_ID) //
-            .policyInstance(POLICY_JSON_VALID) //
-            .properties(new ArrayList<String>()) //
-            .build();
-        String inputJsonString = SdncJsonHelper.createInputJsonString(inputParams);
-
-        whenAsyncPostThenReturn(Mono.empty());
-
-        Mono<String> returnedMono = clientUnderTest
-            .putPolicy(A1ClientHelper.createPolicy(RIC_1_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE_1_ID));
-        verify(asyncRestClientMock).postWithAuthHeader(PUT_POLICY_URL, inputJsonString, CONTROLLER_USERNAME,
-            CONTROLLER_PASSWORD);
-        StepVerifier.create(returnedMono).expectComplete().verify();
-    }
-
-    @Test
-    void testDeletePolicy() {
-        SdncOnapA1Client.SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() //
-            .nearRtRicId(RIC_1_URL) //
-            .policyTypeId(POLICY_TYPE_1_ID) //
-            .policyInstanceId(POLICY_1_ID) //
-            .build();
-        String inputJsonString = SdncJsonHelper.createInputJsonString(inputParams);
-
-        whenAsyncPostThenReturn(Mono.empty());
-
-        Mono<String> returnedMono = clientUnderTest
-            .deletePolicy(A1ClientHelper.createPolicy(RIC_1_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE_1_ID));
-        verify(asyncRestClientMock).postWithAuthHeader(DELETE_POLICY_URL, inputJsonString, CONTROLLER_USERNAME,
-            CONTROLLER_PASSWORD);
-        StepVerifier.create(returnedMono).expectComplete().verify();
-    }
-
-    @Test
-    void testDeleteAllPolicies() {
-        SdncOnapA1Client.SdncOnapAdapterInput inputParams = ImmutableSdncOnapAdapterInput.builder() //
-            .nearRtRicId(RIC_1_URL) //
-            .build();
-        String inputJsonStringGetTypeIds = SdncJsonHelper.createInputJsonString(inputParams);
-        inputParams = ImmutableSdncOnapAdapterInput.builder() //
-            .nearRtRicId(RIC_1_URL) //
-            .policyTypeId(POLICY_TYPE_1_ID) //
-            .build();
-        String inputJsonStringGetPolicyIdsType1 = SdncJsonHelper.createInputJsonString(inputParams);
-        inputParams = ImmutableSdncOnapAdapterInput.builder() //
-            .nearRtRicId(RIC_1_URL) //
-            .policyTypeId(POLICY_TYPE_2_ID) //
-            .build();
-        String inputJsonStringGetPolicyIdsType2 = SdncJsonHelper.createInputJsonString(inputParams);
-        inputParams = ImmutableSdncOnapAdapterInput.builder() //
-            .nearRtRicId(RIC_1_URL) //
-            .policyTypeId(POLICY_TYPE_1_ID) //
-            .policyInstanceId(POLICY_1_ID) //
-            .build();
-        String inputJsonStringDeletePolicy1 = SdncJsonHelper.createInputJsonString(inputParams);
-        inputParams = ImmutableSdncOnapAdapterInput.builder() //
-            .nearRtRicId(RIC_1_URL) //
-            .policyTypeId(POLICY_TYPE_2_ID) //
-            .policyInstanceId(POLICY_2_ID) //
-            .build();
-        String inputJsonStringDeletePolicy2 = SdncJsonHelper.createInputJsonString(inputParams);
-
-        List<String> policyTypeIds = Arrays.asList(POLICY_TYPE_1_ID, POLICY_TYPE_2_ID);
-        Mono<String> policyTypeIdsResp =
-            A1ClientHelper.createOutputJsonResponse("policy-type-id-list", policyTypeIds.toString());
-        List<String> policyIdsType1 = Arrays.asList(POLICY_1_ID);
-        Mono<String> policyIdsType1Resp =
-            A1ClientHelper.createOutputJsonResponse("policy-instance-id-list", policyIdsType1.toString());
-        List<String> policyIdsType2 = Arrays.asList(POLICY_2_ID);
-        Mono<String> policyIdsType2Resp =
-            A1ClientHelper.createOutputJsonResponse("policy-instance-id-list", policyIdsType2.toString());
-        whenAsyncPostThenReturn(policyTypeIdsResp).thenReturn(policyIdsType1Resp).thenReturn(Mono.empty())
-            .thenReturn(policyIdsType2Resp).thenReturn(Mono.empty());
-
-        Flux<String> returnedFlux = clientUnderTest.deleteAllPolicies();
-        StepVerifier.create(returnedFlux).expectComplete().verify();
-        verify(asyncRestClientMock).postWithAuthHeader(POLICYTYPES_IDENTITIES_URL, inputJsonStringGetTypeIds,
-            CONTROLLER_USERNAME, CONTROLLER_PASSWORD);
-        verify(asyncRestClientMock).postWithAuthHeader(POLICIES_IDENTITIES_URL, inputJsonStringGetPolicyIdsType1,
-            CONTROLLER_USERNAME, CONTROLLER_PASSWORD);
-        verify(asyncRestClientMock).postWithAuthHeader(DELETE_POLICY_URL, inputJsonStringDeletePolicy1,
-            CONTROLLER_USERNAME, CONTROLLER_PASSWORD);
-        verify(asyncRestClientMock).postWithAuthHeader(POLICIES_IDENTITIES_URL, inputJsonStringGetPolicyIdsType2,
-            CONTROLLER_USERNAME, CONTROLLER_PASSWORD);
-        verify(asyncRestClientMock).postWithAuthHeader(DELETE_POLICY_URL, inputJsonStringDeletePolicy2,
-            CONTROLLER_USERNAME, CONTROLLER_PASSWORD);
-    }
-
-    private OngoingStubbing<Mono<String>> whenAsyncPostThenReturn(Mono<String> response) {
-        return when(asyncRestClientMock.postWithAuthHeader(anyString(), anyString(), anyString(), anyString()))
-            .thenReturn(response);
-    }
-}
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/clients/SdncOscA1ClientTest.java b/policy-agent/src/test/java/org/oransc/policyagent/clients/SdncOscA1ClientTest.java
deleted file mode 100644 (file)
index a6f6187..0000000
+++ /dev/null
@@ -1,374 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.clients;
-
-import static org.junit.Assert.fail;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import com.google.gson.Gson;
-import com.google.gson.JsonElement;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.nio.file.Files;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Optional;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.mockito.stubbing.OngoingStubbing;
-import org.oransc.policyagent.clients.A1Client.A1ProtocolType;
-import org.oransc.policyagent.clients.ImmutableAdapterOutput.Builder;
-import org.oransc.policyagent.clients.SdncOscA1Client.AdapterOutput;
-import org.oransc.policyagent.clients.SdncOscA1Client.AdapterRequest;
-import org.oransc.policyagent.configuration.ControllerConfig;
-import org.oransc.policyagent.configuration.ImmutableControllerConfig;
-import org.oransc.policyagent.repository.Policy;
-import org.oransc.policyagent.repository.Ric;
-import org.springframework.http.HttpStatus;
-import org.springframework.web.reactive.function.client.WebClientResponseException;
-
-import reactor.core.publisher.Mono;
-import reactor.test.StepVerifier;
-
-@ExtendWith(MockitoExtension.class)
-class SdncOscA1ClientTest {
-    private static final String CONTROLLER_USERNAME = "username";
-    private static final String CONTROLLER_PASSWORD = "password";
-    private static final String RIC_1_URL = "RicUrl";
-    private static final String GET_A1_POLICY_URL = "/A1-ADAPTER-API:getA1Policy";
-    private static final String PUT_A1_URL = "/A1-ADAPTER-API:putA1Policy";
-    private static final String DELETE_A1_URL = "/A1-ADAPTER-API:deleteA1Policy";
-    private static final String GET_A1_POLICY_STATUS_URL = "/A1-ADAPTER-API:getA1PolicyStatus";
-    private static final String POLICY_TYPE_1_ID = "type1";
-    private static final String POLICY_1_ID = "policy1";
-    private static final String POLICY_2_ID = "policy2";
-    private static final String POLICY_JSON_VALID = "{\"scope\":{\"ueId\":\"ue1\"}}";
-
-    SdncOscA1Client clientUnderTest;
-
-    @Mock
-    AsyncRestClient asyncRestClientMock;
-
-    private ControllerConfig controllerConfig() {
-        return ImmutableControllerConfig.builder() //
-            .name("name") //
-            .baseUrl("baseUrl") //
-            .password(CONTROLLER_PASSWORD) //
-            .userName(CONTROLLER_USERNAME) //
-            .build();
-    }
-
-    @BeforeEach
-    void init() {
-        Ric ric = A1ClientHelper.createRic(RIC_1_URL);
-
-        clientUnderTest = new SdncOscA1Client(A1ProtocolType.SDNC_OSC_STD_V1_1, ric.getConfig(), controllerConfig(),
-            asyncRestClientMock);
-    }
-
-    @Test
-    void createClientWithWrongProtocol_thenErrorIsThrown() {
-        try {
-            new SdncOscA1Client(A1ProtocolType.STD_V1_1, null, null, new AsyncRestClient("", null));
-            fail("Should have thrown exception.");
-        } catch (IllegalArgumentException e) {
-            return;
-        }
-    }
-
-    @Test
-    void getPolicyTypeIdentities_STD() {
-        List<String> policyTypeIds = clientUnderTest.getPolicyTypeIdentities().block();
-        assertEquals(1, policyTypeIds.size(), "should hardcoded to one");
-        assertEquals("", policyTypeIds.get(0), "should hardcoded to empty");
-    }
-
-    @Test
-    void getPolicyTypeIdentities_OSC() {
-        clientUnderTest = new SdncOscA1Client(A1ProtocolType.SDNC_OSC_OSC_V1, //
-            A1ClientHelper.createRic(RIC_1_URL).getConfig(), //
-            controllerConfig(), asyncRestClientMock);
-
-        String response = createOkResponseWithBody(Arrays.asList(POLICY_TYPE_1_ID));
-        whenAsyncPostThenReturn(Mono.just(response));
-
-        List<String> policyTypeIds = clientUnderTest.getPolicyTypeIdentities().block();
-
-        assertEquals(1, policyTypeIds.size());
-        assertEquals(POLICY_TYPE_1_ID, policyTypeIds.get(0));
-
-        String expUrl = RIC_1_URL + "/a1-p/policytypes";
-        ImmutableAdapterRequest expectedParams = ImmutableAdapterRequest.builder() //
-            .nearRtRicUrl(expUrl) //
-            .build();
-        String expInput = SdncJsonHelper.createInputJsonString(expectedParams);
-        verify(asyncRestClientMock).postWithAuthHeader(GET_A1_POLICY_URL, expInput, CONTROLLER_USERNAME,
-            CONTROLLER_PASSWORD);
-    }
-
-    @Test
-    void getTypeSchema_STD() {
-        String policyType = clientUnderTest.getPolicyTypeSchema("").block();
-
-        assertEquals("{}", policyType);
-    }
-
-    @Test
-    void getTypeSchema_OSC() throws IOException {
-        clientUnderTest = new SdncOscA1Client(A1ProtocolType.SDNC_OSC_OSC_V1, //
-            A1ClientHelper.createRic(RIC_1_URL).getConfig(), //
-            controllerConfig(), asyncRestClientMock);
-
-        String ricResponse = loadFile("test_osc_get_schema_response.json");
-        JsonElement elem = gson().fromJson(ricResponse, JsonElement.class);
-        String responseFromController = createOkResponseWithBody(elem);
-        whenAsyncPostThenReturn(Mono.just(responseFromController));
-
-        String response = clientUnderTest.getPolicyTypeSchema("policyTypeId").block();
-
-        JsonElement respJson = gson().fromJson(response, JsonElement.class);
-        assertEquals("policyTypeId", respJson.getAsJsonObject().get("title").getAsString(),
-            "title should be updated to contain policyType ID");
-    }
-
-    @Test
-    void parseJsonArrayOfString() {
-        // One integer and one string
-        String inputString = "[1, \"1\" ]";
-
-        List<String> result = SdncJsonHelper.parseJsonArrayOfString(inputString).collectList().block();
-        assertEquals(2, result.size());
-        assertEquals("1", result.get(0));
-        assertEquals("1", result.get(1));
-    }
-
-    @Test
-    void getPolicyIdentities_STD() {
-
-        String policyIdsResp = createOkResponseWithBody(Arrays.asList(POLICY_1_ID, POLICY_2_ID));
-        whenAsyncPostThenReturn(Mono.just(policyIdsResp));
-
-        List<String> returned = clientUnderTest.getPolicyIdentities().block();
-
-        assertEquals(2, returned.size());
-
-        ImmutableAdapterRequest expectedParams = ImmutableAdapterRequest.builder() //
-            .nearRtRicUrl(policiesUrl()) //
-            .build();
-        String expInput = SdncJsonHelper.createInputJsonString(expectedParams);
-        verify(asyncRestClientMock).postWithAuthHeader(GET_A1_POLICY_URL, expInput, CONTROLLER_USERNAME,
-            CONTROLLER_PASSWORD);
-
-    }
-
-    @Test
-    void getPolicyIdentities_OSC() {
-        clientUnderTest = new SdncOscA1Client(A1ProtocolType.SDNC_OSC_OSC_V1, //
-            A1ClientHelper.createRic(RIC_1_URL).getConfig(), //
-            controllerConfig(), asyncRestClientMock);
-
-        String policytypeIdsResp = createOkResponseWithBody(Arrays.asList(POLICY_TYPE_1_ID));
-        String policyIdsResp = createOkResponseWithBody(Arrays.asList(POLICY_1_ID, POLICY_2_ID));
-        whenAsyncPostThenReturn(Mono.just(policytypeIdsResp)).thenReturn(Mono.just(policyIdsResp));
-
-        List<String> returned = clientUnderTest.getPolicyIdentities().block();
-
-        assertEquals(2, returned.size());
-
-        ImmutableAdapterRequest expectedParams = ImmutableAdapterRequest.builder() //
-            .nearRtRicUrl(RIC_1_URL + "/a1-p/policytypes/type1/policies") //
-            .build();
-        String expInput = SdncJsonHelper.createInputJsonString(expectedParams);
-        verify(asyncRestClientMock).postWithAuthHeader(GET_A1_POLICY_URL, expInput, CONTROLLER_USERNAME,
-            CONTROLLER_PASSWORD);
-    }
-
-    @Test
-    void putPolicyValidResponse() {
-        whenPostReturnOkResponse();
-
-        String returned = clientUnderTest
-            .putPolicy(A1ClientHelper.createPolicy(RIC_1_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE_1_ID))
-            .block();
-
-        assertEquals("OK", returned);
-        final String expUrl = policiesUrl() + "/" + POLICY_1_ID;
-        AdapterRequest expectedInputParams = ImmutableAdapterRequest.builder() //
-            .nearRtRicUrl(expUrl) //
-            .body(POLICY_JSON_VALID) //
-            .build();
-        String expInput = SdncJsonHelper.createInputJsonString(expectedInputParams);
-
-        verify(asyncRestClientMock).postWithAuthHeader(PUT_A1_URL, expInput, CONTROLLER_USERNAME, CONTROLLER_PASSWORD);
-    }
-
-    @Test
-    void putPolicyRejected() {
-        final String policyJson = "{}";
-        AdapterOutput adapterOutput = ImmutableAdapterOutput.builder() //
-            .body("NOK") //
-            .httpStatus(HttpStatus.BAD_REQUEST.value()) // ERROR
-            .build();
-
-        String resp = SdncJsonHelper.createOutputJsonString(adapterOutput);
-        whenAsyncPostThenReturn(Mono.just(resp));
-
-        Mono<String> returnedMono = clientUnderTest
-            .putPolicy(A1ClientHelper.createPolicy(RIC_1_URL, POLICY_1_ID, policyJson, POLICY_TYPE_1_ID));
-        StepVerifier.create(returnedMono) //
-            .expectSubscription() //
-            .expectErrorMatches(t -> t instanceof WebClientResponseException) //
-            .verify();
-
-        final String expUrl = policiesUrl() + "/" + POLICY_1_ID;
-        AdapterRequest expRequestParams = ImmutableAdapterRequest.builder() //
-            .nearRtRicUrl(expUrl) //
-            .body(policyJson) //
-            .build();
-        String expRequest = SdncJsonHelper.createInputJsonString(expRequestParams);
-        verify(asyncRestClientMock).postWithAuthHeader(PUT_A1_URL, expRequest, CONTROLLER_USERNAME,
-            CONTROLLER_PASSWORD);
-        StepVerifier.create(returnedMono)
-            .expectErrorMatches(throwable -> throwable instanceof WebClientResponseException).verify();
-    }
-
-    @Test
-    void deletePolicy() {
-        whenPostReturnOkResponse();
-
-        String returned = clientUnderTest
-            .deletePolicy(A1ClientHelper.createPolicy(RIC_1_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE_1_ID))
-            .block();
-
-        assertEquals("OK", returned);
-        final String expUrl = policiesUrl() + "/" + POLICY_1_ID;
-        AdapterRequest expectedInputParams = ImmutableAdapterRequest.builder() //
-            .nearRtRicUrl(expUrl) //
-            .build();
-        String expInput = SdncJsonHelper.createInputJsonString(expectedInputParams);
-
-        verify(asyncRestClientMock).postWithAuthHeader(DELETE_A1_URL, expInput, CONTROLLER_USERNAME,
-            CONTROLLER_PASSWORD);
-    }
-
-    @Test
-    void getStatus() {
-        whenPostReturnOkResponse();
-
-        Policy policy = A1ClientHelper.createPolicy(RIC_1_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE_1_ID);
-
-        String returnedStatus = clientUnderTest.getPolicyStatus(policy).block();
-
-        assertEquals("OK", returnedStatus, "unexpected status");
-
-        final String expUrl = policiesUrl() + "/" + POLICY_1_ID + "/status";
-        AdapterRequest expectedInputParams = ImmutableAdapterRequest.builder() //
-            .nearRtRicUrl(expUrl) //
-            .build();
-        String expInput = SdncJsonHelper.createInputJsonString(expectedInputParams);
-
-        verify(asyncRestClientMock).postWithAuthHeader(GET_A1_POLICY_STATUS_URL, expInput, CONTROLLER_USERNAME,
-            CONTROLLER_PASSWORD);
-    }
-
-    @Test
-    void getVersion_STD() {
-        whenPostReturnOkResponse();
-
-        A1ProtocolType returnedVersion = clientUnderTest.getProtocolVersion().block();
-
-        assertEquals(A1ProtocolType.SDNC_OSC_STD_V1_1, returnedVersion);
-
-        whenPostReturnOkResponseNoBody();
-
-        returnedVersion = clientUnderTest.getProtocolVersion().block();
-
-        assertEquals(A1ProtocolType.SDNC_OSC_STD_V1_1, returnedVersion);
-    }
-
-    @Test
-    void getVersion_OSC() {
-        clientUnderTest = new SdncOscA1Client(A1ProtocolType.SDNC_OSC_OSC_V1, //
-            A1ClientHelper.createRic(RIC_1_URL).getConfig(), //
-            controllerConfig(), asyncRestClientMock);
-
-        whenAsyncPostThenReturn(Mono.error(new Exception("Error"))).thenReturn(Mono.just(createOkResponseString(true)));
-
-        A1ProtocolType returnedVersion = clientUnderTest.getProtocolVersion().block();
-
-        assertEquals(A1ProtocolType.SDNC_OSC_OSC_V1, returnedVersion);
-    }
-
-    private String policiesUrl() {
-        return RIC_1_URL + "/A1-P/v1/policies";
-    }
-
-    private Gson gson() {
-        return SdncOscA1Client.gson;
-    }
-
-    private String loadFile(String fileName) throws IOException {
-        ClassLoader loader = Thread.currentThread().getContextClassLoader();
-        URL url = loader.getResource(fileName);
-        File file = new File(url.getFile());
-        return new String(Files.readAllBytes(file.toPath()));
-    }
-
-    private void whenPostReturnOkResponse() {
-        whenAsyncPostThenReturn(Mono.just(createOkResponseString(true)));
-    }
-
-    private void whenPostReturnOkResponseNoBody() {
-        whenAsyncPostThenReturn(Mono.just(createOkResponseString(false)));
-    }
-
-    private String createOkResponseWithBody(Object body) {
-        AdapterOutput output = ImmutableAdapterOutput.builder() //
-            .body(gson().toJson(body)) //
-            .httpStatus(HttpStatus.OK.value()) //
-            .build();
-        return SdncJsonHelper.createOutputJsonString(output);
-    }
-
-    private String createOkResponseString(boolean withBody) {
-        Builder responseBuilder = ImmutableAdapterOutput.builder().httpStatus(HttpStatus.OK.value());
-        if (withBody) {
-            responseBuilder.body(HttpStatus.OK.name());
-        } else {
-            responseBuilder.body(Optional.empty());
-        }
-        return SdncJsonHelper.createOutputJsonString(responseBuilder.build());
-    }
-
-    private OngoingStubbing<Mono<String>> whenAsyncPostThenReturn(Mono<String> response) {
-        return when(asyncRestClientMock.postWithAuthHeader(anyString(), anyString(), anyString(), anyString()))
-            .thenReturn(response);
-    }
-}
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/clients/StdA1ClientTest.java b/policy-agent/src/test/java/org/oransc/policyagent/clients/StdA1ClientTest.java
deleted file mode 100644 (file)
index beb2ca9..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.clients;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.oransc.policyagent.configuration.RicConfig;
-import org.oransc.policyagent.repository.Policy;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-import reactor.test.StepVerifier;
-
-@ExtendWith(MockitoExtension.class)
-class StdA1ClientTest {
-    private static final String RIC_URL = "RicUrl";
-    private static final String POLICY_TYPE_1_NAME = "type1";
-    private static final String POLICY_1_ID = "policy1";
-    private static final String POLICY_2_ID = "policy2";
-    private static final String POLICY_JSON = "{\"policyId\":\"policy1\"}";
-    private static final String POLICY_TYPE = "typeName";
-
-    StdA1ClientVersion1 clientUnderTest;
-
-    @Mock
-    AsyncRestClient asyncRestClientMock;
-
-    @Mock
-    RicConfig ricConfigMock;
-
-    @BeforeEach
-    void init() {
-        clientUnderTest = new StdA1ClientVersion1(asyncRestClientMock, ricConfigMock);
-    }
-
-    private String policiesUrl() {
-        return RIC_URL + "/A1-P/v1/policies";
-    }
-
-    private String policiesBaseUrl() {
-        return policiesUrl() + "/";
-    }
-
-    @Test
-    void testGetPolicyTypeIdentities() {
-        List<String> policyTypeIds = clientUnderTest.getPolicyTypeIdentities().block();
-        assertEquals(1, policyTypeIds.size(), "should hardcoded to one");
-        assertEquals("", policyTypeIds.get(0), "should hardcoded to empty");
-    }
-
-    @Test
-    void testGetPolicyIdentities() {
-        doReturn(RIC_URL).when(ricConfigMock).baseUrl();
-        Mono<String> policyIds = Mono.just(Arrays.asList(POLICY_1_ID, POLICY_2_ID).toString());
-        when(asyncRestClientMock.get(anyString())).thenReturn(policyIds);
-
-        List<String> result = clientUnderTest.getPolicyIdentities().block();
-        assertEquals(2, result.size(), "");
-
-        verify(asyncRestClientMock).get(policiesUrl());
-    }
-
-    @Test
-    void testGetValidPolicyType() {
-        String policyType = clientUnderTest.getPolicyTypeSchema(POLICY_TYPE_1_NAME).block();
-        assertEquals("{}", policyType, "");
-    }
-
-    @Test
-    void testPutPolicyValidResponse() {
-        doReturn(RIC_URL).when(ricConfigMock).baseUrl();
-        when(asyncRestClientMock.put(anyString(), anyString())).thenReturn(Mono.just(POLICY_JSON));
-
-        Mono<String> policyMono =
-            clientUnderTest.putPolicy(A1ClientHelper.createPolicy(RIC_URL, POLICY_1_ID, POLICY_JSON, POLICY_TYPE));
-
-        verify(asyncRestClientMock).put(policiesBaseUrl() + POLICY_1_ID, POLICY_JSON);
-        StepVerifier.create(policyMono).expectNext(POLICY_JSON).expectComplete().verify();
-    }
-
-    @Test
-    void testDeletePolicy() {
-        doReturn(RIC_URL).when(ricConfigMock).baseUrl();
-        final String url = policiesBaseUrl() + POLICY_1_ID;
-        when(asyncRestClientMock.delete(url)).thenReturn(Mono.empty());
-
-        Policy policy = A1ClientHelper.createPolicy(RIC_URL, POLICY_1_ID, POLICY_JSON, POLICY_TYPE);
-        Mono<?> responseMono = clientUnderTest.deletePolicy(policy);
-        verify(asyncRestClientMock).delete(url);
-        StepVerifier.create(responseMono).expectComplete().verify();
-    }
-
-    @Test
-    void testDeleteAllPolicies() {
-        doReturn(RIC_URL).when(ricConfigMock).baseUrl();
-        Mono<String> policyIds = Mono.just(Arrays.asList(POLICY_1_ID, POLICY_2_ID).toString());
-        when(asyncRestClientMock.get(policiesUrl())).thenReturn(policyIds);
-        when(asyncRestClientMock.delete(anyString())).thenReturn(Mono.empty());
-
-        Flux<String> responseFlux = clientUnderTest.deleteAllPolicies();
-        StepVerifier.create(responseFlux).expectComplete().verify();
-        verify(asyncRestClientMock).get(policiesUrl());
-        verify(asyncRestClientMock).delete(policiesBaseUrl() + POLICY_1_ID);
-        verify(asyncRestClientMock).delete(policiesBaseUrl() + POLICY_2_ID);
-    }
-}
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigParserTest.java b/policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigParserTest.java
deleted file mode 100644 (file)
index 5a6b023..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.configuration;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-import com.google.common.base.Charsets;
-import com.google.common.io.Resources;
-import com.google.gson.Gson;
-import com.google.gson.JsonIOException;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import com.google.gson.JsonSyntaxException;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.util.Map;
-
-import org.junit.jupiter.api.Test;
-import org.oransc.policyagent.exceptions.ServiceException;
-
-class ApplicationConfigParserTest {
-
-    ApplicationConfigParser parserUnderTest = new ApplicationConfigParser();
-
-    @Test
-    void whenCorrectConfig() throws Exception {
-        JsonObject jsonRootObject = getJsonRootObject();
-
-        ApplicationConfigParser.ConfigParserResult result = parserUnderTest.parse(jsonRootObject);
-
-        String topicUrl = result.dmaapProducerTopicUrl();
-        assertEquals("http://admin:admin@localhost:6845/events/A1-POLICY-AGENT-WRITE", topicUrl, "controller contents");
-
-        topicUrl = result.dmaapConsumerTopicUrl();
-        assertEquals(
-            "http://admin:admin@localhost:6845/events/A1-POLICY-AGENT-READ/users/policy-agent?timeout=15000&limit=100",
-            topicUrl, "controller contents");
-
-        Map<String, ControllerConfig> controllers = result.controllerConfigs();
-        assertEquals(1, controllers.size(), "size");
-        ImmutableControllerConfig expectedControllerConfig = ImmutableControllerConfig.builder() //
-            .baseUrl("http://localhost:8083/") //
-            .name("controller1") //
-            .userName("user") //
-            .password("password") //
-            .build(); //
-        assertEquals(expectedControllerConfig, controllers.get("controller1"), "controller contents");
-    }
-
-    private JsonObject getJsonRootObject() throws JsonIOException, JsonSyntaxException, IOException {
-        JsonObject rootObject = JsonParser.parseReader(new InputStreamReader(getCorrectJson())).getAsJsonObject();
-        return rootObject;
-    }
-
-    private static InputStream getCorrectJson() throws IOException {
-        URL url = ApplicationConfigParser.class.getClassLoader()
-            .getResource("test_application_configuration_with_dmaap_config.json");
-        String string = Resources.toString(url, Charsets.UTF_8);
-        return new ByteArrayInputStream((string.getBytes(StandardCharsets.UTF_8)));
-    }
-
-    @Test
-    void whenDmaapConfigHasSeveralStreamsPublishing() throws Exception {
-        JsonObject jsonRootObject = getJsonRootObject();
-        JsonObject json = jsonRootObject.getAsJsonObject("config").getAsJsonObject("streams_publishes");
-        JsonObject fake_info_object = new JsonObject();
-        fake_info_object.addProperty("fake_info", "fake");
-        json.add("fake_info_object", new Gson().toJsonTree(fake_info_object));
-        DataPublishing data = new Gson().fromJson(json.toString(), DataPublishing.class);
-        final String expectedMessage =
-            "Invalid configuration. Number of streams must be one, config: " + data.toString();
-
-        Exception actualException = assertThrows(ServiceException.class, () -> parserUnderTest.parse(jsonRootObject));
-
-        assertEquals(expectedMessage, actualException.getMessage(),
-            "Wrong error message when the DMaaP config has several streams publishing");
-    }
-
-    class DataPublishing {
-        private JsonObject dmaap_publisher;
-        private JsonObject fake_info_object;
-
-        @Override
-        public String toString() {
-            return String.format("[dmaap_publisher=%s, fake_info_object=%s]", dmaap_publisher.toString(),
-                fake_info_object.toString());
-        }
-    }
-
-    @Test
-    void whenDmaapConfigHasSeveralStreamsSubscribing() throws Exception {
-        JsonObject jsonRootObject = getJsonRootObject();
-        JsonObject json = jsonRootObject.getAsJsonObject("config").getAsJsonObject("streams_subscribes");
-        JsonObject fake_info_object = new JsonObject();
-        fake_info_object.addProperty("fake_info", "fake");
-        json.add("fake_info_object", new Gson().toJsonTree(fake_info_object));
-        DataSubscribing data = new Gson().fromJson(json.toString(), DataSubscribing.class);
-        final String expectedMessage =
-            "Invalid configuration. Number of streams must be one, config: " + data.toString();
-
-        Exception actualException = assertThrows(ServiceException.class, () -> parserUnderTest.parse(jsonRootObject));
-
-        assertEquals(expectedMessage, actualException.getMessage(),
-            "Wrong error message when the DMaaP config has several streams subscribing");
-    }
-
-    private class DataSubscribing {
-        private JsonObject dmaap_subscriber;
-        private JsonObject fake_info_object;
-
-        @Override
-        public String toString() {
-            return String.format("[dmaap_subscriber=%s, fake_info_object=%s]", dmaap_subscriber.toString(),
-                fake_info_object.toString());
-        }
-    }
-
-    @Test
-    void whenWrongMemberNameInObject() throws Exception {
-        JsonObject jsonRootObject = getJsonRootObject();
-        JsonObject json = jsonRootObject.getAsJsonObject("config");
-        json.remove("ric");
-        final String message = "Could not find member: 'ric' in: " + json;
-
-        Exception actualException = assertThrows(ServiceException.class, () -> parserUnderTest.parse(jsonRootObject));
-
-        assertEquals(message, actualException.getMessage(), "Wrong error message when wrong member name in object");
-    }
-
-    JsonObject getDmaapInfo(JsonObject jsonRootObject, String streamsPublishesOrSubscribes,
-        String dmaapPublisherOrSubscriber) throws Exception {
-        return jsonRootObject.getAsJsonObject("config").getAsJsonObject(streamsPublishesOrSubscribes)
-            .getAsJsonObject(dmaapPublisherOrSubscriber).getAsJsonObject("dmaap_info");
-    }
-}
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigTest.java b/policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigTest.java
deleted file mode 100644 (file)
index 5667fd2..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.configuration;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Vector;
-
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.oransc.policyagent.configuration.ApplicationConfig.RicConfigUpdate;
-import org.oransc.policyagent.configuration.ApplicationConfigParser.ConfigParserResult;
-import org.oransc.policyagent.exceptions.ServiceException;
-
-@ExtendWith(MockitoExtension.class)
-class ApplicationConfigTest {
-
-    private static final ImmutableRicConfig RIC_CONFIG_1 = ImmutableRicConfig.builder() //
-        .name("ric1") //
-        .baseUrl("ric1_url") //
-        .managedElementIds(new Vector<>()) //
-        .controllerName("") //
-        .build();
-
-    ConfigParserResult configParserResult(RicConfig... rics) {
-        return ImmutableConfigParserResult.builder() //
-            .ricConfigs(Arrays.asList(rics)) //
-            .dmaapConsumerTopicUrl("dmaapConsumerTopicUrl") //
-            .dmaapProducerTopicUrl("dmaapProducerTopicUrl") //
-            .controllerConfigs(new HashMap<>()) //
-            .build();
-    }
-
-    @Test
-    void gettingNotAddedRicShouldThrowException() {
-        ApplicationConfig appConfigUnderTest = new ApplicationConfig();
-
-        appConfigUnderTest.setConfiguration(configParserResult(RIC_CONFIG_1));
-
-        Exception exception = assertThrows(ServiceException.class, () -> {
-            appConfigUnderTest.getRic("name");
-        });
-
-        assertEquals("Could not find ric configuration: name", exception.getMessage());
-    }
-
-    @Test
-    void addRicShouldNotifyAllObserversOfRicAdded() throws Exception {
-        ApplicationConfig appConfigUnderTest = new ApplicationConfig();
-
-        RicConfigUpdate update = appConfigUnderTest.setConfiguration(configParserResult(RIC_CONFIG_1)).blockFirst();
-        assertEquals(RicConfigUpdate.Type.ADDED, update.getType());
-        assertTrue(appConfigUnderTest.getRicConfigs().contains(RIC_CONFIG_1), "Ric not added to configurations.");
-
-        assertEquals(RIC_CONFIG_1, appConfigUnderTest.getRic(RIC_CONFIG_1.name()),
-            "Not correct Ric retrieved from configurations.");
-
-        update = appConfigUnderTest.setConfiguration(configParserResult(RIC_CONFIG_1)).blockFirst();
-        assertNull(update, "Nothing should be updated");
-        assertTrue(appConfigUnderTest.getRicConfigs().contains(RIC_CONFIG_1), "Ric should remain.");
-
-    }
-
-    @Test
-    void changedRicShouldNotifyAllObserversOfRicChanged() throws Exception {
-        ApplicationConfig appConfigUnderTest = new ApplicationConfig();
-
-        appConfigUnderTest.setConfiguration(configParserResult(RIC_CONFIG_1));
-
-        ImmutableRicConfig changedRicConfig = ImmutableRicConfig.builder() //
-            .name("ric1") //
-            .baseUrl("changed_ric1_url") //
-            .managedElementIds(new Vector<>()) //
-            .controllerName("") //
-            .build();
-
-        RicConfigUpdate update = appConfigUnderTest.setConfiguration(configParserResult(changedRicConfig)).blockFirst();
-
-        assertEquals(RicConfigUpdate.Type.CHANGED, update.getType());
-        assertEquals(changedRicConfig, appConfigUnderTest.getRic(RIC_CONFIG_1.name()),
-            "Changed Ric not retrieved from configurations.");
-    }
-
-    @Test
-    void removedRicShouldNotifyAllObserversOfRicRemoved() {
-        ApplicationConfig appConfigUnderTest = new ApplicationConfig();
-
-        ImmutableRicConfig ricConfig2 = ImmutableRicConfig.builder() //
-            .name("ric2") //
-            .baseUrl("ric2_url") //
-            .managedElementIds(new Vector<>()) //
-            .controllerName("") //
-            .build();
-
-        appConfigUnderTest.setConfiguration(configParserResult(RIC_CONFIG_1, ricConfig2));
-
-        RicConfigUpdate update = appConfigUnderTest.setConfiguration(configParserResult(ricConfig2)).blockFirst();
-
-        assertEquals(RicConfigUpdate.Type.REMOVED, update.getType());
-        assertEquals(1, appConfigUnderTest.getRicConfigs().size(), "Ric not deleted from configurations.");
-    }
-
-}
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/dmaap/DmaapMessageConsumerTest.java b/policy-agent/src/test/java/org/oransc/policyagent/dmaap/DmaapMessageConsumerTest.java
deleted file mode 100644 (file)
index 92c4bb0..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.dmaap;
-
-import static ch.qos.logback.classic.Level.WARN;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.read.ListAppender;
-
-import java.time.Duration;
-import java.util.LinkedList;
-
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.oransc.policyagent.clients.AsyncRestClient;
-import org.oransc.policyagent.configuration.ApplicationConfig;
-import org.oransc.policyagent.utils.LoggingUtils;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import reactor.core.publisher.Mono;
-
-@ExtendWith(MockitoExtension.class)
-class DmaapMessageConsumerTest {
-    @Mock
-    private ApplicationConfig applicationConfigMock;
-    @Mock
-    private AsyncRestClient messageRouterConsumerMock;
-    @Mock
-    private DmaapMessageHandler messageHandlerMock;
-
-    private DmaapMessageConsumer messageConsumerUnderTest;
-
-    @AfterEach
-    void resetLogging() {
-        LoggingUtils.getLogListAppender(DmaapMessageConsumer.class);
-    }
-
-    @Test
-    void dmaapNotConfigured_thenSleepAndRetryUntilConfig() throws Exception {
-        messageConsumerUnderTest = spy(new DmaapMessageConsumer(applicationConfigMock));
-
-        doNothing().when(messageConsumerUnderTest).sleep(any(Duration.class));
-        doReturn(false, false, false, true).when(messageConsumerUnderTest).isStopped();
-        doReturn(false, true, true).when(messageConsumerUnderTest).isDmaapConfigured();
-        doReturn(new LinkedList<>()).when(messageConsumerUnderTest).fetchAllMessages();
-
-        messageConsumerUnderTest.start().join();
-
-        InOrder orderVerifier = inOrder(messageConsumerUnderTest);
-        orderVerifier.verify(messageConsumerUnderTest).sleep(DmaapMessageConsumer.TIME_BETWEEN_DMAAP_RETRIES);
-        orderVerifier.verify(messageConsumerUnderTest).fetchAllMessages();
-    }
-
-    @Test
-    void dmaapConfigurationRemoved_thenStopPollingDmaapSleepAndRetry() throws Exception {
-        messageConsumerUnderTest = spy(new DmaapMessageConsumer(applicationConfigMock));
-
-        doNothing().when(messageConsumerUnderTest).sleep(any(Duration.class));
-        doReturn(false, false, false, false, true).when(messageConsumerUnderTest).isStopped();
-        doReturn(true, true, false).when(messageConsumerUnderTest).isDmaapConfigured();
-        doReturn(new LinkedList<>()).when(messageConsumerUnderTest).fetchAllMessages();
-
-        messageConsumerUnderTest.start().join();
-
-        InOrder orderVerifier = inOrder(messageConsumerUnderTest);
-        orderVerifier.verify(messageConsumerUnderTest).fetchAllMessages();
-        orderVerifier.verify(messageConsumerUnderTest).sleep(DmaapMessageConsumer.TIME_BETWEEN_DMAAP_RETRIES);
-    }
-
-    @Test
-    void dmaapConfiguredAndNoMessages_thenPollOnce() throws Exception {
-        setUpMrConfig();
-
-        messageConsumerUnderTest = spy(new DmaapMessageConsumer(applicationConfigMock));
-
-        Mono<ResponseEntity<String>> response = Mono.empty();
-
-        doReturn(false, true).when(messageConsumerUnderTest).isStopped();
-        doReturn(messageRouterConsumerMock).when(messageConsumerUnderTest).getMessageRouterConsumer();
-        doReturn(response).when(messageRouterConsumerMock).getForEntity(any());
-
-        messageConsumerUnderTest.start().join();
-
-        verify(messageRouterConsumerMock).getForEntity(any());
-        verifyNoMoreInteractions(messageRouterConsumerMock);
-    }
-
-    @Test
-    void dmaapConfiguredAndErrorGettingMessages_thenLogWarningAndSleep() throws Exception {
-        setUpMrConfig();
-
-        messageConsumerUnderTest = spy(new DmaapMessageConsumer(applicationConfigMock));
-
-        doNothing().when(messageConsumerUnderTest).sleep(any(Duration.class));
-        doReturn(false, true).when(messageConsumerUnderTest).isStopped();
-        doReturn(messageRouterConsumerMock).when(messageConsumerUnderTest).getMessageRouterConsumer();
-
-        Mono<ResponseEntity<String>> response = Mono.just(new ResponseEntity<>("Error", HttpStatus.BAD_REQUEST));
-        when(messageRouterConsumerMock.getForEntity(any())).thenReturn(response);
-
-        final ListAppender<ILoggingEvent> logAppender =
-            LoggingUtils.getLogListAppender(DmaapMessageConsumer.class, WARN);
-
-        messageConsumerUnderTest.start().join();
-
-        assertThat(logAppender.list.get(0).getFormattedMessage())
-            .isEqualTo("Cannot fetch because of Error respons: 400 BAD_REQUEST Error");
-
-        verify(messageConsumerUnderTest).sleep(DmaapMessageConsumer.TIME_BETWEEN_DMAAP_RETRIES);
-    }
-
-    @Test
-    void dmaapConfiguredAndOneMessage_thenPollOnceAndProcessMessage() throws Exception {
-        // The message from MR is here an array of Json objects
-        setUpMrConfig();
-        messageConsumerUnderTest = spy(new DmaapMessageConsumer(applicationConfigMock));
-
-        String message = "{\"apiVersion\":\"1.0\"," //
-            + "\"operation\":\"GET\"," //
-            + "\"correlationId\":\"1592341013115594000\"," //
-            + "\"originatorId\":\"849e6c6b420\"," //
-            + "\"payload\":{}," //
-            + "\"requestId\":\"23343221\", " //
-            + "\"target\":\"policy-agent\"," //
-            + "\"timestamp\":\"2020-06-16 20:56:53.115665\"," //
-            + "\"type\":\"request\"," //
-            + "\"url\":\"/rics\"}";
-        String messages = "[" + message + "]";
-
-        doReturn(false, true).when(messageConsumerUnderTest).isStopped();
-        doReturn(messageRouterConsumerMock).when(messageConsumerUnderTest).getMessageRouterConsumer();
-
-        Mono<ResponseEntity<String>> response = Mono.just(new ResponseEntity<>(messages, HttpStatus.OK));
-        when(messageRouterConsumerMock.getForEntity(any())).thenReturn(response);
-
-        doReturn(messageHandlerMock).when(messageConsumerUnderTest).getDmaapMessageHandler();
-
-        messageConsumerUnderTest.start().join();
-
-        ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
-        verify(messageHandlerMock).handleDmaapMsg(captor.capture());
-        String messageAfterJsonParsing = captor.getValue();
-        assertThat(messageAfterJsonParsing).contains("apiVersion");
-
-        verifyNoMoreInteractions(messageHandlerMock);
-    }
-
-    @Test
-    void dmaapConfiguredAndOneMessage_thenPollOnceAndProcessMessage2() throws Exception {
-        // The message from MR is here an array of String (which is the case when the MR
-        // simulator is used)
-        setUpMrConfig();
-        messageConsumerUnderTest = spy(new DmaapMessageConsumer(applicationConfigMock));
-
-        doReturn(false, true).when(messageConsumerUnderTest).isStopped();
-        doReturn(messageRouterConsumerMock).when(messageConsumerUnderTest).getMessageRouterConsumer();
-
-        Mono<ResponseEntity<String>> response = Mono.just(new ResponseEntity<>("[\"aMessage\"]", HttpStatus.OK));
-        when(messageRouterConsumerMock.getForEntity(any())).thenReturn(response);
-
-        doReturn(messageHandlerMock).when(messageConsumerUnderTest).getDmaapMessageHandler();
-
-        messageConsumerUnderTest.start().join();
-
-        verify(messageHandlerMock).handleDmaapMsg("aMessage");
-        verifyNoMoreInteractions(messageHandlerMock);
-    }
-
-    private void setUpMrConfig() {
-        when(applicationConfigMock.getDmaapConsumerTopicUrl()).thenReturn("url");
-        when(applicationConfigMock.getDmaapProducerTopicUrl()).thenReturn("url");
-    }
-}
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/dmaap/DmaapMessageHandlerTest.java b/policy-agent/src/test/java/org/oransc/policyagent/dmaap/DmaapMessageHandlerTest.java
deleted file mode 100644 (file)
index f0efddc..0000000
+++ /dev/null
@@ -1,290 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- *  Copyright (C) 2019 Nordix Foundation.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * SPDX-License-Identifier: Apache-2.0
- * ============LICENSE_END=========================================================
- */
-
-package org.oransc.policyagent.dmaap;
-
-import static ch.qos.logback.classic.Level.WARN;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.read.ListAppender;
-
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonObject;
-
-import java.io.IOException;
-import java.nio.charset.Charset;
-import java.util.Optional;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentCaptor;
-import org.oransc.policyagent.clients.AsyncRestClient;
-import org.oransc.policyagent.dmaap.DmaapRequestMessage.Operation;
-import org.oransc.policyagent.repository.ImmutablePolicyType;
-import org.oransc.policyagent.repository.PolicyType;
-import org.oransc.policyagent.utils.LoggingUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.reactive.function.client.WebClientResponseException;
-
-import reactor.core.publisher.Mono;
-import reactor.test.StepVerifier;
-
-class DmaapMessageHandlerTest {
-    private static final Logger logger = LoggerFactory.getLogger(DmaapMessageHandlerTest.class);
-    private static final String URL = "url";
-
-    private final AsyncRestClient dmaapClient = mock(AsyncRestClient.class);
-    private final AsyncRestClient agentClient = mock(AsyncRestClient.class);
-    private DmaapMessageHandler testedObject;
-    private static Gson gson = new GsonBuilder() //
-        .create(); //
-
-    @BeforeEach
-    private void setUp() throws Exception {
-        testedObject = spy(new DmaapMessageHandler(dmaapClient, agentClient));
-    }
-
-    static JsonObject payloadAsJson() {
-        return gson.fromJson(payloadAsString(), JsonObject.class);
-    }
-
-    static String payloadAsString() {
-        PolicyType pt = ImmutablePolicyType.builder().name("name").schema("schema").build();
-        return gson.toJson(pt);
-    }
-
-    DmaapRequestMessage dmaapRequestMessage(Operation operation) {
-        Optional<JsonObject> payload =
-            ((operation == Operation.PUT || operation == Operation.POST) ? Optional.of(payloadAsJson())
-                : Optional.empty());
-        return ImmutableDmaapRequestMessage.builder() //
-            .apiVersion("apiVersion") //
-            .correlationId("correlationId") //
-            .operation(operation) //
-            .originatorId("originatorId") //
-            .payload(payload) //
-            .requestId("requestId") //
-            .target("target") //
-            .timestamp("timestamp") //
-            .url(URL) //
-            .build();
-    }
-
-    private String dmaapInputMessage(Operation operation) {
-        return gson.toJson(dmaapRequestMessage(operation));
-    }
-
-    private Mono<ResponseEntity<String>> okResponse() {
-        ResponseEntity<String> entity = new ResponseEntity<>("OK", HttpStatus.OK);
-        return Mono.just(entity);
-    }
-
-    private Mono<ResponseEntity<String>> notOkResponse() {
-        ResponseEntity<String> entity = new ResponseEntity<>("NOK", HttpStatus.BAD_GATEWAY);
-        return Mono.just(entity);
-    }
-
-    @Test
-    void testMessageParsing() {
-        String message = dmaapInputMessage(Operation.DELETE);
-        logger.info(message);
-        DmaapRequestMessage parsedMessage = gson.fromJson(message, ImmutableDmaapRequestMessage.class);
-        assertNotNull(parsedMessage);
-        assertFalse(parsedMessage.payload().isPresent());
-
-        message = dmaapInputMessage(Operation.PUT);
-        logger.info(message);
-        parsedMessage = gson.fromJson(message, ImmutableDmaapRequestMessage.class);
-        assertNotNull(parsedMessage);
-        assertTrue(parsedMessage.payload().isPresent());
-    }
-
-    @Test
-    void unparseableMessage_thenWarning() {
-        final ListAppender<ILoggingEvent> logAppender =
-            LoggingUtils.getLogListAppender(DmaapMessageHandler.class, WARN);
-
-        String msg = "bad message";
-        testedObject.handleDmaapMsg(msg);
-
-        assertThat(logAppender.list.get(0).getFormattedMessage()).startsWith(
-            "handleDmaapMsg failure org.oransc.policyagent.exceptions.ServiceException: Received unparsable "
-                + "message from DMAAP: \"" + msg + "\", reason: ");
-    }
-
-    @Test
-    void successfulDelete() throws IOException {
-        doReturn(okResponse()).when(agentClient).deleteForEntity(anyString());
-        doReturn(Mono.just("OK")).when(dmaapClient).post(anyString(), anyString());
-
-        String message = dmaapInputMessage(Operation.DELETE);
-
-        StepVerifier //
-            .create(testedObject.createTask(message)) //
-            .expectSubscription() //
-            .expectNext("OK") //
-            .verifyComplete(); //
-
-        verify(agentClient).deleteForEntity(URL);
-        verifyNoMoreInteractions(agentClient);
-
-        verify(dmaapClient).post(anyString(), anyString());
-
-        verifyNoMoreInteractions(dmaapClient);
-    }
-
-    @Test
-    void successfulGet() throws IOException {
-        doReturn(okResponse()).when(agentClient).getForEntity(anyString());
-        doReturn(Mono.just("OK")).when(dmaapClient).post(anyString(), anyString());
-
-        StepVerifier //
-            .create(testedObject.createTask(dmaapInputMessage(Operation.GET))) //
-            .expectSubscription() //
-            .expectNext("OK") //
-            .verifyComplete(); //
-
-        verify(agentClient).getForEntity(URL);
-        verifyNoMoreInteractions(agentClient);
-
-        verify(dmaapClient).post(anyString(), anyString());
-        verifyNoMoreInteractions(dmaapClient);
-    }
-
-    @Test
-    void exceptionFromAgentWhenGet_thenPostError() throws IOException {
-        String errorBody = "Unavailable";
-        WebClientResponseException webClientResponseException = new WebClientResponseException(
-            HttpStatus.SERVICE_UNAVAILABLE.value(), "", (HttpHeaders) null, errorBody.getBytes(), (Charset) null);
-        doReturn(Mono.error(webClientResponseException)).when(agentClient).getForEntity(anyString());
-        doReturn(Mono.just("OK")).when(dmaapClient).post(anyString(), anyString());
-
-        StepVerifier //
-            .create(testedObject.createTask(dmaapInputMessage(Operation.GET))) //
-            .expectSubscription() //
-            .verifyComplete(); //
-
-        ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
-        verify(dmaapClient).post(anyString(), captor.capture());
-        String actualMessage = captor.getValue();
-        assertThat(actualMessage).contains(HttpStatus.SERVICE_UNAVAILABLE.toString()) //
-            .contains(errorBody);
-    }
-
-    @Test
-    void successfulPut() throws IOException {
-        doReturn(okResponse()).when(agentClient).putForEntity(anyString(), anyString());
-        doReturn(Mono.just("OK")).when(dmaapClient).post(anyString(), anyString());
-
-        StepVerifier //
-            .create(testedObject.createTask(dmaapInputMessage(Operation.PUT))) //
-            .expectSubscription() //
-            .expectNext("OK") //
-            .verifyComplete(); //
-
-        verify(agentClient).putForEntity(URL, payloadAsString());
-        verifyNoMoreInteractions(agentClient);
-
-        verify(dmaapClient).post(anyString(), anyString());
-        verifyNoMoreInteractions(dmaapClient);
-    }
-
-    @Test
-    void successfulPost() throws IOException {
-        doReturn(okResponse()).when(agentClient).postForEntity(anyString(), anyString());
-        doReturn(Mono.just("OK")).when(dmaapClient).post(anyString(), anyString());
-
-        StepVerifier //
-            .create(testedObject.createTask(dmaapInputMessage(Operation.POST))) //
-            .expectSubscription() //
-            .expectNext("OK") //
-            .verifyComplete(); //
-
-        verify(agentClient).postForEntity(URL, payloadAsString());
-        verifyNoMoreInteractions(agentClient);
-
-        verify(dmaapClient).post(anyString(), anyString());
-        verifyNoMoreInteractions(dmaapClient);
-    }
-
-    @Test
-    void exceptionWhenCallingPolicyAgent_thenNotFoundResponse() throws IOException {
-
-        doReturn(notOkResponse()).when(agentClient).putForEntity(anyString(), anyString());
-        doReturn(Mono.just("OK")).when(dmaapClient).post(anyString(), anyString());
-
-        testedObject.createTask(dmaapInputMessage(Operation.PUT)).block();
-
-        verify(agentClient).putForEntity(anyString(), anyString());
-        verifyNoMoreInteractions(agentClient);
-
-        ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
-        verify(dmaapClient).post(anyString(), captor.capture());
-        String actualMessage = captor.getValue();
-        assertThat(actualMessage).as("Message \"%s\" sent to DMaaP contains %s", actualMessage, HttpStatus.BAD_GATEWAY)
-            .contains(HttpStatus.BAD_GATEWAY.toString());
-
-        verifyNoMoreInteractions(dmaapClient);
-    }
-
-    @Test
-    void unsupportedOperationInMessage_thenNotFoundResponseWithNotImplementedOperation() throws Exception {
-        String message = dmaapInputMessage(Operation.PUT).toString();
-        String badOperation = "BAD";
-        message = message.replace(Operation.PUT.toString(), badOperation);
-
-        testedObject.handleDmaapMsg(message);
-
-        ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
-        verify(dmaapClient).post(anyString(), captor.capture());
-        String actualMessage = captor.getValue();
-        assertThat(actualMessage).contains("Not implemented operation") //
-            .contains("BAD_REQUEST");
-    }
-
-    @Test
-    void putWithoutPayload_thenNotFoundResponseWithWarning() throws Exception {
-        String message = dmaapInputMessage(Operation.PUT).toString();
-        message = message.replace(",\"payload\":{\"name\":\"name\",\"schema\":\"schema\"}", "");
-
-        final ListAppender<ILoggingEvent> logAppender =
-            LoggingUtils.getLogListAppender(DmaapMessageHandler.class, WARN);
-
-        testedObject.handleDmaapMsg(message);
-
-        assertThat(logAppender.list.get(0).getFormattedMessage())
-            .startsWith("Expected payload in message from DMAAP: ");
-    }
-}
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/repository/LockTest.java b/policy-agent/src/test/java/org/oransc/policyagent/repository/LockTest.java
deleted file mode 100644 (file)
index 4b8743f..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.repository;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.io.IOException;
-
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.oransc.policyagent.exceptions.ServiceException;
-import org.oransc.policyagent.repository.Lock.LockType;
-
-import reactor.core.publisher.Mono;
-import reactor.test.StepVerifier;
-
-@ExtendWith(MockitoExtension.class)
-class LockTest {
-
-    @SuppressWarnings("squid:S2925") // "Thread.sleep" should not be used in tests.
-    private void sleep() {
-        try {
-            Thread.sleep(100);
-        } catch (InterruptedException e) {
-            // Do nothing.
-        }
-    }
-
-    private void asynchUnlock(Lock lock) {
-        Thread thread = new Thread(() -> {
-            sleep();
-            lock.unlockBlocking();
-        });
-        thread.start();
-    }
-
-    @Test
-    void testLock() throws IOException, ServiceException {
-        Lock lock = new Lock();
-        lock.lockBlocking(LockType.SHARED);
-        lock.unlockBlocking();
-
-        lock.lockBlocking(LockType.EXCLUSIVE);
-        asynchUnlock(lock);
-
-        lock.lockBlocking(LockType.SHARED);
-        lock.unlockBlocking();
-
-        assertThat(lock.getLockCounter()).isZero();
-    }
-
-    @Test
-    void testReactiveLock() {
-        Lock lock = new Lock();
-
-        Mono<Lock> seq = lock.lock(LockType.EXCLUSIVE) //
-            .flatMap(l -> lock.lock(LockType.EXCLUSIVE)) //
-            .flatMap(l -> lock.unlock());
-
-        asynchUnlock(lock);
-        StepVerifier.create(seq) //
-            .expectSubscription() //
-            .expectNext(lock) //
-            .verifyComplete();
-
-        assertThat(lock.getLockCounter()).isZero();
-
-    }
-
-}
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/tasks/EnvironmentProcessorTest.java b/policy-agent/src/test/java/org/oransc/policyagent/tasks/EnvironmentProcessorTest.java
deleted file mode 100644 (file)
index efabba3..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.tasks;
-
-import static ch.qos.logback.classic.Level.WARN;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.read.ListAppender;
-
-import java.util.Properties;
-
-import org.junit.jupiter.api.Test;
-import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.EnvProperties;
-import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.ImmutableEnvProperties;
-import org.oransc.policyagent.exceptions.EnvironmentLoaderException;
-import org.oransc.policyagent.utils.LoggingUtils;
-import reactor.test.StepVerifier;
-
-class EnvironmentProcessorTest {
-    private static final String CONSUL_HOST = "CONSUL_HOST";
-    private static final String CONSUL_HOST_VALUE = "consulHost";
-
-    private static final String CONFIG_BINDING_SERVICE = "CONFIG_BINDING_SERVICE";
-    private static final String CONFIG_BINDING_SERVICE_VALUE = "configBindingService";
-
-    private static final String HOSTNAME = "HOSTNAME";
-    private static final String HOSTNAME_VALUE = "hostname";
-
-    @Test
-    void allPropertiesAvailableWithHostname_thenAllPropertiesAreReturnedWithGivenConsulPort() {
-        Properties systemEnvironment = new Properties();
-        String consulPort = "8080";
-        systemEnvironment.put(CONSUL_HOST, CONSUL_HOST_VALUE);
-        systemEnvironment.put("CONSUL_PORT", consulPort);
-        systemEnvironment.put(CONFIG_BINDING_SERVICE, CONFIG_BINDING_SERVICE_VALUE);
-        systemEnvironment.put(HOSTNAME, HOSTNAME_VALUE);
-
-        EnvProperties expectedEnvProperties = ImmutableEnvProperties.builder() //
-            .consulHost(CONSUL_HOST_VALUE) //
-            .consulPort(Integer.valueOf(consulPort)) //
-            .cbsName(CONFIG_BINDING_SERVICE_VALUE) //
-            .appName(HOSTNAME_VALUE) //
-            .build();
-
-        StepVerifier.create(EnvironmentProcessor.readEnvironmentVariables(systemEnvironment))
-            .expectNext(expectedEnvProperties).expectComplete();
-    }
-
-    @Test
-    void consulHostMissing_thenExceptionReturned() {
-        Properties systemEnvironment = new Properties();
-
-        StepVerifier.create(EnvironmentProcessor.readEnvironmentVariables(systemEnvironment))
-            .expectErrorMatches(throwable -> throwable instanceof EnvironmentLoaderException
-                && throwable.getMessage().equals("$CONSUL_HOST environment has not been defined"))
-            .verify();
-    }
-
-    @Test
-    void withAllPropertiesExceptConsulPort_thenAllPropertiesAreReturnedWithDefaultConsulPortAndWarning() {
-        Properties systemEnvironment = new Properties();
-        systemEnvironment.put(CONSUL_HOST, CONSUL_HOST_VALUE);
-        systemEnvironment.put(CONFIG_BINDING_SERVICE, CONFIG_BINDING_SERVICE_VALUE);
-        systemEnvironment.put(HOSTNAME, HOSTNAME_VALUE);
-
-        String defaultConsulPort = "8500";
-        EnvProperties expectedEnvProperties = ImmutableEnvProperties.builder() //
-            .consulHost(CONSUL_HOST_VALUE) //
-            .consulPort(Integer.valueOf(defaultConsulPort)) //
-            .cbsName(CONFIG_BINDING_SERVICE_VALUE) //
-            .appName(HOSTNAME_VALUE) //
-            .build();
-
-        final ListAppender<ILoggingEvent> logAppender =
-            LoggingUtils.getLogListAppender(EnvironmentProcessor.class, WARN);
-
-        StepVerifier.create(EnvironmentProcessor.readEnvironmentVariables(systemEnvironment))
-            .expectNext(expectedEnvProperties).expectComplete();
-
-        assertThat(logAppender.list.get(0).getFormattedMessage())
-            .isEqualTo("$CONSUL_PORT variable will be set to default port " + defaultConsulPort);
-    }
-
-    @Test
-    void configBindingServiceMissing_thenExceptionReturned() {
-        Properties systemEnvironment = new Properties();
-        systemEnvironment.put(CONSUL_HOST, CONSUL_HOST_VALUE);
-
-        StepVerifier.create(EnvironmentProcessor.readEnvironmentVariables(systemEnvironment))
-            .expectErrorMatches(throwable -> throwable instanceof EnvironmentLoaderException
-                && throwable.getMessage().equals("$CONFIG_BINDING_SERVICE environment has not been defined"))
-            .verify();
-    }
-
-    @Test
-    void allPropertiesAvailableWithServiceName_thenAllPropertiesAreReturned() {
-        Properties systemEnvironment = new Properties();
-        String consulPort = "8080";
-        systemEnvironment.put(CONSUL_HOST, CONSUL_HOST_VALUE);
-        systemEnvironment.put("CONSUL_PORT", consulPort);
-        systemEnvironment.put(CONFIG_BINDING_SERVICE, CONFIG_BINDING_SERVICE_VALUE);
-        systemEnvironment.put("SERVICE_NAME", HOSTNAME_VALUE);
-
-        EnvProperties expectedEnvProperties = ImmutableEnvProperties.builder() //
-            .consulHost(CONSUL_HOST_VALUE) //
-            .consulPort(Integer.valueOf(consulPort)) //
-            .cbsName(CONFIG_BINDING_SERVICE_VALUE) //
-            .appName(HOSTNAME_VALUE) //
-            .build();
-
-        StepVerifier.create(EnvironmentProcessor.readEnvironmentVariables(systemEnvironment))
-            .expectNext(expectedEnvProperties).expectComplete();
-    }
-
-    @Test
-    void serviceNameAndHostnameMissing_thenExceptionIsReturned() {
-        Properties systemEnvironment = new Properties();
-        systemEnvironment.put(CONSUL_HOST, CONSUL_HOST_VALUE);
-        systemEnvironment.put(CONFIG_BINDING_SERVICE, CONFIG_BINDING_SERVICE_VALUE);
-
-        StepVerifier.create(EnvironmentProcessor.readEnvironmentVariables(systemEnvironment))
-            .expectErrorMatches(throwable -> throwable instanceof EnvironmentLoaderException && throwable.getMessage()
-                .equals("Neither $HOSTNAME/$SERVICE_NAME have not been defined as system environment"))
-            .verify();
-    }
-}
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/tasks/RefreshConfigTaskTest.java b/policy-agent/src/test/java/org/oransc/policyagent/tasks/RefreshConfigTaskTest.java
deleted file mode 100644 (file)
index 673ed68..0000000
+++ /dev/null
@@ -1,386 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.tasks;
-
-import static ch.qos.logback.classic.Level.ERROR;
-import static ch.qos.logback.classic.Level.WARN;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.awaitility.Awaitility.await;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.read.ListAppender;
-
-import com.google.common.base.Charsets;
-import com.google.common.io.Resources;
-import com.google.gson.JsonIOException;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import com.google.gson.JsonSyntaxException;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.time.Duration;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Properties;
-import java.util.Vector;
-
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
-import org.mockito.Spy;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.CbsClient;
-import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.EnvProperties;
-import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.ImmutableEnvProperties;
-import org.oransc.policyagent.clients.A1ClientFactory;
-import org.oransc.policyagent.configuration.ApplicationConfig;
-import org.oransc.policyagent.configuration.ApplicationConfig.RicConfigUpdate.Type;
-import org.oransc.policyagent.configuration.ApplicationConfigParser;
-import org.oransc.policyagent.configuration.ApplicationConfigParser.ConfigParserResult;
-import org.oransc.policyagent.configuration.ImmutableConfigParserResult;
-import org.oransc.policyagent.configuration.ImmutableRicConfig;
-import org.oransc.policyagent.configuration.RicConfig;
-import org.oransc.policyagent.repository.ImmutablePolicy;
-import org.oransc.policyagent.repository.ImmutablePolicyType;
-import org.oransc.policyagent.repository.Policies;
-import org.oransc.policyagent.repository.Policy;
-import org.oransc.policyagent.repository.PolicyTypes;
-import org.oransc.policyagent.repository.Ric;
-import org.oransc.policyagent.repository.Rics;
-import org.oransc.policyagent.repository.Services;
-import org.oransc.policyagent.utils.LoggingUtils;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-import reactor.test.StepVerifier;
-
-@ExtendWith(MockitoExtension.class)
-class RefreshConfigTaskTest {
-
-    private static final boolean CONFIG_FILE_EXISTS = true;
-    private static final boolean CONFIG_FILE_DOES_NOT_EXIST = false;
-
-    private RefreshConfigTask refreshTaskUnderTest;
-
-    @Spy
-    ApplicationConfig appConfig;
-
-    @Mock
-    CbsClient cbsClient;
-
-    private static final String RIC_1_NAME = "ric1";
-    private static final ImmutableRicConfig CORRECT_RIC_CONIFG = ImmutableRicConfig.builder() //
-        .name(RIC_1_NAME) //
-        .baseUrl("http://localhost:8080/") //
-        .managedElementIds(new Vector<String>(Arrays.asList("kista_1", "kista_2"))) //
-        .controllerName("") //
-        .build();
-
-    private static EnvProperties properties() {
-        return ImmutableEnvProperties.builder() //
-            .consulHost("host") //
-            .consulPort(123) //
-            .cbsName("cbsName") //
-            .appName("appName") //
-            .build();
-    }
-
-    private RefreshConfigTask createTestObject(boolean configFileExists) {
-        return createTestObject(configFileExists, new Rics(), new Policies(), true);
-    }
-
-    private RefreshConfigTask createTestObject(boolean configFileExists, Rics rics, Policies policies,
-        boolean stubConfigFileExists) {
-        RefreshConfigTask obj = spy(new RefreshConfigTask(appConfig, rics, policies, new Services(), new PolicyTypes(),
-            new A1ClientFactory(appConfig)));
-        if (stubConfigFileExists) {
-            doReturn(configFileExists).when(obj).fileExists(any());
-        }
-        return obj;
-    }
-
-    @Test
-    void startWithStubbedRefresh_thenTerminationLogged() {
-        refreshTaskUnderTest = this.createTestObject(CONFIG_FILE_DOES_NOT_EXIST, null, null, false);
-        doReturn(Flux.empty()).when(refreshTaskUnderTest).createRefreshTask();
-
-        final ListAppender<ILoggingEvent> logAppender = LoggingUtils.getLogListAppender(RefreshConfigTask.class, ERROR);
-
-        refreshTaskUnderTest.start();
-
-        assertThat(logAppender.list.get(0).getFormattedMessage()).isEqualTo("Configuration refresh terminated");
-    }
-
-    @Test
-    void startWithStubbedRefreshReturnError_thenErrorAndTerminationLogged() {
-        refreshTaskUnderTest = this.createTestObject(CONFIG_FILE_DOES_NOT_EXIST, null, null, false);
-        String errorMessage = "Error";
-        doReturn(Flux.error(new Exception(errorMessage))).when(refreshTaskUnderTest).createRefreshTask();
-
-        final ListAppender<ILoggingEvent> logAppender = LoggingUtils.getLogListAppender(RefreshConfigTask.class, ERROR);
-
-        refreshTaskUnderTest.start();
-
-        ILoggingEvent event = logAppender.list.get(0);
-        assertThat(event.getFormattedMessage())
-            .isEqualTo("Configuration refresh terminated due to exception java.lang.Exception: " + errorMessage);
-    }
-
-    @Test
-    void stop_thenTaskIsDisposed() throws Exception {
-        refreshTaskUnderTest = this.createTestObject(CONFIG_FILE_DOES_NOT_EXIST, null, null, false);
-        refreshTaskUnderTest.systemEnvironment = new Properties();
-
-        refreshTaskUnderTest.start();
-        refreshTaskUnderTest.stop();
-
-        assertThat(refreshTaskUnderTest.getRefreshTask().isDisposed()).as("Refresh task is disposed").isTrue();
-    }
-
-    @Test
-    void whenTheConfigurationFits_thenConfiguredRicsArePutInRepository() throws Exception {
-        refreshTaskUnderTest = this.createTestObject(CONFIG_FILE_EXISTS);
-        refreshTaskUnderTest.systemEnvironment = new Properties();
-        // When
-        doReturn(getCorrectJson()).when(refreshTaskUnderTest).createInputStream(any());
-        doReturn("fileName").when(appConfig).getLocalConfigurationFilePath();
-
-        StepVerifier //
-            .create(refreshTaskUnderTest.createRefreshTask()) //
-            .expectSubscription() //
-            .expectNext(Type.ADDED) //
-            .expectNext(Type.ADDED) //
-            .thenCancel() //
-            .verify();
-
-        // Then
-        verify(refreshTaskUnderTest).loadConfigurationFromFile();
-
-        verify(refreshTaskUnderTest, times(2)).runRicSynchronization(any(Ric.class));
-
-        Iterable<RicConfig> ricConfigs = appConfig.getRicConfigs();
-        RicConfig ricConfig = ricConfigs.iterator().next();
-        assertThat(ricConfigs).isNotNull();
-        assertThat(ricConfig).isEqualTo(CORRECT_RIC_CONIFG);
-    }
-
-    @Test
-    void whenFileExistsButJsonIsIncorrect_thenNoRicsArePutInRepositoryAndErrorIsLogged() throws Exception {
-        refreshTaskUnderTest = this.createTestObject(CONFIG_FILE_EXISTS);
-        refreshTaskUnderTest.systemEnvironment = new Properties();
-
-        // When
-        doReturn(getIncorrectJson()).when(refreshTaskUnderTest).createInputStream(any());
-        doReturn("fileName").when(appConfig).getLocalConfigurationFilePath();
-
-        final ListAppender<ILoggingEvent> logAppender = LoggingUtils.getLogListAppender(RefreshConfigTask.class, ERROR);
-
-        StepVerifier //
-            .create(refreshTaskUnderTest.createRefreshTask()) //
-            .expectSubscription() //
-            .expectNoEvent(Duration.ofMillis(100)) //
-            .thenCancel() //
-            .verify();
-
-        // Then
-        verify(refreshTaskUnderTest).loadConfigurationFromFile();
-        assertThat(appConfig.getRicConfigs()).isEmpty();
-
-        await().until(() -> logAppender.list.size() > 0);
-        assertThat(logAppender.list.get(0).getFormattedMessage())
-            .startsWith("Local configuration file not loaded: fileName, ");
-    }
-
-    @Test
-    void whenPeriodicConfigRefreshNoConsul_thenErrorIsLogged() {
-        refreshTaskUnderTest = this.createTestObject(CONFIG_FILE_DOES_NOT_EXIST);
-        refreshTaskUnderTest.systemEnvironment = new Properties();
-
-        EnvProperties props = properties();
-        doReturn(Mono.just(props)).when(refreshTaskUnderTest).getEnvironment(any());
-
-        doReturn(Mono.just(cbsClient)).when(refreshTaskUnderTest).createCbsClient(props);
-        when(cbsClient.get(any())).thenReturn(Mono.error(new IOException()));
-
-        final ListAppender<ILoggingEvent> logAppender = LoggingUtils.getLogListAppender(RefreshConfigTask.class, WARN);
-
-        StepVerifier //
-            .create(refreshTaskUnderTest.createRefreshTask()) //
-            .expectSubscription() //
-            .expectNoEvent(Duration.ofMillis(1000)) //
-            .thenCancel() //
-            .verify();
-
-        await().until(() -> logAppender.list.size() > 0);
-        assertThat(logAppender.list.get(0).getFormattedMessage())
-            .isEqualTo("Could not refresh application configuration. java.io.IOException");
-    }
-
-    @Test
-    void whenPeriodicConfigRefreshSuccess_thenNewConfigIsCreatedAndRepositoryUpdated() throws Exception {
-        Rics rics = new Rics();
-        Policies policies = new Policies();
-        refreshTaskUnderTest = this.createTestObject(CONFIG_FILE_DOES_NOT_EXIST, rics, policies, false);
-        refreshTaskUnderTest.systemEnvironment = new Properties();
-
-        RicConfig changedRicConfig = getRicConfig(RIC_1_NAME);
-        rics.put(new Ric(changedRicConfig));
-        RicConfig removedRicConfig = getRicConfig("removed");
-        Ric removedRic = new Ric(removedRicConfig);
-        rics.put(removedRic);
-        appConfig.setConfiguration(configParserResult(changedRicConfig, removedRicConfig));
-
-        Policy policy = getPolicy(removedRic);
-        policies.put(policy);
-
-        EnvProperties props = properties();
-        doReturn(Mono.just(props)).when(refreshTaskUnderTest).getEnvironment(any());
-        doReturn(Mono.just(cbsClient)).when(refreshTaskUnderTest).createCbsClient(props);
-
-        JsonObject configAsJson = getJsonRootObject(true);
-        String newBaseUrl = "newBaseUrl";
-        modifyTheRicConfiguration(configAsJson, newBaseUrl);
-        when(cbsClient.get(any())).thenReturn(Mono.just(configAsJson));
-        doNothing().when(refreshTaskUnderTest).runRicSynchronization(any(Ric.class));
-
-        StepVerifier //
-            .create(refreshTaskUnderTest.createRefreshTask()) //
-            .expectSubscription() //
-            .expectNext(Type.CHANGED) //
-            .expectNext(Type.ADDED) //
-            .expectNext(Type.REMOVED) //
-            .thenCancel() //
-            .verify();
-
-        assertThat(appConfig.getRicConfigs()).hasSize(2);
-        assertThat(appConfig.getRic(RIC_1_NAME).baseUrl()).isEqualTo(newBaseUrl);
-        String ric2Name = "ric2";
-        assertThat(appConfig.getRic(ric2Name)).isNotNull();
-
-        assertThat(rics.size()).isEqualTo(2);
-        assertThat(rics.get(RIC_1_NAME).getConfig().baseUrl()).isEqualTo(newBaseUrl);
-        assertThat(rics.get(ric2Name)).isNotNull();
-
-        assertThat(policies.size()).isZero();
-    }
-
-    @Test
-    void whenPeriodicConfigRefreshInvalidJson_thenErrorIsLogged() throws Exception {
-        Rics rics = new Rics();
-        Policies policies = new Policies();
-        refreshTaskUnderTest = this.createTestObject(CONFIG_FILE_DOES_NOT_EXIST, rics, policies, false);
-        refreshTaskUnderTest.systemEnvironment = new Properties();
-
-        appConfig.setConfiguration(configParserResult());
-
-        EnvProperties props = properties();
-        doReturn(Mono.just(props)).when(refreshTaskUnderTest).getEnvironment(any());
-        doReturn(Mono.just(cbsClient)).when(refreshTaskUnderTest).createCbsClient(props);
-
-        JsonObject configAsJson = getJsonRootObject(false);
-        when(cbsClient.get(any())).thenReturn(Mono.just(configAsJson));
-
-        final ListAppender<ILoggingEvent> logAppender = LoggingUtils.getLogListAppender(RefreshConfigTask.class, ERROR);
-
-        StepVerifier //
-            .create(refreshTaskUnderTest.createRefreshTask()) //
-            .expectSubscription() //
-            .expectNoEvent(Duration.ofMillis(1000)) //
-            .thenCancel() //
-            .verify();
-
-        await().until(() -> logAppender.list.size() > 0);
-        assertThat(logAppender.list.get(0).getFormattedMessage())
-            .startsWith("Could not parse configuration org.oransc.policyagent.exceptions.ServiceException: ");
-    }
-
-    private RicConfig getRicConfig(String name) {
-        RicConfig ricConfig = ImmutableRicConfig.builder() //
-            .name(name) //
-            .baseUrl("url") //
-            .managedElementIds(Collections.emptyList()) //
-            .controllerName("controllerName") //
-            .build();
-        return ricConfig;
-    }
-
-    private Policy getPolicy(Ric ric) {
-        ImmutablePolicyType type = ImmutablePolicyType.builder() //
-            .name("type") //
-            .schema("{}") //
-            .build();
-        Policy policy = ImmutablePolicy.builder() //
-            .id("id") //
-            .type(type) //
-            .lastModified("lastModified") //
-            .ric(ric) //
-            .json("{}") //
-            .ownerServiceName("ownerServiceName") //
-            .isTransient(false) //
-            .build();
-        return policy;
-    }
-
-    ConfigParserResult configParserResult(RicConfig... rics) {
-        return ImmutableConfigParserResult.builder() //
-            .ricConfigs(Arrays.asList(rics)) //
-            .dmaapConsumerTopicUrl("") //
-            .dmaapProducerTopicUrl("") //
-            .controllerConfigs(new HashMap<>()) //
-            .build();
-    }
-
-    private void modifyTheRicConfiguration(JsonObject configAsJson, String newBaseUrl) {
-        ((JsonObject) configAsJson.getAsJsonObject("config") //
-            .getAsJsonArray("ric").get(0)) //
-                .addProperty("baseUrl", newBaseUrl);
-    }
-
-    private JsonObject getJsonRootObject(boolean valid) throws JsonIOException, JsonSyntaxException, IOException {
-        JsonObject rootObject = JsonParser
-            .parseReader(new InputStreamReader(valid ? getCorrectJson() : getIncorrectJson())).getAsJsonObject();
-        return rootObject;
-    }
-
-    private static InputStream getCorrectJson() throws IOException {
-        URL url = ApplicationConfigParser.class.getClassLoader().getResource("test_application_configuration.json");
-        String string = Resources.toString(url, Charsets.UTF_8);
-        return new ByteArrayInputStream((string.getBytes(StandardCharsets.UTF_8)));
-    }
-
-    private static InputStream getIncorrectJson() {
-        String string = "{}"; //
-        return new ByteArrayInputStream((string.getBytes(StandardCharsets.UTF_8)));
-    }
-}
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/tasks/RicSupervisionTest.java b/policy-agent/src/test/java/org/oransc/policyagent/tasks/RicSupervisionTest.java
deleted file mode 100644 (file)
index db99728..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.tasks;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Vector;
-
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.oransc.policyagent.clients.A1Client;
-import org.oransc.policyagent.clients.A1ClientFactory;
-import org.oransc.policyagent.configuration.ImmutableRicConfig;
-import org.oransc.policyagent.repository.ImmutablePolicy;
-import org.oransc.policyagent.repository.ImmutablePolicyType;
-import org.oransc.policyagent.repository.Lock.LockType;
-import org.oransc.policyagent.repository.Policies;
-import org.oransc.policyagent.repository.Policy;
-import org.oransc.policyagent.repository.PolicyType;
-import org.oransc.policyagent.repository.PolicyTypes;
-import org.oransc.policyagent.repository.Ric;
-import org.oransc.policyagent.repository.Ric.RicState;
-import org.oransc.policyagent.repository.Rics;
-import reactor.core.publisher.Mono;
-
-@ExtendWith(MockitoExtension.class)
-class RicSupervisionTest {
-    private static final String POLICY_TYPE_1_NAME = "type1";
-    private static final PolicyType POLICY_TYPE_1 = ImmutablePolicyType.builder() //
-        .name(POLICY_TYPE_1_NAME) //
-        .schema("") //
-        .build();
-
-    private static final Ric RIC_1 = new Ric(ImmutableRicConfig.builder() //
-        .name("RIC_1") //
-        .baseUrl("baseUrl1") //
-        .managedElementIds(new Vector<String>(Arrays.asList("kista_1", "kista_2"))) //
-        .controllerName("controllerName") //
-        .build());
-
-    private static final String POLICY_1_ID = "policyId1";
-    private static final Policy POLICY_1 = ImmutablePolicy.builder() //
-        .id(POLICY_1_ID) //
-        .json("") //
-        .ownerServiceName("service") //
-        .ric(RIC_1) //
-        .type(POLICY_TYPE_1) //
-        .lastModified("now") //
-        .isTransient(false) //
-        .build();
-
-    private static final Policy POLICY_2 = ImmutablePolicy.builder() //
-        .id("policyId2") //
-        .json("") //
-        .ownerServiceName("service") //
-        .ric(RIC_1) //
-        .type(POLICY_TYPE_1) //
-        .lastModified("now") //
-        .isTransient(false) //
-        .build();
-
-    @Mock
-    private A1Client a1ClientMock;
-
-    @Mock
-    private A1ClientFactory a1ClientFactory;
-
-    @Mock
-    private RicSynchronizationTask synchronizationTaskMock;
-
-    private final PolicyTypes types = new PolicyTypes();
-    private Policies policies = new Policies();
-    private Rics rics = new Rics();
-
-    @BeforeEach
-    void init() {
-        types.clear();
-        policies.clear();
-        rics.clear();
-        RIC_1.setState(RicState.UNAVAILABLE);
-        RIC_1.clearSupportedPolicyTypes();
-    }
-
-    @AfterEach
-    void verifyNoRicLocks() {
-        for (Ric ric : this.rics.getRics()) {
-            ric.getLock().lockBlocking(LockType.EXCLUSIVE);
-            ric.getLock().unlockBlocking();
-            assertThat(ric.getLock().getLockCounter()).isZero();
-        }
-    }
-
-    @Test
-    void whenRicIdleAndNoChangedPoliciesOrPolicyTypes_thenNoSynchronization() {
-        doReturn(Mono.just(a1ClientMock)).when(a1ClientFactory).createA1Client(any(Ric.class));
-        RIC_1.setState(RicState.AVAILABLE);
-        RIC_1.addSupportedPolicyType(POLICY_TYPE_1);
-        rics.put(RIC_1);
-
-        types.put(POLICY_TYPE_1);
-
-        policies.put(POLICY_1);
-
-        setUpGetPolicyIdentitiesToReturn(new ArrayList<>(Arrays.asList(POLICY_1_ID)));
-        setUpGetPolicyTypeIdentitiesToReturn(new ArrayList<>(Arrays.asList(POLICY_TYPE_1_NAME)));
-
-        RicSupervision supervisorUnderTest = spy(new RicSupervision(rics, policies, a1ClientFactory, types, null));
-
-        supervisorUnderTest.checkAllRics();
-
-        verify(supervisorUnderTest).checkAllRics();
-        verifyNoMoreInteractions(supervisorUnderTest);
-    }
-
-    @Test
-    void whenRicUndefined_thenSynchronization() {
-        doReturn(Mono.just(a1ClientMock)).when(a1ClientFactory).createA1Client(any(Ric.class));
-        RIC_1.setState(RicState.UNAVAILABLE);
-        rics.put(RIC_1);
-
-        RicSupervision supervisorUnderTest = spy(new RicSupervision(rics, policies, a1ClientFactory, types, null));
-
-        doReturn(synchronizationTaskMock).when(supervisorUnderTest).createSynchronizationTask();
-
-        supervisorUnderTest.checkAllRics();
-
-        verify(supervisorUnderTest).checkAllRics();
-        verify(supervisorUnderTest).createSynchronizationTask();
-        verify(synchronizationTaskMock).run(RIC_1);
-        verifyNoMoreInteractions(supervisorUnderTest);
-    }
-
-    @Test
-    void whenRicSynchronizing_thenNoSynchronization() {
-        doReturn(Mono.just(a1ClientMock)).when(a1ClientFactory).createA1Client(any(Ric.class));
-        RIC_1.setState(RicState.SYNCHRONIZING);
-        rics.put(RIC_1);
-
-        RicSupervision supervisorUnderTest = spy(new RicSupervision(rics, policies, a1ClientFactory, types, null));
-
-        supervisorUnderTest.checkAllRics();
-
-        verify(supervisorUnderTest).checkAllRics();
-        verifyNoMoreInteractions(supervisorUnderTest);
-    }
-
-    @Test
-    void whenRicIdleAndErrorGettingPolicyIdentities_thenNoSynchronization() {
-        doReturn(Mono.just(a1ClientMock)).when(a1ClientFactory).createA1Client(any(Ric.class));
-        RIC_1.setState(RicState.AVAILABLE);
-        RIC_1.addSupportedPolicyType(POLICY_TYPE_1);
-        rics.put(RIC_1);
-
-        setUpGetPolicyIdentitiesToReturn(new Exception("Failed"));
-
-        RicSupervision supervisorUnderTest = spy(new RicSupervision(rics, policies, a1ClientFactory, types, null));
-        supervisorUnderTest.checkAllRics();
-
-        verify(supervisorUnderTest).checkAllRics();
-        verifyNoMoreInteractions(supervisorUnderTest);
-        assertThat(RIC_1.getState()).isEqualTo(RicState.UNAVAILABLE);
-    }
-
-    @Test
-    void whenRicIdleAndNotSameAmountOfPolicies_thenSynchronization() {
-        doReturn(Mono.just(a1ClientMock)).when(a1ClientFactory).createA1Client(any(Ric.class));
-        RIC_1.setState(RicState.AVAILABLE);
-        rics.put(RIC_1);
-
-        policies.put(POLICY_1);
-        policies.put(POLICY_2);
-
-        setUpGetPolicyIdentitiesToReturn(new ArrayList<>(Arrays.asList(POLICY_1_ID)));
-
-        RicSupervision supervisorUnderTest = spy(new RicSupervision(rics, policies, a1ClientFactory, types, null));
-
-        doReturn(synchronizationTaskMock).when(supervisorUnderTest).createSynchronizationTask();
-
-        supervisorUnderTest.checkAllRics();
-
-        verify(supervisorUnderTest).checkAllRics();
-        verify(supervisorUnderTest).createSynchronizationTask();
-        verify(synchronizationTaskMock).run(RIC_1);
-        verifyNoMoreInteractions(supervisorUnderTest);
-    }
-
-    @Test
-    void whenRicIdleAndSameAmountOfPoliciesButNotSamePolicies_thenSynchronization() {
-        doReturn(Mono.just(a1ClientMock)).when(a1ClientFactory).createA1Client(any(Ric.class));
-        RIC_1.setState(RicState.AVAILABLE);
-        rics.put(RIC_1);
-
-        policies.put(POLICY_1);
-        policies.put(POLICY_2);
-
-        setUpGetPolicyIdentitiesToReturn(new ArrayList<>(Arrays.asList(POLICY_1_ID, "Another_policy")));
-
-        RicSupervision supervisorUnderTest = spy(new RicSupervision(rics, policies, a1ClientFactory, types, null));
-
-        doReturn(synchronizationTaskMock).when(supervisorUnderTest).createSynchronizationTask();
-
-        supervisorUnderTest.checkAllRics();
-
-        verify(supervisorUnderTest).checkAllRics();
-        verify(supervisorUnderTest).createSynchronizationTask();
-        verify(synchronizationTaskMock).run(RIC_1);
-        verifyNoMoreInteractions(supervisorUnderTest);
-    }
-
-    @Test
-    void whenRicIdleAndErrorGettingPolicyTypes_thenNoSynchronization() {
-        doReturn(Mono.just(a1ClientMock)).when(a1ClientFactory).createA1Client(any(Ric.class));
-        RIC_1.setState(RicState.AVAILABLE);
-        RIC_1.addSupportedPolicyType(POLICY_TYPE_1);
-        rics.put(RIC_1);
-
-        setUpGetPolicyIdentitiesToReturn(Collections.emptyList());
-        setUpGetPolicyTypeIdentitiesToReturn(new Exception("Failed"));
-
-        RicSupervision supervisorUnderTest = spy(new RicSupervision(rics, policies, a1ClientFactory, types, null));
-        supervisorUnderTest.checkAllRics();
-
-        verify(supervisorUnderTest).checkAllRics();
-        verifyNoMoreInteractions(supervisorUnderTest);
-    }
-
-    @Test
-    void whenRicIdleAndNotSameAmountOfPolicyTypes_thenSynchronization() {
-        doReturn(Mono.just(a1ClientMock)).when(a1ClientFactory).createA1Client(any(Ric.class));
-        RIC_1.setState(RicState.AVAILABLE);
-        RIC_1.addSupportedPolicyType(POLICY_TYPE_1);
-        rics.put(RIC_1);
-
-        types.put(POLICY_TYPE_1);
-
-        setUpGetPolicyIdentitiesToReturn(Collections.emptyList());
-        setUpGetPolicyTypeIdentitiesToReturn(new ArrayList<>(Arrays.asList(POLICY_TYPE_1_NAME, "another_policy_type")));
-
-        RicSupervision supervisorUnderTest = spy(new RicSupervision(rics, policies, a1ClientFactory, types, null));
-
-        doReturn(synchronizationTaskMock).when(supervisorUnderTest).createSynchronizationTask();
-
-        supervisorUnderTest.checkAllRics();
-
-        verify(supervisorUnderTest).checkAllRics();
-        verify(supervisorUnderTest).createSynchronizationTask();
-        verify(synchronizationTaskMock).run(RIC_1);
-        verifyNoMoreInteractions(supervisorUnderTest);
-    }
-
-    @Test
-    void whenRicIdleAndSameAmountOfPolicyTypesButNotSameTypes_thenSynchronization() {
-        doReturn(Mono.just(a1ClientMock)).when(a1ClientFactory).createA1Client(any(Ric.class));
-        PolicyType policyType2 = ImmutablePolicyType.builder() //
-            .name("policyType2") //
-            .schema("") //
-            .build();
-
-        RIC_1.setState(RicState.AVAILABLE);
-        RIC_1.addSupportedPolicyType(POLICY_TYPE_1);
-        RIC_1.addSupportedPolicyType(policyType2);
-        rics.put(RIC_1);
-
-        setUpGetPolicyIdentitiesToReturn(Collections.emptyList());
-        setUpGetPolicyTypeIdentitiesToReturn(new ArrayList<>(Arrays.asList(POLICY_TYPE_1_NAME, "another_policy_type")));
-
-        RicSupervision supervisorUnderTest = spy(new RicSupervision(rics, policies, a1ClientFactory, types, null));
-
-        doReturn(synchronizationTaskMock).when(supervisorUnderTest).createSynchronizationTask();
-
-        supervisorUnderTest.checkAllRics();
-
-        verify(supervisorUnderTest).checkAllRics();
-        verify(supervisorUnderTest).createSynchronizationTask();
-        verify(synchronizationTaskMock).run(RIC_1);
-        verifyNoMoreInteractions(supervisorUnderTest);
-    }
-
-    @SuppressWarnings("unchecked")
-    private void setUpGetPolicyIdentitiesToReturn(Object returnValue) {
-        if (returnValue instanceof List<?>) {
-            when(a1ClientMock.getPolicyIdentities()).thenReturn(Mono.just((List<String>) returnValue));
-        } else if (returnValue instanceof Exception) {
-            when(a1ClientMock.getPolicyIdentities()).thenReturn(Mono.error((Exception) returnValue));
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    private void setUpGetPolicyTypeIdentitiesToReturn(Object returnValue) {
-        if (returnValue instanceof List<?>) {
-            when(a1ClientMock.getPolicyTypeIdentities()).thenReturn(Mono.just((List<String>) returnValue));
-        } else if (returnValue instanceof Exception) {
-            when(a1ClientMock.getPolicyTypeIdentities()).thenReturn(Mono.error((Exception) returnValue));
-        }
-    }
-}
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/tasks/RicSynchronizationTaskTest.java b/policy-agent/src/test/java/org/oransc/policyagent/tasks/RicSynchronizationTaskTest.java
deleted file mode 100644 (file)
index 6667029..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.tasks;
-
-import static ch.qos.logback.classic.Level.WARN;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoInteractions;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.read.ListAppender;
-
-import java.time.Duration;
-import java.util.Arrays;
-import java.util.Collections;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.oransc.policyagent.clients.A1Client;
-import org.oransc.policyagent.clients.A1ClientFactory;
-import org.oransc.policyagent.clients.AsyncRestClient;
-import org.oransc.policyagent.configuration.ImmutableRicConfig;
-import org.oransc.policyagent.repository.ImmutablePolicy;
-import org.oransc.policyagent.repository.ImmutablePolicyType;
-import org.oransc.policyagent.repository.Policies;
-import org.oransc.policyagent.repository.Policy;
-import org.oransc.policyagent.repository.PolicyType;
-import org.oransc.policyagent.repository.PolicyTypes;
-import org.oransc.policyagent.repository.Ric;
-import org.oransc.policyagent.repository.Ric.RicState;
-import org.oransc.policyagent.repository.Service;
-import org.oransc.policyagent.repository.Services;
-import org.oransc.policyagent.utils.LoggingUtils;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-@ExtendWith(MockitoExtension.class)
-class RicSynchronizationTaskTest {
-    private static final String POLICY_TYPE_1_NAME = "type1";
-    private static final PolicyType POLICY_TYPE_1 = ImmutablePolicyType.builder() //
-        .name(POLICY_TYPE_1_NAME) //
-        .schema("") //
-        .build();
-
-    private static final String RIC_1_NAME = "ric1";
-    private static final Ric RIC_1 = new Ric(ImmutableRicConfig.builder() //
-        .name(RIC_1_NAME) //
-        .baseUrl("baseUrl1") //
-        .managedElementIds(Collections.emptyList()) //
-        .controllerName("controllerName") //
-        .build());
-
-    private static Policy createPolicy(String policyId, boolean isTransient) {
-        return ImmutablePolicy.builder() //
-            .id(policyId) //
-            .json("") //
-            .ownerServiceName("service") //
-            .ric(RIC_1) //
-            .type(POLICY_TYPE_1) //
-            .lastModified("now") //
-            .isTransient(isTransient) //
-            .build();
-    }
-
-    private static final Policy POLICY_1 = createPolicy("policyId1", false);
-
-    private static final String SERVICE_1_NAME = "service1";
-    private static final String SERVICE_1_CALLBACK_URL = "callbackUrl";
-    private static final Service SERVICE_1 = new Service(SERVICE_1_NAME, Duration.ofSeconds(1), SERVICE_1_CALLBACK_URL);
-
-    @Mock
-    private A1Client a1ClientMock;
-
-    @Mock
-    private A1ClientFactory a1ClientFactoryMock;
-
-    private PolicyTypes policyTypes;
-    private Policies policies;
-    private Services services;
-
-    @BeforeEach
-    void init() {
-        policyTypes = new PolicyTypes();
-        policies = new Policies();
-        services = new Services();
-        RIC_1.setState(RicState.UNAVAILABLE);
-        RIC_1.clearSupportedPolicyTypes();
-    }
-
-    @Test
-    void ricAlreadySynchronizing_thenNoSynchronization() {
-        RIC_1.setState(RicState.SYNCHRONIZING);
-        RIC_1.addSupportedPolicyType(POLICY_TYPE_1);
-
-        policyTypes.put(POLICY_TYPE_1);
-        policies.put(POLICY_1);
-
-        RicSynchronizationTask synchronizerUnderTest =
-            new RicSynchronizationTask(a1ClientFactoryMock, policyTypes, policies, services);
-
-        synchronizerUnderTest.run(RIC_1);
-
-        verifyNoInteractions(a1ClientMock);
-
-        assertThat(policyTypes.size()).isEqualTo(1);
-        assertThat(policies.size()).isEqualTo(1);
-        assertThat(RIC_1.getState()).isEqualTo(RicState.SYNCHRONIZING);
-        assertThat(RIC_1.getSupportedPolicyTypeNames()).hasSize(1);
-    }
-
-    @Test
-    void ricIdlePolicyTypeInRepo_thenSynchronizationWithReuseOfTypeFromRepoAndCorrectServiceNotified() {
-        RIC_1.setState(RicState.AVAILABLE);
-
-        policyTypes.put(POLICY_TYPE_1);
-
-        services.put(SERVICE_1);
-        Service serviceWithoutCallbackUrlShouldNotBeNotified = new Service("service2", Duration.ofSeconds(1), "");
-        services.put(serviceWithoutCallbackUrlShouldNotBeNotified);
-
-        setUpCreationOfA1Client();
-        simulateRicWithOnePolicyType();
-
-        RicSynchronizationTask synchronizerUnderTest =
-            spy(new RicSynchronizationTask(a1ClientFactoryMock, policyTypes, policies, services));
-
-        AsyncRestClient restClientMock = setUpCreationOfAsyncRestClient(synchronizerUnderTest);
-        when(restClientMock.put(anyString(), anyString())).thenReturn(Mono.just("Ok"));
-
-        synchronizerUnderTest.run(RIC_1);
-
-        verify(a1ClientMock, times(1)).getPolicyTypeIdentities();
-        verifyNoMoreInteractions(a1ClientMock);
-
-        verify(synchronizerUnderTest).run(RIC_1);
-        verify(synchronizerUnderTest).createNotificationClient(SERVICE_1_CALLBACK_URL);
-        verifyNoMoreInteractions(synchronizerUnderTest);
-
-        verify(restClientMock).put("", "Synchronization completed for:" + RIC_1_NAME);
-        verifyNoMoreInteractions(restClientMock);
-
-        assertThat(policyTypes.size()).isEqualTo(1);
-        assertThat(policies.size()).isZero();
-        assertThat(RIC_1.getState()).isEqualTo(RicState.AVAILABLE);
-    }
-
-    @Test
-    void ricIdlePolicyTypeNotInRepo_thenSynchronizationWithTypeFromRic() throws Exception {
-        RIC_1.setState(RicState.AVAILABLE);
-
-        setUpCreationOfA1Client();
-        simulateRicWithOnePolicyType();
-        String typeSchema = "schema";
-        when(a1ClientMock.getPolicyTypeSchema(POLICY_TYPE_1_NAME)).thenReturn(Mono.just(typeSchema));
-
-        RicSynchronizationTask synchronizerUnderTest =
-            new RicSynchronizationTask(a1ClientFactoryMock, policyTypes, policies, services);
-
-        synchronizerUnderTest.run(RIC_1);
-
-        verify(a1ClientMock).getPolicyTypeIdentities();
-        verifyNoMoreInteractions(a1ClientMock);
-
-        assertThat(policyTypes.size()).isEqualTo(1);
-        assertThat(policyTypes.getType(POLICY_TYPE_1_NAME).schema()).isEqualTo(typeSchema);
-        assertThat(policies.size()).isZero();
-        assertThat(RIC_1.getState()).isEqualTo(RicState.AVAILABLE);
-    }
-
-    @Test
-    void ricIdleAndHavePolicies_thenSynchronizationWithRecreationOfPolicies() {
-        RIC_1.setState(RicState.AVAILABLE);
-
-        Policy transientPolicy = createPolicy("transientPolicyId", true);
-
-        policies.put(transientPolicy);
-        policies.put(POLICY_1);
-
-        setUpCreationOfA1Client();
-        simulateRicWithNoPolicyTypes();
-
-        when(a1ClientMock.deleteAllPolicies()).thenReturn(Flux.just("OK"));
-        when(a1ClientMock.putPolicy(any(Policy.class))).thenReturn(Mono.just("OK"));
-
-        RicSynchronizationTask synchronizerUnderTest =
-            new RicSynchronizationTask(a1ClientFactoryMock, policyTypes, policies, services);
-
-        synchronizerUnderTest.run(RIC_1);
-
-        verify(a1ClientMock).deleteAllPolicies();
-        verify(a1ClientMock).putPolicy(POLICY_1);
-        verifyNoMoreInteractions(a1ClientMock);
-
-        assertThat(policyTypes.size()).isZero();
-        assertThat(policies.size()).isEqualTo(1); // The transient policy shall be deleted
-        assertThat(RIC_1.getState()).isEqualTo(RicState.AVAILABLE);
-    }
-
-    @Test
-    void ricIdleAndErrorDeletingPoliciesFirstTime_thenSynchronizationWithDeletionOfPolicies() {
-        RIC_1.setState(RicState.AVAILABLE);
-
-        policies.put(POLICY_1);
-
-        setUpCreationOfA1Client();
-        simulateRicWithNoPolicyTypes();
-
-        when(a1ClientMock.deleteAllPolicies()) //
-            .thenReturn(Flux.error(new Exception("Exception"))) //
-            .thenReturn(Flux.just("OK"));
-
-        RicSynchronizationTask synchronizerUnderTest =
-            new RicSynchronizationTask(a1ClientFactoryMock, policyTypes, policies, services);
-
-        synchronizerUnderTest.run(RIC_1);
-
-        verify(a1ClientMock, times(2)).deleteAllPolicies();
-        verifyNoMoreInteractions(a1ClientMock);
-
-        assertThat(policyTypes.size()).isZero();
-        assertThat(policies.size()).isZero();
-        assertThat(RIC_1.getState()).isEqualTo(RicState.AVAILABLE);
-    }
-
-    @Test
-    void ricIdleAndErrorDeletingPoliciesAllTheTime_thenSynchronizationWithFailedRecovery() {
-        RIC_1.setState(RicState.AVAILABLE);
-
-        policies.put(POLICY_1);
-
-        setUpCreationOfA1Client();
-        simulateRicWithNoPolicyTypes();
-
-        String originalErrorMessage = "Exception";
-        when(a1ClientMock.deleteAllPolicies()).thenReturn(Flux.error(new Exception(originalErrorMessage)));
-
-        RicSynchronizationTask synchronizerUnderTest =
-            new RicSynchronizationTask(a1ClientFactoryMock, policyTypes, policies, services);
-
-        final ListAppender<ILoggingEvent> logAppender =
-            LoggingUtils.getLogListAppender(RicSynchronizationTask.class, WARN);
-
-        synchronizerUnderTest.run(RIC_1);
-
-        verifyCorrectLogMessage(0, logAppender,
-            "Synchronization failure for ric: " + RIC_1_NAME + ", reason: " + originalErrorMessage);
-
-        verify(a1ClientMock, times(2)).deleteAllPolicies();
-        verifyNoMoreInteractions(a1ClientMock);
-
-        assertThat(policyTypes.size()).isZero();
-        assertThat(policies.size()).isZero();
-        assertThat(RIC_1.getState()).isEqualTo(RicState.UNAVAILABLE);
-    }
-
-    @Test
-    void ricIdlePolicyTypeInRepo_thenSynchronizationWithErrorOnServiceNotificationErrorLogged() {
-        RIC_1.setState(RicState.AVAILABLE);
-
-        policyTypes.put(POLICY_TYPE_1);
-
-        services.put(SERVICE_1);
-
-        setUpCreationOfA1Client();
-        simulateRicWithOnePolicyType();
-
-        final ListAppender<ILoggingEvent> logAppender =
-            LoggingUtils.getLogListAppender(RicSynchronizationTask.class, WARN);
-
-        RicSynchronizationTask synchronizerUnderTest =
-            spy(new RicSynchronizationTask(a1ClientFactoryMock, policyTypes, policies, services));
-
-        AsyncRestClient restClientMock = setUpCreationOfAsyncRestClient(synchronizerUnderTest);
-        String originalErrorMessage = "Exception";
-        when(restClientMock.put(anyString(), anyString())).thenReturn(Mono.error(new Exception(originalErrorMessage)));
-
-        synchronizerUnderTest.run(RIC_1);
-
-        ILoggingEvent loggingEvent = logAppender.list.get(0);
-        assertThat(loggingEvent.getLevel()).isEqualTo(WARN);
-        verifyCorrectLogMessage(0, logAppender,
-            "Service notification failed for service: " + SERVICE_1_NAME + ". Cause: " + originalErrorMessage);
-    }
-
-    private void setUpCreationOfA1Client() {
-        when(a1ClientFactoryMock.createA1Client(any(Ric.class))).thenReturn(Mono.just(a1ClientMock));
-        doReturn(Flux.empty()).when(a1ClientMock).deleteAllPolicies();
-    }
-
-    private AsyncRestClient setUpCreationOfAsyncRestClient(RicSynchronizationTask synchronizerUnderTest) {
-        AsyncRestClient restClientMock = mock(AsyncRestClient.class);
-        doReturn(restClientMock).when(synchronizerUnderTest).createNotificationClient(anyString());
-        return restClientMock;
-    }
-
-    private void simulateRicWithOnePolicyType() {
-        when(a1ClientMock.getPolicyTypeIdentities()).thenReturn(Mono.just(Arrays.asList(POLICY_TYPE_1_NAME)));
-    }
-
-    private void simulateRicWithNoPolicyTypes() {
-        when(a1ClientMock.getPolicyTypeIdentities()).thenReturn(Mono.just(Collections.emptyList()));
-    }
-
-    private void verifyCorrectLogMessage(int messageIndex, ListAppender<ILoggingEvent> logAppender,
-        String expectedMessage) {
-        ILoggingEvent loggingEvent = logAppender.list.get(messageIndex);
-        assertThat(loggingEvent.getFormattedMessage()).isEqualTo(expectedMessage);
-    }
-}
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/tasks/ServiceSupervisionTest.java b/policy-agent/src/test/java/org/oransc/policyagent/tasks/ServiceSupervisionTest.java
deleted file mode 100644 (file)
index 1631303..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.tasks;
-
-import static ch.qos.logback.classic.Level.WARN;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.awaitility.Awaitility.await;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoInteractions;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.read.ListAppender;
-
-import java.time.Duration;
-import java.util.Collections;
-
-import org.awaitility.Durations;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.oransc.policyagent.clients.A1Client;
-import org.oransc.policyagent.clients.A1ClientFactory;
-import org.oransc.policyagent.configuration.ImmutableRicConfig;
-import org.oransc.policyagent.configuration.RicConfig;
-import org.oransc.policyagent.repository.ImmutablePolicy;
-import org.oransc.policyagent.repository.ImmutablePolicyType;
-import org.oransc.policyagent.repository.Policies;
-import org.oransc.policyagent.repository.Policy;
-import org.oransc.policyagent.repository.PolicyType;
-import org.oransc.policyagent.repository.Ric;
-import org.oransc.policyagent.repository.Service;
-import org.oransc.policyagent.repository.Services;
-import org.oransc.policyagent.utils.LoggingUtils;
-import reactor.core.publisher.Mono;
-
-@ExtendWith(MockitoExtension.class)
-class ServiceSupervisionTest {
-
-    private static final String SERVICE_NAME = "Service name";
-    private static final String RIC_NAME = "name";
-    private static final String POLICY_ID = "policy";
-
-    @Mock
-    A1ClientFactory a1ClientFactoryMock;
-    @Mock
-    A1Client a1ClientMock;
-
-    private Services services;
-    private Service service;
-    private Policies policies;
-    private RicConfig ricConfig = ImmutableRicConfig.builder() //
-        .name(RIC_NAME) //
-        .baseUrl("baseUrl") //
-        .managedElementIds(Collections.emptyList()) //
-        .controllerName("") //
-        .build();
-    private Ric ric = new Ric(ricConfig);
-    private PolicyType policyType = ImmutablePolicyType.builder() //
-        .name("plicyTypeName") //
-        .schema("schema") //
-        .build();
-    private Policy policy = ImmutablePolicy.builder() //
-        .id(POLICY_ID) //
-        .json("json") //
-        .ownerServiceName(SERVICE_NAME) //
-        .ric(ric) //
-        .type(policyType) //
-        .lastModified("lastModified") //
-        .isTransient(false) //
-        .build();
-
-    @Test
-    void serviceExpired_policyAndServiceAreDeletedInRepoAndPolicyIsDeletedInRic() {
-        setUpRepositoryWithKeepAliveInterval(Duration.ofSeconds(2));
-
-        setUpCreationOfA1Client();
-        when(a1ClientMock.deletePolicy(any(Policy.class))).thenReturn(Mono.just("Policy deleted"));
-
-        ServiceSupervision serviceSupervisionUnderTest =
-            new ServiceSupervision(services, policies, a1ClientFactoryMock);
-
-        await().atMost(Durations.FIVE_SECONDS).with().pollInterval(Durations.ONE_SECOND).until(service::isExpired);
-
-        serviceSupervisionUnderTest.checkAllServices().blockLast();
-
-        assertThat(policies.size()).isZero();
-        assertThat(services.size()).isZero();
-
-        verify(a1ClientMock).deletePolicy(policy);
-        verifyNoMoreInteractions(a1ClientMock);
-    }
-
-    @Test
-    void serviceExpiredButDeleteInRicFails_policyAndServiceAreDeletedInRepoAndErrorLoggedForRic() {
-        setUpRepositoryWithKeepAliveInterval(Duration.ofSeconds(2));
-
-        setUpCreationOfA1Client();
-        String originalErrorMessage = "Failed";
-        when(a1ClientMock.deletePolicy(any(Policy.class))).thenReturn(Mono.error(new Exception(originalErrorMessage)));
-
-        ServiceSupervision serviceSupervisionUnderTest =
-            new ServiceSupervision(services, policies, a1ClientFactoryMock);
-
-        await().atMost(Durations.FIVE_SECONDS).with().pollInterval(Durations.ONE_SECOND).until(service::isExpired);
-
-        final ListAppender<ILoggingEvent> logAppender = LoggingUtils.getLogListAppender(ServiceSupervision.class, WARN);
-
-        serviceSupervisionUnderTest.checkAllServices().blockLast();
-
-        assertThat(policies.size()).isZero();
-        assertThat(services.size()).isZero();
-
-        ILoggingEvent loggingEvent = logAppender.list.get(0);
-        assertThat(loggingEvent.getLevel()).isEqualTo(WARN);
-        String expectedLogMessage =
-            "Could not delete policy: " + POLICY_ID + " from ric: " + RIC_NAME + ". Cause: " + originalErrorMessage;
-        assertThat(loggingEvent.getFormattedMessage()).isEqualTo(expectedLogMessage);
-    }
-
-    @Test
-    void serviceNotExpired_shouldNotBeChecked() {
-        setUpRepositoryWithKeepAliveInterval(Duration.ofSeconds(2));
-
-        ServiceSupervision serviceSupervisionUnderTest =
-            new ServiceSupervision(services, policies, a1ClientFactoryMock);
-
-        serviceSupervisionUnderTest.checkAllServices().blockLast();
-
-        assertThat(policies.size()).isEqualTo(1);
-        assertThat(services.size()).isEqualTo(1);
-
-        verifyNoInteractions(a1ClientFactoryMock);
-        verifyNoInteractions(a1ClientMock);
-    }
-
-    @Test
-    void serviceWithoutKeepAliveInterval_shouldNotBeChecked() {
-        setUpRepositoryWithKeepAliveInterval(Duration.ofSeconds(0));
-
-        ServiceSupervision serviceSupervisionUnderTest =
-            new ServiceSupervision(services, policies, a1ClientFactoryMock);
-
-        serviceSupervisionUnderTest.checkAllServices().blockLast();
-
-        assertThat(policies.size()).isEqualTo(1);
-        assertThat(services.size()).isEqualTo(1);
-
-        verifyNoInteractions(a1ClientFactoryMock);
-        verifyNoInteractions(a1ClientMock);
-    }
-
-    private void setUpCreationOfA1Client() {
-        when(a1ClientFactoryMock.createA1Client(any(Ric.class))).thenReturn(Mono.just(a1ClientMock));
-    }
-
-    private void setUpRepositoryWithKeepAliveInterval(Duration keepAliveInterval) {
-        services = new Services();
-        service = new Service(SERVICE_NAME, keepAliveInterval, "callbackUrl");
-        services.put(service);
-
-        policies = new Policies();
-        policies.put(policy);
-    }
-}
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/utils/LoggingUtils.java b/policy-agent/src/test/java/org/oransc/policyagent/utils/LoggingUtils.java
deleted file mode 100644 (file)
index a594091..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.utils;
-
-import ch.qos.logback.classic.Level;
-import ch.qos.logback.classic.Logger;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.read.ListAppender;
-
-import org.slf4j.LoggerFactory;
-
-public class LoggingUtils {
-
-    /**
-     * Returns a ListAppender that contains all logging events. Call this method right before calling the tested
-     * method.
-     *
-     * @return the log list appender for the given class.
-     */
-    public static ListAppender<ILoggingEvent> getLogListAppender(Class<?> logClass) {
-        return getLogListAppender(logClass, Level.ALL);
-    }
-
-    /**
-     * Returns a ListAppender that contains events for the given level. Call this method right before calling the tested
-     * method.
-     *
-     * @param logClass class whose appender is wanted.
-     * @param level the log level to log at.
-     *
-     * @return the log list appender for the given class logging on the given level.
-     */
-    public static ListAppender<ILoggingEvent> getLogListAppender(Class<?> logClass, Level level) {
-        Logger logger = (Logger) LoggerFactory.getLogger(logClass);
-        logger.setLevel(level);
-        ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
-        listAppender.start();
-        logger.addAppender(listAppender);
-
-        return listAppender;
-    }
-}
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/utils/MockA1Client.java b/policy-agent/src/test/java/org/oransc/policyagent/utils/MockA1Client.java
deleted file mode 100644 (file)
index fc0eba3..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.utils;
-
-import java.nio.charset.StandardCharsets;
-import java.time.Duration;
-import java.util.List;
-import java.util.Vector;
-
-import org.oransc.policyagent.clients.A1Client;
-import org.oransc.policyagent.repository.Policies;
-import org.oransc.policyagent.repository.Policy;
-import org.oransc.policyagent.repository.PolicyType;
-import org.oransc.policyagent.repository.PolicyTypes;
-import org.springframework.http.HttpStatus;
-import org.springframework.web.reactive.function.client.WebClientResponseException;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-import reactor.core.publisher.MonoSink;
-
-public class MockA1Client implements A1Client {
-    Policies policies = new Policies();
-    private final PolicyTypes policyTypes;
-    private final Duration asynchDelay;
-
-    public MockA1Client(PolicyTypes policyTypes, Duration asynchDelay) {
-        this.policyTypes = policyTypes;
-        this.asynchDelay = asynchDelay;
-    }
-
-    @Override
-    public Mono<List<String>> getPolicyTypeIdentities() {
-        List<String> result = new Vector<>();
-        for (PolicyType p : this.policyTypes.getAll()) {
-            result.add(p.name());
-        }
-        return mono(result);
-    }
-
-    @Override
-    public Mono<List<String>> getPolicyIdentities() {
-        Vector<String> result = new Vector<>();
-        for (Policy policy : policies.getAll()) {
-            result.add(policy.id());
-        }
-
-        return mono(result);
-    }
-
-    @Override
-    public Mono<String> getPolicyTypeSchema(String policyTypeId) {
-        try {
-            return mono(this.policyTypes.getType(policyTypeId).schema());
-        } catch (Exception e) {
-            return Mono.error(e);
-        }
-    }
-
-    @Override
-    public Mono<String> putPolicy(Policy p) {
-        this.policies.put(p);
-        return mono("OK");
-
-    }
-
-    @Override
-    public Mono<String> deletePolicy(Policy policy) {
-        this.policies.remove(policy);
-        return mono("OK");
-    }
-
-    public Policies getPolicies() {
-        return this.policies;
-    }
-
-    @Override
-    public Mono<A1ProtocolType> getProtocolVersion() {
-        return mono(A1ProtocolType.STD_V1_1);
-    }
-
-    @Override
-    public Flux<String> deleteAllPolicies() {
-        this.policies.clear();
-        return mono("OK") //
-            .flatMapMany(Flux::just);
-    }
-
-    @Override
-    public Mono<String> getPolicyStatus(Policy policy) {
-        return mono("OK");
-    }
-
-    private <T> Mono<T> mono(T value) {
-        if (this.asynchDelay.isZero()) {
-            return Mono.just(value);
-        } else {
-            return Mono.create(monoSink -> asynchResponse(monoSink, value));
-        }
-    }
-
-    Mono<String> monoError(String responseBody, HttpStatus status) {
-        byte[] responseBodyBytes = responseBody.getBytes(StandardCharsets.UTF_8);
-        WebClientResponseException a1Exception = new WebClientResponseException(status.value(),
-            status.getReasonPhrase(), null, responseBodyBytes, StandardCharsets.UTF_8, null);
-        return Mono.error(a1Exception);
-    }
-
-    @SuppressWarnings("squid:S2925") // "Thread.sleep" should not be used in tests.
-    private void sleep() {
-        try {
-            Thread.sleep(this.asynchDelay.toMillis());
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-        }
-    }
-
-    private <T> void asynchResponse(MonoSink<T> callback, T str) {
-        Thread thread = new Thread(() -> {
-            sleep(); // Simulate a network delay
-            callback.success(str);
-        });
-        thread.start();
-    }
-
-}
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/utils/MockA1ClientFactory.java b/policy-agent/src/test/java/org/oransc/policyagent/utils/MockA1ClientFactory.java
deleted file mode 100644 (file)
index c77259c..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================LICENSE_END===================================
- */
-
-package org.oransc.policyagent.utils;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-
-import java.lang.invoke.MethodHandles;
-import java.time.Duration;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.oransc.policyagent.clients.A1Client;
-import org.oransc.policyagent.clients.A1ClientFactory;
-import org.oransc.policyagent.configuration.ApplicationConfig;
-import org.oransc.policyagent.repository.PolicyTypes;
-import org.oransc.policyagent.repository.Ric;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import reactor.core.publisher.Mono;
-
-public class MockA1ClientFactory extends A1ClientFactory {
-    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-    private final Map<String, MockA1Client> clients = new HashMap<>();
-    private PolicyTypes policyTypes;
-    private Duration asynchDelay = Duration.ofSeconds(0);
-
-    public MockA1ClientFactory(PolicyTypes policyTypes) {
-        super(mock(ApplicationConfig.class));
-        this.policyTypes = policyTypes;
-    }
-
-    @Override
-    public Mono<A1Client> createA1Client(Ric ric) {
-        return Mono.just(getOrCreateA1Client(ric.name()));
-    }
-
-    public MockA1Client getOrCreateA1Client(String ricName) {
-        if (!clients.containsKey(ricName)) {
-            logger.debug("Creating client for RIC: {}", ricName);
-            MockA1Client client = spy(new MockA1Client(policyTypes, asynchDelay));
-            clients.put(ricName, client);
-        }
-        return clients.get(ricName);
-    }
-
-    public void setPolicyTypes(PolicyTypes policyTypes) {
-        this.policyTypes = policyTypes;
-    }
-
-    /**
-     * Simulate network latency. The REST responses will be generated by separate
-     * threads
-     * 
-     * @param delay the delay between the request and the response
-     */
-    public void setResponseDelay(Duration delay) {
-        this.asynchDelay = delay;
-    }
-
-    public void reset() {
-        this.asynchDelay = Duration.ofSeconds(0);
-        clients.clear();
-    }
-
-    public PolicyTypes getPolicyTypes() {
-        return this.policyTypes;
-    }
-
-}
diff --git a/policy-agent/src/test/resources/policy_types/demo-policy-schema-1.json b/policy-agent/src/test/resources/policy_types/demo-policy-schema-1.json
deleted file mode 100644 (file)
index 02bc864..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-{
-  "$schema": "http://json-schema.org/draft-07/schema#",
-  "title": "STD_PolicyModelUnconstrained_0.2.0",
-  "description": "Standard model of a policy with unconstrained scope id combinations",
-  "type": "object",
-  "properties": {
-    "scope": {
-      "type": "object",
-      "properties": {
-        "ueId": {"type": "string"},
-        "groupId": {"type": "string"},
-        "sliceId": {"type": "string"},
-        "qosId": {"type": "string"},
-        "cellId": {"type": "string"}
-      },
-      "minProperties": 1,
-      "additionalProperties": false
-    },
-    "qosObjectives": {
-      "type": "object",
-      "properties": {
-        "gfbr": {"type": "number"},
-        "mfbr": {"type": "number"},
-        "priorityLevel": {"type": "number"},
-        "pdb": {"type": "number"}
-      },
-      "additionalProperties": false
-    },
-    "qoeObjectives": {
-      "type": "object",
-      "properties": {
-        "qoeScore": {"type": "number"},
-        "initialBuffering": {"type": "number"},
-        "reBuffFreq": {"type": "number"},
-        "stallRatio": {"type": "number"}
-      },
-      "additionalProperties": false
-    },
-    "resources": {
-      "type": "array",
-      "items": {
-        "type": "object",
-        "properties": {
-          "cellIdList": {
-            "type": "array",
-            "minItems": 1,
-            "uniqueItems": true,
-            "items": {
-              "type": "string"
-            }
-          },
-          "preference": {
-            "type": "string",
-            "enum": [
-              "SHALL",
-              "PREFER",
-              "AVOID",
-              "FORBID"
-            ]
-          },
-          "primary": {"type": "boolean"}
-        },
-        "additionalProperties": false,
-        "required": ["cellIdList", "preference"]
-      }
-    }
-  },
-  "minProperties": 2,
-  "additionalProperties": false,
-  "required": ["scope"]
-}
diff --git a/policy-agent/src/test/resources/policy_types/demo-policy-schema-2.json b/policy-agent/src/test/resources/policy_types/demo-policy-schema-2.json
deleted file mode 100644 (file)
index f3eb28f..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-{
-  "$schema": "http://json-schema.org/draft-07/schema#",
-  "title": "Example_QoETarget_1.0.0",
-  "description": "Example QoE Target policy type",
-  "type": "object",
-  "properties": {
-    "scope": {
-      "type": "object",
-      "properties": {
-        "ueId": {
-          "type": "string"
-        },
-        "sliceId": {
-          "type": "string"
-        },
-        "qosId": {
-          "type": "string"
-        },
-        "cellId": {
-          "type": "string"
-        }
-      },
-      "additionalProperties": false,
-      "required": [
-        "ueId",
-        "sliceId"
-      ]
-    },
-    "statement": {
-      "type": "object",
-      "properties": {
-        "qoeScore": {
-          "type": "number"
-        },
-        "initialBuffering": {
-          "type": "number"
-        },
-        "reBuffFreq": {
-          "type": "number"
-        },
-        "stallRatio": {
-          "type": "number"
-        }
-      },
-      "minProperties": 1,
-      "additionalProperties": false
-    }
-  }
-}
\ No newline at end of file
diff --git a/policy-agent/src/test/resources/policy_types/demo-policy-schema-3.json b/policy-agent/src/test/resources/policy_types/demo-policy-schema-3.json
deleted file mode 100644 (file)
index a73dd59..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-{
-  "$schema": "http://json-schema.org/draft-07/schema#",
-  "title": "ERIC_QoSNudging_0.2.0",
-  "description": "QoS nudging policy type with priorityLevel and ueId and qosId as scope",
-  "type": "object",
-  "properties": {
-    "scope": {
-      "type": "object",
-      "properties": {
-        "ueId": {"type": "string"},
-        "qosId": {"type": "string"}
-      },
-      "additionalProperties": false,
-      "required": ["ueId", "qosId"]
-    },
-    "qosObjectives": {
-      "type": "object",
-      "properties": {
-        "priorityLevel": {"type": "number"}
-      },
-      "additionalProperties": false,
-      "required": ["priorityLevel"]
-    }
-  },
-  "additionalProperties": false,
-  "required": ["scope", "qosObjectives"]
-}
diff --git a/policy-agent/src/test/resources/test_application_configuration.json b/policy-agent/src/test/resources/test_application_configuration.json
deleted file mode 100644 (file)
index 3cbc371..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-{
-   "config": {
-      "//description": "Application configuration",
-      "ric": [
-         {
-            "name": "ric1",
-            "baseUrl": "http://localhost:8080/",
-            "managedElementIds": [
-               "kista_1",
-               "kista_2"
-            ]
-         },
-         {
-            "name": "ric2",
-            "baseUrl": "http://localhost:8081/",
-            "managedElementIds": [
-               "kista_3",
-               "kista_4"
-            ]
-         }
-      ],
-      "streams_publishes": {
-         "dmaap_publisher": {
-            "type": "message_router",
-            "dmaap_info": {
-               "topic_url": "http://admin:admin@localhost:6845/events/A1-POLICY-AGENT-WRITE"
-            }
-         }
-      },
-      "streams_subscribes": {
-         "dmaap_subscriber": {
-            "type": "message_router",
-            "dmaap_info": {
-               "topic_url": "http://admin:admin@localhost:6845/events/A1-POLICY-AGENT-READ/users/policy-agent?timeout=15000&limit=100"
-            }
-         }
-      }
-   }
-}
\ No newline at end of file
diff --git a/policy-agent/src/test/resources/test_application_configuration_with_dmaap_config.json b/policy-agent/src/test/resources/test_application_configuration_with_dmaap_config.json
deleted file mode 100644 (file)
index 61ab31e..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-{
-   "config": {
-      "controller": [
-         {
-            "name": "controller1",
-            "baseUrl": "http://localhost:8083/",
-            "userName": "user",
-            "password": "password"
-         }
-      ],
-      "ric": [
-         {
-            "name": "ric1",
-            "controller": "controller1",
-            "baseUrl": "http://localhost:8083/",
-            "managedElementIds": [
-               "kista_1",
-               "kista_2"
-            ]
-         },
-         {
-            "name": "ric2",
-            "baseUrl": "http://localhost:8085/",
-            "managedElementIds": [
-               "kista_3",
-               "kista_4"
-            ]
-         }
-      ],
-      "streams_publishes": {
-         "dmaap_publisher": {
-            "type": "message_router",
-            "dmaap_info": {
-               "topic_url": "http://admin:admin@localhost:6845/events/A1-POLICY-AGENT-WRITE"
-            }
-         }
-      },
-      "streams_subscribes": {
-         "dmaap_subscriber": {
-            "type": "message_router",
-            "dmaap_info": {
-               "topic_url": "http://admin:admin@localhost:6845/events/A1-POLICY-AGENT-READ/users/policy-agent?timeout=15000&limit=100"
-            }
-         }
-      }
-   }
-}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index cb8302e..92d50a6 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -34,8 +34,8 @@
     </properties>
     <modules>
         <module>policy-agent</module>
-        <module>sdnc-a1-controller</module>
         <module>enrichment-coordinator-service</module>
+        <module>r-app-catalogue</module>
     </modules>
     <build>
         <plugins>
diff --git a/r-app-catalogue/.gitignore b/r-app-catalogue/.gitignore
new file mode 100644 (file)
index 0000000..ad56f2d
--- /dev/null
@@ -0,0 +1,3 @@
+.swagger-codegen-ignore
+.swagger-codegen/
+api/README.md
diff --git a/r-app-catalogue/Dockerfile b/r-app-catalogue/Dockerfile
new file mode 100644 (file)
index 0000000..a85f57d
--- /dev/null
@@ -0,0 +1,39 @@
+#
+# ============LICENSE_START=======================================================
+#  Copyright (C) 2020 Nordix Foundation.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+# ============LICENSE_END=========================================================
+#
+FROM openjdk:11-jre-slim
+
+ARG JAR
+
+WORKDIR /opt/app/r-app-catalogue
+RUN mkdir -p /var/log/r-app-catalogue
+
+EXPOSE 8081 8433
+
+ADD /config/application.yaml /opt/app/r-app-catalogue/config/application.yaml
+ADD target/${JAR} /opt/app/r-app-catalogue/r-app-catalogue.jar
+
+
+RUN chmod -R 777 /opt/app/r-app-catalogue/config/
+
+CMD ["java", "-jar", "/opt/app/r-app-catalogue/r-app-catalogue.jar"]
+
+
+
+
diff --git a/r-app-catalogue/README.md b/r-app-catalogue/README.md
new file mode 100644 (file)
index 0000000..863713d
--- /dev/null
@@ -0,0 +1,27 @@
+# O-RAN-SC Non-RT RIC rAPP Catalogue
+
+The O-RAN Non-RT RIC rApp Catalogue provides an OpenApi 3.0 REST API for services to register themselves and discover
+other services.
+
+**NOTE!** The definition of the REST API is done in the `api/rac-api.json` file. The yaml version of the file is
+generated during compilation.
+
+The application is a SpringBoot application generated using the openapitools openapi-generator-maven-plugin.
+
+To start the application run:
+`mvn spring-boot:run`
+
+## License
+
+Copyright (C) 2020 Nordix Foundation. All rights reserved.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/r-app-catalogue/api/rac-api.json b/r-app-catalogue/api/rac-api.json
new file mode 100644 (file)
index 0000000..64f19d8
--- /dev/null
@@ -0,0 +1,252 @@
+{
+    "openapi": "3.0.0",
+    "info": {
+        "title": "rAPP Catalogue API",
+        "description": "The Non RT-RIC Service Catalogue provides a way for services to register themselves for other services to discover.",
+        "version": "1.0.0"
+    },
+    "servers": [
+        {
+            "url": "/"
+        }
+    ],
+    "paths": {
+        "/services": {
+            "get": {
+                "summary": "Services",
+                "deprecated": false,
+                "operationId": "getServices",
+                "responses": {
+                    "200": {
+                        "description": "Services",
+                        "content": {
+                            "application/json": {
+                                "schema": {
+                                    "type": "array",
+                                    "items": {
+                                        "$ref": "#/components/schemas/service"
+                                    }
+                                }
+                            }
+                        }
+                    }
+                },
+                "tags": [
+                    "rAPP Catalogue API"
+                ]
+            }
+        },
+        "/services/{serviceName}": {
+            "get": {
+                "summary": "Individual Service",
+                "deprecated": false,
+                "operationId": "getIndividualService",
+                "responses": {
+                    "200": {
+                        "description": "Service",
+                        "content": {
+                            "application/json": {
+                                "schema": {
+                                    "$ref": "#/components/schemas/service"
+                                }
+                            }
+                        }
+                    },
+                    "404": {
+                        "description": "Service is not found",
+                        "content": {
+                            "application/json": {
+                                "schema": {
+                                    "$ref": "#/components/schemas/error_information"
+                                }
+                            }
+                        }
+                    }
+                },
+                "parameters": [
+                    {
+                        "in": "path",
+                        "name": "serviceName",
+                        "description": "serviceName",
+                        "schema": {
+                            "type": "string"
+                        },
+                        "required": true,
+                        "example": "DroneIdentifier"
+                    }
+                ],
+                "tags": [
+                    "rAPP Catalogue API"
+                ]
+            },
+            "put": {
+                "summary": "Create or update a Service",
+                "deprecated": false,
+                "operationId": "putIndividualService",
+                "responses": {
+                    "200": {
+                        "description": "Service updated"
+                    },
+                    "201": {
+                        "description": "Service created",
+                        "headers": {
+                            "Location": {
+                                "schema": {
+                                    "type": "string"
+                                },
+                                "description": "URL to the created Service"
+                            }
+                        }
+                    },
+                    "400": {
+                        "description": "Provided service is not correct",
+                        "content": {
+                            "application/json": {
+                                "schema": {
+                                    "$ref": "#/components/schemas/error_information"
+                                },
+                                "example": {
+                                    "detail": "Service is missing required property: version",
+                                    "status": 400
+                                }
+                            }
+                        }
+                    }
+                },
+                "parameters": [
+                    {
+                        "name": "serviceName",
+                        "in": "path",
+                        "required": true,
+                        "schema": {
+                            "type": "string"
+                        },
+                        "example": "DroneIdentifier"
+                    }
+                ],
+                "requestBody": {
+                    "description": "Service to create/update",
+                    "required": true,
+                    "content": {
+                        "application/json": {
+                            "schema": {
+                                "$ref": "#/components/schemas/inputService"
+                            }
+                        }
+                    }
+                },
+                "tags": [
+                    "rAPP Catalogue API"
+                ]
+            },
+            "delete": {
+                "summary": "Remove a Service from the catalogue",
+                "deprecated": false,
+                "operationId": "deleteIndividualService",
+                "responses": {
+                    "204": {
+                        "description": "Service deleted"
+                    }
+                },
+                "parameters": [
+                    {
+                        "name": "serviceName",
+                        "in": "path",
+                        "required": true,
+                        "schema": {
+                            "type": "string"
+                        },
+                        "example": "DroneIdentifier"
+                    }
+                ],
+                "tags": [
+                    "rAPP Catalogue API"
+                ]
+            }
+        }
+    },
+    "components": {
+        "schemas": {
+            "inputService": {
+                "description": "A Service to register",
+                "type": "object",
+                "title": "inputService",
+                "required": [
+                    "version"
+                ],
+                "properties": {
+                    "version": {
+                        "description": "Version of the Service",
+                        "type": "string",
+                        "example": "1.0.0"
+                    },
+                    "display_name": {
+                        "description": "Display name for the Service",
+                        "type": "string",
+                        "example": "Drone Identifier"
+                    },
+                    "description": {
+                        "description": "Description of the Service",
+                        "type": "string",
+                        "example": "Detects if a UE is a drone"
+                    }
+                }
+            },
+            "service": {
+                "description": "A Service",
+                "type": "object",
+                "title": "service",
+                "required": [
+                    "name",
+                    "version",
+                    "registrationDate"
+                ],
+                "properties": {
+                    "name": {
+                        "description": "Unique identifier of the Service",
+                        "type": "string",
+                        "example": "DroneIdentifier"
+                    },
+                    "version": {
+                        "description": "Version of the Service",
+                        "type": "string",
+                        "example": "1.0.0"
+                    },
+                    "display_name": {
+                        "description": "Display name for the Service",
+                        "type": "string",
+                        "example": "Drone Identifier"
+                    },
+                    "description": {
+                        "description": "Description of the Service",
+                        "type": "string",
+                        "example": "Detects if a UE is a drone"
+                    },
+                    "registrationDate": {
+                        "description": "Date when the Service was registered in the catalogue",
+                        "type": "string",
+                        "example": "2020-11-03"
+                    }
+                }
+            },
+            "error_information": {
+                "description": "Problem as defined in https://tools.ietf.org/html/rfc7807",
+                "type": "object",
+                "title": "error_information",
+                "properties": {
+                    "detail": {
+                        "description": "A human-readable explanation specific to this occurrence of the problem.",
+                        "type": "string",
+                        "example": "Service not found"
+                    },
+                    "status": {
+                        "format": "int32",
+                        "description": "The HTTP status code for this occurrence of the problem.",
+                        "type": "integer",
+                        "example": 404
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/r-app-catalogue/api/rac-api.yaml b/r-app-catalogue/api/rac-api.yaml
new file mode 100644 (file)
index 0000000..748cf2b
--- /dev/null
@@ -0,0 +1,181 @@
+openapi: 3.0.0
+info:
+  title: rAPP Catalogue API
+  description: The Non RT-RIC Service Catalogue provides a way for services to register
+    themselves for other services to discover.
+  version: 1.0.0
+servers:
+- url: /
+paths:
+  /services:
+    get:
+      tags:
+      - rAPP Catalogue API
+      summary: Services
+      operationId: getServices
+      responses:
+        200:
+          description: Services
+          content:
+            application/json:
+              schema:
+                type: array
+                items:
+                  $ref: '#/components/schemas/service'
+      deprecated: false
+  /services/{serviceName}:
+    get:
+      tags:
+      - rAPP Catalogue API
+      summary: Individual Service
+      operationId: getIndividualService
+      parameters:
+      - name: serviceName
+        in: path
+        description: serviceName
+        required: true
+        style: simple
+        explode: false
+        schema:
+          type: string
+        example: DroneIdentifier
+      responses:
+        200:
+          description: Service
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/service'
+        404:
+          description: Service is not found
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/error_information'
+      deprecated: false
+    put:
+      tags:
+      - rAPP Catalogue API
+      summary: Create or update a Service
+      operationId: putIndividualService
+      parameters:
+      - name: serviceName
+        in: path
+        required: true
+        style: simple
+        explode: false
+        schema:
+          type: string
+        example: DroneIdentifier
+      requestBody:
+        description: Service to create/update
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/inputService'
+        required: true
+      responses:
+        200:
+          description: Service updated
+        201:
+          description: Service created
+          headers:
+            Location:
+              description: URL to the created Service
+              style: simple
+              explode: false
+              schema:
+                type: string
+        400:
+          description: Provided service is not correct
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/error_information'
+              example:
+                detail: 'Service is missing required property: version'
+                status: 400
+      deprecated: false
+    delete:
+      tags:
+      - rAPP Catalogue API
+      summary: Remove a Service from the catalogue
+      operationId: deleteIndividualService
+      parameters:
+      - name: serviceName
+        in: path
+        required: true
+        style: simple
+        explode: false
+        schema:
+          type: string
+        example: DroneIdentifier
+      responses:
+        204:
+          description: Service deleted
+      deprecated: false
+components:
+  schemas:
+    inputService:
+      title: inputService
+      required:
+      - version
+      type: object
+      properties:
+        version:
+          type: string
+          description: Version of the Service
+          example: 1.0.0
+        display_name:
+          type: string
+          description: Display name for the Service
+          example: Drone Identifier
+        description:
+          type: string
+          description: Description of the Service
+          example: Detects if a UE is a drone
+      description: A Service to register
+    service:
+      title: service
+      required:
+      - name
+      - registrationDate
+      - version
+      type: object
+      properties:
+        name:
+          type: string
+          description: Unique identifier of the Service
+          example: DroneIdentifier
+        version:
+          type: string
+          description: Version of the Service
+          example: 1.0.0
+        display_name:
+          type: string
+          description: Display name for the Service
+          example: Drone Identifier
+        description:
+          type: string
+          description: Description of the Service
+          example: Detects if a UE is a drone
+        registrationDate:
+          type: string
+          description: Date when the Service was registered in the catalogue
+          example: 2020-11-03
+      description: A Service
+    error_information:
+      title: error_information
+      type: object
+      properties:
+        detail:
+          type: string
+          description: A human-readable explanation specific to this occurrence of
+            the problem.
+          example: Service not found
+        status:
+          type: integer
+          description: The HTTP status code for this occurrence of the problem.
+          format: int32
+          example: 404
+      description: Problem as defined in https://tools.ietf.org/html/rfc7807
diff --git a/r-app-catalogue/config/application.yaml b/r-app-catalogue/config/application.yaml
new file mode 100644 (file)
index 0000000..fadf7d2
--- /dev/null
@@ -0,0 +1,4 @@
+spring:
+  profiles:
+    active: prod
+
diff --git a/r-app-catalogue/pom.xml b/r-app-catalogue/pom.xml
new file mode 100644 (file)
index 0000000..a2a2dfc
--- /dev/null
@@ -0,0 +1,286 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+* ========================LICENSE_START=================================\r
+* O-RAN-SC\r
+* %%\r
+* Copyright (C) 2020 Nordix Foundation\r
+* %%\r
+* Licensed under the Apache License, Version 2.0 (the "License");\r
+* you may not use this file except in compliance with the License.\r
+* You may obtain a copy of the License at\r
+*\r
+* http://www.apache.org/licenses/LICENSE-2.0\r
+*\r
+* Unless required by applicable law or agreed to in writing, software\r
+* distributed under the License is distributed on an "AS IS" BASIS,\r
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+* See the License for the specific language governing permissions and\r
+* limitations under the License.\r
+* ========================LICENSE_END===================================\r
+-->\r
+<project xmlns="http://maven.apache.org/POM/4.0.0"\r
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+    <modelVersion>4.0.0</modelVersion>\r
+\r
+    <parent>\r
+        <groupId>org.springframework.boot</groupId>\r
+        <artifactId>spring-boot-starter-parent</artifactId>\r
+        <version>2.3.4.RELEASE</version>\r
+        <relativePath />\r
+    </parent>\r
+    <groupId>org.o-ran-sc.nonrtric</groupId>\r
+    <artifactId>r-app-catalogue</artifactId>\r
+    <version>1.0.0-SNAPSHOT</version>\r
+    <licenses>\r
+        <license>\r
+            <name>The Apache Software License, Version 2.0</name>\r
+            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>\r
+        </license>\r
+    </licenses>\r
+    <properties>\r
+        <java.version>11</java.version>\r
+        <swagger-annotations.version>1.5.22</swagger-annotations.version>\r
+        <springfox.version>2.9.2</springfox.version>\r
+        <jackson-databind-nullable.version>0.2.1</jackson-databind-nullable.version>\r
+        <openapi-generator-maven-plugin.version>4.3.1</openapi-generator-maven-plugin.version>\r
+        <swagger-codegen-maven-plugin.version>3.0.11</swagger-codegen-maven-plugin.version>\r
+        <jacoco-maven-plugin.version>0.8.6</jacoco-maven-plugin.version>\r
+        <docker-maven-plugin.version>0.30.0</docker-maven-plugin.version>\r
+    </properties>\r
+\r
+    <dependencies>\r
+        <dependency>\r
+            <groupId>io.swagger</groupId>\r
+            <artifactId>swagger-annotations</artifactId>\r
+            <version>${swagger-annotations.version}</version>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>com.fasterxml.jackson.core</groupId>\r
+            <artifactId>jackson-annotations</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.springframework</groupId>\r
+            <artifactId>spring-beans</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.springframework.boot</groupId>\r
+            <artifactId>spring-boot-autoconfigure</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.springframework</groupId>\r
+            <artifactId>spring-web</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.springframework.boot</groupId>\r
+            <artifactId>spring-boot</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.springframework</groupId>\r
+            <artifactId>spring-webmvc</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.springframework</groupId>\r
+            <artifactId>spring-context</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>io.springfox</groupId>\r
+            <artifactId>springfox-swagger2</artifactId>\r
+            <version>${springfox.version}</version>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>io.springfox</groupId>\r
+            <artifactId>springfox-core</artifactId>\r
+            <version>${springfox.version}</version>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>io.springfox</groupId>\r
+            <artifactId>springfox-spring-web</artifactId>\r
+            <version>${springfox.version}</version>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>io.springfox</groupId>\r
+            <artifactId>springfox-spi</artifactId>\r
+            <version>${springfox.version}</version>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.assertj</groupId>\r
+            <artifactId>assertj-core</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.apache.tomcat.embed</groupId>\r
+            <artifactId>tomcat-embed-core</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.openapitools</groupId>\r
+            <artifactId>jackson-databind-nullable</artifactId>\r
+            <version>${jackson-databind-nullable.version}</version>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>javax.validation</groupId>\r
+            <artifactId>validation-api</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>com.fasterxml.jackson.core</groupId>\r
+            <artifactId>jackson-databind</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.yaml</groupId>\r
+            <artifactId>snakeyaml</artifactId>\r
+            <scope>runtime</scope>\r
+        </dependency>\r
+        <!-- TEST -->\r
+        <dependency>\r
+            <groupId>org.springframework</groupId>\r
+            <artifactId>spring-test</artifactId>\r
+            <scope>test</scope>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.junit.jupiter</groupId>\r
+            <artifactId>junit-jupiter-api</artifactId>\r
+            <scope>test</scope>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.mockito</groupId>\r
+            <artifactId>mockito-junit-jupiter</artifactId>\r
+            <scope>test</scope>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.mockito</groupId>\r
+            <artifactId>mockito-core</artifactId>\r
+            <scope>test</scope>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.junit.jupiter</groupId>\r
+            <artifactId>junit-jupiter-engine</artifactId>\r
+            <scope>test</scope>\r
+        </dependency>\r
+    </dependencies>\r
+\r
+    <build>\r
+        <plugins>\r
+            <plugin>\r
+                <groupId>org.openapitools</groupId>\r
+                <artifactId>openapi-generator-maven-plugin</artifactId>\r
+                <version>${openapi-generator-maven-plugin.version}</version>\r
+                <executions>\r
+                    <execution>\r
+                        <goals>\r
+                            <goal>generate</goal>\r
+                        </goals>\r
+                        <configuration>\r
+                            <inputSpec>${project.basedir}/api/rac-api.json</inputSpec>\r
+                            <generatorName>spring</generatorName>\r
+                            <apiPackage>org.oransc.rappcatalogue.api</apiPackage>\r
+                            <modelPackage>org.oransc.rappcatalogue.model</modelPackage>\r
+                            <configOptions>\r
+                                <delegatePattern>true</delegatePattern>\r
+                            </configOptions>\r
+                        </configuration>\r
+                    </execution>\r
+                </executions>\r
+            </plugin>\r
+            <plugin>\r
+                <groupId>io.swagger.codegen.v3</groupId>\r
+                <artifactId>swagger-codegen-maven-plugin</artifactId>\r
+                <version>${swagger-codegen-maven-plugin.version}</version>\r
+                <executions>\r
+                    <execution>\r
+                        <goals>\r
+                            <goal>generate</goal>\r
+                        </goals>\r
+                        <configuration>\r
+                            <inputSpec>${project.basedir}/api/rac-api.json</inputSpec>\r
+                            <language>openapi-yaml</language>\r
+                            <output>${project.basedir}/api/</output>\r
+                            <configOptions>\r
+                                <outputFile>rac-api.yaml</outputFile>\r
+                            </configOptions>\r
+                        </configuration>\r
+                    </execution>\r
+                </executions>\r
+            </plugin>\r
+            <plugin>\r
+                <groupId>org.jacoco</groupId>\r
+                <artifactId>jacoco-maven-plugin</artifactId>\r
+                <version>${jacoco-maven-plugin.version}</version>\r
+                <executions>\r
+                    <execution>\r
+                        <id>default-prepare-agent</id>\r
+                        <goals>\r
+                            <goal>prepare-agent</goal>\r
+                        </goals>\r
+                    </execution>\r
+                    <execution>\r
+                        <id>default-report</id>\r
+                        <phase>prepare-package</phase>\r
+                        <goals>\r
+                            <goal>report</goal>\r
+                        </goals>\r
+                    </execution>\r
+                </executions>\r
+            </plugin>\r
+            <plugin>\r
+                <groupId>io.fabric8</groupId>\r
+                <artifactId>docker-maven-plugin</artifactId>\r
+                <version>${docker-maven-plugin.version}</version>\r
+                <inherited>false</inherited>\r
+                <executions>\r
+                    <execution>\r
+                        <id>generate-r-app-catalogue-image</id>\r
+                        <phase>package</phase>\r
+                        <goals>\r
+                            <goal>build</goal>\r
+                        </goals>\r
+                        <configuration>\r
+                            <pullRegistry>${env.CONTAINER_PULL_REGISTRY}</pullRegistry>\r
+                            <images>\r
+                                <image>\r
+                                    <name>o-ran-sc/nonrtric-r-app-catalogue:${project.version}</name>\r
+                                    <build>\r
+                                        <cleanup>try</cleanup>\r
+                                        <contextDir>${basedir}</contextDir>\r
+                                        <dockerFile>Dockerfile</dockerFile>\r
+                                        <args>\r
+                                            <JAR>${project.build.finalName}.jar</JAR>\r
+                                        </args>\r
+                                        <tags>\r
+                                            <tag>${project.version}</tag>\r
+                                        </tags>\r
+                                    </build>\r
+                                </image>\r
+                            </images>\r
+                        </configuration>\r
+                    </execution>\r
+                    <execution>\r
+                        <id>push-r-app-catalogue-image</id>\r
+                        <goals>\r
+                            <goal>build</goal>\r
+                            <goal>push</goal>\r
+                        </goals>\r
+                        <configuration>\r
+                            <pullRegistry>${env.CONTAINER_PULL_REGISTRY}</pullRegistry>\r
+                            <pushRegistry>${env.CONTAINER_PUSH_REGISTRY}</pushRegistry>\r
+                            <images>\r
+                                <image>\r
+                                    <name>o-ran-sc/nonrtric-r-app-catalogue:${project.version}</name>\r
+                                    <build>\r
+                                        <contextDir>${basedir}</contextDir>\r
+                                        <dockerFile>Dockerfile</dockerFile>\r
+                                        <args>\r
+                                            <JAR>${project.build.finalName}.jar</JAR>\r
+                                        </args>\r
+                                        <tags>\r
+                                            <tag>${project.version}</tag>\r
+                                            <tag>latest</tag>\r
+                                        </tags>\r
+                                    </build>\r
+                                </image>\r
+                            </images>\r
+                        </configuration>\r
+                    </execution>\r
+                </executions>\r
+            </plugin>\r
+        </plugins>\r
+    </build>\r
+</project>
\ No newline at end of file
diff --git a/r-app-catalogue/src/main/java/org/oransc/rappcatalogue/api/GeneralRappCatalogueControllerAdvisor.java b/r-app-catalogue/src/main/java/org/oransc/rappcatalogue/api/GeneralRappCatalogueControllerAdvisor.java
new file mode 100644 (file)
index 0000000..939f7bf
--- /dev/null
@@ -0,0 +1,64 @@
+/*-
+ * ========================LICENSE_START=================================
+ * Copyright (C) 2020 Nordix Foundation. All rights reserved.
+ * ======================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================LICENSE_END===================================
+ */
+
+package org.oransc.rappcatalogue.api;
+
+import static org.springframework.http.HttpStatus.BAD_REQUEST;
+import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
+import static org.springframework.http.HttpStatus.NOT_FOUND;
+
+import org.oransc.rappcatalogue.exception.HeaderException;
+import org.oransc.rappcatalogue.exception.InvalidServiceException;
+import org.oransc.rappcatalogue.exception.ServiceNotFoundException;
+import org.oransc.rappcatalogue.model.ErrorInformation;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
+
+@ControllerAdvice
+public class GeneralRappCatalogueControllerAdvisor extends ResponseEntityExceptionHandler {
+    @ExceptionHandler(InvalidServiceException.class)
+    public ResponseEntity<Object> handleInvalidServiceException(
+        InvalidServiceException ex) {
+
+        return new ResponseEntity<>(getErrorInformation(ex, BAD_REQUEST), BAD_REQUEST);
+    }
+
+    @ExceptionHandler(ServiceNotFoundException.class)
+    public ResponseEntity<Object> handleServiceNotFoundException(
+        ServiceNotFoundException ex) {
+
+        return new ResponseEntity<>(getErrorInformation(ex, NOT_FOUND), NOT_FOUND);
+    }
+
+    @ExceptionHandler(HeaderException.class)
+    public ResponseEntity<Object> handleHeaderException(
+        HeaderException ex) {
+
+        return new ResponseEntity<>(getErrorInformation(ex, INTERNAL_SERVER_ERROR), INTERNAL_SERVER_ERROR);
+    }
+
+    private ErrorInformation getErrorInformation(Exception cause, HttpStatus status) {
+        ErrorInformation errorInfo = new ErrorInformation();
+        errorInfo.setDetail(cause.getMessage());
+        errorInfo.setStatus(status.value());
+        return errorInfo;
+    }
+}
diff --git a/r-app-catalogue/src/main/java/org/oransc/rappcatalogue/api/ServicesApiDelegateImpl.java b/r-app-catalogue/src/main/java/org/oransc/rappcatalogue/api/ServicesApiDelegateImpl.java
new file mode 100644 (file)
index 0000000..bb3a6dc
--- /dev/null
@@ -0,0 +1,141 @@
+/*-\r
+ * ========================LICENSE_START=================================\r
+ * Copyright (C) 2020 Nordix Foundation. All rights reserved.\r
+ * ======================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * ========================LICENSE_END===================================\r
+ */\r
+\r
+package org.oransc.rappcatalogue.api;\r
+\r
+import java.io.IOException;\r
+import java.sql.Date;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.Optional;\r
+import java.util.concurrent.ConcurrentHashMap;\r
+import javax.servlet.http.HttpServletRequest;\r
+import javax.servlet.http.HttpServletResponse;\r
+import org.oransc.rappcatalogue.exception.HeaderException;\r
+import org.oransc.rappcatalogue.exception.InvalidServiceException;\r
+import org.oransc.rappcatalogue.exception.ServiceNotFoundException;\r
+import org.oransc.rappcatalogue.model.InputService;\r
+import org.oransc.rappcatalogue.model.Service;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.http.HttpStatus;\r
+import org.springframework.http.ResponseEntity;\r
+import org.springframework.web.context.request.NativeWebRequest;\r
+\r
+@org.springframework.stereotype.Service\r
+public class ServicesApiDelegateImpl implements ServicesApiDelegate {\r
+\r
+    private static final String LOCATION_HEADER = "Location";\r
+\r
+    @Autowired\r
+    private NativeWebRequest nativeWebRequest;\r
+\r
+    private ConcurrentHashMap<String, Service> registeredServices = new ConcurrentHashMap<>();\r
+\r
+    ServicesApiDelegateImpl(NativeWebRequest nativeWebRequest) {\r
+        this.nativeWebRequest = nativeWebRequest;\r
+    }\r
+\r
+    @Override\r
+    public Optional<NativeWebRequest> getRequest() {\r
+        return Optional.of(nativeWebRequest);\r
+    }\r
+\r
+    @Override\r
+    public ResponseEntity<Service> getIndividualService(String serviceName) {\r
+        Service service = registeredServices.get(serviceName);\r
+        if (service != null) {\r
+            return ResponseEntity.ok(service);\r
+        } else {\r
+            throw new ServiceNotFoundException(serviceName);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public ResponseEntity<List<Service>> getServices() {\r
+        return ResponseEntity.ok(new ArrayList<>(registeredServices.values()));\r
+    }\r
+\r
+    @Override\r
+    public ResponseEntity<Void> putIndividualService(String serviceName, InputService inputService) {\r
+        if (isServiceValid(inputService)) {\r
+            if (registeredServices.put(serviceName, createService(serviceName, inputService)) == null) {\r
+                try {\r
+                    getRequest().ifPresent(request -> addLocationHeaderToResponse(serviceName, request));\r
+                } catch (Exception e) {\r
+                    registeredServices.remove(serviceName);\r
+                    throw e;\r
+                }\r
+                return new ResponseEntity<>(HttpStatus.CREATED);\r
+            } else {\r
+                return new ResponseEntity<>(HttpStatus.OK);\r
+            }\r
+        } else {\r
+            throw new InvalidServiceException();\r
+        }\r
+    }\r
+\r
+    private void addLocationHeaderToResponse(String serviceName, NativeWebRequest request) {\r
+        try {\r
+            HttpServletRequest nativeRequest = request.getNativeRequest(HttpServletRequest.class);\r
+            HttpServletResponse nativeResponse = request.getNativeResponse(HttpServletResponse.class);\r
+            if (nativeRequest != null && nativeResponse != null) {\r
+                StringBuffer requestURL = nativeRequest.getRequestURL();\r
+                nativeResponse.addHeader(LOCATION_HEADER, requestURL.toString());\r
+                nativeResponse.getWriter().print("");\r
+            } else {\r
+                throw new HeaderException(LOCATION_HEADER, serviceName,\r
+                    new Exception("Native Request or Response missing"));\r
+            }\r
+        } catch (IOException e) {\r
+            throw new HeaderException(LOCATION_HEADER, serviceName, e);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public ResponseEntity<Void> deleteIndividualService(String serviceName) {\r
+        registeredServices.remove(serviceName);\r
+        return new ResponseEntity<>(HttpStatus.NO_CONTENT);\r
+    }\r
+\r
+    /*\r
+     * java:S2589: Boolean expressions should not be gratuitous.\r
+     * Even though the version property is marked as @NotNull, it might be null coming from the client, hence the null\r
+     * check is needed.\r
+     */\r
+    @SuppressWarnings("java:S2589")\r
+    private boolean isServiceValid(InputService service) {\r
+        String version = service.getVersion();\r
+        return version != null && !version.isBlank();\r
+    }\r
+\r
+    private Service createService(String serviceName, InputService inputService) {\r
+        Service service = new Service();\r
+        service.setName(serviceName);\r
+        service.setDescription(inputService.getDescription());\r
+        service.setDisplayName(inputService.getDisplayName());\r
+        service.setVersion(inputService.getVersion());\r
+        service.setRegistrationDate(getTodaysDate());\r
+        return service;\r
+    }\r
+\r
+    private String getTodaysDate() {\r
+        long millis = System.currentTimeMillis();\r
+        Date date = new Date(millis);\r
+        return date.toString();\r
+    }\r
+}\r
@@ -1,9 +1,7 @@
 /*-
  * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
+ * Copyright (C) 2020 Nordix Foundation. All rights reserved.
+ * ======================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  * ========================LICENSE_END===================================
  */
 
-package org.oransc.policyagent.configuration;
+package org.oransc.rappcatalogue.exception;
 
-import com.google.common.collect.ImmutableList;
+public class HeaderException extends RuntimeException {
 
-import org.immutables.value.Value;
+    private static final long serialVersionUID = -7798178963078284655L;
 
-@Value.Immutable
-public interface RicConfig {
-    public String name();
-
-    public String controllerName();
-
-    public String baseUrl();
-
-    public ImmutableList<String> managedElementIds();
+    public HeaderException(String header, String serviceName, Exception cause) {
+        super(String.format("Unable to set header %s in put response for service %s. Cause: %s", header, serviceName,
+            cause.getMessage()));
+    }
 
 }
@@ -1,9 +1,7 @@
 /*-
  * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
+ * Copyright (C) 2020 Nordix Foundation. All rights reserved.
+ * ======================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  * ========================LICENSE_END===================================
  */
 
-package org.oransc.policyagent.exceptions;
+package org.oransc.rappcatalogue.exception;
 
-public class EnvironmentLoaderException extends ServiceException {
+public class InvalidServiceException extends RuntimeException {
+    private static final long serialVersionUID = 3849219105170316564L;
 
-    private static final long serialVersionUID = 1L;
-
-    public EnvironmentLoaderException(String message) {
-        super(message);
+    public InvalidServiceException() {
+        super("Service is missing required property: version");
     }
 }
@@ -1,9 +1,7 @@
 /*-
  * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2020 Nordix Foundation
- * %%
+ * Copyright (C) 2020 Nordix Foundation. All rights reserved.
+ * ======================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  * ========================LICENSE_END===================================
  */
 
-package org.oransc.policyagent.clients;
+package org.oransc.rappcatalogue.exception;
 
-/**
- * Builder for A1 influenced REST APIs
- */
-interface A1UriBuilder {
-    String createPutPolicyUri(String type, String policyId);
-
-    String createDeleteUri(String type, String policyId);
+public class ServiceNotFoundException extends RuntimeException {
+    private static final long serialVersionUID = 6579271315716003988L;
 
-    String createGetPolicyStatusUri(String type, String policyId);
+    public ServiceNotFoundException(String serviceName) {
+        super(String.format("Service %s not found", serviceName));
+    }
 }
diff --git a/r-app-catalogue/src/test/java/org/oransc/rappcatalogue/api/GeneralRappCatalogueControllerAdvisorTest.java b/r-app-catalogue/src/test/java/org/oransc/rappcatalogue/api/GeneralRappCatalogueControllerAdvisorTest.java
new file mode 100644 (file)
index 0000000..24afa09
--- /dev/null
@@ -0,0 +1,78 @@
+/*-
+ * ========================LICENSE_START=================================
+ * Copyright (C) 2020 Nordix Foundation. All rights reserved.
+ * ======================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================LICENSE_END===================================
+ */
+
+package org.oransc.rappcatalogue.api;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.http.HttpStatus.BAD_REQUEST;
+import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
+import static org.springframework.http.HttpStatus.NOT_FOUND;
+
+import org.junit.jupiter.api.Test;
+import org.oransc.rappcatalogue.exception.HeaderException;
+import org.oransc.rappcatalogue.exception.InvalidServiceException;
+import org.oransc.rappcatalogue.exception.ServiceNotFoundException;
+import org.oransc.rappcatalogue.model.ErrorInformation;
+import org.springframework.http.ResponseEntity;
+
+class GeneralRappCatalogueControllerAdvisorTest {
+
+    @Test
+    void handleInvalidServiceException_shouldReturnBadRequestWithMessage() {
+        GeneralRappCatalogueControllerAdvisor advisorUnderTest = new GeneralRappCatalogueControllerAdvisor();
+
+        InvalidServiceException exception = new InvalidServiceException();
+
+        ResponseEntity<Object> response = advisorUnderTest.handleInvalidServiceException(exception);
+
+        assertThat(response.getStatusCode()).isEqualTo(BAD_REQUEST);
+        ErrorInformation body = (ErrorInformation) response.getBody();
+        assertThat(body.getStatus()).isEqualTo(BAD_REQUEST.value());
+        assertThat(body.getDetail()).isEqualTo("Service is missing required property: version");
+    }
+
+    @Test
+    void handleServiceNotFoundException_shouldReturnNotFoundWithMessage() {
+        GeneralRappCatalogueControllerAdvisor advisorUnderTest = new GeneralRappCatalogueControllerAdvisor();
+
+        ServiceNotFoundException exception = new ServiceNotFoundException("Name");
+
+        ResponseEntity<Object> response = advisorUnderTest.handleServiceNotFoundException(exception);
+
+        assertThat(response.getStatusCode()).isEqualTo(NOT_FOUND);
+        ErrorInformation body = (ErrorInformation) response.getBody();
+        assertThat(body.getStatus()).isEqualTo(NOT_FOUND.value());
+        assertThat(body.getDetail()).isEqualTo("Service Name not found");
+    }
+
+    @Test
+    void handleHeaderException_shouldReturnInternalServerErrorWithMessage() {
+        GeneralRappCatalogueControllerAdvisor advisorUnderTest = new GeneralRappCatalogueControllerAdvisor();
+
+        String serviceName = "Service";
+        HeaderException exception = new HeaderException("Header", serviceName, new Exception("Cause"));
+
+        ResponseEntity<Object> response = advisorUnderTest.handleHeaderException(exception);
+
+        assertThat(response.getStatusCode()).isEqualTo(INTERNAL_SERVER_ERROR);
+        ErrorInformation body = (ErrorInformation) response.getBody();
+        assertThat(body.getStatus()).isEqualTo(INTERNAL_SERVER_ERROR.value());
+        assertThat(body.getDetail())
+            .isEqualTo("Unable to set header Header in put response for service " + serviceName + ". Cause: Cause");
+    }
+}
diff --git a/r-app-catalogue/src/test/java/org/oransc/rappcatalogue/api/ServicesApiDelegateImplTest.java b/r-app-catalogue/src/test/java/org/oransc/rappcatalogue/api/ServicesApiDelegateImplTest.java
new file mode 100644 (file)
index 0000000..f2f30ff
--- /dev/null
@@ -0,0 +1,271 @@
+package org.oransc.rappcatalogue.api;\r
+\r
+import static org.assertj.core.api.Assertions.assertThat;\r
+import static org.junit.jupiter.api.Assertions.assertThrows;\r
+import static org.mockito.Mockito.mock;\r
+import static org.mockito.Mockito.verify;\r
+import static org.mockito.Mockito.when;\r
+import static org.springframework.http.HttpStatus.CREATED;\r
+import static org.springframework.http.HttpStatus.NO_CONTENT;\r
+import static org.springframework.http.HttpStatus.OK;\r
+\r
+import java.io.IOException;\r
+import java.io.PrintWriter;\r
+import java.sql.Date;\r
+import java.util.Arrays;\r
+import java.util.List;\r
+import javax.servlet.http.HttpServletRequest;\r
+import javax.servlet.http.HttpServletResponse;\r
+import org.junit.jupiter.api.Test;\r
+import org.junit.jupiter.api.extension.ExtendWith;\r
+import org.mockito.Mock;\r
+import org.mockito.junit.jupiter.MockitoExtension;\r
+import org.oransc.rappcatalogue.exception.HeaderException;\r
+import org.oransc.rappcatalogue.exception.InvalidServiceException;\r
+import org.oransc.rappcatalogue.exception.ServiceNotFoundException;\r
+import org.oransc.rappcatalogue.model.InputService;\r
+import org.oransc.rappcatalogue.model.Service;\r
+import org.springframework.http.ResponseEntity;\r
+import org.springframework.web.context.request.NativeWebRequest;\r
+\r
+@ExtendWith(MockitoExtension.class)\r
+class ServicesApiDelegateImplTest {\r
+\r
+    @Mock\r
+    NativeWebRequest webRequestMock;\r
+\r
+    private static final String INVALID_SERVICE_MESSAGE = "Service is missing required property: version";\r
+    private static final String SERVICE_NAME = "Service Name";\r
+    private static final String SERVICE_DESCRIPTION = "description";\r
+    private static final String SERVICE_VERSION = "1.0";\r
+    private static final String SERVICE_DISPLAY_NAME = "Display Name";\r
+\r
+    @Test\r
+    void getAddedService_shouldReturnService() {\r
+        ServicesApiDelegateImpl delegateUnderTest = new ServicesApiDelegateImpl(webRequestMock);\r
+\r
+        InputService service = new InputService();\r
+        service.setDescription(SERVICE_DESCRIPTION);\r
+        service.setVersion(SERVICE_VERSION);\r
+        service.setDisplayName(SERVICE_DISPLAY_NAME);\r
+\r
+        whenPrintResponseShouldWork();\r
+\r
+        delegateUnderTest.putIndividualService(SERVICE_NAME, service);\r
+\r
+        ResponseEntity<Service> response = delegateUnderTest.getIndividualService(SERVICE_NAME);\r
+\r
+        assertThat(response.getStatusCode()).isEqualTo(OK);\r
+        assertThat(response.getBody().getName()).isEqualTo(SERVICE_NAME);\r
+    }\r
+\r
+    @Test\r
+    void getMissingService_shouldThrowException() {\r
+        ServicesApiDelegateImpl delegateUnderTest = new ServicesApiDelegateImpl(null);\r
+\r
+        Exception exception = assertThrows(ServiceNotFoundException.class, () -> {\r
+            delegateUnderTest.getIndividualService(SERVICE_NAME);\r
+        });\r
+\r
+        String expectedMessage = "Service " + SERVICE_NAME + " not found";\r
+        String actualMessage = exception.getMessage();\r
+\r
+        assertThat(actualMessage).isEqualTo(expectedMessage);\r
+    }\r
+\r
+    @Test\r
+    void putNewValidService_shouldBeCreatedAndRegisteredAndUrlToNewServiceAddedToLocationHeaderInResponse() {\r
+        ServicesApiDelegateImpl delegateUnderTest = new ServicesApiDelegateImpl(webRequestMock);\r
+\r
+        InputService service = new InputService();\r
+        service.setDescription(SERVICE_DESCRIPTION);\r
+        service.setVersion(SERVICE_VERSION);\r
+        service.setDisplayName(SERVICE_DISPLAY_NAME);\r
+\r
+        String urlToCreatedService = "URL to created Service";\r
+        HttpServletResponse servletResponseMock = whenPrintResponseShouldWork(urlToCreatedService);\r
+\r
+        ResponseEntity<Void> putResponse = delegateUnderTest.putIndividualService(SERVICE_NAME, service);\r
+\r
+        assertThat(putResponse.getStatusCode()).isEqualTo(CREATED);\r
+        verify(servletResponseMock).addHeader("Location", urlToCreatedService);\r
+\r
+        ResponseEntity<Service> getResponse = delegateUnderTest.getIndividualService(SERVICE_NAME);\r
+\r
+        assertThat(getResponse.getStatusCode()).isEqualTo(OK);\r
+        Service body = getResponse.getBody();\r
+        assertThat(body.getName()).isEqualTo(SERVICE_NAME);\r
+        assertThat(body.getRegistrationDate()).isEqualTo(getTodaysDate());\r
+    }\r
+\r
+    @Test\r
+    void putModifiedService_shouldBeModified() {\r
+        ServicesApiDelegateImpl delegateUnderTest = new ServicesApiDelegateImpl(webRequestMock);\r
+\r
+        InputService service = new InputService();\r
+        service.setDescription(SERVICE_DESCRIPTION);\r
+        service.setVersion(SERVICE_VERSION);\r
+        service.setDisplayName(SERVICE_DISPLAY_NAME);\r
+\r
+        whenPrintResponseShouldWork();\r
+\r
+        delegateUnderTest.putIndividualService(SERVICE_NAME, service);\r
+\r
+        String newDescription = "New description";\r
+        service.setDescription(newDescription);\r
+        ResponseEntity<Void> putResponse = delegateUnderTest.putIndividualService(SERVICE_NAME, service);\r
+\r
+        assertThat(putResponse.getStatusCode()).isEqualTo(OK);\r
+\r
+        ResponseEntity<Service> getResponse = delegateUnderTest.getIndividualService(SERVICE_NAME);\r
+\r
+        assertThat(getResponse.getStatusCode()).isEqualTo(OK);\r
+        assertThat(getResponse.getBody().getDescription()).isEqualTo(newDescription);\r
+    }\r
+\r
+    @Test\r
+    void putServiceWithVersionNull_shouldThrowException() {\r
+        ServicesApiDelegateImpl delegateUnderTest = new ServicesApiDelegateImpl(null);\r
+\r
+        InputService service = new InputService();\r
+        service.setDescription(SERVICE_DESCRIPTION);\r
+        service.setDisplayName(SERVICE_DISPLAY_NAME);\r
+\r
+        Exception exception = assertThrows(InvalidServiceException.class, () -> {\r
+            delegateUnderTest.putIndividualService(SERVICE_NAME, service);\r
+        });\r
+\r
+        assertThat(exception.getMessage()).isEqualTo(INVALID_SERVICE_MESSAGE);\r
+    }\r
+\r
+    @Test\r
+    void putServiceWithBlankVersion_shouldThrowException() {\r
+        ServicesApiDelegateImpl delegateUnderTest = new ServicesApiDelegateImpl(null);\r
+\r
+        InputService service = new InputService();\r
+        service.setVersion("");\r
+        service.setDescription(SERVICE_DESCRIPTION);\r
+        service.setDisplayName(SERVICE_DISPLAY_NAME);\r
+\r
+        Exception exception = assertThrows(InvalidServiceException.class, () -> {\r
+            delegateUnderTest.putIndividualService(SERVICE_NAME, service);\r
+        });\r
+\r
+        assertThat(exception.getMessage()).isEqualTo(INVALID_SERVICE_MESSAGE);\r
+    }\r
+\r
+    @Test\r
+    void putServiceWhenIoExceptionAddingHeader_shouldThrowExceptionAndNoServiceCreated() throws Exception {\r
+        ServicesApiDelegateImpl delegateUnderTest = new ServicesApiDelegateImpl(webRequestMock);\r
+\r
+        whenGetRequestUrlThenReturnUrl();\r
+        HttpServletResponse servletResponseMock = mock(HttpServletResponse.class);\r
+        when(webRequestMock.getNativeResponse(HttpServletResponse.class)).thenReturn(servletResponseMock);\r
+        when(servletResponseMock.getWriter()).thenThrow(new IOException("Error"));\r
+\r
+        InputService service = new InputService();\r
+        service.setVersion("1.0");\r
+        service.setDescription(SERVICE_DESCRIPTION);\r
+        service.setDisplayName(SERVICE_DISPLAY_NAME);\r
+\r
+        Exception exception = assertThrows(HeaderException.class, () -> {\r
+            delegateUnderTest.putIndividualService(SERVICE_NAME, service);\r
+        });\r
+\r
+        assertThat(exception.getMessage())\r
+            .isEqualTo("Unable to set header Location in put response for service " + SERVICE_NAME + ". Cause: Error");\r
+\r
+        ResponseEntity<List<Service>> response = delegateUnderTest.getServices();\r
+        assertThat(response.getBody()).isEmpty();\r
+    }\r
+\r
+    @Test\r
+    void getServices_shouldProvideArrayOfAddedServiceNames() throws Exception {\r
+        ServicesApiDelegateImpl delegateUnderTest = new ServicesApiDelegateImpl(webRequestMock);\r
+\r
+        InputService service1 = new InputService();\r
+        service1.setDescription("description 1");\r
+        service1.setVersion(SERVICE_VERSION);\r
+        service1.setDisplayName("Display Name 1");\r
+\r
+        InputService service2 = new InputService();\r
+        service2.setDescription("description 2");\r
+        service2.setVersion(SERVICE_VERSION);\r
+        service2.setDisplayName("Display Name 2");\r
+\r
+        whenPrintResponseShouldWork();\r
+\r
+        String serviceName1 = "Service Name 1";\r
+        delegateUnderTest.putIndividualService(serviceName1, service1);\r
+        String serviceName2 = "Service Name 2";\r
+        delegateUnderTest.putIndividualService(serviceName2, service2);\r
+\r
+        ResponseEntity<List<Service>> response = delegateUnderTest.getServices();\r
+\r
+        assertThat(response.getStatusCode()).isEqualTo(OK);\r
+        List<Service> services = response.getBody();\r
+        assertThat(services).hasSize(2);\r
+        List<String> expectedServiceNames = Arrays.asList(serviceName1, serviceName2);\r
+        assertThat(expectedServiceNames).contains(services.get(0).getName()) //\r
+            .contains(services.get(1).getName());\r
+    }\r
+\r
+    @Test\r
+    void deleteService_shouldBeOk() {\r
+        ServicesApiDelegateImpl delegateUnderTest = new ServicesApiDelegateImpl(webRequestMock);\r
+\r
+        InputService service = new InputService();\r
+        service.setDescription(SERVICE_DESCRIPTION);\r
+        service.setVersion(SERVICE_VERSION);\r
+        service.setDisplayName(SERVICE_DISPLAY_NAME);\r
+\r
+        whenPrintResponseShouldWork();\r
+\r
+        delegateUnderTest.putIndividualService(SERVICE_NAME, service);\r
+\r
+        ResponseEntity<List<Service>> servicesResponse = delegateUnderTest.getServices();\r
+\r
+        assertThat(servicesResponse.getBody()).hasSize(1);\r
+\r
+        ResponseEntity<Void> deleteResponse = delegateUnderTest.deleteIndividualService(SERVICE_NAME);\r
+\r
+        assertThat(deleteResponse.getStatusCode()).isEqualTo(NO_CONTENT);\r
+\r
+        servicesResponse = delegateUnderTest.getServices();\r
+\r
+        assertThat(servicesResponse.getBody()).isEmpty();\r
+    }\r
+\r
+    private void whenGetRequestUrlThenReturnUrl() {\r
+        whenGetRequestUrlThenReturnUrl("URL");\r
+    }\r
+\r
+    private void whenGetRequestUrlThenReturnUrl(String url) {\r
+        HttpServletRequest servletRequestMock = mock(HttpServletRequest.class);\r
+        when(webRequestMock.getNativeRequest(HttpServletRequest.class)).thenReturn(servletRequestMock);\r
+        when(servletRequestMock.getRequestURL()).thenReturn(new StringBuffer(url));\r
+    }\r
+\r
+    private HttpServletResponse whenPrintResponseShouldWork() {\r
+        return whenPrintResponseShouldWork("URL");\r
+    }\r
+\r
+    private HttpServletResponse whenPrintResponseShouldWork(String url) {\r
+        whenGetRequestUrlThenReturnUrl(url);\r
+        HttpServletResponse servletResponseMock = mock(HttpServletResponse.class);\r
+        when(webRequestMock.getNativeResponse(HttpServletResponse.class)).thenReturn(servletResponseMock);\r
+        PrintWriter printWriterMock = mock(PrintWriter.class);\r
+        try {\r
+            when(servletResponseMock.getWriter()).thenReturn(printWriterMock);\r
+        } catch (IOException e) {\r
+            // Nothing\r
+        }\r
+        return servletResponseMock;\r
+    }\r
+\r
+    private String getTodaysDate() {\r
+        long millis = System.currentTimeMillis();\r
+        Date date = new Date(millis);\r
+        return date.toString();\r
+    }\r
+}\r
index 0a325f0..436f776 100644 (file)
@@ -1,6 +1,4 @@
-This source repository contains the code for the SDNC-A1 Controller northbound interface.
-
-It contains an OSGI bundle named "nonrt-ric-api" that provides the interface for A1 operations.
+This module builds the sdnc-a1-northbound which inturn creates the nonrt-ric-api-provider & nonrt-ric-api-model bundles.
 
 To compile, run "mvn clean install".
 
diff --git a/sdnc-a1-controller/northbound/features/README.md b/sdnc-a1-controller/northbound/features/README.md
new file mode 100644 (file)
index 0000000..5e0fae1
--- /dev/null
@@ -0,0 +1,21 @@
+This module builds the submodule sdnc-a1-northbound-all,features-sdnc-a1-northbound & installer which creates the features & installers which can be installed in Karaf Server.
+
+To compile, run "mvn clean install".
+
+## License
+
+Copyright (C) 2019 Nordix Foundation.
+Licensed under the Apache License, Version 2.0 (the "License")
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+For more information about license please see the [LICENSE](LICENSE.txt) file for details.
+
diff --git a/sdnc-a1-controller/northbound/features/features-sdnc-a1-northbound/README.md b/sdnc-a1-controller/northbound/features/features-sdnc-a1-northbound/README.md
new file mode 100644 (file)
index 0000000..2633949
--- /dev/null
@@ -0,0 +1,21 @@
+This module creates features-sdnc-a1-northbound features from sdnc-a1-northbound-all feature.
+
+To compile, run "mvn clean install".
+
+## License
+
+Copyright (C) 2019 Nordix Foundation.
+Licensed under the Apache License, Version 2.0 (the "License")
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+For more information about license please see the [LICENSE](LICENSE.txt) file for details.
+
diff --git a/sdnc-a1-controller/northbound/features/installer/README.md b/sdnc-a1-controller/northbound/features/installer/README.md
new file mode 100644 (file)
index 0000000..1eaaa68
--- /dev/null
@@ -0,0 +1,21 @@
+This module is responsible for creating sdnc-a1-northbound-features-installer installer which contains sdnc-a1-northbound-all feature. This is then installed into Karaf Server when deployed.
+
+To compile, run "mvn clean install".
+
+## License
+
+Copyright (C) 2019 Nordix Foundation.
+Licensed under the Apache License, Version 2.0 (the "License")
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+For more information about license please see the [LICENSE](LICENSE.txt) file for details.
+
diff --git a/sdnc-a1-controller/northbound/features/sdnc-a1-northbound-all/README.md b/sdnc-a1-controller/northbound/features/sdnc-a1-northbound-all/README.md
new file mode 100644 (file)
index 0000000..6bd2cc1
--- /dev/null
@@ -0,0 +1,21 @@
+This module creates the sdnc-a1-northbound-all feature from sdnc-nonrt-ric-api feature.
+
+To compile, run "mvn clean install".
+
+## License
+
+Copyright (C) 2019 Nordix Foundation.
+Licensed under the Apache License, Version 2.0 (the "License")
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+For more information about license please see the [LICENSE](LICENSE.txt) file for details.
+
diff --git a/sdnc-a1-controller/northbound/nonrt-ric-api/README.md b/sdnc-a1-controller/northbound/nonrt-ric-api/README.md
new file mode 100644 (file)
index 0000000..8a349d4
--- /dev/null
@@ -0,0 +1,21 @@
+This module builds the model, provider, install & features to create the bundles, features & installers.
+
+To compile, run "mvn clean install".
+
+## License
+
+Copyright (C) 2019 Nordix Foundation.
+Licensed under the Apache License, Version 2.0 (the "License")
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+For more information about license please see the [LICENSE](LICENSE.txt) file for details.
+
diff --git a/sdnc-a1-controller/northbound/nonrt-ric-api/features/README.md b/sdnc-a1-controller/northbound/nonrt-ric-api/features/README.md
new file mode 100644 (file)
index 0000000..6b41cbd
--- /dev/null
@@ -0,0 +1,21 @@
+This module builds the two submodules sdnc-nonrt-ric-api & features-nonrt-ric-api which creates the A1 northbound feature.
+
+To compile, run "mvn clean install".
+
+## License
+
+Copyright (C) 2019 Nordix Foundation.
+Licensed under the Apache License, Version 2.0 (the "License")
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+For more information about license please see the [LICENSE](LICENSE.txt) file for details.
+
diff --git a/sdnc-a1-controller/northbound/nonrt-ric-api/features/features-nonrt-ric-api/README.md b/sdnc-a1-controller/northbound/nonrt-ric-api/features/features-nonrt-ric-api/README.md
new file mode 100644 (file)
index 0000000..2661993
--- /dev/null
@@ -0,0 +1,21 @@
+This module creates the features-nonrt-ric-api feature from sdnc-nonrt-ric-api feature
+
+To compile, run "mvn clean install".
+
+## License
+
+Copyright (C) 2019 Nordix Foundation.
+Licensed under the Apache License, Version 2.0 (the "License")
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+For more information about license please see the [LICENSE](LICENSE.txt) file for details.
+
diff --git a/sdnc-a1-controller/northbound/nonrt-ric-api/features/sdnc-nonrt-ric-api/README.md b/sdnc-a1-controller/northbound/nonrt-ric-api/features/sdnc-nonrt-ric-api/README.md
new file mode 100644 (file)
index 0000000..54ab911
--- /dev/null
@@ -0,0 +1,21 @@
+This module creates the sdnc-nonrt-ric-api feature from the nonrt-ric-api-model & nonrt-ric-api-provider bundles.
+
+To compile, run "mvn clean install".
+
+## License
+
+Copyright (C) 2019 Nordix Foundation.
+Licensed under the Apache License, Version 2.0 (the "License")
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+For more information about license please see the [LICENSE](LICENSE.txt) file for details.
+
diff --git a/sdnc-a1-controller/northbound/nonrt-ric-api/installer/README.md b/sdnc-a1-controller/northbound/nonrt-ric-api/installer/README.md
new file mode 100644 (file)
index 0000000..10f6790
--- /dev/null
@@ -0,0 +1,21 @@
+This module installs the sdnc-nonrt-ric-api feature into the Karaf Server.
+
+To compile, run "mvn clean install".
+
+## License
+
+Copyright (C) 2019 Nordix Foundation.
+Licensed under the Apache License, Version 2.0 (the "License")
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+For more information about license please see the [LICENSE](LICENSE.txt) file for details.
+
diff --git a/sdnc-a1-controller/northbound/nonrt-ric-api/model/README.md b/sdnc-a1-controller/northbound/nonrt-ric-api/model/README.md
new file mode 100644 (file)
index 0000000..0cc666d
--- /dev/null
@@ -0,0 +1,21 @@
+This module contains the yang definition of the A1 northbound API and creates the nonrt-ric-api-model bundle.
+
+To compile, run "mvn clean install".
+
+## License
+
+Copyright (C) 2019 Nordix Foundation.
+Licensed under the Apache License, Version 2.0 (the "License")
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+For more information about license please see the [LICENSE](LICENSE.txt) file for details.
+
diff --git a/sdnc-a1-controller/northbound/nonrt-ric-api/provider/README.md b/sdnc-a1-controller/northbound/nonrt-ric-api/provider/README.md
new file mode 100644 (file)
index 0000000..456b92f
--- /dev/null
@@ -0,0 +1,21 @@
+This module provides the implementation for the A1 Northbound API and creates the nonrt-ric-api-provider bundle.
+
+To compile, run "mvn clean install".
+
+## License
+
+Copyright (C) 2019 Nordix Foundation.
+Licensed under the Apache License, Version 2.0 (the "License")
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+For more information about license please see the [LICENSE](LICENSE.txt) file for details.
+
index ce55f56..5f0619a 100644 (file)
@@ -1,10 +1,4 @@
-This source repository contains the code for SDNC-A1 Controller operations, administration and maintenance utilities.
-
-It adds the features from northbound directory and creates the docker image for SDNC-A1 controller.
-
-It also contains the keystore, the script to start OpenDaylight, and the healthcheck script.
-
-The docker-compose file is also included in this directory.
+This module builds the submodule sdnc-a1 which inturn creates the SDNC A1 docker image
 
 To compile, run "mvn clean install".
 
diff --git a/sdnc-a1-controller/oam/installation/README.md b/sdnc-a1-controller/oam/installation/README.md
new file mode 100644 (file)
index 0000000..ce55f56
--- /dev/null
@@ -0,0 +1,28 @@
+This source repository contains the code for SDNC-A1 Controller operations, administration and maintenance utilities.
+
+It adds the features from northbound directory and creates the docker image for SDNC-A1 controller.
+
+It also contains the keystore, the script to start OpenDaylight, and the healthcheck script.
+
+The docker-compose file is also included in this directory.
+
+To compile, run "mvn clean install".
+
+## License
+
+Copyright (C) 2019 Nordix Foundation.
+Licensed under the Apache License, Version 2.0 (the "License")
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+For more information about license please see the [LICENSE](LICENSE.txt) file for details.
+
+
diff --git a/sdnc-a1-controller/oam/installation/sdnc-a1/README.md b/sdnc-a1-controller/oam/installation/sdnc-a1/README.md
new file mode 100644 (file)
index 0000000..f9148d4
--- /dev/null
@@ -0,0 +1,22 @@
+This module is responsible for creating Docker images. The feature installers are added into the docker images so that it can be installed in karaf server.
+
+To compile, run "mvn clean install".
+
+## License
+
+Copyright (C) 2019 Nordix Foundation.
+Licensed under the Apache License, Version 2.0 (the "License")
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+For more information about license please see the [LICENSE](LICENSE.txt) file for details.
+
+
diff --git a/sdnc-a1-controller/oam/platform-logic/README.md b/sdnc-a1-controller/oam/platform-logic/README.md
new file mode 100644 (file)
index 0000000..e62e6b7
--- /dev/null
@@ -0,0 +1,22 @@
+This module builds the submodule setup & installer
+
+To compile, run "mvn clean install".
+
+## License
+
+Copyright (C) 2019 Nordix Foundation.
+Licensed under the Apache License, Version 2.0 (the "License")
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+For more information about license please see the [LICENSE](LICENSE.txt) file for details.
+
+
diff --git a/sdnc-a1-controller/oam/platform-logic/installer/README.md b/sdnc-a1-controller/oam/platform-logic/installer/README.md
new file mode 100644 (file)
index 0000000..5a11efd
--- /dev/null
@@ -0,0 +1,22 @@
+This module builds the platform-logic-installer which contains the DG's but A1 controller in O-RAN doesn't support DG.
+
+To compile, run "mvn clean install".
+
+## License
+
+Copyright (C) 2019 Nordix Foundation.
+Licensed under the Apache License, Version 2.0 (the "License")
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+For more information about license please see the [LICENSE](LICENSE.txt) file for details.
+
+
diff --git a/sdnc-a1-controller/oam/platform-logic/setup/README.md b/sdnc-a1-controller/oam/platform-logic/setup/README.md
new file mode 100644 (file)
index 0000000..b9d665d
--- /dev/null
@@ -0,0 +1,22 @@
+This module should contains the Directed Graphs (DG) but A1 controller in O-RAN doesn't support DG.
+
+To compile, run "mvn clean install".
+
+## License
+
+Copyright (C) 2019 Nordix Foundation.
+Licensed under the Apache License, Version 2.0 (the "License")
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+For more information about license please see the [LICENSE](LICENSE.txt) file for details.
+
+
index 89e22de..6091e4a 100644 (file)
@@ -14,3 +14,4 @@ logs
 .timer*
 .pid*
 .result*
+tmp
index e4482b6..3b02510 100755 (executable)
@@ -23,9 +23,13 @@ TC_ONELINE_DESCR="Sanity test, create service and then create,update and delete
 #App names to include in the test, space separated list
 INCLUDED_IMAGES="CBS CONSUL CP CR MR PA RICSIM SDNC"
 
+#SUPPORTED TEST ENV FILE
+SUPPORTED_PROFILES="ONAP-MASTER ONAP-GUILIN"
+
 . ../common/testcase_common.sh  $@
 . ../common/agent_api_functions.sh
 . ../common/ricsimulator_api_functions.sh
+. ../common/cr_api_functions.sh
 
 #### TEST BEGIN ####
 
@@ -45,9 +49,24 @@ for __httpx in $TESTED_PROTOCOLS ; do
         echo "#####################################################################"
         echo "#####################################################################"
 
+        # Clean container and start all needed containers #
+        clean_containers
+
+        if [ $__httpx == "HTTPS" ]; then
+            use_agent_rest_https
+        else
+            use_agent_rest_http
+        fi
+
+        start_policy_agent
+
+        set_agent_trace
+
+        # Create service to be able to receive events when rics becomes available
+        # Must use rest towards the agent since dmaap is not configured yet
+        api_put_service 201 "ric-registration" 0 "$CR_PATH/ric-registration"
 
         if [ $__httpx == "HTTPS" ]; then
-            CR_PATH="https://$CR_APP_NAME:$CR_EXTERNAL_SECURE_PORT/callbacks"
             use_cr_https
             use_simulator_https
             use_mr_https
@@ -60,7 +79,6 @@ for __httpx in $TESTED_PROTOCOLS ; do
                 use_agent_rest_https
             fi
         else
-            CR_PATH="http://$CR_APP_NAME:$CR_EXTERNAL_PORT/callbacks"
             use_cr_http
             use_simulator_http
             use_mr_http
@@ -74,16 +92,18 @@ for __httpx in $TESTED_PROTOCOLS ; do
             fi
         fi
 
-        # Clean container and start all needed containers #
-        clean_containers
-
         start_ric_simulators ricsim_g1 1  OSC_2.1.0
         start_ric_simulators ricsim_g2 1  STD_1.1.3
+        if [ "$PMS_VERSION" == "V2" ]; then
+            start_ric_simulators ricsim_g3 1  STD_2.0.0
+        fi
 
         start_mr
 
         start_cr
 
+        start_control_panel
+
         start_consul_cbs
 
         if [[ $interface = *"SDNC"* ]]; then
@@ -95,27 +115,37 @@ for __httpx in $TESTED_PROTOCOLS ; do
 
         consul_config_app                      ".consul_config.json"
 
-        start_control_panel
+        mr_equal requests_submitted 0
 
-        start_policy_agent
+        sim_put_policy_type 201 ricsim_g1_1 1 testdata/OSC/sim_1.json
 
-        set_agent_debug
-        set_agent_trace
+        if [ "$PMS_VERSION" == "V2" ]; then
 
-        cr_equal received_callbacks 0
-        mr_equal requests_submitted 0
+            sim_put_policy_type 201 ricsim_g3_1 STD_QOS_0_2_0 testdata/STD2/sim_qos.json
 
-        sim_put_policy_type 201 ricsim_g1_1 1 testdata/OSC/sim_1.json
+            api_equal json:rics 3 60
+
+            api_equal json:policy-types 2 120
+
+            api_equal json:policies 0
 
-        api_equal json:rics 2 60
+            api_equal json:policy-instances 0
 
-        api_equal json:policy_schemas 2 120
+            cr_equal received_callbacks 3 120
 
-        api_equal json:policy_types 2
+            cr_api_check_all_sync_events 200 ric-registration ricsim_g1_1 ricsim_g2_1 ricsim_g3_1
 
-        api_equal json:policies 0
+        else
+            api_equal json:rics 2 60
+
+            api_equal json:policy_schemas 2 120
 
-        api_equal json:policy_ids 0
+            api_equal json:policy_types 2
+
+            api_equal json:policies 0
+
+            api_equal json:policy_ids 0
+        fi
 
         echo "############################################"
         echo "############## Health check ################"
@@ -129,7 +159,7 @@ for __httpx in $TESTED_PROTOCOLS ; do
 
         api_put_service 201 "serv1" 1000 "$CR_PATH/1"
 
-        api_get_service_ids 200 "serv1"
+        api_get_service_ids 200 "serv1" "ric-registration"
 
         api_put_services_keepalive 200 "serv1"
 
@@ -137,30 +167,66 @@ for __httpx in $TESTED_PROTOCOLS ; do
         echo "############## RIC Repository ##############"
         echo "############################################"
 
-        api_get_rics 200 NOTYPE "ricsim_g1_1:me1_ricsim_g1_1,me2_ricsim_g1_1:1:AVAILABLE  ricsim_g2_1:me1_ricsim_g2_1,me2_ricsim_g2_1:EMPTYTYPE:AVAILABLE"
+        if [ "$PMS_VERSION" == "V2" ]; then
+            api_get_rics 200 NOTYPE "ricsim_g1_1:me1_ricsim_g1_1,me2_ricsim_g1_1:1:AVAILABLE  ricsim_g2_1:me1_ricsim_g2_1,me2_ricsim_g2_1:EMPTYTYPE:AVAILABLE ricsim_g3_1:me1_ricsim_g3_1,me2_ricsim_g3_1:STD_QOS_0_2_0:AVAILABLE"
+        else
+            api_get_rics 200 NOTYPE "ricsim_g1_1:me1_ricsim_g1_1,me2_ricsim_g1_1:1:AVAILABLE  ricsim_g2_1:me1_ricsim_g2_1,me2_ricsim_g2_1:EMPTYTYPE:AVAILABLE"
+        fi
 
         echo "############################################"
         echo "########### A1 Policy Management ###########"
         echo "############################################"
 
-        api_put_policy 201 "serv1" ricsim_g1_1 1 5000 NOTRANSIENT testdata/OSC/pi1_template.json
-        api_put_policy 200 "serv1" ricsim_g1_1 1 5000 NOTRANSIENT testdata/OSC/pi1_template.json
+        if [ "$PMS_VERSION" == "V2" ]; then
+            notificationurl=$CR_PATH"/test"
+        else
+            notificationurl=""
+        fi
+        api_put_policy 201 "serv1" ricsim_g1_1 1 5000 NOTRANSIENT $notificationurl testdata/OSC/pi1_template.json
+        api_put_policy 200 "serv1" ricsim_g1_1 1 5000 NOTRANSIENT $notificationurl testdata/OSC/pi1_template.json
+        if [ "$PMS_VERSION" == "V2" ]; then
+            api_put_policy 201 "serv1" ricsim_g3_1 STD_QOS_0_2_0 5200 true $notificationurl testdata/STD2/pi_qos_template.json
+            api_put_policy 200 "serv1" ricsim_g3_1 STD_QOS_0_2_0 5200 true $notificationurl testdata/STD2/pi_qos_template.json
+        fi
 
-        api_put_policy 201 "serv1" ricsim_g2_1 NOTYPE 5100 NOTRANSIENT testdata/STD/pi1_template.json
-        api_put_policy 200 "serv1" ricsim_g2_1 NOTYPE 5100 NOTRANSIENT testdata/STD/pi1_template.json
+        api_put_policy 201 "serv1" ricsim_g2_1 NOTYPE 5100 NOTRANSIENT $notificationurl testdata/STD/pi1_template.json
+        api_put_policy 200 "serv1" ricsim_g2_1 NOTYPE 5100 NOTRANSIENT $notificationurl testdata/STD/pi1_template.json
+
+        if [ "$PMS_VERSION" == "V2" ]; then
+            api_equal json:policies 3
+        else
+            api_equal json:policies 2
+        fi
 
         api_delete_policy 204 5000
 
         api_delete_policy 204 5100
 
-        api_equal json:policies 0
+        if [ "$PMS_VERSION" == "V2" ]; then
+            api_delete_policy 204 5200
+        fi
 
-        api_equal json:policy_ids 0
+        if [ "$PMS_VERSION" == "V2" ]; then
+            api_equal json:policies 0
 
-        cr_equal received_callbacks 0
+            api_equal json:policy-instances 0
+        else
+            api_equal json:policies 0
+
+            api_equal json:policy_ids 0
+        fi
+
+        if [ "$PMS_VERSION" == "V2" ]; then
+            cr_equal received_callbacks 3
+        fi
 
         if [[ $interface = *"DMAAP"* ]]; then
-            VAL=11 # Number of Agent API calls over DMAAP
+
+            if [ "$PMS_VERSION" == "V2" ]; then
+                VAL=14 # Number of Agent API calls over DMAAP
+            else
+                VAL=11 # Number of Agent API calls over DMAAP
+            fi
             mr_equal requests_fetched $VAL
             mr_equal responses_submitted $VAL
             mr_equal responses_fetched $VAL
@@ -173,14 +239,24 @@ for __httpx in $TESTED_PROTOCOLS ; do
         if [[ $interface = *"SDNC"* ]]; then
             sim_contains_str ricsim_g1_1 remote_hosts "a1-controller"
             sim_contains_str ricsim_g2_1 remote_hosts "a1-controller"
+            if [ "$PMS_VERSION" == "V2" ]; then
+                sim_contains_str ricsim_g3_1 remote_hosts "a1-controller"
+            fi
         else
             sim_contains_str ricsim_g1_1 remote_hosts "policy-agent"
             sim_contains_str ricsim_g2_1 remote_hosts "policy-agent"
+            if [ "$PMS_VERSION" == "V2" ]; then
+                sim_contains_str ricsim_g3_1 remote_hosts "policy-agent"
+            fi
         fi
 
         check_policy_agent_logs
         check_control_panel_logs
 
+        if [[ $interface = *"SDNC"* ]]; then
+            check_sdnc_logs
+        fi
+
         store_logs          "${__httpx}__${interface}"
 
     done
index 42b8f58..e0d6ecb 100755 (executable)
@@ -22,6 +22,9 @@ TC_ONELINE_DESCR="Basic use case, register service, create/update policy, delete
 #App names to include in the test, space separated list
 INCLUDED_IMAGES="CBS CONSUL CP CR MR PA RICSIM"
 
+#SUPPORTED TEST ENV FILE
+SUPPORTED_PROFILES="ONAP-MASTER ONAP-GUILIN ORAN-MASTER"
+
 . ../common/testcase_common.sh $@
 . ../common/agent_api_functions.sh
 . ../common/ricsimulator_api_functions.sh
@@ -30,12 +33,6 @@ INCLUDED_IMAGES="CBS CONSUL CP CR MR PA RICSIM"
 
 generate_uuid
 
-#Local vars in test script
-##########################
-# Path to callback receiver
-CR_PATH="http://$CR_APP_NAME:$CR_EXTERNAL_PORT/callbacks"
-
-use_cr_http
 use_simulator_http
 use_mr_http
 use_agent_rest_http
@@ -47,9 +44,11 @@ start_ric_simulators  ricsim_g1 3 OSC_2.1.0
 
 start_ric_simulators  ricsim_g2 5 STD_1.1.3
 
-start_mr
+if [ "$PMS_VERSION" == "V2" ]; then
+    start_ric_simulators ricsim_g3 1  STD_2.0.0
+fi
 
-start_cr
+start_mr
 
 start_consul_cbs
 
@@ -70,55 +69,84 @@ sim_print ricsim_g1_1 interface
 
 sim_print ricsim_g2_1 interface
 
-sim_put_policy_type 201 ricsim_g1_1 1 testdata/OSC/sim_1.json
+if [ "$PMS_VERSION" == "V2" ]; then
+    sim_print ricsim_g3_1 interface
+fi
 
-api_equal json:policy_types 2 60
+sim_put_policy_type 201 ricsim_g1_1 1 testdata/OSC/sim_1.json
 
+if [ "$PMS_VERSION" == "V2" ]; then
+    sim_put_policy_type 201 ricsim_g3_1 STD_QOS_0_2_0 testdata/STD2/sim_qos.json
+    api_equal json:policy-types 3 60
+else
+    api_equal json:policy_types 2 60
+fi
 
 # Create policies
+
+if [ "$PMS_VERSION" == "V2" ]; then
+    notificationurl=$CR_PATH"/test"
+else
+    notificationurl=""
+fi
+
 use_agent_rest_http
 
 api_put_service 201 "service1" 3600 "$CR_PATH/1"
 
-api_put_policy 201 "service1" ricsim_g1_1 1 2000 NOTRANSIENT testdata/OSC/pi1_template.json 1
+api_put_policy 201 "service1" ricsim_g1_1 1 2000 NOTRANSIENT $notificationurl testdata/OSC/pi1_template.json 1
 
 sim_equal ricsim_g1_1 num_instances 1
 
 
 use_agent_dmaap_http
 
-api_put_policy 201 "service1" ricsim_g1_1 1 3000 NOTRANSIENT testdata/OSC/pi1_template.json 1
+api_put_policy 201 "service1" ricsim_g1_1 1 3000 NOTRANSIENT $notificationurl testdata/OSC/pi1_template.json 1
 
 sim_equal ricsim_g1_1 num_instances 2
 
 
 use_agent_rest_http
 
-api_put_policy 201 "service1" ricsim_g2_1 NOTYPE 2100 NOTRANSIENT testdata/STD/pi1_template.json 1
+api_put_policy 201 "service1" ricsim_g2_1 NOTYPE 2100 NOTRANSIENT $notificationurl testdata/STD/pi1_template.json 1
 
 sim_equal ricsim_g2_1 num_instances 1
 
 
 use_agent_dmaap_http
 
-api_put_policy 201 "service1" ricsim_g2_1 NOTYPE 3100 NOTRANSIENT testdata/STD/pi1_template.json 1
+api_put_policy 201 "service1" ricsim_g2_1 NOTYPE 3100 NOTRANSIENT $notificationurl testdata/STD/pi1_template.json 1
 
 sim_equal ricsim_g2_1 num_instances 2
 
+if [ "$PMS_VERSION" == "V2" ]; then
+    use_agent_rest_http
+
+    api_put_policy 201 "service1" ricsim_g3_1 STD_QOS_0_2_0 2200 true $notificationurl testdata/STD2/pi_qos_template.json 1
+
+    sim_equal ricsim_g3_1 num_instances 1
+
+    use_agent_dmaap_http
+
+    api_put_policy 201 "service1" ricsim_g3_1 STD_QOS_0_2_0 3200 NOTRANSIENT $notificationurl testdata/STD2/pi_qos_template.json 1
+
+    sim_equal ricsim_g3_1 num_instances 2
+
+fi
 
 #Update policies
 use_agent_rest_http
 
 api_put_service 200 "service1" 3600 "$CR_PATH/1"
 
-api_put_policy 200 "service1" ricsim_g1_1 1 2000 NOTRANSIENT testdata/OSC/pi1_template.json 1
+api_put_policy 200 "service1" ricsim_g1_1 1 2000 NOTRANSIENT $notificationurl testdata/OSC/pi1_template.json 1
 
 sim_equal ricsim_g1_1 num_instances 2
 
 
 use_agent_dmaap_http
 
-api_put_policy 200 "service1" ricsim_g1_1 1 3000 NOTRANSIENT testdata/OSC/pi1_template.json 1
+api_put_policy 200 "service1" ricsim_g1_1 1 3000 NOTRANSIENT $notificationurl testdata/OSC/pi1_template.json 1
 
 sim_equal ricsim_g1_1 num_instances 2
 
@@ -126,22 +154,53 @@ sim_equal ricsim_g1_1 num_instances 2
 use_agent_rest_http
 
 
-api_put_policy 200 "service1" ricsim_g2_1 NOTYPE 2100 NOTRANSIENT testdata/STD/pi1_template.json 1
+api_put_policy 200 "service1" ricsim_g2_1 NOTYPE 2100 NOTRANSIENT $notificationurl testdata/STD/pi1_template.json 1
 
 sim_equal ricsim_g2_1 num_instances 2
 
 
 use_agent_dmaap_http
 
-api_put_policy 200 "service1" ricsim_g2_1 NOTYPE 3100 NOTRANSIENT testdata/STD/pi1_template.json 1
+api_put_policy 200 "service1" ricsim_g2_1 NOTYPE 3100 NOTRANSIENT $notificationurl testdata/STD/pi1_template.json 1
 
 sim_equal ricsim_g2_1 num_instances 2
 
+if [ "$PMS_VERSION" == "V2" ]; then
+    use_agent_rest_http
+
+    api_put_policy 200 "service1" ricsim_g3_1 STD_QOS_0_2_0 2200 true $notificationurl testdata/STD2/pi_qos_template.json 1
+
+    sim_equal ricsim_g3_1 num_instances 2
+
+
+    use_agent_dmaap_http
+
+    api_put_policy 200 "service1" ricsim_g3_1 STD_QOS_0_2_0 3200 true $notificationurl testdata/STD2/pi_qos_template.json 1
+
+    sim_equal ricsim_g3_1 num_instances 2
+fi
+
 # Check policies
-api_get_policy 200 2000 testdata/OSC/pi1_template.json
-api_get_policy 200 3000 testdata/OSC/pi1_template.json
-api_get_policy 200 2100 testdata/STD/pi1_template.json
-api_get_policy 200 3100 testdata/STD/pi1_template.json
+if [ "$PMS_VERSION" == "V2" ]; then
+    api_get_policy 200 2000 testdata/OSC/pi1_template.json "service1" ricsim_g1_1 1 false $notificationurl
+    api_get_policy 200 3000 testdata/OSC/pi1_template.json "service1" ricsim_g1_1 1 false $notificationurl
+    api_get_policy 200 2100 testdata/STD/pi1_template.json "service1" ricsim_g2_1 NOTYPE false $notificationurl
+    api_get_policy 200 3100 testdata/STD/pi1_template.json "service1" ricsim_g2_1 NOTYPE false $notificationurl
+    api_get_policy 200 2200 testdata/STD2/pi_qos_template.json "service1" ricsim_g3_1 STD_QOS_0_2_0 true $notificationurl
+    api_get_policy 200 3200 testdata/STD2/pi_qos_template.json "service1" ricsim_g3_1 STD_QOS_0_2_0 true $notificationurl
+else
+    api_get_policy 200 2000 testdata/OSC/pi1_template.json
+    api_get_policy 200 3000 testdata/OSC/pi1_template.json
+    api_get_policy 200 2100 testdata/STD/pi1_template.json
+    api_get_policy 200 3100 testdata/STD/pi1_template.json
+fi
+
+sim_equal ricsim_g1_1 num_instances 2
+sim_equal ricsim_g2_1 num_instances 2
+
+if [ "$PMS_VERSION" == "V2" ]; then
+    sim_equal ricsim_g3_1 num_instances 2
+fi
 
 # Remove policies
 
@@ -153,14 +212,27 @@ use_agent_dmaap_http
 api_delete_policy 204 2100
 use_agent_rest_http
 api_delete_policy 204 3100
+if [ "$PMS_VERSION" == "V2" ]; then
+    use_agent_dmaap_http
+    api_delete_policy 204 2200
+    use_agent_rest_http
+    api_delete_policy 204 3200
+fi
 
 sim_equal ricsim_g1_1 num_instances 0
 sim_equal ricsim_g2_1 num_instances 0
 
+if [ "$PMS_VERSION" == "V2" ]; then
+    sim_equal ricsim_g3_1 num_instances 0
+fi
+
 # Check remote host access to simulator
 
 sim_contains_str ricsim_g1_1 remote_hosts "policy-agent"
 sim_contains_str ricsim_g2_1 remote_hosts "policy-agent"
+if [ "$PMS_VERSION" == "V2" ]; then
+    sim_contains_str ricsim_g3_1 remote_hosts "policy-agent"
+fi
 
 # Check policy removal
 use_agent_rest_http
@@ -169,14 +241,17 @@ api_get_policy 404 3000
 api_get_policy 404 2100
 api_get_policy 404 3100
 
+if [ "$PMS_VERSION" == "V2" ]; then
+    api_get_policy 404 2200
+    api_get_policy 404 3200
+fi
+
 # Remove the service
 use_agent_dmaap_http
 api_delete_services 204 "service1"
 
 api_get_services 404 "service1"
 
-
-
 check_policy_agent_logs
 
 #### TEST COMPLETE ####
index b617d3f..e20adab 100755 (executable)
@@ -23,9 +23,14 @@ TC_ONELINE_DESCR="Full agent API walk through using agent REST/DMAAP and with/wi
 #App names to include in the test, space separated list
 INCLUDED_IMAGES="CBS CONSUL CP CR MR PA RICSIM SDNC"
 
+
+#SUPPORTED TEST ENV FILE
+SUPPORTED_PROFILES="ONAP-MASTER ONAP-GUILIN"
+
 . ../common/testcase_common.sh  $@
 . ../common/agent_api_functions.sh
 . ../common/ricsimulator_api_functions.sh
+. ../common/cr_api_functions.sh
 
 #### TEST BEGIN ####
 
@@ -33,8 +38,10 @@ generate_uuid
 
 # Tested variants of REST/DMAAP/SDNC config
 TESTED_VARIANTS="REST   DMAAP   REST+SDNC   DMAAP+SDNC"
+
 #Test agent and simulator protocol versions (others are http only)
 TESTED_PROTOCOLS="HTTP HTTPS"
+
 for __httpx in $TESTED_PROTOCOLS ; do
     for interface in $TESTED_VARIANTS ; do
 
@@ -44,8 +51,25 @@ for __httpx in $TESTED_PROTOCOLS ; do
         echo "#####################################################################"
         echo "#####################################################################"
 
+        # Clean container and start all needed containers #
+        clean_containers
+
+        if [ $__httpx == "HTTPS" ]; then
+            use_agent_rest_https
+        else
+            use_agent_rest_http
+        fi
+
+        start_policy_agent
+
+        set_agent_trace
+
+        # Create service to be able to receive events when rics becomes available
+        # Must use rest towards the agent since dmaap is not configured yet
+        api_put_service 201 "ric-registration" 0 "$CR_PATH/ric-registration"
+
+
         if [ $__httpx == "HTTPS" ]; then
-            CR_PATH="https://$CR_APP_NAME:$CR_EXTERNAL_SECURE_PORT/callbacks"
             use_cr_https
             use_simulator_https
             use_mr_https
@@ -58,7 +82,6 @@ for __httpx in $TESTED_PROTOCOLS ; do
                 use_agent_rest_https
             fi
         else
-            CR_PATH="http://$CR_APP_NAME:$CR_EXTERNAL_PORT/callbacks"
             use_cr_http
             use_simulator_http
             use_mr_http
@@ -72,16 +95,18 @@ for __httpx in $TESTED_PROTOCOLS ; do
             fi
         fi
 
-        # Clean container and start all needed containers #
-        clean_containers
-
         start_ric_simulators ricsim_g1 1  OSC_2.1.0
         start_ric_simulators ricsim_g2 1  STD_1.1.3
+        if [ "$PMS_VERSION" == "V2" ]; then
+            start_ric_simulators ricsim_g3 1  STD_2.0.0
+        fi
 
         start_mr
 
         start_cr
 
+        start_control_panel
+
         start_consul_cbs
 
         if [[ $interface = *"SDNC"* ]]; then
@@ -93,27 +118,37 @@ for __httpx in $TESTED_PROTOCOLS ; do
 
         consul_config_app                      ".consul_config.json"
 
-        start_control_panel
+        sim_put_policy_type 201 ricsim_g1_1 1 testdata/OSC/sim_1.json
+        sim_put_policy_type 201 ricsim_g1_1 2 testdata/OSC/sim_2.json
 
-        start_policy_agent
+        if [ "$PMS_VERSION" == "V2" ]; then
+            sim_put_policy_type 201 ricsim_g3_1 STD_QOS_0_2_0 testdata/STD2/sim_qos.json
+            sim_put_policy_type 201 ricsim_g3_1 STD_QOS2_0.1.0 testdata/STD2/sim_qos2.json
 
-        set_agent_debug
+            api_equal json:rics 3 60
 
-        cr_equal received_callbacks 0
-        mr_equal requests_submitted 0
+            api_equal json:policy-types 5 120
 
-        sim_put_policy_type 201 ricsim_g1_1 1 testdata/OSC/sim_1.json
-        sim_put_policy_type 201 ricsim_g1_1 2 testdata/OSC/sim_2.json
+            api_equal json:policies 0
 
-        api_equal json:rics 2 60
+            api_equal json:policy-instances 0
+        else
+            api_equal json:rics 2 60
 
-        api_equal json:policy_schemas 3 120
+            api_equal json:policy_schemas 3 120
 
-        api_equal json:policy_types 3
+            api_equal json:policy_types 3
 
-        api_equal json:policies 0
+            api_equal json:policies 0
 
-        api_equal json:policy_ids 0
+            api_equal json:policy_ids 0
+        fi
+
+        if [ "$PMS_VERSION" == "V2" ]; then
+            cr_equal received_callbacks 3 120
+            cr_api_check_all_sync_events 200 ric-registration ricsim_g1_1 ricsim_g2_1 ricsim_g3_1
+        fi
+        mr_equal requests_submitted 0
 
 
         echo "############################################"
@@ -145,18 +180,18 @@ for __httpx in $TESTED_PROTOCOLS ; do
 
         api_get_services 200 "service1" "service1" 2000 "$CR_PATH/1"
 
-        api_get_service_ids 200 "service1" "service2"
+        api_get_service_ids 200 "service1" "service2" "ric-registration"
 
 
         api_put_service 201 "service3" 5000 "$CR_PATH/3"
 
 
-        api_get_service_ids 200 "service1" "service2" "service3"
+        api_get_service_ids 200 "service1" "service2" "service3" "ric-registration"
 
 
         api_get_services 200 "service1" "service1" 2000 "$CR_PATH/1"
 
-        api_get_services 200 NOSERVICE "service1" 2000 "$CR_PATH/1" "service2" 300 "ftp://localhost:80/test" "service3" 5000 "$CR_PATH/3"
+        api_get_services 200 NOSERVICE "service1" 2000 "$CR_PATH/1" "service2" 300 "ftp://localhost:80/test" "service3" 5000 "$CR_PATH/3"  "ric-registration" 0 "$CR_PATH/ric-registration"
 
         api_get_services 200
 
@@ -178,159 +213,270 @@ for __httpx in $TESTED_PROTOCOLS ; do
 
         api_put_services_keepalive 404 "service5"
 
-        api_get_service_ids 200 "service1" "service2" "service3"
+        api_get_service_ids 200 "service1" "service2" "service3"  "ric-registration"
 
         api_delete_services 204 "service1"
 
-        api_get_service_ids 200 "service2" "service3"
+        api_get_service_ids 200 "service2" "service3" "ric-registration"
 
 
         api_put_service 201 "service1" 50 "$CR_PATH/1"
 
-        api_get_service_ids 200 "service1" "service2" "service3"
+        api_get_service_ids 200 "service1" "service2" "service3"  "ric-registration"
 
 
         api_delete_services 204 "service1"
         api_delete_services 204 "service3"
 
-        api_equal json:services 1
+        api_equal json:services 2
 
         api_delete_services 204 "service2"
 
-        api_equal json:services 0
+        api_equal json:services 1
 
 
         echo "############################################"
         echo "############## RIC Repository ##############"
         echo "############################################"
 
-        api_get_rics 200 NOTYPE "ricsim_g1_1:me1_ricsim_g1_1,me2_ricsim_g1_1:1,2:AVAILABLE  ricsim_g2_1:me1_ricsim_g2_1,me2_ricsim_g2_1:EMPTYTYPE:AVAILABLE"
-
+        if [ "$PMS_VERSION" == "V2" ]; then
+            api_get_rics 200 NOTYPE "ricsim_g1_1:me1_ricsim_g1_1,me2_ricsim_g1_1:1,2:AVAILABLE  ricsim_g2_1:me1_ricsim_g2_1,me2_ricsim_g2_1:EMPTYTYPE:AVAILABLE ricsim_g3_1:me1_ricsim_g3_1,me2_ricsim_g3_1:STD_QOS_0_2_0,STD_QOS2_0.1.0:AVAILABLE"
+        else
+            api_get_rics 200 NOTYPE "ricsim_g1_1:me1_ricsim_g1_1,me2_ricsim_g1_1:1,2:AVAILABLE  ricsim_g2_1:me1_ricsim_g2_1,me2_ricsim_g2_1:EMPTYTYPE:AVAILABLE"
+        fi
         api_get_rics 200 1 "ricsim_g1_1:me1_ricsim_g1_1,me2_ricsim_g1_1:1,2:AVAILABLE"
 
         api_get_rics 404 47
 
         api_get_rics 404 "test"
 
+        if [ "$PMS_VERSION" == "V2" ]; then
+            api_get_ric 200 me1_ricsim_g1_1 NORIC "ricsim_g1_1:me1_ricsim_g1_1,me2_ricsim_g1_1:1,2:AVAILABLE"
+
+            api_get_ric 200 me2_ricsim_g1_1 NORIC "ricsim_g1_1:me1_ricsim_g1_1,me2_ricsim_g1_1:1,2:AVAILABLE"
+
+            api_get_ric 200 me1_ricsim_g2_1 NORIC "ricsim_g2_1:me1_ricsim_g2_1,me2_ricsim_g2_1:EMPTYTYPE:AVAILABLE"
+
+            api_get_ric 200 me2_ricsim_g2_1 NORIC "ricsim_g2_1:me1_ricsim_g2_1,me2_ricsim_g2_1:EMPTYTYPE:AVAILABLE"
+
+            api_get_ric 200 me1_ricsim_g3_1 NORIC "ricsim_g3_1:me1_ricsim_g3_1,me2_ricsim_g3_1:STD_QOS_0_2_0,STD_QOS2_0.1.0:AVAILABLE"
 
-        api_get_ric 200 me1_ricsim_g1_1 ricsim_g1_1
+            api_get_ric 200 me2_ricsim_g3_1 NORIC "ricsim_g3_1:me1_ricsim_g3_1,me2_ricsim_g3_1:STD_QOS_0_2_0,STD_QOS2_0.1.0:AVAILABLE"
 
-        api_get_ric 200 me2_ricsim_g1_1 ricsim_g1_1
+            api_get_ric 200 NOME      ricsim_g1_1 "ricsim_g1_1:me1_ricsim_g1_1,me2_ricsim_g1_1:1,2:AVAILABLE"
 
-        api_get_ric 200 me1_ricsim_g2_1 ricsim_g2_1
+            api_get_ric 200 NOME      ricsim_g2_1 "ricsim_g2_1:me1_ricsim_g2_1,me2_ricsim_g2_1:EMPTYTYPE:AVAILABLE"
 
-        api_get_ric 200 me2_ricsim_g2_1 ricsim_g2_1
+            api_get_ric 200 NOME      ricsim_g3_1 "ricsim_g3_1:me1_ricsim_g3_1,me2_ricsim_g3_1:STD_QOS_0_2_0,STD_QOS2_0.1.0:AVAILABLE"
 
-        api_get_ric 404 test
+            api_get_ric 404 NOME test1
+
+            api_get_ric 404 test NORIC
+
+            api_get_ric 400 me1_ricsim_g1_1 ricsim_g1_1
+
+            api_get_ric 400 me1_ricsim_g1_1 TESTRIC
+
+            api_get_ric 400 TESTME ricsim_g1_1
+
+        else
+            api_get_ric 200 me1_ricsim_g1_1 ricsim_g1_1
 
+            api_get_ric 200 me2_ricsim_g1_1 ricsim_g1_1
+
+            api_get_ric 200 me1_ricsim_g2_1 ricsim_g2_1
+
+            api_get_ric 200 me2_ricsim_g2_1 ricsim_g2_1
+
+            api_get_ric 404 test
+        fi
 
         echo "############################################"
         echo "########### A1 Policy Management ###########"
         echo "############################################"
-        deviation "TR9 - agent modify the type with type id - test combo $interface and $__httpx"
-        #Behaviour accepted for now
-        api_get_policy_schema 200 1 testdata/OSC/1-agent-modified.json
-        deviation "TR9 - agent modify the type with type id - test combo $interface and $__httpx"
-        #Behaviour accepted for now
-        api_get_policy_schema 200 2 testdata/OSC/2-agent-modified.json
 
-        api_get_policy_schema 404 3
-        deviation "TR9 - agent modify the type with type id - test combo $interface and $__httpx"
-        #Behaviour accepted for now
-        api_get_policy_schemas 200 NORIC testdata/OSC/1-agent-modified.json testdata/OSC/2-agent-modified.json NOFILE
-        deviation "TR9 - agent modify the type with type id - test combo $interface and $__httpx"
-        #Behaviour accepted for now
-        api_get_policy_schemas 200 ricsim_g1_1 testdata/OSC/1-agent-modified.json testdata/OSC/2-agent-modified.json
+        if [ "$PMS_VERSION" == "V2" ]; then
+            deviation "TR9 - agent modify the type with type id - test combo $interface and $__httpx"
+            #Behaviour accepted for now
+            api_get_policy_type 200 1 testdata/OSC/1-agent-modified.json
+            deviation "TR9 - agent modify the type with type id - test combo $interface and $__httpx"
+            #Behaviour accepted for now
+            api_get_policy_type 200 2 testdata/OSC/2-agent-modified.json
+            deviation "TR9 - agent modify the type with type id - test combo $interface and $__httpx"
+            #Behaviour accepted for now
+            api_get_policy_type 200 STD_QOS_0_2_0 testdata/STD2/qos-agent-modified.json
+            deviation "TR9 - agent modify the type with type id - test combo $interface and $__httpx"
+            #Behaviour accepted for now
+            api_get_policy_type 200 STD_QOS2_0.1.0 testdata/STD2/qos2-agent-modified.json
+
+            api_get_policy_type 404 3
+        else
+            deviation "TR9 - agent modify the type with type id - test combo $interface and $__httpx"
+            #Behaviour accepted for now
+            api_get_policy_schema 200 1 testdata/OSC/1-agent-modified.json
+            deviation "TR9 - agent modify the type with type id - test combo $interface and $__httpx"
+            #Behaviour accepted for now
+            api_get_policy_schema 200 2 testdata/OSC/2-agent-modified.json
+
+            api_get_policy_schema 404 3
+        fi
 
-        api_get_policy_schemas 200 ricsim_g2_1 NOFILE
+        if [ "$PMS_VERSION" == "V2" ]; then
+            api_get_policy_schemas 404
+        else
+            deviation "TR9 - agent modify the type with type id - test combo $interface and $__httpx"
+            #Behaviour accepted for now
+            api_get_policy_schemas 200 NORIC testdata/OSC/1-agent-modified.json testdata/OSC/2-agent-modified.json NOFILE
+            deviation "TR9 - agent modify the type with type id - test combo $interface and $__httpx"
+            #Behaviour accepted for now
+            api_get_policy_schemas 200 ricsim_g1_1 testdata/OSC/1-agent-modified.json testdata/OSC/2-agent-modified.json
 
-        api_get_policy_schemas 404 test
+            api_get_policy_schemas 200 ricsim_g2_1 NOFILE
 
+            api_get_policy_schemas 404 test
+        fi
 
 
-        api_get_policy_types 200 NORIC 1 2 EMPTY
+        if [ "$PMS_VERSION" == "V2" ]; then
+            api_get_policy_types 200 NORIC 1 2 EMPTY STD_QOS_0_2_0 STD_QOS2_0.1.0
+        else
+            api_get_policy_types 200 NORIC 1 2 EMPTY
+        fi
 
         api_get_policy_types 200 ricsim_g1_1 1 2
 
         api_get_policy_types 200 ricsim_g2_1 EMPTY
 
+        if [ "$PMS_VERSION" == "V2" ]; then
+            api_get_policy_types 200 ricsim_g3_1 STD_QOS_0_2_0 STD_QOS2_0.1.0
+        fi
+
         api_get_policy_types 404 dummy-ric
 
 
 
         api_put_service 201 "service10" 3600 "$CR_PATH/1"
 
+        if [ "$PMS_VERSION" == "V2" ]; then
+            notificationurl=$CR_PATH"/test"
+        else
+            notificationurl=""
+        fi
         deviation "TR10 - agent allows policy creation on unregistered service (orig problem) - test combo $interface and $__httpx"
         #Kept until decison
         #api_put_policy 400 "unregistered-service" ricsim_g1_1 1 2000 NOTRANSIENT testdata/OSC/pi1_template.json
         #Allow 201 for now
-        api_put_policy 201 "unregistered-service" ricsim_g1_1 1 2000 NOTRANSIENT testdata/OSC/pi1_template.json
+        api_put_policy 201 "unregistered-service" ricsim_g1_1 1 2000 NOTRANSIENT $notificationurl testdata/OSC/pi1_template.json
+
+        api_put_policy 201 "service10" ricsim_g1_1 1 5000 NOTRANSIENT $notificationurl testdata/OSC/pi1_template.json
+        api_put_policy 200 "service10" ricsim_g1_1 1 5000 NOTRANSIENT $notificationurl testdata/OSC/pi1_template.json
+
+        api_put_policy 200 "service10" ricsim_g1_1 1 5000 true $notificationurl testdata/OSC/pi1_template.json
+        api_put_policy 200 "service10" ricsim_g1_1 1 5000 false $notificationurl testdata/OSC/pi1_template.json
 
-        api_put_policy 201 "service10" ricsim_g1_1 1 5000 NOTRANSIENT testdata/OSC/pi1_template.json
-        api_put_policy 200 "service10" ricsim_g1_1 1 5000 NOTRANSIENT testdata/OSC/pi1_template.json
+        api_put_policy 201 "service10" ricsim_g2_1 NOTYPE 5100 NOTRANSIENT $notificationurl testdata/STD/pi1_template.json
+        api_put_policy 200 "service10" ricsim_g2_1 NOTYPE 5100 NOTRANSIENT $notificationurl testdata/STD/pi1_template.json
 
-        api_put_policy 200 "service10" ricsim_g1_1 1 5000 true testdata/OSC/pi1_template.json
-        api_put_policy 200 "service10" ricsim_g1_1 1 5000 false testdata/OSC/pi1_template.json
+        api_put_policy 200 "service10" ricsim_g2_1 NOTYPE 5100 true $notificationurl testdata/STD/pi1_template.json
+        api_put_policy 200 "service10" ricsim_g2_1 NOTYPE 5100 false $notificationurl testdata/STD/pi1_template.json
 
-        api_put_policy 201 "service10" ricsim_g2_1 NOTYPE 5100 NOTRANSIENT testdata/STD/pi1_template.json
-        api_put_policy 200 "service10" ricsim_g2_1 NOTYPE 5100 NOTRANSIENT testdata/STD/pi1_template.json
+        if [ "$PMS_VERSION" == "V2" ]; then
+            api_put_policy 201 "service10" ricsim_g3_1 STD_QOS2_0.1.0 5200 NOTRANSIENT $notificationurl testdata/STD2/pi_qos2_template.json
+            api_put_policy 200 "service10" ricsim_g3_1 STD_QOS2_0.1.0 5200 NOTRANSIENT $notificationurl testdata/STD2/pi_qos2_template.json
 
-        api_put_policy 200 "service10" ricsim_g2_1 NOTYPE 5100 true testdata/STD/pi1_template.json
-        api_put_policy 200 "service10" ricsim_g2_1 NOTYPE 5100 false testdata/STD/pi1_template.json
+            api_put_policy 200 "service10" ricsim_g3_1 STD_QOS2_0.1.0 5200 true $notificationurl testdata/STD2/pi_qos2_template.json
+            api_put_policy 200 "service10" ricsim_g3_1 STD_QOS2_0.1.0 5200 false $notificationurl testdata/STD2/pi_qos2_template.json
+        fi
 
         VAL='NOT IN EFFECT'
         api_get_policy_status 200 5000 OSC "$VAL" "false"
         api_get_policy_status 200 5100 STD "UNDEFINED"
+        if [ "$PMS_VERSION" == "V2" ]; then
+            api_get_policy_status 200 5200 STD "UNDEFINED"
+        fi
 
 
         deviation "TR10 - agent allows policy creation on unregistered service (side effect of orig. problem)- test combo $interface and $__httpx"
         #kept until decision
         #api_equal json:policies 2
         #Allow 3 for now
-        api_equal json:policies 3
+        if [ "$PMS_VERSION" == "V2" ]; then
+            api_equal json:policies 4
+        else
+            api_equal json:policies 3
+        fi
 
         deviation "TR10 - agent allows policy creation on unregistered service (side effect of orig. problem)- test combo $interface and $__httpx"
         #kept until decision
         #api_equal json:policy_ids 2
         #Allow 3 for now
-        api_equal json:policy_ids 3
+        if [ "$PMS_VERSION" == "V2" ]; then
+            api_equal json:policy-instances 4
+        else
+            api_equal json:policy_ids 3
+        fi
 
         deviation "TR10 - agent allows policy creation on unregistered service (side effect of orig. problem)- test combo $interface and $__httpx"
         #kept until decision
         #api_get_policy_ids 200 NORIC NOSERVICE NOTYPE 5000 5100
         #Allow policy create with unregistered service for now
-        api_get_policy_ids 200 NORIC NOSERVICE NOTYPE 5000 5100 2000
-
+        if [ "$PMS_VERSION" == "V2" ]; then
+            api_get_policy_ids 200 NORIC NOSERVICE NOTYPE 5000 5100 2000 5200
+        else
+            api_get_policy_ids 200 NORIC NOSERVICE NOTYPE 5000 5100 2000
+        fi
 
         deviation "TR10 - agent allows policy creation on unregistered service (side effect of orig. problem)- test combo $interface and $__httpx"
         #kept until decision
         #api_get_policy_ids 200 ricsim_g1_1 NOSERVICE NOTYPE 5000
         #Allow policy create with unregistered service for now
-        api_get_policy_ids 200 ricsim_g1_1 NOSERVICE NOTYPE 5000 2000
+        if [ "$PMS_VERSION" == "V2" ]; then
+            api_get_policy_ids 200 ricsim_g1_1 NOSERVICE NOTYPE 5000 2000
 
-        api_get_policy_ids 200 ricsim_g2_1 NOSERVICE NOTYPE 5100
+            api_get_policy_ids 200 ricsim_g2_1 NOSERVICE NOTYPE 5100
 
+            api_get_policy_ids 200 ricsim_g3_1 NOSERVICE NOTYPE 5200
+
+            api_get_policy_ids 200 NORIC "service10" NOTYPE 5000 5100 5200
+        else
+            api_get_policy_ids 200 ricsim_g1_1 NOSERVICE NOTYPE 5000 2000
+
+            api_get_policy_ids 200 ricsim_g2_1 NOSERVICE NOTYPE 5100
 
-        api_get_policy_ids 200 NORIC "service10" NOTYPE 5000 5100
+
+            api_get_policy_ids 200 NORIC "service10" NOTYPE 5000 5100
+        fi
 
         deviation "TR10 - agent allows policy creation on unregistered service (side effect of orig. problem)- test combo $interface and $__httpx"
         #kept until decision
         #api_get_policy_ids 200 NORIC NOSERVICE 1 5000
         #Allow policy create with unregistered service for now
+
         api_get_policy_ids 200 NORIC NOSERVICE 1 5000 2000
 
         api_get_policy_ids 200 NORIC NOSERVICE 2 NOID
 
+        if [ "$PMS_VERSION" == "V2" ]; then
+            api_get_policy_ids 200 NORIC NOSERVICE STD_QOS2_0.1.0 5200
+        fi
+
         api_get_policy_ids 200 ricsim_g2_1 NOSERVICE 1 NOID
 
+        if [ "$PMS_VERSION" == "V2" ]; then
+            api_get_policy 200 5000 testdata/OSC/pi1_template.json "service10" ricsim_g1_1 1 false $notificationurl
 
-        api_get_policy 200 5000 testdata/OSC/pi1_template.json
+            api_get_policy 200 5100 testdata/STD/pi1_template.json "service10" ricsim_g2_1 NOTYPE false $notificationurl
 
-        api_get_policy 200 5100 testdata/STD/pi1_template.json
+            api_get_policy 200 5200 testdata/STD2/pi_qos2_template.json "service10" ricsim_g3_1 NOTYPE false $notificationurl
 
+            api_get_policies 200 ricsim_g1_1 "service10" 1 5000 ricsim_g1_1 "service10" STD_QOS2_0 true $notificationurl testdata/OSC/pi1_template.json
+        else
+            api_get_policy 200 5000 testdata/OSC/pi1_template.json
 
-        api_get_policies 200 ricsim_g1_1 "service10" 1 5000 ricsim_g1_1 "service10" 1 testdata/OSC/pi1_template.json
+            api_get_policy 200 5100 testdata/STD/pi1_template.json
 
+            api_get_policies 200 ricsim_g1_1 "service10" 1 5000 ricsim_g1_1 "service10" 1 testdata/OSC/pi1_template.json
+        fi
 
         deviation "TR10 - agent allows policy creation on unregistered service (side effect of orig. problem)- test combo $interface and $__httpx"
         #kept until decision
@@ -342,17 +488,33 @@ for __httpx in $TESTED_PROTOCOLS ; do
 
         api_delete_policy 204 5000
 
+        if [ "$PMS_VERSION" == "V2" ]; then
+
+            api_delete_policy 204 5200
+        fi
+
         api_equal json:policies 1
 
-        api_equal json:policy_ids 1
+
+        if [ "$PMS_VERSION" == "V2" ]; then
+            api_equal json:policy-instances 1
+        else
+            api_equal json:policy_ids 1
+        fi
 
         api_delete_policy 204 5100
 
         api_equal json:policies 0
 
-        api_equal json:policy_ids 0
+        if [ "$PMS_VERSION" == "V2" ]; then
+            api_equal json:policy-instances 0
+        else
+            api_equal json:policy_ids 0
+        fi
 
-        cr_equal received_callbacks 0
+        if [ "$PMS_VERSION" == "V2" ]; then
+            cr_equal received_callbacks 3
+        fi
 
         if [[ $interface = *"DMAAP"* ]]; then
             mr_greater requests_submitted 0
@@ -369,14 +531,24 @@ for __httpx in $TESTED_PROTOCOLS ; do
         if [[ $interface = *"SDNC"* ]]; then
             sim_contains_str ricsim_g1_1 remote_hosts "a1-controller"
             sim_contains_str ricsim_g2_1 remote_hosts "a1-controller"
+            if [ "$PMS_VERSION" == "V2" ]; then
+                sim_contains_str ricsim_g3_1 remote_hosts "a1-controller"
+            fi
         else
             sim_contains_str ricsim_g1_1 remote_hosts "policy-agent"
             sim_contains_str ricsim_g2_1 remote_hosts "policy-agent"
+            if [ "$PMS_VERSION" == "V2" ]; then
+                sim_contains_str ricsim_g3_1 remote_hosts "policy-agent"
+            fi
         fi
 
         check_policy_agent_logs
         check_control_panel_logs
 
+        if [[ $interface = *"SDNC"* ]]; then
+            check_sdnc_logs
+        fi
+
         store_logs          "${__httpx}__${interface}"
 
     done
index c840800..bc566df 100755 (executable)
@@ -23,17 +23,16 @@ TC_ONELINE_DESCR="Testing of service registration timeouts and keepalive"
 #App names to include in the test, space separated list
 INCLUDED_IMAGES="CBS CONSUL CP CR MR PA RICSIM"
 
+#SUPPORTED TEST ENV FILE
+SUPPORTED_PROFILES="ONAP-MASTER ONAP-GUILIN"
+
 . ../common/testcase_common.sh  $@
 . ../common/agent_api_functions.sh
 . ../common/ricsimulator_api_functions.sh
+. ../common/cr_api_functions.sh
 
 generate_uuid
 
-#Local vars in test script
-##########################
-# Path to callback receiver
-CR_PATH="http://$CR_APP_NAME:$CR_EXTERNAL_PORT/callbacks"
-
 use_cr_http
 use_simulator_http
 use_mr_http
@@ -45,6 +44,10 @@ use_agent_rest_http
 clean_containers
 
 start_ric_simulators ricsim_g1 1  OSC_2.1.0
+start_ric_simulators ricsim_g2 1  STD_1.1.3
+if [ "$PMS_VERSION" == "V2" ]; then
+    start_ric_simulators ricsim_g3 1  STD_2.0.0
+fi
 
 start_mr
 
@@ -61,8 +64,6 @@ start_policy_agent
 
 set_agent_debug
 
-#Verify no callbacks or dmaap messages has been sent
-cr_equal received_callbacks 0
 mr_equal requests_submitted 0
 
 #Check agent alive
@@ -70,6 +71,10 @@ api_get_status 200
 
 #Print simulator interface version
 sim_print ricsim_g1_1 interface
+sim_print ricsim_g2_1 interface
+if [ "$PMS_VERSION" == "V2" ]; then
+    sim_print ricsim_g3_1 interface
+fi
 
 api_put_service 201 "service1" 15 "$CR_PATH/service1"
 
@@ -151,32 +156,81 @@ api_put_service 201 "service10" 600 "$CR_PATH/service10"
 
 sim_put_policy_type 201 ricsim_g1_1 1 testdata/OSC/sim_1.json
 
-api_equal json:rics 1 60
+if [ "$PMS_VERSION" == "V2" ]; then
+
+    sim_put_policy_type 201 ricsim_g3_1 STD_QOS2_0.1.0 testdata/STD2/sim_qos2.json
+
+    api_equal json:rics 3 60
+
+    #api_equal json:policy_schemas 2 120
 
-api_equal json:policy_schemas 1 120
+    api_equal json:policy-types 3 120
 
-api_equal json:policy_types 1
+    api_equal json:policies 0
+else
+    api_equal json:rics 2 60
 
-api_equal json:policies 0
+    api_equal json:policy_schemas 2 120
 
-api_put_policy 201 "service10" ricsim_g1_1 1 5000 NOTRANSIENT testdata/OSC/pi1_template.json
+    api_equal json:policy_types 2
 
-api_equal json:policies 1
+    api_equal json:policies 0
+fi
+
+if [ "$PMS_VERSION" == "V2" ]; then
+    notificationurl=$CR_PATH"/test"
+else
+    notificationurl=""
+fi
+
+api_put_policy 201 "service10" ricsim_g1_1 1 5000 NOTRANSIENT $notificationurl testdata/OSC/pi1_template.json
+api_put_policy 201 "service10" ricsim_g2_1 NOTYPE 5100 NOTRANSIENT $notificationurl testdata/STD/pi1_template.json
+
+if [ "$PMS_VERSION" == "V2" ]; then
+    api_put_policy 201 "service10" ricsim_g3_1 STD_QOS2_0.1.0 5200 NOTRANSIENT $notificationurl testdata/STD2/pi_qos2_template.json
+    api_equal json:policies 3
+else
+    api_equal json:policies 2
+fi
 
 sim_equal ricsim_g1_1 num_instances 1
+sim_equal ricsim_g2_1 num_instances 1
 
-api_put_policy 201 "service10" ricsim_g1_1 1 5001 true testdata/OSC/pi1_template.json
+api_put_policy 201 "service10" ricsim_g1_1 1 5001 true $notificationurl testdata/OSC/pi1_template.json
+api_put_policy 201 "service10" ricsim_g2_1 NOTYPE 5101 true $notificationurl testdata/STD/pi1_template.json
 
-api_equal json:policies 2
+if [ "$PMS_VERSION" == "V2" ]; then
+    api_put_policy 201 "service10" ricsim_g3_1 STD_QOS2_0.1.0 5201 true $notificationurl testdata/STD2/pi_qos2_template.json
+    api_equal json:policies 6
+else
+    api_equal json:policies 4
+fi
 
 sim_equal ricsim_g1_1 num_instances 2
+sim_equal ricsim_g2_1 num_instances 2
+if [ "$PMS_VERSION" == "V2" ]; then
+    sim_equal ricsim_g3_1 num_instances 2
+fi
 
 sim_post_delete_instances 200 ricsim_g1_1
+sim_post_delete_instances 200 ricsim_g2_1
+
+if [ "$PMS_VERSION" == "V2" ]; then
+    sim_post_delete_instances 200 ricsim_g3_1
+fi
 
 #Wait for recreate of non transient policy
-api_equal json:policies 1 180
+if [ "$PMS_VERSION" == "V2" ]; then
+    api_equal json:policies 3 180
+else
+    api_equal json:policies 2 180
+fi
 
 sim_equal ricsim_g1_1 num_instances 1
+sim_equal ricsim_g2_1 num_instances 1
+if [ "$PMS_VERSION" == "V2" ]; then
+    sim_equal ricsim_g3_1 num_instances 1
+fi
 
 api_put_service 200 "service10" 10 "$CR_PATH/service10"
 
@@ -184,12 +238,13 @@ api_put_service 200 "service10" 10 "$CR_PATH/service10"
 api_equal json:policies 0 120
 
 sim_equal ricsim_g1_1 num_instances 0
-
+sim_equal ricsim_g2_1 num_instances 0
+if [ "$PMS_VERSION" == "V2" ]; then
+    sim_equal ricsim_g3_1 num_instances 0
+fi
 
 api_get_service_ids 200
 
-deviation "TR18 Agents sends callback with empty body"
-cr_equal received_callbacks 4
 mr_equal requests_submitted 0
 
 check_policy_agent_logs
index a61f1bb..0a1a014 100755 (executable)
@@ -29,6 +29,8 @@ INCLUDED_IMAGES="ECS PRODSTUB"
 
 #### TEST BEGIN ####
 
+FLAT_A1_EI="1"
+
 clean_containers
 
 use_ecs_rest_http
@@ -44,9 +46,13 @@ set_ecs_debug
 set_ecs_trace
 
 # Setup prodstub sim to accept calls for producers, types and jobs
-prodstub_arm_supervision 200 prod-a
-prodstub_arm_supervision 200 prod-b
-prodstub_arm_supervision 200 prod-c
+prodstub_arm_producer 200 prod-a
+prodstub_arm_producer 200 prod-b
+prodstub_arm_producer 200 prod-c
+
+prodstub_arm_producer 200 prod-d
+prodstub_arm_type 200 prod-d type4
+prodstub_arm_job_create 200 prod-d job8
 
 prodstub_arm_type 200 prod-a type1
 prodstub_arm_type 200 prod-b type2
@@ -56,22 +62,22 @@ prodstub_disarm_type 200 prod-b type3
 prodstub_arm_type 200 prod-b type1
 prodstub_disarm_type 200 prod-b type1
 
-prodstub_arm_create 200 prod-a job1
-prodstub_arm_create 200 prod-a job2
-prodstub_arm_create 200 prod-b job3
+prodstub_arm_job_create 200 prod-a job1
+prodstub_arm_job_create 200 prod-a job2
+prodstub_arm_job_create 200 prod-b job3
 
-prodstub_arm_delete 200 prod-a job1
-prodstub_arm_delete 200 prod-a job2
-prodstub_arm_delete 200 prod-b job3
+prodstub_arm_job_delete 200 prod-a job1
+prodstub_arm_job_delete 200 prod-a job2
+prodstub_arm_job_delete 200 prod-b job3
 
-prodstub_arm_create 200 prod-b job4
-prodstub_arm_create 200 prod-a job4
+prodstub_arm_job_create 200 prod-b job4
+prodstub_arm_job_create 200 prod-a job4
 
-prodstub_arm_create 200 prod-b job5
-prodstub_arm_create 200 prod-a job5
-prodstub_arm_delete 200 prod-a job5
+prodstub_arm_job_create 200 prod-b job5
+prodstub_arm_job_create 200 prod-a job5
+prodstub_arm_job_delete 200 prod-a job5
 
-prodstub_arm_create 200 prod-b job6
+prodstub_arm_job_create 200 prod-b job6
 
 # ecs status
 ecs_api_service_status 200
@@ -90,14 +96,27 @@ ecs_api_edp_get_producer_status 404 test-prod
 
 ecs_api_edp_delete_producer 404 test-prod
 
-ecs_api_a1_get_job_ids 404 test-type NOWNER
-ecs_api_a1_get_job_ids 404 test-type test-owner
+if [  -z "$FLAT_A1_EI" ]; then
+    ecs_api_a1_get_job_ids 404 test-type NOWNER
+    ecs_api_a1_get_job_ids 404 test-type test-owner
+
+    ecs_api_a1_get_job 404 test-type test-job
+
+    ecs_api_a1_get_job_status 404 test-type test-job
+else
+    ecs_api_a1_get_job_ids 200 test-type NOWNER EMPTY
+    ecs_api_a1_get_job_ids 200 test-type test-owner EMPTY
 
-ecs_api_a1_get_job 404 test-type test-job
+    ecs_api_a1_get_job 404 test-job
 
-ecs_api_a1_get_job_status 404 test-type test-job
+    ecs_api_a1_get_job_status 404 test-job
+fi
 
-ecs_api_a1_delete_job 404 test-type test-job
+if [  -z "$FLAT_A1_EI" ]; then
+    ecs_api_a1_delete_job 404 test-type test-job
+else
+    ecs_api_a1_delete_job 404 test-job
+fi
 
 ecs_api_edp_get_producer_jobs 404 test-prod
 
@@ -108,7 +127,11 @@ ecs_api_edp_put_producer 201 prod-a http://producer-stub:8092/callbacks/create/p
 ecs_api_edp_put_producer 200 prod-a http://producer-stub:8092/callbacks/create/prod-a http://producer-stub:8092/callbacks/delete/prod-a http://producer-stub:8092/callbacks/supervision/prod-a type1 testdata/ecs/ei-type-1.json
 
 ecs_api_a1_get_type_ids 200 type1
-ecs_api_a1_get_type 200 type1 testdata/ecs/ei-type-1.json
+if [  -z "$FLAT_A1_EI" ]; then
+    ecs_api_a1_get_type 200 type1 testdata/ecs/ei-type-1.json
+else
+    ecs_api_a1_get_type 200 type1 testdata/ecs/empty-type.json
+fi
 
 ecs_api_edp_get_type_ids 200 type1
 ecs_api_edp_get_type 200 type1 testdata/ecs/ei-type-1.json prod-a
@@ -121,40 +144,72 @@ ecs_api_edp_get_producer_status 200 prod-a ENABLED
 ecs_api_a1_get_job_ids 200 type1 NOWNER EMPTY
 ecs_api_a1_get_job_ids 200 type1 test-owner EMPTY
 
-ecs_api_a1_get_job 404 type1 test-job
+if [  -z "$FLAT_A1_EI" ]; then
+    ecs_api_a1_get_job 404 type1 test-job
 
-ecs_api_a1_get_job_status 404 type1 test-job
+    ecs_api_a1_get_job_status 404 type1 test-job
+else
+    ecs_api_a1_get_job 404 test-job
+
+    ecs_api_a1_get_job_status 404 test-job
+fi
 
 ecs_api_edp_get_producer_jobs 200 prod-a EMPTY
 
 
 #job1 - prod-a
-ecs_api_a1_put_job 201 type1 job1 http://localhost:80/target1 ric1 testdata/ecs/job-template.json
+if [  -z "$FLAT_A1_EI" ]; then
+    ecs_api_a1_put_job 201 type1 job1 http://localhost:80/target1 ric1 testdata/ecs/job-template.json
+else
+    ecs_api_a1_put_job 201 job1 type1 http://localhost:80/target1 ric1 http://localhost:80/status1 testdata/ecs/job-template.json
+fi
 
 prodstub_check_jobdata 200 prod-a job1 type1 http://localhost:80/target1 testdata/ecs/job-template.json
 
 ecs_api_a1_get_job_ids 200 type1 NOWNER job1
 ecs_api_a1_get_job_ids 200 type1 ric1 job1
+if [ ! -z "$FLAT_A1_EI" ]; then
+    ecs_api_a1_get_job_ids 200 NOTYPE NOWNER job1
+fi
+
+if [  -z "$FLAT_A1_EI" ]; then
+    ecs_api_a1_get_job 200 type1 job1 http://localhost:80/target1 ric1 testdata/ecs/job-template.json
 
-ecs_api_a1_get_job 200 type1 job1 http://localhost:80/target1 ric1 testdata/ecs/job-template.json
+    ecs_api_a1_get_job_status 200 type1 job1 ENABLED
+else
+    ecs_api_a1_get_job 200 job1 type1 http://localhost:80/target1 ric1 http://localhost:80/status1 testdata/ecs/job-template.json
 
-ecs_api_a1_get_job_status 200 type1 job1 ENABLED
+    ecs_api_a1_get_job_status 200 job1 ENABLED
+fi
 
 ecs_api_edp_get_producer_jobs 200 prod-a job1 type1 http://localhost:80/target1 testdata/ecs/job-template.json
 
 
 #job2 - prod-a
-ecs_api_a1_put_job 201 type1 job2 http://localhost:80/target2 ric2 testdata/ecs/job-template.json
+if [  -z "$FLAT_A1_EI" ]; then
+    ecs_api_a1_put_job 201 type1 job2 http://localhost:80/target2 ric2 testdata/ecs/job-template.json
+else
+    ecs_api_a1_put_job 201 job2 type1 http://localhost:80/target2 ric2 http://localhost:80/status2 testdata/ecs/job-template.json
+fi
 
 prodstub_check_jobdata 200 prod-a job2 type1 http://localhost:80/target2 testdata/ecs/job-template.json
 
 ecs_api_a1_get_job_ids 200 type1 NOWNER job1 job2
 ecs_api_a1_get_job_ids 200 type1 ric1 job1
 ecs_api_a1_get_job_ids 200 type1 ric2 job2
+if [ ! -z "$FLAT_A1_EI" ]; then
+    ecs_api_a1_get_job_ids 200 NOTYPE NOWNER job1 job2
+fi
+
+if [  -z "$FLAT_A1_EI" ]; then
+    ecs_api_a1_get_job 200 type1 job2 http://localhost:80/target2 ric2 testdata/ecs/job-template.json
 
-ecs_api_a1_get_job 200 type1 job2 http://localhost:80/target2 ric2 testdata/ecs/job-template.json
+    ecs_api_a1_get_job_status 200 type1 job2 ENABLED
+else
+    ecs_api_a1_get_job 200 job2 type1 http://localhost:80/target2 ric2 http://localhost:80/status2 testdata/ecs/job-template.json
 
-ecs_api_a1_get_job_status 200 type1 job2 ENABLED
+    ecs_api_a1_get_job_status 200 job2 ENABLED
+fi
 
 ecs_api_edp_get_producer_jobs 200 prod-a job1 type1 http://localhost:80/target1 testdata/ecs/job-template.json job2 type1 http://localhost:80/target2 testdata/ecs/job-template.json
 
@@ -163,8 +218,13 @@ ecs_api_edp_get_producer_jobs 200 prod-a job1 type1 http://localhost:80/target1
 ecs_api_edp_put_producer 201 prod-b http://producer-stub:8092/callbacks/create/prod-b http://producer-stub:8092/callbacks/delete/prod-b http://producer-stub:8092/callbacks/supervision/prod-b type2 testdata/ecs/ei-type-2.json
 
 ecs_api_a1_get_type_ids 200 type1 type2
-ecs_api_a1_get_type 200 type1 testdata/ecs/ei-type-1.json
-ecs_api_a1_get_type 200 type2 testdata/ecs/ei-type-2.json
+if [  -z "$FLAT_A1_EI" ]; then
+    ecs_api_a1_get_type 200 type1 testdata/ecs/ei-type-1.json
+    ecs_api_a1_get_type 200 type2 testdata/ecs/ei-type-2.json
+else
+    ecs_api_a1_get_type 200 type1 testdata/ecs/empty-type.json
+    ecs_api_a1_get_type 200 type2 testdata/ecs/empty-type.json
+fi
 
 ecs_api_edp_get_type_ids 200 type1 type2
 ecs_api_edp_get_type 200 type1 testdata/ecs/ei-type-1.json prod-a
@@ -178,7 +238,11 @@ ecs_api_edp_get_producer_status 200 prod-b ENABLED
 
 
 #job3 - prod-b
-ecs_api_a1_put_job 201 type2 job3 http://localhost:80/target3 ric3 testdata/ecs/job-template.json
+if [  -z "$FLAT_A1_EI" ]; then
+    ecs_api_a1_put_job 201 type2 job3 http://localhost:80/target3 ric3 testdata/ecs/job-template.json
+else
+    ecs_api_a1_put_job 201 job3 type2 http://localhost:80/target3 ric3 http://localhost:80/status3 testdata/ecs/job-template.json
+fi
 
 prodstub_check_jobdata 200 prod-b job3 type2 http://localhost:80/target3 testdata/ecs/job-template.json
 
@@ -188,9 +252,15 @@ ecs_api_a1_get_job_ids 200 type1 ric1 job1
 ecs_api_a1_get_job_ids 200 type1 ric2 job2
 ecs_api_a1_get_job_ids 200 type2 ric3 job3
 
-ecs_api_a1_get_job 200 type2 job3 http://localhost:80/target3 ric3 testdata/ecs/job-template.json
+if [  -z "$FLAT_A1_EI" ]; then
+    ecs_api_a1_get_job 200 type2 job3 http://localhost:80/target3 ric3 testdata/ecs/job-template.json
 
-ecs_api_a1_get_job_status 200 type2 job3 ENABLED
+    ecs_api_a1_get_job_status 200 type2 job3 ENABLED
+else
+    ecs_api_a1_get_job 200 job3 type2 http://localhost:80/target3 ric3 http://localhost:80/status3 testdata/ecs/job-template.json
+
+    ecs_api_a1_get_job_status 200 job3 ENABLED
+fi
 
 ecs_api_edp_get_producer_jobs 200 prod-a job1 type1 http://localhost:80/target1 testdata/ecs/job-template.json job2 type1 http://localhost:80/target2 testdata/ecs/job-template.json
 ecs_api_edp_get_producer_jobs 200 prod-b job3 type2 http://localhost:80/target3 testdata/ecs/job-template.json
@@ -206,12 +276,62 @@ ecs_api_edp_get_producer 200 prod-c http://producer-stub:8092/callbacks/create/p
 
 ecs_api_edp_get_producer_status 200 prod-c ENABLED
 
-ecs_api_a1_delete_job 204 type2 job3
+if [  -z "$FLAT_A1_EI" ]; then
+    ecs_api_a1_delete_job 204 type2 job3
+else
+    ecs_api_a1_delete_job 204 job3
+fi
 
 ecs_api_edp_delete_producer 204 prod-b
 
 
-check_sndc_logs
+prodstub_equal create/prod-d/job8 0
+prodstub_equal delete/prod-d/job8 0
+
+ecs_api_edp_put_producer 201 prod-d http://producer-stub:8092/callbacks/create/prod-d http://producer-stub:8092/callbacks/delete/prod-d http://producer-stub:8092/callbacks/supervision/prod-d type4 testdata/ecs/ei-type-1.json
+
+ecs_api_a1_get_job_ids 200 type4 NOWNER EMPTY
+
+if [  -z "$FLAT_A1_EI" ]; then
+    ecs_api_a1_put_job 201 type4 job8 http://localhost:80/target8 ric4 testdata/ecs/job-template.json
+else
+    ecs_api_a1_put_job 201 job8 type4 http://localhost:80/target8 ric4 http://localhost:80/status4 testdata/ecs/job-template.json
+fi
+read -p "<continue>"
+prodstub_equal create/prod-d/job8 1
+prodstub_equal delete/prod-d/job8 0
+
+ecs_api_a1_get_job_ids 200 type4 NOWNER job8
+
+ecs_api_edp_put_producer 200 prod-d http://producer-stub:8092/callbacks/create/prod-d http://producer-stub:8092/callbacks/delete/prod-d http://producer-stub:8092/callbacks/supervision/prod-d NOTYPE
+
+if [  -z "$FLAT_A1_EI" ]; then
+    ecs_api_a1_get_job_ids 404 type4 NOWNER
+else
+    ecs_api_a1_get_job_ids 200 type4 NOWNER EMPTY
+    ecs_api_a1_get_job_ids 200 NOTYPE NOWNER job1 job2 job8
+fi
+
+prodstub_equal create/prod-d/job8 1
+prodstub_equal delete/prod-d/job8 0
+
+
+
+ecs_api_edp_put_producer 200 prod-d http://producer-stub:8092/callbacks/create/prod-d http://producer-stub:8092/callbacks/delete/prod-d http://producer-stub:8092/callbacks/supervision/prod-d type4 testdata/ecs/ei-type-1.json
+
+if [  -z "$FLAT_A1_EI" ]; then
+    ecs_api_a1_get_job_ids 404 type4 NOWNER
+else
+    ecs_api_a1_get_job_ids 200 type4 NOWNER EMPTY
+    ecs_api_a1_get_job_ids 200 NOTYPE NOWNER job1 job2 job8
+fi
+
+
+
+
+
+
+check_sdnc_logs
 
 check_ecs_logs
 
index ead424c..bd33bee 100755 (executable)
@@ -23,12 +23,20 @@ TC_ONELINE_DESCR="Sample tests of the SDNC A1 controller restconf API using http
 #App names to include in the test, space separated list
 INCLUDED_IMAGES="RICSIM SDNC"
 
+#SUPPORTED TEST ENV FILE
+SUPPORTED_PROFILES="ONAP-MASTER ONAP-GUILIN"
+
 . ../common/testcase_common.sh  $@
 . ../common/controller_api_functions.sh
 . ../common/ricsimulator_api_functions.sh
 
 #### TEST BEGIN ####
 
+FLAVOUR="ORAN"
+if [[ $SDNC_A1_CONTROLLER_IMAGE == *"onap"* ]]; then
+    FLAVOUR="ONAP"
+fi
+
 generate_uuid
 
 #Test agent and simulator protocol versions (others are http only)
@@ -50,6 +58,9 @@ for __nb_httpx in $NB_TESTED_PROTOCOLS ; do
 
         start_ric_simulators ricsim_g1 1  OSC_2.1.0
         start_ric_simulators ricsim_g2 1  STD_1.1.3
+        if [ "$PMS_VERSION" == "V2" ]; then
+            start_ric_simulators ricsim_g3 1  STD_2.0.0
+        fi
 
         start_sdnc
 
@@ -83,9 +94,18 @@ for __nb_httpx in $NB_TESTED_PROTOCOLS ; do
         controller_api_get_A1_policy_type 200 OSC ricsim_g1_1 1 testdata/OSC/sim_1.json
         controller_api_get_A1_policy_type 404 OSC ricsim_g1_1 99
 
-        controller_api_put_A1_policy 202 OSC ricsim_g1_1 1 4000 testdata/OSC/pi1_template.json
+        RESP=202
+        if [ $FLAVOUR == "ONAP" ]; then
+            RESP=200
+        fi
+        controller_api_put_A1_policy $RESP OSC ricsim_g1_1 1 4000 testdata/OSC/pi1_template.json
         controller_api_put_A1_policy 404 OSC ricsim_g1_1 5 1001 testdata/OSC/pi1_template.json
-        controller_api_put_A1_policy 201 STD ricsim_g2_1   5000 testdata/STD/pi1_template.json
+
+        RESP=201
+        if [ $FLAVOUR == "ONAP" ]; then
+            RESP=200
+        fi
+        controller_api_put_A1_policy $RESP STD ricsim_g2_1   5000 testdata/STD/pi1_template.json
 
         controller_api_get_A1_policy_ids 200 OSC ricsim_g1_1 1 4000
         controller_api_get_A1_policy_ids 200 STD ricsim_g2_1 5000
@@ -97,8 +117,17 @@ for __nb_httpx in $NB_TESTED_PROTOCOLS ; do
         controller_api_get_A1_policy_status 200 OSC ricsim_g1_1 1 4000 "$VAL" "false"
         controller_api_get_A1_policy_status 200 STD ricsim_g2_1 5000 "UNDEFINED"
 
-        controller_api_delete_A1_policy 202 OSC ricsim_g1_1 1 4000
-        controller_api_delete_A1_policy 204 STD ricsim_g2_1 5000
+        RESP=202
+        if [ $FLAVOUR == "ONAP" ]; then
+            RESP=200
+        fi
+        controller_api_delete_A1_policy $RESP OSC ricsim_g1_1 1 4000
+
+        RESP=204
+        if [ $FLAVOUR == "ONAP" ]; then
+            RESP=200
+        fi
+        controller_api_delete_A1_policy $RESP STD ricsim_g2_1 5000
 
         check_sdnc_logs
 
index fb7bc34..61ae8d6 100755 (executable)
 #  ============LICENSE_END=================================================
 #
 
-TC_ONELINE_DESCR="Resync 10000 policies using OSC interface over REST"
+TC_ONELINE_DESCR="Resync 10000 policies using OSC and STD interface"
 
 #App names to include in the test, space separated list
 INCLUDED_IMAGES="CBS CONSUL CP CR MR PA RICSIM SDNC"
 
+#SUPPORTED TEST ENV FILE
+SUPPORTED_PROFILES="ONAP-MASTER ONAP-GUILIN"
+
 . ../common/testcase_common.sh  $@
 . ../common/agent_api_functions.sh
 . ../common/ricsimulator_api_functions.sh
@@ -44,7 +47,6 @@ for __httpx in $TESTED_PROTOCOLS ; do
         echo "#####################################################################"
 
         if [ $__httpx == "HTTPS" ]; then
-            CR_PATH="https://$CR_APP_NAME:$CR_EXTERNAL_SECURE_PORT/callbacks"
             use_cr_https
             use_simulator_https
             use_mr_https
@@ -57,7 +59,6 @@ for __httpx in $TESTED_PROTOCOLS ; do
                 use_agent_rest_https
             fi
         else
-            CR_PATH="http://$CR_APP_NAME:$CR_EXTERNAL_PORT/callbacks"
             use_cr_http
             use_simulator_http
             use_mr_http
@@ -78,6 +79,10 @@ for __httpx in $TESTED_PROTOCOLS ; do
 
         start_ric_simulators ricsim_g2 4 STD_1.1.3
 
+        if [ "$PMS_VERSION" == "V2" ]; then
+            start_ric_simulators ricsim_g3 4  STD_2.0.0
+        fi
+
         start_mr
 
         start_cr
@@ -105,67 +110,84 @@ for __httpx in $TESTED_PROTOCOLS ; do
 
         sim_print ricsim_g2_1 interface
 
+        if [ "$PMS_VERSION" == "V2" ]; then
+            sim_print ricsim_g3_1 interface
+        fi
+
         sim_put_policy_type 201 ricsim_g1_1 1 testdata/OSC/sim_1.json
 
-        api_equal json:policy_types 2 120  #Wait for the agent to refresh types from the simulator
+        if [ "$PMS_VERSION" == "V2" ]; then
+            api_equal json:policy-types 2 120  #Wait for the agent to refresh types from the simulator
+        else
+            api_equal json:policy_types 2 120  #Wait for the agent to refresh types from the simulator
+        fi
 
         api_put_service 201 "serv1" 3600 "$CR_PATH/1"
 
         START_ID=2000
-        NUM_POLICIES=10000
+        NUM_POLICIES=10000  # Must be at least 100
+
+        if [ "$PMS_VERSION" == "V2" ]; then
+            notificationurl=$CR_PATH"/test"
+        else
+            notificationurl=""
+        fi
 
         if [[ $interface == *"BATCH"* ]]; then
-            api_put_policy_batch 201 "serv1" ricsim_g1_1 1 $START_ID NOTRANSIENT testdata/OSC/pi1_template.json $NUM_POLICIES
+            api_put_policy_batch 201 "serv1" ricsim_g1_1 1 $START_ID NOTRANSIENT $notificationurl testdata/OSC/pi1_template.json $NUM_POLICIES
         else
-            api_put_policy 201 "serv1" ricsim_g1_1 1 $START_ID NOTRANSIENT testdata/OSC/pi1_template.json $NUM_POLICIES
+            api_put_policy 201 "serv1" ricsim_g1_1 1 $START_ID NOTRANSIENT $notificationurl testdata/OSC/pi1_template.json $NUM_POLICIES
         fi
 
-        sim_equal ricsim_g1_1 num_instances 10000
+        sim_equal ricsim_g1_1 num_instances $NUM_POLICIES
 
         sim_post_delete_instances 200 ricsim_g1_1
 
         sim_equal ricsim_g1_1 num_instances 0
 
-        sim_equal ricsim_g1_1 num_instances 10000 300
+        sim_equal ricsim_g1_1 num_instances $NUM_POLICIES 300
 
-        START_ID=$(($START_ID+$NUM_POLICIES))
+        START_ID2=$(($START_ID+$NUM_POLICIES))
 
         if [[ $interface == *"BATCH"* ]]; then
-            api_put_policy_batch 201 "serv1" ricsim_g2_1 NOTYPE $START_ID NOTRANSIENT testdata/STD/pi1_template.json $NUM_POLICIES
+            api_put_policy_batch 201 "serv1" ricsim_g2_1 NOTYPE $START_ID2 NOTRANSIENT $notificationurl testdata/STD/pi1_template.json $NUM_POLICIES
         else
-            api_put_policy 201 "serv1" ricsim_g2_1 NOTYPE $START_ID NOTRANSIENT testdata/STD/pi1_template.json $NUM_POLICIES
+            api_put_policy 201 "serv1" ricsim_g2_1 NOTYPE $START_ID2 NOTRANSIENT $notificationurl testdata/STD/pi1_template.json $NUM_POLICIES
         fi
-        sim_equal ricsim_g2_1 num_instances 10000
+        sim_equal ricsim_g2_1 num_instances $NUM_POLICIES
 
         sim_post_delete_instances 200 ricsim_g2_1
 
         sim_equal ricsim_g2_1 num_instances 0
 
-        sim_equal ricsim_g2_1 num_instances 10000 300
+        sim_equal ricsim_g2_1 num_instances $NUM_POLICIES 300
 
-        api_delete_policy 204 2435
+        api_delete_policy 204 $(($START_ID+47))
 
-        api_delete_policy 204 8693
+        api_delete_policy 204 $(($START_ID+$NUM_POLICIES-39))
 
         sim_post_delete_instances 200 ricsim_g1_1
 
-        sim_equal ricsim_g1_1 num_instances 9998 300
+        sim_equal ricsim_g1_1 num_instances $(($NUM_POLICIES-2)) 300
 
-        api_delete_policy 204 12435
+        api_delete_policy 204 $(($START_ID2+37))
 
-        api_delete_policy 204 18693
+        api_delete_policy 204 $(($START_ID2+$NUM_POLICIES-93))
 
-        api_delete_policy 204 18697
+        api_delete_policy 204 $(($START_ID2+$NUM_POLICIES-91))
 
         sim_post_delete_instances 200 ricsim_g2_1
 
-        sim_equal ricsim_g1_1 num_instances 9998 300
+        sim_equal ricsim_g1_1 num_instances $(($NUM_POLICIES-2)) 300
 
-        sim_equal ricsim_g2_1 num_instances 9997 300
+        sim_equal ricsim_g2_1 num_instances $(($NUM_POLICIES-3)) 300
 
-        api_equal json:policies 19995
+        api_equal json:policies $(($NUM_POLICIES-2+$NUM_POLICIES-3))
 
         check_policy_agent_logs
+        if [[ $interface = *"SDNC"* ]]; then
+            check_sdnc_logs
+        fi
 
         store_logs          "${__httpx}__${interface}"
 
index 856d6f5..3edb022 100755 (executable)
 TC_ONELINE_DESCR="Resync of RIC via changes in the consul config"
 
 #App names to include in the test, space separated list
-INCLUDED_IMAGES="CBS CONSUL CP CR MR PA RICSIM SDNC"
+INCLUDED_IMAGES="CBS CONSUL CP CR MR PA RICSIM"
+
+#SUPPORTED TEST ENV FILE
+SUPPORTED_PROFILES="ONAP-MASTER ONAP-GUILIN"
 
 . ../common/testcase_common.sh  $@
 . ../common/agent_api_functions.sh
 . ../common/ricsimulator_api_functions.sh
-. ../common/controller_api_functions.sh
+. ../common/cr_api_functions.sh
 
 #### TEST BEGIN ####
 
@@ -35,9 +38,20 @@ generate_uuid
 # Clean container and start all needed containers #
 clean_containers
 
+start_policy_agent
+
+set_agent_trace
+
+# Create service to be able to receive events when rics becomes available
+# Must use rest towards the agent since dmaap is not configured yet
+api_put_service 201 "ric-registration" 0 "$CR_PATH/ric-registration"
+
 # Start one RIC of each type
 start_ric_simulators ricsim_g1 1  OSC_2.1.0
 start_ric_simulators ricsim_g2 1  STD_1.1.3
+if [ "$PMS_VERSION" == "V2" ]; then
+    start_ric_simulators ricsim_g3 1  STD_2.0.0
+fi
 
 start_mr
 
@@ -45,37 +59,56 @@ start_cr
 
 start_consul_cbs
 
+start_control_panel
+
 prepare_consul_config      NOSDNC  ".consul_config.json"
 
 consul_config_app                  ".consul_config.json"
 
-start_control_panel
-
-start_policy_agent
+if [ "$PMS_VERSION" == "V2" ]; then
+    api_equal json:rics 3 120
 
-api_equal json:rics 2 120
+    cr_equal received_callbacks 3 120
 
+    cr_api_check_all_sync_events 200 ric-registration ricsim_g1_1 ricsim_g2_1 ricsim_g3_1
+else
+    api_equal json:rics 2 120
+fi
 
-# Add an OSC RIC and check
+# Add an STD RIC and check
 start_ric_simulators ricsim_g2 2  STD_1.1.3
 
 prepare_consul_config      NOSDNC  ".consul_config.json"
 
 consul_config_app                  ".consul_config.json"
 
-api_equal json:rics 3 120
+if [ "$PMS_VERSION" == "V2" ]; then
+    api_equal json:rics 4 120
+
+    cr_equal received_callbacks 4 120
+
+    cr_api_check_all_sync_events 200 ric-registration ricsim_g2_2
+else
+    api_equal json:rics 3 120
+fi
 
 check_policy_agent_logs
 check_control_panel_logs
 
-# Remove one OSC RIC and check
+# Remove one RIC RIC and check
 start_ric_simulators ricsim_g2 1  STD_1.1.3
 
 prepare_consul_config      NOSDNC  ".consul_config.json"
 
 consul_config_app                  ".consul_config.json"
 
-api_equal json:rics 2 120
+if [ "$PMS_VERSION" == "V2" ]; then
+    api_equal json:rics 3 120
+
+    cr_equal received_callbacks 4 120
+else
+    api_equal json:rics 2 120
+fi
 
 check_policy_agent_logs
 check_control_panel_logs
index 4b2e3cb..959f00f 100755 (executable)
@@ -22,18 +22,18 @@ TC_ONELINE_DESCR="Change supported policy types and reconfigure rics"
 #App names to include in the test, space separated list
 INCLUDED_IMAGES="CBS CONSUL CP CR MR PA RICSIM SDNC"
 
+#SUPPORTED TEST ENV FILE
+SUPPORTED_PROFILES="ONAP-MASTER ONAP-GUILIN"
+
 . ../common/testcase_common.sh  $@
 . ../common/agent_api_functions.sh
 . ../common/ricsimulator_api_functions.sh
+. ../common/cr_api_functions.sh
 
 #### TEST BEGIN ####
 
 generate_uuid
 
-#Local vars in test script
-##########################
-# Path to callback receiver
-CR_PATH="http://$CR_APP_NAME:$CR_EXTERNAL_PORT/callbacks"
 use_cr_http
 
 NUM_RICS=10
@@ -64,16 +64,14 @@ for interface in $TESTED_VARIANTS ; do
 
     start_consul_cbs
 
+    # Create first config
     if [[ $interface = *"SDNC"* ]]; then
         start_sdnc
-        prepare_consul_config      SDNC  ".consul_config_2.json"
+        prepare_consul_config      SDNC  ".consul_config_initial.json"
     else
-        prepare_consul_config      NOSDNC  ".consul_config_2.json"
+        prepare_consul_config      NOSDNC  ".consul_config_initial.json"
     fi
 
-    consul_config_app                  ".consul_config_2.json"
-
-
     # Create 2nd config and save for later
     start_ric_simulators ricsim_g1 $NUM_RICS OSC_2.1.0
 
@@ -85,11 +83,17 @@ for interface in $TESTED_VARIANTS ; do
 
     start_policy_agent
 
-    set_agent_debug
     set_agent_trace
 
     api_get_status 200
 
+    # Create service to be able to receive events when rics becomes available
+    # Must use rest towards the agent since dmaap is not configured yet
+    api_put_service 201 "ric-registration" 0 "$CR_PATH/ric-registration"
+
+    #Load first config
+    consul_config_app                  ".consul_config_initial.json"
+
     for ((i=1; i<=${NUM_RICS}; i++))
     do
         sim_print ricsim_g1_$i interface
@@ -98,6 +102,11 @@ for interface in $TESTED_VARIANTS ; do
     # All sims running but 2 are not configured in consul
     api_equal json:rics 8 120
 
+    if [ "$PMS_VERSION" == "V2" ]; then
+        cr_equal received_callbacks?id=ric-registration 8 120
+        cr_api_check_all_sync_events 200 ric-registration ricsim_g1_1 ricsim_g1_2  ricsim_g1_3 ricsim_g1_4 ricsim_g1_5 ricsim_g1_6  ricsim_g1_7  ricsim_g1_8
+    fi
+
     api_get_rics 200 NOTYPE "ricsim_g1_1:me1_ricsim_g1_1,me2_ricsim_g1_1:NOTYPE:???? \
                              ricsim_g1_2:me1_ricsim_g1_2,me2_ricsim_g1_2:NOTYPE:???? \
                              ricsim_g1_3:me1_ricsim_g1_3,me2_ricsim_g1_3:NOTYPE:???? \
@@ -136,19 +145,32 @@ for interface in $TESTED_VARIANTS ; do
     sim_put_policy_type 201 ricsim_g1_6 5 testdata/OSC/sim_5.json
     sim_put_policy_type 201 ricsim_g1_7 5 testdata/OSC/sim_5.json
     sim_put_policy_type 201 ricsim_g1_8 5 testdata/OSC/sim_5.json
-    sim_put_policy_type 201 ricsim_g1_9 5 testdata/OSC/sim_5.json
-
-    api_equal json:policy_types 5 120
 
-    echo "Check the number of types in the agent for each ric"
-    api_equal json:policy_types?ric=ricsim_g1_1 1 120
-    api_equal json:policy_types?ric=ricsim_g1_2 2 120
-    api_equal json:policy_types?ric=ricsim_g1_3 3 120
-    api_equal json:policy_types?ric=ricsim_g1_4 4 120
-    api_equal json:policy_types?ric=ricsim_g1_5 5 120
-    api_equal json:policy_types?ric=ricsim_g1_6 4 120
-    api_equal json:policy_types?ric=ricsim_g1_7 3 120
-    api_equal json:policy_types?ric=ricsim_g1_8 2 120
+    if [ "$PMS_VERSION" == "V2" ]; then
+        api_equal json:policy-types 5 120
+
+        echo "Check the number of types in the agent for each ric"
+        api_equal json:policy-types?ric_id=ricsim_g1_1 1 120
+        api_equal json:policy-types?ric_id=ricsim_g1_2 2 120
+        api_equal json:policy-types?ric_id=ricsim_g1_3 3 120
+        api_equal json:policy-types?ric_id=ricsim_g1_4 4 120
+        api_equal json:policy-types?ric_id=ricsim_g1_5 5 120
+        api_equal json:policy-types?ric_id=ricsim_g1_6 4 120
+        api_equal json:policy-types?ric_id=ricsim_g1_7 3 120
+        api_equal json:policy-types?ric_id=ricsim_g1_8 2 120
+    else
+        api_equal json:policy_types 5 120
+
+        echo "Check the number of types in the agent for each ric"
+        api_equal json:policy_types?ric=ricsim_g1_1 1 120
+        api_equal json:policy_types?ric=ricsim_g1_2 2 120
+        api_equal json:policy_types?ric=ricsim_g1_3 3 120
+        api_equal json:policy_types?ric=ricsim_g1_4 4 120
+        api_equal json:policy_types?ric=ricsim_g1_5 5 120
+        api_equal json:policy_types?ric=ricsim_g1_6 4 120
+        api_equal json:policy_types?ric=ricsim_g1_7 3 120
+        api_equal json:policy_types?ric=ricsim_g1_8 2 120
+    fi
 
     api_get_rics 200 NOTYPE "ricsim_g1_1:me1_ricsim_g1_1,me2_ricsim_g1_1:1:???? \
                              ricsim_g1_2:me1_ricsim_g1_2,me2_ricsim_g1_2:1,2:???? \
@@ -159,23 +181,50 @@ for interface in $TESTED_VARIANTS ; do
                              ricsim_g1_7:me1_ricsim_g1_7,me2_ricsim_g1_7:3,4,5:???? \
                              ricsim_g1_8:me1_ricsim_g1_8,me2_ricsim_g1_8:4,5:???? "
 
+    if [ "$PMS_VERSION" == "V2" ]; then
+        cr_equal received_callbacks?id=ric-registration 16 120
+        cr_api_check_all_sync_events 200 ric-registration ricsim_g1_1 ricsim_g1_2  ricsim_g1_3 ricsim_g1_4 ricsim_g1_5 ricsim_g1_6  ricsim_g1_7  ricsim_g1_8
+    fi
 
     #Load config with all rics
     consul_config_app                  ".consul_config_all.json"
 
     api_equal json:rics 10 120
 
-    echo "Check the number of types in the agent for each ric"
-    api_equal json:policy_types?ric=ricsim_g1_1 1 120
-    api_equal json:policy_types?ric=ricsim_g1_2 2 120
-    api_equal json:policy_types?ric=ricsim_g1_3 3 120
-    api_equal json:policy_types?ric=ricsim_g1_4 4 120
-    api_equal json:policy_types?ric=ricsim_g1_5 5 120
-    api_equal json:policy_types?ric=ricsim_g1_6 4 120
-    api_equal json:policy_types?ric=ricsim_g1_7 3 120
-    api_equal json:policy_types?ric=ricsim_g1_8 2 120
-    api_equal json:policy_types?ric=ricsim_g1_9 1 120
-    api_equal json:policy_types?ric=ricsim_g1_10 0 120
+    if [ "$PMS_VERSION" == "V2" ]; then
+        cr_equal received_callbacks?id=ric-registration 18 120
+        cr_api_check_all_sync_events 200 ric-registration ricsim_g1_9  ricsim_g1_10
+    fi
+
+    sim_put_policy_type 201 ricsim_g1_9 5 testdata/OSC/sim_5.json
+
+    if [ "$PMS_VERSION" == "V2" ]; then
+
+        echo "Check the number of types in the agent for each ric"
+        api_equal json:policy-types?ric_id=ricsim_g1_1 1 120
+        api_equal json:policy-types?ric_id=ricsim_g1_2 2 120
+        api_equal json:policy-types?ric_id=ricsim_g1_3 3 120
+        api_equal json:policy-types?ric_id=ricsim_g1_4 4 120
+        api_equal json:policy-types?ric_id=ricsim_g1_5 5 120
+        api_equal json:policy-types?ric_id=ricsim_g1_6 4 120
+        api_equal json:policy-types?ric_id=ricsim_g1_7 3 120
+        api_equal json:policy-types?ric_id=ricsim_g1_8 2 120
+        api_equal json:policy-types?ric_id=ricsim_g1_9 1 120
+        api_equal json:policy-types?ric_id=ricsim_g1_10 0 120
+    else
+
+        echo "Check the number of types in the agent for each ric"
+        api_equal json:policy_types?ric=ricsim_g1_1 1 120
+        api_equal json:policy_types?ric=ricsim_g1_2 2 120
+        api_equal json:policy_types?ric=ricsim_g1_3 3 120
+        api_equal json:policy_types?ric=ricsim_g1_4 4 120
+        api_equal json:policy_types?ric=ricsim_g1_5 5 120
+        api_equal json:policy_types?ric=ricsim_g1_6 4 120
+        api_equal json:policy_types?ric=ricsim_g1_7 3 120
+        api_equal json:policy_types?ric=ricsim_g1_8 2 120
+        api_equal json:policy_types?ric=ricsim_g1_9 1 120
+        api_equal json:policy_types?ric=ricsim_g1_10 0 120
+    fi
 
     api_get_rics 200 NOTYPE "ricsim_g1_1:me1_ricsim_g1_1,me2_ricsim_g1_1:1:???? \
                              ricsim_g1_2:me1_ricsim_g1_2,me2_ricsim_g1_2:1,2:???? \
@@ -188,34 +237,60 @@ for interface in $TESTED_VARIANTS ; do
                              ricsim_g1_9:me1_ricsim_g1_9,me2_ricsim_g1_9:5:???? \
                              ricsim_g1_10:me1_ricsim_g1_10,me2_ricsim_g1_10:NOTYPE:???? "
 
+    if [ "$PMS_VERSION" == "V2" ]; then
+        cr_equal received_callbacks?id=ric-registration 19 120
+        cr_api_check_all_sync_events 200 ric-registration ricsim_g1_9
+    fi
 
     #No policy type in sim #10
 
-    api_equal json:policy_types 5
+    if [ "$PMS_VERSION" == "V2" ]; then
+        api_equal json:policy-types 5
+    else
+        api_equal json:policy_types 5
+    fi
 
     api_put_service 201 "serv1" 3600 "$CR_PATH/serv1"
 
-    api_put_policy 201 "serv1" ricsim_g1_9 5 2000 NOTRANSIENT testdata/OSC/pi5_template.json 1
-
-    api_equal json:policy_ids 1
-
-    sim_equal ricsim_g1_9 num_instances 1
+    if [ "$PMS_VERSION" == "V2" ]; then
+        notificationurl=$CR_PATH"/test"
+    else
+        notificationurl=""
+    fi
 
+    sleep_wait 120
 
     # Load config with reduced number of rics
-    consul_config_app                  ".consul_config_2.json"
+    consul_config_app                  ".consul_config_initial.json"
 
     api_equal json:rics 8 120
 
-    echo "Check the number of types in the agent for each ric"
-    api_equal json:policy_types?ric=ricsim_g1_1 1 120
-    api_equal json:policy_types?ric=ricsim_g1_2 2 120
-    api_equal json:policy_types?ric=ricsim_g1_3 3 120
-    api_equal json:policy_types?ric=ricsim_g1_4 4 120
-    api_equal json:policy_types?ric=ricsim_g1_5 5 120
-    api_equal json:policy_types?ric=ricsim_g1_6 4 120
-    api_equal json:policy_types?ric=ricsim_g1_7 3 120
-    api_equal json:policy_types?ric=ricsim_g1_8 2 120
+    if [ "$PMS_VERSION" == "V2" ]; then
+        cr_equal received_callbacks?id=ric-registration 19 120
+        cr_api_check_all_sync_events 200 ric-registration EMPTY
+    fi
+
+    if [ "$PMS_VERSION" == "V2" ]; then
+        echo "Check the number of types in the agent for each ric"
+        api_equal json:policy-types?ric_id=ricsim_g1_1 1 120
+        api_equal json:policy-types?ric_id=ricsim_g1_2 2 120
+        api_equal json:policy-types?ric_id=ricsim_g1_3 3 120
+        api_equal json:policy-types?ric_id=ricsim_g1_4 4 120
+        api_equal json:policy-types?ric_id=ricsim_g1_5 5 120
+        api_equal json:policy-types?ric_id=ricsim_g1_6 4 120
+        api_equal json:policy-types?ric_id=ricsim_g1_7 3 120
+        api_equal json:policy-types?ric_id=ricsim_g1_8 2 120
+    else
+        echo "Check the number of types in the agent for each ric"
+        api_equal json:policy_types?ric=ricsim_g1_1 1 120
+        api_equal json:policy_types?ric=ricsim_g1_2 2 120
+        api_equal json:policy_types?ric=ricsim_g1_3 3 120
+        api_equal json:policy_types?ric=ricsim_g1_4 4 120
+        api_equal json:policy_types?ric=ricsim_g1_5 5 120
+        api_equal json:policy_types?ric=ricsim_g1_6 4 120
+        api_equal json:policy_types?ric=ricsim_g1_7 3 120
+        api_equal json:policy_types?ric=ricsim_g1_8 2 120
+    fi
 
     api_get_rics 200 NOTYPE "ricsim_g1_1:me1_ricsim_g1_1,me2_ricsim_g1_1:1:???? \
                              ricsim_g1_2:me1_ricsim_g1_2,me2_ricsim_g1_2:1,2:???? \
@@ -228,30 +303,44 @@ for interface in $TESTED_VARIANTS ; do
 
     sleep_wait 120
 
-    api_equal json:policy_ids 0
+    if [ "$PMS_VERSION" == "V2" ]; then
+        api_equal json:policy-instances 0
+    else
+        api_equal json:policy_ids 0
+    fi
 
     api_get_policy_types 404 ricsim_g1_9
 
-    sim_equal ricsim_g1_9 num_instances 0
-
-    api_delete_policy 404 2000
-
     # Load config with all rics
     consul_config_app                  ".consul_config_all.json"
 
     api_equal json:rics 10 120
 
-    echo "Check the number of types in the agent for each ric"
-    api_equal json:policy_types?ric=ricsim_g1_1 1 120
-    api_equal json:policy_types?ric=ricsim_g1_2 2 120
-    api_equal json:policy_types?ric=ricsim_g1_3 3 120
-    api_equal json:policy_types?ric=ricsim_g1_4 4 120
-    api_equal json:policy_types?ric=ricsim_g1_5 5 120
-    api_equal json:policy_types?ric=ricsim_g1_6 4 120
-    api_equal json:policy_types?ric=ricsim_g1_7 3 120
-    api_equal json:policy_types?ric=ricsim_g1_8 2 120
-    api_equal json:policy_types?ric=ricsim_g1_9 1 120
-    api_equal json:policy_types?ric=ricsim_g1_10 0 120
+    if [ "$PMS_VERSION" == "V2" ]; then
+        echo "Check the number of types in the agent for each ric"
+        api_equal json:policy-types?ric_id=ricsim_g1_1 1 120
+        api_equal json:policy-types?ric_id=ricsim_g1_2 2 120
+        api_equal json:policy-types?ric_id=ricsim_g1_3 3 120
+        api_equal json:policy-types?ric_id=ricsim_g1_4 4 120
+        api_equal json:policy-types?ric_id=ricsim_g1_5 5 120
+        api_equal json:policy-types?ric_id=ricsim_g1_6 4 120
+        api_equal json:policy-types?ric_id=ricsim_g1_7 3 120
+        api_equal json:policy-types?ric_id=ricsim_g1_8 2 120
+        api_equal json:policy-types?ric_id=ricsim_g1_9 1 120
+        api_equal json:policy-types?ric_id=ricsim_g1_10 0 120
+    else
+        echo "Check the number of types in the agent for each ric"
+        api_equal json:policy_types?ric=ricsim_g1_1 1 120
+        api_equal json:policy_types?ric=ricsim_g1_2 2 120
+        api_equal json:policy_types?ric=ricsim_g1_3 3 120
+        api_equal json:policy_types?ric=ricsim_g1_4 4 120
+        api_equal json:policy_types?ric=ricsim_g1_5 5 120
+        api_equal json:policy_types?ric=ricsim_g1_6 4 120
+        api_equal json:policy_types?ric=ricsim_g1_7 3 120
+        api_equal json:policy_types?ric=ricsim_g1_8 2 120
+        api_equal json:policy_types?ric=ricsim_g1_9 1 120
+        api_equal json:policy_types?ric=ricsim_g1_10 0 120
+    fi
 
     api_get_rics 200 NOTYPE "ricsim_g1_1:me1_ricsim_g1_1,me2_ricsim_g1_1:1:???? \
                              ricsim_g1_2:me1_ricsim_g1_2,me2_ricsim_g1_2:1,2:???? \
@@ -266,7 +355,11 @@ for interface in $TESTED_VARIANTS ; do
 
     sleep_wait 120
 
-    api_equal json:policy_ids 0
+    if [ "$PMS_VERSION" == "V2" ]; then
+        api_equal json:policy-instances 0
+    else
+        api_equal json:policy_ids 0
+    fi
 
     sim_equal ricsim_g1_9 num_instances 0
 
@@ -278,16 +371,29 @@ for interface in $TESTED_VARIANTS ; do
 
     sleep_wait 120
 
-    api_equal json:policy_types?ric=ricsim_g1_1 1 120
-    api_equal json:policy_types?ric=ricsim_g1_2 2 120
-    api_equal json:policy_types?ric=ricsim_g1_3 3 120
-    api_equal json:policy_types?ric=ricsim_g1_4 3 120
-    api_equal json:policy_types?ric=ricsim_g1_5 4 120
-    api_equal json:policy_types?ric=ricsim_g1_6 3 120
-    api_equal json:policy_types?ric=ricsim_g1_7 2 120
-    api_equal json:policy_types?ric=ricsim_g1_8 2 120
-    api_equal json:policy_types?ric=ricsim_g1_9 1 120
-    api_equal json:policy_types?ric=ricsim_g1_10 0 120
+    if [ "$PMS_VERSION" == "V2" ]; then
+        api_equal json:policy-types?ric_id=ricsim_g1_1 1 120
+        api_equal json:policy-types?ric_id=ricsim_g1_2 2 120
+        api_equal json:policy-types?ric_id=ricsim_g1_3 3 120
+        api_equal json:policy-types?ric_id=ricsim_g1_4 3 120
+        api_equal json:policy-types?ric_id=ricsim_g1_5 4 120
+        api_equal json:policy-types?ric_id=ricsim_g1_6 3 120
+        api_equal json:policy-types?ric_id=ricsim_g1_7 2 120
+        api_equal json:policy-types?ric_id=ricsim_g1_8 2 120
+        api_equal json:policy-types?ric_id=ricsim_g1_9 1 120
+        api_equal json:policy-types?ric_id=ricsim_g1_10 0 120
+    else
+        api_equal json:policy_types?ric=ricsim_g1_1 1 120
+        api_equal json:policy_types?ric=ricsim_g1_2 2 120
+        api_equal json:policy_types?ric=ricsim_g1_3 3 120
+        api_equal json:policy_types?ric=ricsim_g1_4 3 120
+        api_equal json:policy_types?ric=ricsim_g1_5 4 120
+        api_equal json:policy_types?ric=ricsim_g1_6 3 120
+        api_equal json:policy_types?ric=ricsim_g1_7 2 120
+        api_equal json:policy_types?ric=ricsim_g1_8 2 120
+        api_equal json:policy_types?ric=ricsim_g1_9 1 120
+        api_equal json:policy_types?ric=ricsim_g1_10 0 120
+    fi
 
     api_get_rics 200 NOTYPE "ricsim_g1_1:me1_ricsim_g1_1,me2_ricsim_g1_1:1:???? \
                              ricsim_g1_2:me1_ricsim_g1_2,me2_ricsim_g1_2:1,2:???? \
@@ -302,7 +408,11 @@ for interface in $TESTED_VARIANTS ; do
 
     sim_delete_policy_type 204 ricsim_g1_8 4
 
-    api_equal json:policy_types?ric=ricsim_g1_8 1 120
+    if [ "$PMS_VERSION" == "V2" ]; then
+        api_equal json:policy-types?ric_id=ricsim_g1_8 1 120
+    else
+        api_equal json:policy_types?ric=ricsim_g1_8 1 120
+    fi
 
     api_get_rics 200 NOTYPE "ricsim_g1_1:me1_ricsim_g1_1,me2_ricsim_g1_1:1:???? \
                             ricsim_g1_2:me1_ricsim_g1_2,me2_ricsim_g1_2:1,2:???? \
@@ -318,14 +428,15 @@ for interface in $TESTED_VARIANTS ; do
 
 
     check_policy_agent_logs
+    if [[ $interface = *"SDNC"* ]]; then
+        check_sdnc_logs
+    fi
+
     store_logs          ${interface}
 
 done
 
 
-
-
-
 #### TEST COMPLETE ####
 
 
index 25678be..b7e49d4 100755 (executable)
@@ -22,9 +22,13 @@ TC_ONELINE_DESCR="Create 10000 policies in sequence using http/https and Agent R
 #App names to include in the test, space separated list
 INCLUDED_IMAGES="CBS CONSUL CP CR MR PA RICSIM SDNC"
 
+#SUPPORTED TEST ENV FILE
+SUPPORTED_PROFILES="ONAP-MASTER ONAP-GUILIN"
+
 . ../common/testcase_common.sh  $@
 . ../common/agent_api_functions.sh
 . ../common/ricsimulator_api_functions.sh
+. ../common/cr_api_functions.sh
 
 #### TEST BEGIN ####
 
@@ -40,6 +44,7 @@ TESTED_VARIANTS="NOSDNC   SDNC"
 
 #Test agent and simulator protocol versions (others are http only)
 TESTED_PROTOCOLS="HTTP HTTPS"
+
 for __httpx in $TESTED_PROTOCOLS ; do
     for interface in $TESTED_VARIANTS ; do
 
@@ -50,15 +55,11 @@ for __httpx in $TESTED_PROTOCOLS ; do
         echo "#####################################################################"
 
         if [ $__httpx == "HTTPS" ]; then
-            # Path to callback receiver
-            CR_PATH="https://$CR_APP_NAME:$CR_EXTERNAL_SECURE_PORT/callbacks"
             use_cr_https
             use_simulator_https
             use_mr_https
             use_agent_rest_https
         else
-            # Path to callback receiver
-            CR_PATH="http://$CR_APP_NAME:$CR_EXTERNAL_PORT/callbacks"
             use_cr_http
             use_simulator_http
             use_mr_http
@@ -72,6 +73,9 @@ for __httpx in $TESTED_PROTOCOLS ; do
 
         start_ric_simulators ricsim_g1 1 OSC_2.1.0
         start_ric_simulators ricsim_g2 1 STD_1.1.3
+        if [ "$PMS_VERSION" == "V2" ]; then
+            start_ric_simulators ricsim_g3 1  STD_2.0.0
+        fi
 
         start_mr
 
@@ -94,7 +98,6 @@ for __httpx in $TESTED_PROTOCOLS ; do
 
         set_agent_debug
 
-        cr_equal received_callbacks 0
         mr_equal requests_submitted 0
 
 
@@ -102,16 +105,30 @@ for __httpx in $TESTED_PROTOCOLS ; do
 
         sim_print ricsim_g1_1 interface
         sim_print ricsim_g2_1 interface
+        if [ "$PMS_VERSION" == "V2" ]; then
+            sim_print ricsim_g3_1 interface
+        fi
 
         sim_put_policy_type 201 ricsim_g1_1 1 testdata/OSC/sim_1.json
 
+        if [ "$PMS_VERSION" == "V2" ]; then
+            sim_put_policy_type 201 ricsim_g3_1 STD_QOS2_0.1.0 testdata/STD2/sim_qos2.json
 
-        api_equal json:policy_types 2 120  #Wait for the agent to refresh types from the simulators
+            api_equal json:policy-types 3 120  #Wait for the agent to refresh types from the simulators
+        else
+            api_equal json:policy_types 2 120  #Wait for the agent to refresh types from the simulators
+        fi
 
         api_put_service 201 "serv1" 3600 "$CR_PATH/1"
 
+        if [ "$PMS_VERSION" == "V2" ]; then
+            notificationurl=$CR_PATH"/test"
+        else
+            notificationurl=""
+        fi
+
         start_timer "Create polices in OSC via agent REST and $interface using "$__httpx
-        api_put_policy 201 "serv1" ricsim_g1_1 1 $START_ID NOTRANSIENT testdata/OSC/pi1_template.json $NUM_POLICIES
+        api_put_policy 201 "serv1" ricsim_g1_1 1 $START_ID NOTRANSIENT $notificationurl testdata/OSC/pi1_template.json $NUM_POLICIES
         print_timer "Create polices in OSC via agent REST and $interface using "$__httpx
 
         sim_equal ricsim_g1_1 num_instances $NUM_POLICIES
@@ -119,11 +136,22 @@ for __httpx in $TESTED_PROTOCOLS ; do
         START_ID=$(($START_ID+$NUM_POLICIES))
 
         start_timer "Create polices in STD via agent REST and $interface using "$__httpx
-        api_put_policy 201 "serv1" ricsim_g2_1 NOTYPE $START_ID NOTRANSIENT testdata/STD/pi1_template.json $NUM_POLICIES
+        api_put_policy 201 "serv1" ricsim_g2_1 NOTYPE $START_ID NOTRANSIENT $notificationurl testdata/STD/pi1_template.json $NUM_POLICIES
         print_timer "Create polices in STD via agent REST and $interface using "$__httpx
 
         sim_equal ricsim_g2_1 num_instances $NUM_POLICIES
 
+        if [ "$PMS_VERSION" == "V2" ]; then
+
+            START_ID=$(($START_ID+$NUM_POLICIES))
+
+            start_timer "Create polices in STD 2 via agent REST and $interface using "$__httpx
+            api_put_policy 201 "serv1" ricsim_g3_1 STD_QOS2_0.1.0 $START_ID NOTRANSIENT $notificationurl testdata/STD2/pi_qos2_template.json $NUM_POLICIES
+            print_timer "Create polices in STD via agent REST and $interface using "$__httpx
+
+            sim_equal ricsim_g3_1 num_instances $NUM_POLICIES
+        fi
+
         if [ $__httpx == "HTTPS" ]; then
             echo "Using secure ports towards dmaap"
             use_agent_dmaap_https
@@ -135,7 +163,7 @@ for __httpx in $TESTED_PROTOCOLS ; do
         START_ID=$(($START_ID+$NUM_POLICIES))
 
         start_timer "Create polices in OSC via agent DMAAP, one by one, and $interface using "$__httpx
-        api_put_policy 201 "serv1" ricsim_g1_1 1 $START_ID NOTRANSIENT testdata/OSC/pi1_template.json $NUM_POLICIES
+        api_put_policy 201 "serv1" ricsim_g1_1 1 $START_ID NOTRANSIENT $notificationurl testdata/OSC/pi1_template.json $NUM_POLICIES
         print_timer "Create polices in OSC via agent DMAAP, one by one, and $interface using "$__httpx
 
         sim_equal ricsim_g1_1 num_instances $((2*$NUM_POLICIES))
@@ -143,15 +171,26 @@ for __httpx in $TESTED_PROTOCOLS ; do
         START_ID=$(($START_ID+$NUM_POLICIES))
 
         start_timer "Create polices in STD via agent DMAAP, one by one, and $interface using "$__httpx
-        api_put_policy 201 "serv1" ricsim_g2_1 NOTYPE $START_ID NOTRANSIENT testdata/STD/pi1_template.json $NUM_POLICIES
+        api_put_policy 201 "serv1" ricsim_g2_1 NOTYPE $START_ID NOTRANSIENT $notificationurl testdata/STD/pi1_template.json $NUM_POLICIES
         print_timer "Create polices in STD via agent DMAAP, one by one, and $interface using "$__httpx
 
         sim_equal ricsim_g2_1 num_instances $((2*$NUM_POLICIES))
 
+        if [ "$PMS_VERSION" == "V2" ]; then
+
+            START_ID=$(($START_ID+$NUM_POLICIES))
+
+            start_timer "Create polices in STD 2 via agent DMAAP, one by one, and $interface using "$__httpx
+            api_put_policy 201 "serv1" ricsim_g3_1 STD_QOS2_0.1.0 $START_ID NOTRANSIENT $notificationurl testdata/STD2/pi_qos2_template.json $NUM_POLICIES
+            print_timer "Create polices in STD via agent DMAAP, one by one, and $interface using "$__httpx
+
+            sim_equal ricsim_g3_1 num_instances $((2*$NUM_POLICIES))
+        fi
+
         START_ID=$(($START_ID+$NUM_POLICIES))
 
         start_timer "Create polices in OSC via agent DMAAP in batch and $interface using "$__httpx
-        api_put_policy_batch 201 "serv1" ricsim_g1_1 1 $START_ID NOTRANSIENT testdata/OSC/pi1_template.json $NUM_POLICIES
+        api_put_policy_batch 201 "serv1" ricsim_g1_1 1 $START_ID NOTRANSIENT $notificationurl testdata/OSC/pi1_template.json $NUM_POLICIES
         print_timer "Create polices in OSC via agent DMAAP in batch and $interface using "$__httpx
 
         sim_equal ricsim_g1_1 num_instances $((3*$NUM_POLICIES))
@@ -159,20 +198,40 @@ for __httpx in $TESTED_PROTOCOLS ; do
         START_ID=$(($START_ID+$NUM_POLICIES))
 
         start_timer "Create polices in STD via agent DMAAP in batch and $interface using "$__httpx
-        api_put_policy_batch 201 "serv1" ricsim_g2_1 NOTYPE $START_ID NOTRANSIENT testdata/STD/pi1_template.json $NUM_POLICIES
+        api_put_policy_batch 201 "serv1" ricsim_g2_1 NOTYPE $START_ID NOTRANSIENT $notificationurl testdata/STD/pi1_template.json $NUM_POLICIES
         print_timer "Create polices in STD via agent DMAAP in batch and $interface using "$__httpx
 
         sim_equal ricsim_g2_1 num_instances $((3*$NUM_POLICIES))
 
+        if [ "$PMS_VERSION" == "V2" ]; then
+
+            START_ID=$(($START_ID+$NUM_POLICIES))
+
+            start_timer "Create polices in STD via agent DMAAP in batch and $interface using "$__httpx
+            api_put_policy_batch 201 "serv1" ricsim_g3_1 STD_QOS2_0.1.0 $START_ID NOTRANSIENT $notificationurl testdata/STD2/pi_qos2_template.json $NUM_POLICIES
+            print_timer "Create polices in STD via agent DMAAP in batch and $interface using "$__httpx
+
+            sim_equal ricsim_g3_1 num_instances $((3*$NUM_POLICIES))
+        fi
+
         if [ $interface == "SDNC" ]; then
             sim_contains_str ricsim_g1_1 remote_hosts "a1-controller"
             sim_contains_str ricsim_g2_1 remote_hosts "a1-controller"
+            if [ "$PMS_VERSION" == "V2" ]; then
+                sim_contains_str ricsim_g3_1 remote_hosts "a1-controller"
+            fi
         else
             sim_contains_str ricsim_g1_1 remote_hosts "policy-agent"
             sim_contains_str ricsim_g2_1 remote_hosts "policy-agent"
+            if [ "$PMS_VERSION" == "V2" ]; then
+                sim_contains_str ricsim_g3_1 remote_hosts "policy-agent"
+            fi
         fi
 
         check_policy_agent_logs
+        if [[ $interface = *"SDNC"* ]]; then
+            check_sdnc_logs
+        fi
 
         store_logs          "${__httpx}__${interface}"
     done
index 009efc0..3dd2a0e 100755 (executable)
@@ -22,9 +22,13 @@ TC_ONELINE_DESCR="Repeatedly create and delete policies in each RICs for 24h (or
 #App names to include in the test, space separated list
 INCLUDED_IMAGES="CBS CONSUL CP CR MR PA RICSIM SDNC"
 
+#SUPPORTED TEST ENV FILE
+SUPPORTED_PROFILES="ONAP-MASTER ONAP-GUILIN"
+
 . ../common/testcase_common.sh  $@
 . ../common/agent_api_functions.sh
 . ../common/ricsimulator_api_functions.sh
+. ../common/cr_api_functions.sh
 
 #### TEST BEGIN ####
 
@@ -35,6 +39,10 @@ generate_uuid
 
 # Number of RICs per interface type (OSC and STD)
 NUM_RICS=30
+if [ "$PMS_VERSION" == "V2" ]; then
+   NUM_RICS=20 # 3 A1 interfaces test, less sims per interface. total sims will be same
+fi
+
 # Number of policy instances per RIC
 NUM_INSTANCES=5
 
@@ -46,15 +54,11 @@ clean_containers
 HTTPX=HTTPS
 
 if [ $HTTPX == "HTTP" ]; then
-   # Path to callback receiver
-   CR_PATH="http://$CR_APP_NAME:$CR_EXTERNAL_PORT/callbacks"
    use_cr_http
    use_agent_rest_http
    use_sdnc_http
    use_simulator_http
 else
-   # Path to callback receiver
-   CR_PATH="https://$CR_APP_NAME:$CR_EXTERNAL_SECURE_PORT/callbacks"
    use_cr_https
    use_agent_rest_https
    use_sdnc_https
@@ -65,6 +69,10 @@ start_ric_simulators ricsim_g1 $NUM_RICS OSC_2.1.0
 
 start_ric_simulators ricsim_g2 $NUM_RICS STD_1.1.3
 
+if [ "$PMS_VERSION" == "V2" ]; then
+   start_ric_simulators ricsim_g3 $NUM_RICS  STD_2.0.0
+fi
+
 start_mr
 
 start_cr
@@ -95,12 +103,28 @@ do
    sim_print ricsim_g2_$i interface
 done
 
+if [ "$PMS_VERSION" == "V2" ]; then
+   echo "Print the interface for group 2 simulators, shall be STD 2"
+   for ((i=1; i<=$NUM_RICS; i++))
+   do
+      sim_print ricsim_g3_$i interface
+   done
+fi
+
 echo "Load policy type in group 1 simulators"
 for ((i=1; i<=$NUM_RICS; i++))
 do
    sim_put_policy_type 201 ricsim_g1_$i 1 testdata/OSC/sim_1.json
 done
 
+if [ "$PMS_VERSION" == "V2" ]; then
+   echo "Load policy type in group 3 simulators"
+   for ((i=1; i<=$NUM_RICS; i++))
+   do
+      sim_put_policy_type 201 ricsim_g3_$i STD_QOS2_0.1.0 testdata/STD2/sim_qos2.json
+   done
+fi
+
 echo "Check the number of instances in  group 1 simulators, shall be 0"
 for ((i=1; i<=$NUM_RICS; i++))
 do
@@ -113,13 +137,30 @@ do
    sim_equal ricsim_g2_$i num_instances 0
 done
 
+if [ "$PMS_VERSION" == "V2" ]; then
+   echo "Check the number of instances in group 3 simulators, shall be 0"
+   for ((i=1; i<=$NUM_RICS; i++))
+   do
+      sim_equal ricsim_g3_$i num_instances 0
+   done
+fi
+
 echo "Wait for the agent to refresh types from the simulator"
-api_equal json:policy_types 2 120
+if [ "$PMS_VERSION" == "V2" ]; then
+   api_equal json:policy-types 3 120
+else
+   api_equal json:policy_types 2 120
+fi
 
 echo "Check the number of types in the agent for each ric is 1"
 for ((i=1; i<=$NUM_RICS; i++))
 do
-   api_equal json:policy_types?ric=ricsim_g1_$i 1 120
+   if [ "$PMS_VERSION" == "V2" ]; then
+      api_equal json:policy-types?ric_id=ricsim_g1_$i 1 120
+      api_equal json:policy-types?ric_id=ricsim_g3_$i 1 120
+   else
+      api_equal json:policy_types?ric=ricsim_g1_$i 1 120
+   fi
 done
 
 echo "Register a service"
@@ -132,6 +173,12 @@ AGENT_INTERFACES="REST REST_PARALLEL DMAAP DMAAP-BATCH"
 
 MR_MESSAGES=0
 
+if [ "$PMS_VERSION" == "V2" ]; then
+      notificationurl=$CR_PATH"/test"
+else
+      notificationurl=""
+fi
+
 while [ $(($SECONDS-$TEST_START)) -lt $TEST_DURATION ]; do
 
     echo ""
@@ -166,14 +213,14 @@ while [ $(($SECONDS-$TEST_START)) -lt $TEST_DURATION ]; do
       INSTANCE_ID=200000
       INSTANCES=0
       if [ $interface == "REST_PARALLEL" ]; then
-         api_put_policy_parallel 201 "serv1" ricsim_g1_ $NUM_RICS 1 $INSTANCE_ID NOTRANSIENT testdata/OSC/pi1_template.json $NUM_INSTANCES 3
+         api_put_policy_parallel 201 "serv1" ricsim_g1_ $NUM_RICS 1 $INSTANCE_ID NOTRANSIENT $notificationurl testdata/OSC/pi1_template.json $NUM_INSTANCES 3
       fi
       for ((i=1; i<=$NUM_RICS; i++))
       do
          if [ $interface == "DMAAP-BATCH" ]; then
-            api_put_policy_batch 201 "serv1" ricsim_g1_$i 1 $INSTANCE_ID NOTRANSIENT testdata/OSC/pi1_template.json $NUM_INSTANCES
+            api_put_policy_batch 201 "serv1" ricsim_g1_$i 1 $INSTANCE_ID NOTRANSIENT $notificationurl testdata/OSC/pi1_template.json $NUM_INSTANCES
          elif [ $interface == "DMAAP" ] || [ $interface == "REST" ]; then
-            api_put_policy 201 "serv1" ricsim_g1_$i 1 $INSTANCE_ID NOTRANSIENT testdata/OSC/pi1_template.json $NUM_INSTANCES
+            api_put_policy 201 "serv1" ricsim_g1_$i 1 $INSTANCE_ID NOTRANSIENT $notificationurl testdata/OSC/pi1_template.json $NUM_INSTANCES
          fi
          if [ $interface == "DMAAP" ] || [ $interface == "DMAAP-BATCH" ]; then
             MR_MESSAGES=$(($MR_MESSAGES+$NUM_INSTANCES))
@@ -183,18 +230,22 @@ while [ $(($SECONDS-$TEST_START)) -lt $TEST_DURATION ]; do
          INSTANCES=$(($INSTANCES+$NUM_INSTANCES))
       done
 
-      api_equal json:policy_ids $INSTANCES
+      if [ "$PMS_VERSION" == "V2" ]; then
+         api_equal json:policy-instances $INSTANCES
+      else
+         api_equal json:policy_ids $INSTANCES
+      fi
 
       echo "Create $NUM_INSTANCES instances in each STD RIC"
       if [ $interface == "REST_PARALLEL" ]; then
-         api_put_policy_parallel 201 "serv1" ricsim_g2_ $NUM_RICS NOTYPE $INSTANCE_ID NOTRANSIENT testdata/STD/pi1_template.json $NUM_INSTANCES 3
+         api_put_policy_parallel 201 "serv1" ricsim_g2_ $NUM_RICS NOTYPE $INSTANCE_ID NOTRANSIENT $notificationurl testdata/STD/pi1_template.json $NUM_INSTANCES 3
       fi
       for ((i=1; i<=$NUM_RICS; i++))
       do
          if [ $interface == "DMAAP-BATCH" ]; then
-            api_put_policy_batch 201 "serv1" ricsim_g2_$i NOTYPE $INSTANCE_ID NOTRANSIENT testdata/STD/pi1_template.json $NUM_INSTANCES
+            api_put_policy_batch 201 "serv1" ricsim_g2_$i NOTYPE $INSTANCE_ID NOTRANSIENT $notificationurl testdata/STD/pi1_template.json $NUM_INSTANCES
          elif [ $interface == "DMAAP" ] || [ $interface == "REST" ]; then
-            api_put_policy 201 "serv1" ricsim_g2_$i NOTYPE $INSTANCE_ID NOTRANSIENT testdata/STD/pi1_template.json $NUM_INSTANCES
+            api_put_policy 201 "serv1" ricsim_g2_$i NOTYPE $INSTANCE_ID NOTRANSIENT $notificationurl testdata/STD/pi1_template.json $NUM_INSTANCES
          fi
          if [ $interface == "DMAAP" ] || [ $interface == "DMAAP-BATCH" ]; then
             MR_MESSAGES=$(($MR_MESSAGES+$NUM_INSTANCES))
@@ -204,7 +255,38 @@ while [ $(($SECONDS-$TEST_START)) -lt $TEST_DURATION ]; do
          INSTANCES=$(($INSTANCES+$NUM_INSTANCES))
       done
 
-      api_equal json:policy_ids $INSTANCES
+      if [ "$PMS_VERSION" == "V2" ]; then
+         api_equal json:policy-instances $INSTANCES
+      else
+         api_equal json:policy_ids $INSTANCES
+      fi
+
+      if [ "$PMS_VERSION" == "V2" ]; then
+         echo "Create $NUM_INSTANCES instances in each STD 2 RIC"
+         if [ $interface == "REST_PARALLEL" ]; then
+            api_put_policy_parallel 201 "serv1" ricsim_g3_ $NUM_RICS STD_QOS2_0.1.0 $INSTANCE_ID NOTRANSIENT $notificationurl testdata/STD2/pi_qos2_template.json $NUM_INSTANCES 3
+         fi
+         for ((i=1; i<=$NUM_RICS; i++))
+         do
+            if [ $interface == "DMAAP-BATCH" ]; then
+               api_put_policy_batch 201 "serv1" ricsim_g3_$i STD_QOS2_0.1.0 $INSTANCE_ID NOTRANSIENT $notificationurl testdata/STD2/pi_qos2_template.json $NUM_INSTANCES
+            elif [ $interface == "DMAAP" ] || [ $interface == "REST" ]; then
+               api_put_policy 201 "serv1" ricsim_g3_$i STD_QOS2_0.1.0 $INSTANCE_ID NOTRANSIENT $notificationurl testdata/STD2/pi_qos2_template.json $NUM_INSTANCES
+            fi
+            if [ $interface == "DMAAP" ] || [ $interface == "DMAAP-BATCH" ]; then
+               MR_MESSAGES=$(($MR_MESSAGES+$NUM_INSTANCES))
+            fi
+            sim_equal ricsim_g3_$i num_instances $NUM_INSTANCES
+            INSTANCE_ID=$(($INSTANCE_ID+$NUM_INSTANCES))
+            INSTANCES=$(($INSTANCES+$NUM_INSTANCES))
+         done
+
+         if [ "$PMS_VERSION" == "V2" ]; then
+            api_equal json:policy-instances $INSTANCES
+         else
+            api_equal json:policy_ids $INSTANCES
+         fi
+      fi
 
 
       echo "Delete all instances in each OSC RIC"
@@ -228,7 +310,11 @@ while [ $(($SECONDS-$TEST_START)) -lt $TEST_DURATION ]; do
          INSTANCE_ID=$(($INSTANCE_ID+$NUM_INSTANCES))
       done
 
-      api_equal json:policy_ids $INSTANCES
+      if [ "$PMS_VERSION" == "V2" ]; then
+         api_equal json:policy-instances $INSTANCES
+      else
+         api_equal json:policy_ids $INSTANCES
+      fi
 
       echo "Delete all instances in each STD RIC"
 
@@ -250,9 +336,39 @@ while [ $(($SECONDS-$TEST_START)) -lt $TEST_DURATION ]; do
          INSTANCE_ID=$(($INSTANCE_ID+$NUM_INSTANCES))
       done
 
-      api_equal json:policy_ids 0
+      if [ "$PMS_VERSION" == "V2" ]; then
+         api_equal json:policy-instances $INSTANCES
+      else
+         api_equal json:policy_ids $INSTANCES
+      fi
 
-      cr_equal received_callbacks 0
+      if [ "$PMS_VERSION" == "V2" ]; then
+         echo "Delete all instances in each STD 2 RIC"
+
+         if [ $interface == "REST_PARALLEL" ]; then
+            api_delete_policy_parallel 204 $NUM_RICS $INSTANCE_ID $NUM_INSTANCES 3
+         fi
+         for ((i=1; i<=$NUM_RICS; i++))
+         do
+            if [ $interface == "DMAAP-BATCH" ]; then
+               api_delete_policy_batch 204 $INSTANCE_ID $NUM_INSTANCES
+            elif [ $interface == "DMAAP" ] || [ $interface == "REST" ]; then
+               api_delete_policy 204 $INSTANCE_ID $NUM_INSTANCES
+            fi
+            if [ $interface == "DMAAP" ] || [ $interface == "DMAAP-BATCH" ]; then
+               MR_MESSAGES=$(($MR_MESSAGES+$NUM_INSTANCES))
+            fi
+            INSTANCES=$(($INSTANCES-$NUM_INSTANCES))
+            sim_equal ricsim_g3_$i num_instances 0
+            INSTANCE_ID=$(($INSTANCE_ID+$NUM_INSTANCES))
+         done
+
+         if [ "$PMS_VERSION" == "V2" ]; then
+            api_equal json:policy-instances $INSTANCES
+         else
+            api_equal json:policy_ids $INSTANCES
+         fi
+      fi
 
       mr_equal requests_submitted $MR_MESSAGES
       mr_equal requests_fetched $MR_MESSAGES
@@ -266,6 +382,10 @@ while [ $(($SECONDS-$TEST_START)) -lt $TEST_DURATION ]; do
       do
          sim_contains_str ricsim_g1_$i remote_hosts "a1-controller"
          sim_contains_str ricsim_g2_$i remote_hosts "a1-controller"
+
+         if [ "$PMS_VERSION" == "V2" ]; then
+            sim_contains_str ricsim_g3_$i remote_hosts "a1-controller"
+         fi
       done
 
    done
@@ -273,6 +393,7 @@ while [ $(($SECONDS-$TEST_START)) -lt $TEST_DURATION ]; do
 done
 
 check_policy_agent_logs
+check_sdnc_logs
 
 #### TEST COMPLETE ####
 
index 7391331..c6f61d7 100755 (executable)
 TC_ONELINE_DESCR="Create/delete policies in parallel over a number of ric using a number of child process"
 
 #App names to include in the test, space separated list
-INCLUDED_IMAGES="CBS CONSUL, CP, CR, MR, PA, RICSIM, SDNC"
+INCLUDED_IMAGES="CBS CONSUL CP CR MR PA RICSIM SDNC"
+
+#SUPPORTED TEST ENV FILE
+SUPPORTED_PROFILES="ONAP-MASTER ONAP-GUILIN"
 
 . ../common/testcase_common.sh  $@
 . ../common/agent_api_functions.sh
@@ -42,6 +45,12 @@ NUM_POLICIES_PER_RIC=500
 
 generate_uuid
 
+if [ "$PMS_VERSION" == "V2" ]; then
+    notificationurl=$CR_PATH"/test"
+else
+    notificationurl=""
+fi
+
 for __httpx in $TESTED_PROTOCOLS ; do
     for interface in $TESTED_VARIANTS ; do
 
@@ -52,7 +61,6 @@ for __httpx in $TESTED_PROTOCOLS ; do
         echo "#####################################################################"
 
         if [ $__httpx == "HTTPS" ]; then
-            CR_PATH="https://$CR_APP_NAME:$CR_EXTERNAL_SECURE_PORT/callbacks"
             use_cr_https
             use_simulator_https
             use_mr_https
@@ -61,7 +69,6 @@ for __httpx in $TESTED_PROTOCOLS ; do
             fi
             use_agent_rest_https
         else
-            CR_PATH="http://$CR_APP_NAME:$CR_EXTERNAL_PORT/callbacks"
             use_cr_http
             use_simulator_http
             use_mr_http
@@ -89,6 +96,8 @@ for __httpx in $TESTED_PROTOCOLS ; do
 
         start_mr # Not used, but removes error messages from the agent log
 
+        start_cr
+
         start_control_panel
 
         start_policy_agent
@@ -108,22 +117,29 @@ for __httpx in $TESTED_PROTOCOLS ; do
             sim_put_policy_type 201 ricsim_g1_$i 1 testdata/OSC/sim_1.json
         done
 
-
-        api_equal json:policy_types 1 120  #Wait for the agent to refresh types from the simulator
+        if [ "$PMS_VERSION" == "V2" ]; then
+            api_equal json:policy-types 1 120  #Wait for the agent to refresh types from the simulator
+        else
+            api_equal json:policy_types 1 120  #Wait for the agent to refresh types from the simulator
+        fi
 
         api_put_service 201 "serv1" 600 "$CR_PATH/1"
 
         echo "Check the number of types in the agent for each ric is 1"
         for ((i=1; i<=$NUM_RICS; i++))
         do
-            api_equal json:policy_types?ric=ricsim_g1_$i 1 120
+            if [ "$PMS_VERSION" == "V2" ]; then
+                api_equal json:policy-types?ric_id=ricsim_g1_$i 1 120
+            else
+                api_equal json:policy_types?ric=ricsim_g1_$i 1 120
+            fi
         done
 
         START_ID=2000
 
         start_timer "Create $((NUM_POLICIES_PER_RIC*$NUM_RICS)) polices over $interface using "$__httpx
 
-        api_put_policy_parallel 201 "serv1" ricsim_g1_ $NUM_RICS 1 $START_ID NOTRANSIENT testdata/OSC/pi1_template.json $NUM_POLICIES_PER_RIC 7
+        api_put_policy_parallel 201 "serv1" ricsim_g1_ $NUM_RICS 1 $START_ID NOTRANSIENT $notificationurl testdata/OSC/pi1_template.json $NUM_POLICIES_PER_RIC 7
 
         print_timer "Create $((NUM_POLICIES_PER_RIC*$NUM_RICS)) polices over $interface using "$__httpx
 
@@ -158,6 +174,9 @@ for __httpx in $TESTED_PROTOCOLS ; do
         done
 
         check_policy_agent_logs
+        if [[ $interface = *"SDNC"* ]]; then
+            check_sdnc_logs
+        fi
 
         store_logs          "${__httpx}__${interface}"
 
index 3256797..f7e91e3 100755 (executable)
@@ -22,18 +22,15 @@ TC_ONELINE_DESCR="Preparation for test of the Control Panel and the Health Check
 #App names to include in the test, space separated list
 INCLUDED_IMAGES="CBS CONSUL CP CR MR PA RICSIM"
 
+#SUPPORTED TEST ENV FILE
+SUPPORTED_PROFILES="ONAP-MASTER ONAP-GUILIN"
+
 . ../common/testcase_common.sh $@
 . ../common/agent_api_functions.sh
 . ../common/ricsimulator_api_functions.sh
 
 #### TEST BEGIN ####
 
-#Local vars in test script
-##########################
-# Path to callback receiver
-CR_PATH="http://$CR_APP_NAME:$CR_EXTERNAL_PORT/callbacks"
-use_cr_http
-
 clean_containers
 
 OSC_NUM_RICS=6
@@ -43,6 +40,10 @@ start_ric_simulators  $RIC_SIM_PREFIX"_g1" $OSC_NUM_RICS OSC_2.1.0
 
 start_ric_simulators  $RIC_SIM_PREFIX"_g2" $STD_NUM_RICS STD_1.1.3
 
+if [ "$PMS_VERSION" == "V2" ]; then
+    start_ric_simulators  $RIC_SIM_PREFIX"_g3" $STD_NUM_RICS STD_2.0.0
+fi
+
 start_mr #Just to prevent errors in the agent log...
 
 start_control_panel
@@ -71,6 +72,13 @@ do
     sim_print $RIC_SIM_PREFIX"_g2_"$i interface
 done
 
+if [ "$PMS_VERSION" == "V2" ]; then
+    # Print the A1 version for STD 2.X
+    for ((i=1; i<=$STD_NUM_RICS; i++))
+    do
+        sim_print $RIC_SIM_PREFIX"_g3_"$i interface
+    done
+fi
 
 # Load the polictypes in osc
 for ((i=1; i<=$OSC_NUM_RICS; i++))
@@ -82,36 +90,83 @@ done
 
 
 #Check the number of schemas and the individual schemas in OSC
-api_equal json:policy_types 4 120
-
-for ((i=1; i<=$OSC_NUM_RICS; i++))
-do
-    api_equal json:policy_types?ric=$RIC_SIM_PREFIX"_g1_"$i 3 120
-done
-
-# Check the schemas in OSC
-for ((i=1; i<=$OSC_NUM_RICS; i++))
-do
-    api_get_policy_schema 200 2 testdata/OSC/hw-agent-modified.json
-    api_get_policy_schema 200 100 testdata/OSC/qos-agent-modified.json
-    api_get_policy_schema 200 20008 testdata/OSC/tsa-agent-modified.json
-done
-
+if [ "$PMS_VERSION" == "V2" ]; then
+    api_equal json:policy-types 4 120
+
+    for ((i=1; i<=$OSC_NUM_RICS; i++))
+    do
+        api_equal json:policy-types?ric_id=$RIC_SIM_PREFIX"_g1_"$i 3 120
+    done
+
+    # Check the schemas in OSC
+    for ((i=1; i<=$OSC_NUM_RICS; i++))
+    do
+        api_get_policy_type 200 2 testdata/OSC/hw-agent-modified.json
+        api_get_policy_type 200 100 testdata/OSC/qos-agent-modified.json
+        api_get_policy_type 200 20008 testdata/OSC/tsa-agent-modified.json
+    done
+else
+    api_equal json:policy_types 4 120
+
+    for ((i=1; i<=$OSC_NUM_RICS; i++))
+    do
+        api_equal json:policy_types?ric=$RIC_SIM_PREFIX"_g1_"$i 3 120
+    done
+
+    # Check the schemas in OSC
+    for ((i=1; i<=$OSC_NUM_RICS; i++))
+    do
+        api_get_policy_schema 200 2 testdata/OSC/hw-agent-modified.json
+        api_get_policy_schema 200 100 testdata/OSC/qos-agent-modified.json
+        api_get_policy_schema 200 20008 testdata/OSC/tsa-agent-modified.json
+    done
+fi
+
+if [ "$PMS_VERSION" == "V2" ]; then
+
+    # Load the polictypes in std
+    for ((i=1; i<=$STD_NUM_RICS; i++))
+    do
+        sim_put_policy_type 201 $RIC_SIM_PREFIX"_g3_"$i STD_QOS_0_2_0 demo-testdata/STD2/sim_qos.json
+        sim_put_policy_type 201 $RIC_SIM_PREFIX"_g3_"$i STD_QOS2_0.1.0 demo-testdata/STD2/sim_qos2.json
+    done
+
+    #Check the number of schemas and the individual schemas in STD
+    api_equal json:policy-types 6 120
+
+    for ((i=1; i<=$STD_NUM_RICS; i++))
+    do
+        api_equal json:policy-types?ric_id=$RIC_SIM_PREFIX"_g3_"$i 2 120
+    done
+
+    # Check the schemas in STD
+    for ((i=1; i<=$STD_NUM_RICS; i++))
+    do
+        api_get_policy_type 200 STD_QOS_0_2_0 demo-testdata/STD2/qos-agent-modified.json
+        api_get_policy_type 200 'STD_QOS2_0.1.0' demo-testdata/STD2/qos2-agent-modified.json
+    done
+fi
 
 # Create policies
 use_agent_rest_http
 
 api_put_service 201 "Emergency-response-app" 0 "$CR_PATH/1"
 
+if [ "$PMS_VERSION" == "V2" ]; then
+    notificationurl=$CR_PATH"/test"
+else
+    notificationurl=""
+fi
+
 # Create policies in OSC
 for ((i=1; i<=$OSC_NUM_RICS; i++))
 do
     generate_uuid
-    api_put_policy 201 "Emergency-response-app" $RIC_SIM_PREFIX"_g1_"$i 2 $((2000+$i)) NOTRANSIENT testdata/OSC/pihw_template.json 1
+    api_put_policy 201 "Emergency-response-app" $RIC_SIM_PREFIX"_g1_"$i 2 $((2000+$i)) NOTRANSIENT $notificationurl testdata/OSC/pihw_template.json 1
     generate_uuid
-    api_put_policy 201 "Emergency-response-app" $RIC_SIM_PREFIX"_g1_"$i 100 $((3000+$i)) NOTRANSIENT testdata/OSC/piqos_template.json 1
+    api_put_policy 201 "Emergency-response-app" $RIC_SIM_PREFIX"_g1_"$i 100 $((3000+$i)) NOTRANSIENT $notificationurl testdata/OSC/piqos_template.json 1
     generate_uuid
-    api_put_policy 201 "Emergency-response-app" $RIC_SIM_PREFIX"_g1_"$i 20008 $((4000+$i)) NOTRANSIENT testdata/OSC/pitsa_template.json 1
+    api_put_policy 201 "Emergency-response-app" $RIC_SIM_PREFIX"_g1_"$i 20008 $((4000+$i)) NOTRANSIENT $notificationurl testdata/OSC/pitsa_template.json 1
 done
 
 
@@ -126,7 +181,13 @@ done
 for ((i=1; i<=$STD_NUM_RICS; i++))
 do
     generate_uuid
-    api_put_policy 201 "Emergency-response-app" $RIC_SIM_PREFIX"_g2_"$i NOTYPE $((2100+$i)) NOTRANSIENT testdata/STD/pi1_template.json 1
+    api_put_policy 201 "Emergency-response-app" $RIC_SIM_PREFIX"_g2_"$i NOTYPE $((2100+$i)) NOTRANSIENT $notificationurl testdata/STD/pi1_template.json 1
+    if [ "$PMS_VERSION" == "V2" ]; then
+        generate_uuid
+        api_put_policy 201 "Emergency-response-app" $RIC_SIM_PREFIX"_g3_"$i STD_QOS_0_2_0 $((2300+$i)) NOTRANSIENT $notificationurl demo-testdata/STD2/pi1_template.json 1
+        generate_uuid
+        api_put_policy 201 "Emergency-response-app" $RIC_SIM_PREFIX"_g3_"$i 'STD_QOS2_0.1.0' $((2400+$i)) NOTRANSIENT $notificationurl demo-testdata/STD2/pi1_template.json 1
+    fi
 done
 
 
@@ -134,6 +195,9 @@ done
 for ((i=1; i<=$STD_NUM_RICS; i++))
 do
     sim_equal $RIC_SIM_PREFIX"_g2_"$i num_instances 1
+    if [ "$PMS_VERSION" == "V2" ]; then
+        sim_equal $RIC_SIM_PREFIX"_g3_"$i num_instances 2
+    fi
 done
 
 check_policy_agent_logs
index 3696d56..3e0858f 100755 (executable)
@@ -22,6 +22,9 @@ TC_ONELINE_DESCR="Preparation demo setup  - populating a number of ric simulator
 #App names to include in the test, space separated list
 INCLUDED_IMAGES="CBS CONSUL CP CR MR PA RICSIM SDNC"
 
+#SUPPORTED TEST ENV FILE
+SUPPORTED_PROFILES="ONAP-MASTER ONAP-GUILIN"
+
 . ../common/testcase_common.sh $@
 . ../common/agent_api_functions.sh
 . ../common/ricsimulator_api_functions.sh
@@ -30,12 +33,16 @@ INCLUDED_IMAGES="CBS CONSUL CP CR MR PA RICSIM SDNC"
 
 #Local vars in test script
 ##########################
-# Path to callback receiver
-CR_PATH="http://$CR_APP_NAME:$CR_EXTERNAL_PORT/callbacks"
-use_cr_http
-use_agent_rest_http
-use_sdnc_http
-use_simulator_http
+
+if [ "$PMS_VERSION" == "V2" ]; then
+    notificationurl=$CR_PATH"/test"
+else
+    notificationurl=""
+fi
+
+use_agent_rest_https
+use_sdnc_https
+use_simulator_https
 
 clean_containers
 
@@ -46,12 +53,15 @@ start_ric_simulators  $RIC_SIM_PREFIX"_g1" $OSC_NUM_RICS OSC_2.1.0
 
 start_ric_simulators  $RIC_SIM_PREFIX"_g2" $STD_NUM_RICS STD_1.1.3
 
+if [ "$PMS_VERSION" == "V2" ]; then
+    start_ric_simulators $RIC_SIM_PREFIX"_g3" $STD_NUM_RICS STD_2.0.0
+fi
+
 start_mr #Just to prevent errors in the agent log...
 
 start_control_panel
 
-CR_PATH="https://$CR_APP_NAME:$CR_EXTERNAL_SECURE_PORT/callbacks"
-use_cr_http
+start_control_panel
 
 start_sdnc
 
@@ -62,6 +72,8 @@ consul_config_app                  ".consul_config.json"
 
 start_policy_agent
 
+set_agent_trace
+
 api_get_status 200
 
 # Print the A1 version for OSC
@@ -71,12 +83,20 @@ do
 done
 
 
-# Print the A1 version for STD
+# Print the A1 version for STD 1.X
 for ((i=1; i<=$STD_NUM_RICS; i++))
 do
     sim_print $RIC_SIM_PREFIX"_g2_"$i interface
 done
 
+if [ "$PMS_VERSION" == "V2" ]; then
+    # Print the A1 version for STD 2.X
+    for ((i=1; i<=$STD_NUM_RICS; i++))
+    do
+        sim_print $RIC_SIM_PREFIX"_g3_"$i interface
+    done
+fi
+
 
 # Load the polictypes in osc
 for ((i=1; i<=$OSC_NUM_RICS; i++))
@@ -87,19 +107,71 @@ done
 
 
 #Check the number of schemas and the individual schemas in OSC
-api_equal json:policy_types 3 120
+if [ "$PMS_VERSION" == "V2" ]; then
 
-for ((i=1; i<=$OSC_NUM_RICS; i++))
-do
-    api_equal json:policy_types?ric=$RIC_SIM_PREFIX"_g1_"$i 2 120
-done
+    api_equal json:policy-types 3 120
 
-# Check the schemas in OSC
-for ((i=1; i<=$OSC_NUM_RICS; i++))
-do
-    api_get_policy_schema 200 100 demo-testdata/OSC/qos-agent-modified.json
-    api_get_policy_schema 200 20008 demo-testdata/OSC/tsa-agent-modified.json
-done
+    for ((i=1; i<=$OSC_NUM_RICS; i++))
+    do
+        api_equal json:policy-types?ric_id=$RIC_SIM_PREFIX"_g1_"$i 2 120
+    done
+
+    # Check the schemas in OSC
+    for ((i=1; i<=$OSC_NUM_RICS; i++))
+    do
+        api_get_policy_type 200 100 demo-testdata/OSC/qos-agent-modified.json
+        api_get_policy_type 200 20008 demo-testdata/OSC/tsa-agent-modified.json
+    done
+else
+    api_equal json:policy_types 3 120
+
+    for ((i=1; i<=$OSC_NUM_RICS; i++))
+    do
+        api_equal json:policy_types?ric=$RIC_SIM_PREFIX"_g1_"$i 2 120
+    done
+
+    # Check the schemas in OSC
+    for ((i=1; i<=$OSC_NUM_RICS; i++))
+    do
+        api_get_policy_schema 200 100 demo-testdata/OSC/qos-agent-modified.json
+        api_get_policy_schema 200 20008 demo-testdata/OSC/tsa-agent-modified.json
+    done
+fi
+
+
+
+
+if [ "$PMS_VERSION" == "V2" ]; then
+
+    # Load the polictypes in std
+    for ((i=1; i<=$STD_NUM_RICS; i++))
+    do
+        sim_put_policy_type 201 $RIC_SIM_PREFIX"_g3_"$i STD_QOS_0_2_0 demo-testdata/STD2/sim_qos.json
+        sim_put_policy_type 201 $RIC_SIM_PREFIX"_g3_"$i STD_QOS2_0.1.0 demo-testdata/STD2/sim_qos2.json
+    done
+
+    #Check the number of schemas and the individual schemas in STD
+    api_equal json:policy-types 5 120
+
+    for ((i=1; i<=$STD_NUM_RICS; i++))
+    do
+        api_equal json:policy-types?ric_id=$RIC_SIM_PREFIX"_g3_"$i 2 120
+    done
+
+    # Check the schemas in STD
+    for ((i=1; i<=$STD_NUM_RICS; i++))
+    do
+        api_get_policy_type 200 STD_QOS_0_2_0 demo-testdata/STD2/qos-agent-modified.json
+        api_get_policy_type 200 'STD_QOS2_0.1.0' demo-testdata/STD2/qos2-agent-modified.json
+    done
+fi
+
+#Check the number of types
+if [ "$PMS_VERSION" == "V2" ]; then
+    api_equal json:policy-types 5 120
+else
+    api_equal json:policy_types 3 120
+fi
 
 
 # Create policies
@@ -111,9 +183,9 @@ api_put_service 201 "Emergency-response-app" 0 "$CR_PATH/1"
 for ((i=1; i<=$OSC_NUM_RICS; i++))
 do
     generate_uuid
-    api_put_policy 201 "Emergency-response-app" $RIC_SIM_PREFIX"_g1_"$i 100 $((3000+$i)) NOTRANSIENT demo-testdata/OSC/piqos_template.json 1
+    api_put_policy 201 "Emergency-response-app" $RIC_SIM_PREFIX"_g1_"$i 100 $((3000+$i)) NOTRANSIENT $notificationurl demo-testdata/OSC/piqos_template.json 1
     generate_uuid
-    api_put_policy 201 "Emergency-response-app" $RIC_SIM_PREFIX"_g1_"$i 20008 $((4000+$i)) NOTRANSIENT demo-testdata/OSC/pitsa_template.json 1
+    api_put_policy 201 "Emergency-response-app" $RIC_SIM_PREFIX"_g1_"$i 20008 $((4000+$i)) NOTRANSIENT $notificationurl demo-testdata/OSC/pitsa_template.json 1
 done
 
 
@@ -128,7 +200,13 @@ done
 for ((i=1; i<=$STD_NUM_RICS; i++))
 do
     generate_uuid
-    api_put_policy 201 "Emergency-response-app" $RIC_SIM_PREFIX"_g2_"$i NOTYPE $((2100+$i)) NOTRANSIENT demo-testdata/STD/pi1_template.json 1
+    api_put_policy 201 "Emergency-response-app" $RIC_SIM_PREFIX"_g2_"$i NOTYPE $((2100+$i)) NOTRANSIENT $notificationurl demo-testdata/STD/pi1_template.json 1
+    if [ "$PMS_VERSION" == "V2" ]; then
+        generate_uuid
+        api_put_policy 201 "Emergency-response-app" $RIC_SIM_PREFIX"_g3_"$i STD_QOS_0_2_0 $((2300+$i)) NOTRANSIENT $notificationurl demo-testdata/STD2/pi1_template.json 1
+        generate_uuid
+        api_put_policy 201 "Emergency-response-app" $RIC_SIM_PREFIX"_g3_"$i 'STD_QOS2_0.1.0' $((2400+$i)) NOTRANSIENT $notificationurl demo-testdata/STD2/pi1_template.json 1
+    fi
 done
 
 
@@ -136,9 +214,13 @@ done
 for ((i=1; i<=$STD_NUM_RICS; i++))
 do
     sim_equal $RIC_SIM_PREFIX"_g2_"$i num_instances 1
+    if [ "$PMS_VERSION" == "V2" ]; then
+        sim_equal $RIC_SIM_PREFIX"_g3_"$i num_instances 2
+    fi
 done
 
 check_policy_agent_logs
+check_sdnc_logs
 
 #### TEST COMPLETE ####
 
index 0429e36..95e523c 100644 (file)
@@ -4,7 +4,7 @@ A few of the bash scripts are so called 'suites', These suite scripts calls a se
 
 ## Automated test scripts
 There are two types of scripts, filenames in the format FTCXXX.sh test one or more components of the Non-RT RIC. Filenames in the format SuiteZZZZ.sh tests a number of FTCXXX.sh script as one suite. (XXX is an integer selected from the categories described further below).
-FTC is short for Function Test Case.
+FTC is short for Function Test Case. In addition, there are also other test scripts with other naming format used for demo setup etc (e.g PM_DEMO.sh).
 
 The requirements, in terms of the execution enviroment, to run a script or a suite is to have docker, docker-compose and python3 installed (the scripts warns if not installed).
 The scripts have been tested to work on both MacOS and Ubuntu. They should work also in git bash on windows but not yet verified.
@@ -24,7 +24,7 @@ Each test script prints out the overall result of the tests in the end of the ex
 The test scripts produce quite a number of logs; all container logs, a log of all http/htps calls from the test scripts including the payload, some configuration created during test and also a test case log (same as what is printed on the screen during execution). All these logs are stored in `logs/FTCXXX/`. So each test script is using its own log directory.
 
 ## Test case categories
-The test script are number using these basic categories.
+The test script are number using these basic categories where 0-999 are releated to the policy managment and 1000-1999 are related to enrichment management.
 
 1-99 - Basic sanity tests
 
similarity index 77%
rename from test/auto-test/Suite-all.sh
rename to test/auto-test/Suite-policy-all.sh
index 9a51d3b..c032d2d 100755 (executable)
@@ -24,24 +24,17 @@ TS_ONELINE_DESCR="Test suite - all test cases except the stab test(s)"
 suite_setup
 
 ############# TEST CASES #################
-ARG1=$1
-
-./FTC1.sh $ARG1
-
-if [ $ARG1 == "remote-remove" ]; then
-    #Prevent image removal for every test case
-    ARG1="remote"
-fi
-
-./FTC10.sh $ARG1
-./FTC100.sh $ARG1
-./FTC110.sh $ARG1
-./FTC150.sh $ARG1
-./FTC300.sh $ARG1
-./FTC310.sh $ARG1
-./FTC350.sh $ARG1
-./FTC800.sh $ARG1
-./FTC850.sh $ARG1
+
+./FTC1.sh $@
+./FTC10.sh $@
+./FTC100.sh $@
+./FTC110.sh $@
+./FTC150.sh $@
+./FTC300.sh $@
+./FTC310.sh $@
+./FTC350.sh $@
+./FTC800.sh $@
+./FTC850.sh $@
 
 ##########################################
 
similarity index 86%
rename from test/auto-test/Suite-interfaces.sh
rename to test/auto-test/Suite-policy-interfaces.sh
index 7a21646..afa3b66 100755 (executable)
@@ -27,15 +27,9 @@ suite_setup
 
 ARG1=$1
 
-./FTC100.sh $ARG1
-
-if [ $ARG1 == "remote-remove" ]; then
-    #Prevent image removal for every test case
-    ARG1="remote"
-fi
-
-./FTC110.sh $ARG1
-./FTC150.sh $ARG1
+./FTC100.sh $@
+./FTC110.sh $@
+./FTC150.sh $@
 
 ##########################################
 
diff --git a/test/auto-test/demo-testdata/STD2/pi1_template.json b/test/auto-test/demo-testdata/STD2/pi1_template.json
new file mode 100644 (file)
index 0000000..e06b031
--- /dev/null
@@ -0,0 +1,9 @@
+{
+  "scope": {
+    "ueId": "ueXXX",
+    "qosId": "qosXXX"
+  },
+  "qosObjectives": {
+    "priorityLevel": XXX
+  }
+}
\ No newline at end of file
@@ -1,45 +1,36 @@
 {
-  "name": "pt1",
-  "description": "pt1 policy type",
-  "policy_type_id": 1,
-  "create_schema": {
     "$schema": "http://json-schema.org/draft-07/schema#",
-    "title": "OSC_Type1_1.0.0",
-    "description": "Type 1 policy type",
+    "description": "STD QOS policy type",
+    "title": "STD_QOS_0_2_0",
     "type": "object",
     "properties": {
-      "scope": {
+      "qosObjectives": {
+        "additionalProperties": false,
         "type": "object",
         "properties": {
-          "ueId": {
-            "type": "string"
-          },
-          "qosId": {
-            "type": "string"
+          "priorityLevel": {
+            "type": "number"
           }
         },
-        "additionalProperties": false,
         "required": [
-          "ueId",
-          "qosId"
+          "priorityLevel"
         ]
       },
-      "qosObjective": {
+      "scope": {
+        "additionalProperties": false,
         "type": "object",
         "properties": {
-          "priorityLevel": {
-            "type": "number"
+          "qosId": {
+            "type": "string"
+          },
+          "ueId": {
+            "type": "string"
           }
         },
-        "additionalProperties": false,
         "required": [
-          "priorityLevel"
+          "ueId",
+          "qosId"
         ]
       }
-    },
-    "additionalProperties": false,
-    "required": [
-      "scope", "qosObjective"
-    ]
-  }
-}
+    }
+  }
\ No newline at end of file
diff --git a/test/auto-test/demo-testdata/STD2/qos2-agent-modified.json b/test/auto-test/demo-testdata/STD2/qos2-agent-modified.json
new file mode 100644 (file)
index 0000000..43b056b
--- /dev/null
@@ -0,0 +1,36 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "description": "STD QOS2 policy type",
+  "title": "STD_QOS2_0.1.0",
+  "type": "object",
+  "properties": {
+    "qosObjectives": {
+      "additionalProperties": false,
+      "type": "object",
+      "properties": {
+        "priorityLevel": {
+          "type": "number"
+        }
+      },
+      "required": [
+        "priorityLevel"
+      ]
+    },
+    "scope": {
+      "additionalProperties": false,
+      "type": "object",
+      "properties": {
+        "qosId": {
+          "type": "string"
+        },
+        "ueId": {
+          "type": "string"
+        }
+      },
+      "required": [
+        "ueId",
+        "qosId"
+      ]
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/auto-test/demo-testdata/STD2/sim_qos.json b/test/auto-test/demo-testdata/STD2/sim_qos.json
new file mode 100644 (file)
index 0000000..931498c
--- /dev/null
@@ -0,0 +1,56 @@
+{
+    "policySchema": {
+      "$schema": "http://json-schema.org/draft-07/schema#",
+      "title": "STD_QOS_0_2_0",
+      "description": "STD QOS policy type",
+      "type": "object",
+      "properties": {
+        "scope": {
+          "type": "object",
+          "properties": {
+            "ueId": {
+              "type": "string"
+            },
+            "qosId": {
+              "type": "string"
+            }
+          },
+          "additionalProperties": false,
+          "required": [
+            "ueId",
+            "qosId"
+          ]
+        },
+        "qosObjectives": {
+          "type": "object",
+          "properties": {
+            "priorityLevel": {
+              "type": "number"
+            }
+          },
+          "additionalProperties": false,
+          "required": [
+            "priorityLevel"
+          ]
+        }
+      }
+    },
+    "statusSchema": {
+      "$schema": "http://json-schema.org/draft-07/schema#",
+      "title": "STD_QOS_0.2.0",
+      "description": "STD QOS policy type status",
+      "type": "object",
+      "properties": {
+        "enforceStatus": {
+          "type": "string"
+        },
+        "enforceReason": {
+          "type": "string"
+        },
+        "additionalProperties": false,
+        "required": [
+          "enforceStatus"
+        ]
+      }
+    }
+  }
\ No newline at end of file
diff --git a/test/auto-test/demo-testdata/STD2/sim_qos2.json b/test/auto-test/demo-testdata/STD2/sim_qos2.json
new file mode 100644 (file)
index 0000000..355ff8b
--- /dev/null
@@ -0,0 +1,56 @@
+{
+    "policySchema": {
+      "$schema": "http://json-schema.org/draft-07/schema#",
+      "title": "STD_QOS2_0.1.0",
+      "description": "STD QOS2 policy type",
+      "type": "object",
+      "properties": {
+        "scope": {
+          "type": "object",
+          "properties": {
+            "ueId": {
+              "type": "string"
+            },
+            "qosId": {
+              "type": "string"
+            }
+          },
+          "additionalProperties": false,
+          "required": [
+            "ueId",
+            "qosId"
+          ]
+        },
+        "qosObjectives": {
+          "type": "object",
+          "properties": {
+            "priorityLevel": {
+              "type": "number"
+            }
+          },
+          "additionalProperties": false,
+          "required": [
+            "priorityLevel"
+          ]
+        }
+      }
+    },
+    "statusSchema": {
+      "$schema": "http://json-schema.org/draft-07/schema#",
+      "title": "STD_QOS_0.2.0",
+      "description": "STD QOS policy type status",
+      "type": "object",
+      "properties": {
+        "enforceStatus": {
+          "type": "string"
+        },
+        "enforceReason": {
+          "type": "string"
+        },
+        "additionalProperties": false,
+        "required": [
+          "enforceStatus"
+        ]
+      }
+    }
+  }
\ No newline at end of file
diff --git a/test/auto-test/testdata/STD2/pi_qos2_template.json b/test/auto-test/testdata/STD2/pi_qos2_template.json
new file mode 100644 (file)
index 0000000..28a7fba
--- /dev/null
@@ -0,0 +1,8 @@
+{
+  "scope": {
+    "qosId": "qosXXX"
+  },
+  "qosObjectives": {
+    "priorityLevel": XXX
+  }
+}
\ No newline at end of file
diff --git a/test/auto-test/testdata/STD2/pi_qos_template.json b/test/auto-test/testdata/STD2/pi_qos_template.json
new file mode 100644 (file)
index 0000000..e06b031
--- /dev/null
@@ -0,0 +1,9 @@
+{
+  "scope": {
+    "ueId": "ueXXX",
+    "qosId": "qosXXX"
+  },
+  "qosObjectives": {
+    "priorityLevel": XXX
+  }
+}
\ No newline at end of file
diff --git a/test/auto-test/testdata/STD2/qos-agent-modified.json b/test/auto-test/testdata/STD2/qos-agent-modified.json
new file mode 100644 (file)
index 0000000..3748b79
--- /dev/null
@@ -0,0 +1,36 @@
+{
+    "$schema": "http://json-schema.org/draft-07/schema#",
+    "description": "STD QOS policy type",
+    "title": "STD_QOS_0_2_0",
+    "type": "object",
+    "properties": {
+      "qosObjectives": {
+        "additionalProperties": false,
+        "type": "object",
+        "properties": {
+          "priorityLevel": {
+            "type": "number"
+          }
+        },
+        "required": [
+          "priorityLevel"
+        ]
+      },
+      "scope": {
+        "additionalProperties": false,
+        "type": "object",
+        "properties": {
+          "qosId": {
+            "type": "string"
+          },
+          "ueId": {
+            "type": "string"
+          }
+        },
+        "required": [
+          "ueId",
+          "qosId"
+        ]
+      }
+    }
+  }
\ No newline at end of file
diff --git a/test/auto-test/testdata/STD2/qos2-agent-modified.json b/test/auto-test/testdata/STD2/qos2-agent-modified.json
new file mode 100644 (file)
index 0000000..1423a23
--- /dev/null
@@ -0,0 +1,32 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "description": "STD QOS2 policy type",
+  "title": "STD_QOS2_0.1.0",
+  "type": "object",
+  "properties": {
+    "qosObjectives": {
+      "additionalProperties": false,
+      "type": "object",
+      "properties": {
+        "priorityLevel": {
+          "type": "number"
+        }
+      },
+      "required": [
+        "priorityLevel"
+      ]
+    },
+    "scope": {
+      "additionalProperties": false,
+      "type": "object",
+      "properties": {
+        "qosId": {
+          "type": "string"
+        }
+      },
+      "required": [
+        "qosId"
+      ]
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/auto-test/testdata/STD2/sim_qos.json b/test/auto-test/testdata/STD2/sim_qos.json
new file mode 100644 (file)
index 0000000..931498c
--- /dev/null
@@ -0,0 +1,56 @@
+{
+    "policySchema": {
+      "$schema": "http://json-schema.org/draft-07/schema#",
+      "title": "STD_QOS_0_2_0",
+      "description": "STD QOS policy type",
+      "type": "object",
+      "properties": {
+        "scope": {
+          "type": "object",
+          "properties": {
+            "ueId": {
+              "type": "string"
+            },
+            "qosId": {
+              "type": "string"
+            }
+          },
+          "additionalProperties": false,
+          "required": [
+            "ueId",
+            "qosId"
+          ]
+        },
+        "qosObjectives": {
+          "type": "object",
+          "properties": {
+            "priorityLevel": {
+              "type": "number"
+            }
+          },
+          "additionalProperties": false,
+          "required": [
+            "priorityLevel"
+          ]
+        }
+      }
+    },
+    "statusSchema": {
+      "$schema": "http://json-schema.org/draft-07/schema#",
+      "title": "STD_QOS_0.2.0",
+      "description": "STD QOS policy type status",
+      "type": "object",
+      "properties": {
+        "enforceStatus": {
+          "type": "string"
+        },
+        "enforceReason": {
+          "type": "string"
+        },
+        "additionalProperties": false,
+        "required": [
+          "enforceStatus"
+        ]
+      }
+    }
+  }
\ No newline at end of file
diff --git a/test/auto-test/testdata/STD2/sim_qos2.json b/test/auto-test/testdata/STD2/sim_qos2.json
new file mode 100644 (file)
index 0000000..f60ed89
--- /dev/null
@@ -0,0 +1,52 @@
+{
+    "policySchema": {
+      "$schema": "http://json-schema.org/draft-07/schema#",
+      "title": "STD_QOS2_0.1.0",
+      "description": "STD QOS2 policy type",
+      "type": "object",
+      "properties": {
+        "scope": {
+          "type": "object",
+          "properties": {
+            "qosId": {
+              "type": "string"
+            }
+          },
+          "additionalProperties": false,
+          "required": [
+            "qosId"
+          ]
+        },
+        "qosObjectives": {
+          "type": "object",
+          "properties": {
+            "priorityLevel": {
+              "type": "number"
+            }
+          },
+          "additionalProperties": false,
+          "required": [
+            "priorityLevel"
+          ]
+        }
+      }
+    },
+    "statusSchema": {
+      "$schema": "http://json-schema.org/draft-07/schema#",
+      "title": "STD_QOS_0.2.0",
+      "description": "STD QOS policy type status",
+      "type": "object",
+      "properties": {
+        "enforceStatus": {
+          "type": "string"
+        },
+        "enforceReason": {
+          "type": "string"
+        },
+        "additionalProperties": false,
+        "required": [
+          "enforceStatus"
+        ]
+      }
+    }
+  }
\ No newline at end of file
diff --git a/test/auto-test/testdata/ecs/empty-type.json b/test/auto-test/testdata/ecs/empty-type.json
new file mode 100644 (file)
index 0000000..9e26dfe
--- /dev/null
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/test/auto-test/testdata/ecs/job-template2.json b/test/auto-test/testdata/ecs/job-template2.json
new file mode 100644 (file)
index 0000000..c1126ea
--- /dev/null
@@ -0,0 +1,6 @@
+{
+    "jobparam1":"value1_XXXX",
+    "jobparam2":"value2_XXXX",
+    "jobparam3":"value3_XXXX",
+    "jobparam4":"value3_XXXX"
+}
\ No newline at end of file
index b35966a..24dfc9d 100644 (file)
@@ -1,12 +1,12 @@
-## Introduction ##
+# Introduction #
 This dir contains most scripts needed for the auto-test environment. There are scripts with functions to adapt to the apis of the components of the Non-RT RIC; Policy Agent, A1 Controller and Ric (A1) simulator.
 Some of the scripts can also be used for other kinds of tests, for example basic tests.
 
 ## Overview for common test scripts and files ##
 
-`test_env.sh` \
+`test_env*.sh` \
 Common env variables for test in the auto-test dir. All configuration of port numbers, image names and version etc shall be made in this file.
-Used by the auto test scripts/suites but could be used for other test script as well. It is possible to configure a test case with a different file using the command line argument '--env-file'.
+Used by the auto test scripts/suites but could be used for other test script as well. The test cases shall be started with the file for the intended target using command line argument '--env-file'. There are preconfigured env files, pattern 'test_env*.sh', in ../common.
 
 `testcase_common.sh` \
 Common functions for auto test cases in the auto-test dir. This script is the foundation of test auto environment which sets up images and enviroment variables needed by this script as well as the script adapting to the APIs.
@@ -15,15 +15,24 @@ The included functions are described in detail further below.
 `testsuite_common.sh` \
 Common functions for running two or more auto test scripts as a suite.
 
+`api_curl.sh` \
+A common curl based function for the agent and ecs apis. Also partly used for the Callback receiver api.
+
 `agent_api_functions.sh` \
 Contains functions for adapting towards the Policy Agent API, also via dmaap (using a message-router stub interface)
 
+`ecs_api_functions.sh` \
+Contains functions for adapting towards the ECS API
+
 `controller_api_functions.sh` \
 Contains functions for adaping towards the A1-controller API.
 
 `ricsimulator_api_functions.sh` \
 Contains functions for adapting towards the RIC (A1) simulator admin API.
 
+`prodstub_api_functions.sh` \
+Contains functions for adapting towards the Producer stub interface - simulates a producer.
+
 `compare_json.py` \
 A python script to compare two json obects for equality. Note that the comparsion always sort json-arrays before comparing (that is, it does not care about the order of items within the array). In addition, the target json object may specify individual parameter values where equality is 'dont care'.
 
@@ -45,11 +54,13 @@ A python script to extract the information from an sdnc (A1 Controller) reply js
 `do_curl_function.sh`
 A script for executing a curl call with a specific url and optional payload. It also compare the response with an expected result in terms of response code and optional returned payload. Intended to be used by test script (for example basic test scripts of other components)
 
+`cr_api_functions.sh` \
+Contains functions for adapting towards the Callback receiver for checking received callback event.
 
 
-## Descriptions of functions in testcase_common.sh ##
+# Description of functions in testcase_common.sh #
 
-#### Script args ####
+## Script args ##
 The script can be started with these arguments
 
 | arg list |
@@ -64,23 +75,23 @@ The script can be started with these arguments
 | `auto-clean` | all containers will be automatically stopped and removed when the test case is complete. Requires the function 'auto_clean_containers' to be included last in the applicable auto-test script |
 | `--stop-at-error` | intended for debugging and make the script stop at first 'FAIL' and save all logs with a prefix 'STOP_AT_ERROR' |
 | `--ricsim-prefix <prefix>` | use another prefix for the ric simulator container name than the standard 'ricsim'. Note that the testscript has to read and use the env var `$RIC_SIM_PREFIX` instead of a hardcoded name of the ric(s). |
-| `--env-file` | point to a different file with environment variables, instead of the default 'test_env.sh' |
+| `--env-file` | point to a file with environment variables (the previous default, test_env.sh, replaced with one env file for each branch in test/common) |
 | `--use-local-image <app-nam> [<app-name>]*` | nnly applicable when running as 'remote' or 'remote-remove'. Mainly for debugging when a locally built image shall be used together with other remote images from nexus.Accepts a space separated list of PA, CP, RICSIM, SDNC for Policy Agent, Control Panel, A1-controller and the Ric simulator |
 
 
-#### Function: print_result ####
+## Function: print_result ##
 Print a test report of an auto-test script.
 | arg list |
 |--|
 | None |
 
-#### Function: start_timer ####
+## Function: start_timer ##
 Start a timer for time measurement. Only one timer can be running.
 | arg list |
 |--|
 | None - but any args will be printed (It is good practice to use same args for this function as for the `print_timer`) |
 
-#### Function: print_timer ####
+## Function: print_timer ##
 Print the value of the timer (in seconds) previously started by 'start_timer'. (Note that timer is still running after this function). The result of the timer as well as the args to the function will also be printed in the test report.
 | arg list |
 |--|
@@ -90,7 +101,7 @@ Print the value of the timer (in seconds) previously started by 'start_timer'. (
 | --------- | ----------- |
 | `<timer-message-to-print>` | Any text message to be printed along with the timer result.(It is good practice to use same args for this function as for the `start_timer`) |
 
-#### Function: print_and_reset_timer ####
+## Function: print_and_reset_timer ##
 Print the value of the timer (in seconds) previously started by 'start_timer'. Also reset the timer to 0. The result of the timer as well as the args to the function will also be printed in the test report.
 | arg list |
 |--|
@@ -100,7 +111,7 @@ Print the value of the timer (in seconds) previously started by 'start_timer'. A
 | --------- | ----------- |
 | `<timer-message-to-print>` | Any text message to be printed along with the timer result.(It is good practice to use same args for this function as for the `start_timer`) |
 
-#### Function: deviation ####
+## Function: deviation ##
 Mark a test as a deviation from the requirements. The list of deviations will be printed in the test report.
 | arg list |
 |--|
@@ -110,19 +121,19 @@ Mark a test as a deviation from the requirements. The list of deviations will be
 | --------- | ----------- |
 | `<deviation-message-to-print>` | Any text message describing the deviation. The text will also be printed in the test report. The intention is to mark known deviations, compared to required functionality |
 
-#### Function: clean_containers ####
+## Function: clean_containers ##
 Stop and remove all containers. Containers not part of the test are not affected.
 | arg list |
 |--|
 | None |
 
-#### Function: auto_clean_containers ####
+## Function: auto_clean_containers ##
 Stop and remove all containers. Containers not part of the test are not affected. This function has effect only if the test script is started with arg `auto-clean`. This intention is to use this function as the last step in an auto-test script.
 | arg list |
 |--|
 | None |
 
-#### Function: sleep_wait ####
+## Function: sleep_wait ##
 Make the script sleep for a number of seconds.
 | arg list |
 |--|
@@ -133,14 +144,14 @@ Make the script sleep for a number of seconds.
 | `<sleep-time-in-sec> ` | Number of seconds to sleep |
 | `<any-text-in-quotes-to-be-printed>` | Optional. The text will be printed, if present |
 
-#### Function: generate_uuid ####
+## Function: generate_uuid ##
 Geneate a UUID prefix to use along with the policy instance number when creating/deleting policies. Sets the env var UUID.
 UUID is then automatically added to the policy id in GET/PUT/DELETE.
 | arg list |
 |--|
 | None |
 
-#### Function: consul_config_app ####
+## Function: consul_config_app ##
 Function to load a json config from a file into consul for the Policy Agent
 
 | arg list |
@@ -151,7 +162,7 @@ Function to load a json config from a file into consul for the Policy Agent
 | --------- | ----------- |
 | `<json-config-file>` | The path to the json file to be loaded to Consul/CBS |
 
-#### Function: prepare_consul_config ####
+## Function: prepare_consul_config ##
 Function to prepare a Consul config based on the previously configured (and started simulators). Note that all simulator must be running and the test script has to configure if http or https shall be used for the components (this is done by the functions 'use_simulator_http', 'use_simulator_https', 'use_sdnc_http', 'use_sdnc_https', 'use_mr_http', 'use_mr_https')
 | arg list |
 |--|
@@ -162,25 +173,25 @@ Function to prepare a Consul config based on the previously configured (and star
 | `SDNC|NOSDNC` | Configure based on a1-controller (SNDC) or without a controller/adapter (NOSDNC) |
 | `<output-file>` | The path to the json output file containing the prepared config. This file is used in 'consul_config_app'  |
 
-#### Function: start_consul_cbs ####
+## Function: start_consul_cbs ##
 Start the Consul and CBS containers
 | arg list |
 |--|
 | None |
 
-#### Function: use_simulator_http ####
+## Function: use_simulator_http ##
 Use http for all API calls (A1) toward the simulator. This is the default. Admin API calls to the simulator are not affected. Note that this function shall be called before preparing the config for Consul.
 | arg list |
 |--|
 | None |
 
-#### Function: use_simulator_https ####
+## Function: use_simulator_https ##
 Use https for all API calls (A1) toward the simulator. Admin API calls to the simulator are not affected. Note that this function shall be called before preparing the config for Consul.
 | arg list |
 |--|
 | None |
 
-#### Function: start_ric_simulators ####
+## Function: start_ric_simulators ##
 Start a group of simulator where a group may contain 1 more simulators.
 | arg list |
 |--|
@@ -192,116 +203,134 @@ Start a group of simulator where a group may contain 1 more simulators.
 |`<count>`| And integer, 1 or greater. Specifies the number of simulators to start|
 |`<interface-id>`| Shall be the interface id of the simulator. See the repo 'a1-interface' for the available ids. |
 
-#### Function: start_control_panel ####
+## Function: start_control_panel ##
 Start the Control Panel container
 | arg list |
 |--|
 | None |
 
-#### Function: start_sdnc ####
+## Function: start_sdnc ##
 Start the SDNC A1 Controller container and its database container
 | arg list |
 |--|
 | None |
 
-#### Function: use_sdnc_http ####
+## Function: use_sdnc_http ##
 Use http for all API calls towards the SDNC A1 Controller. This is the default. Note that this function shall be called before preparing the config for Consul.
 | arg list |
 |--|
 | None |
 
-#### Function: use_sdnc_http ####
+## Function: use_sdnc_http ##
 Use https for all API calls towards the SDNC A1 Controller. Note that this function shall be called before preparing the config for Consul.
 | arg list |
 |--|
 | None |
 
-#### Function: start_mr ####
+## Function: start_mr ##
 Start the Message Router stub interface container
 | arg list |
 |--|
 | None |
 
-#### Function: use_mr_http ####
+## Function: use_mr_http ##
 Use http for all Dmaap calls to the MR. This is the default. The admin API is not affected. Note that this function shall be called before preparing the config for Consul.
 | arg list |
 |--|
 | None |
 
-#### Function: use_mr_https ####
+## Function: use_mr_https ##
 Use https for all Dmaap call to the MR. The admin API is not affected. Note that this function shall be called before preparing the config for Consul.
 | arg list |
 |--|
 | None |
 
-#### Function: start_cr ####
+## Function: start_cr ##
 Start the Callback Receiver container
 | arg list |
 |--|
 | None |
 
-#### Function: use_cr_http ####
+## Function: use_cr_http ##
 Use http for getting event from CR.  The admin API is not affected. This is the default.
 | arg list |
 |--|
 | None |
 
-#### Function: use_cr_https ####
+## Function: use_cr_https ##
 Use https for getting event from CR. The admin API is not affected.
 Note: Not yet used as callback event is not fully implemented/deciced.
 | arg list |
 |--|
 | None |
 
-#### Function: start_policy_agent ####
+## Function: start_prod_stub ##
+Start the Producer stubb container
+| arg list |
+|--|
+| None |
+
+## Function: use_prod_stub_http ##
+Use http for the API.  The admin API is not affected. This is the default protocol.
+| arg list |
+|--|
+| None |
+
+## Function: use_prod_stub_https ##
+Use https for the API. The admin API is not affected.
+| arg list |
+|--|
+| None |
+
+## Function: start_policy_agent ##
 Start the Policy Agent container. If the test script is configured to use a stand alone Policy Agent (for example other container or stand alone app) the script will prompt for starting the stand alone Policy Agent.
 | arg list |
 |--|
 | None |
 
-#### Function: use_agent_stand_alone ####
+## Function: use_agent_stand_alone ##
 Configure to run the Policy Agent as a stand alone container or app. See also 'start_policy_agent'
 | arg list |
 |--|
 | None |
 
-#### Function: use_agent_rest_http ####
+## Function: use_agent_rest_http ##
 Use http for all API calls to the Policy Agent. This is the default.
 | arg list |
 |--|
 | None |
 
-#### Function: use_agent_rest_https ####
+## Function: use_agent_rest_https ##
 Use https for all API calls to the Policy Agent.
 | arg list |
 |--|
 | None |
 
-#### Function: use_agent_dmaap_http ####
+## Function: use_agent_dmaap_http ##
 Send and recieve all API calls to the Policy Agent over Dmaap via the MR over http.
 | arg list |
 |--|
 | None |
 
-#### Function: use_agent_dmaap_https ####
+## Function: use_agent_dmaap_https ##
 Send and recieve all API calls to the Policy Agent over Dmaap via the MR over https.
 | arg list |
 |--|
 | None |
 
-#### Function: set_agent_debug ####
+## Function: set_agent_debug ##
 Configure the Policy Agent log on debug level. The Policy Agent must be running.
 | arg list |
 |--|
 | None |
 
-#### Function: set_agent_trace ####
+## Function: set_agent_trace ##
 Configure the Policy Agent log on trace level. The Policy Agent must be running.
 | arg list |
 |--|
 | None |
 
-#### Function: use_agent_retries ####
+## Function: use_agent_retries ##
 Configure the Policy Agent to make upto 5 retries if an API calls return any of the specified http return codes.
 | arg list |
 |--|
@@ -311,19 +340,79 @@ Configure the Policy Agent to make upto 5 retries if an API calls return any of
 | --------- | ----------- |
 | `[<response-code>]*` | A space separated list of http response codes, may be empty to reset to 'no codes'.  |
 
-#### Function: check_policy_agent_logs ####
+## Function: start_ecs ##
+Start the ECS container.
+| arg list |
+|--|
+| None |
+
+## Function: restart_ecs ##
+Restart the ECS container.
+| arg list |
+|--|
+| None |
+
+## Function: use_ecs_rest_http ##
+Use http for all API calls to the ECS. This is the default protocol.
+| arg list |
+|--|
+| None |
+
+## Function: use_ecs_rest_https ##
+Use https for all API calls to the ECS.
+| arg list |
+|--|
+| None |
+
+## Function: use_ecs_dmaap_http ##
+Send and recieve all API calls to the ECS over Dmaap via the MR using http.
+| arg list |
+|--|
+| None |
+
+## Function: use_ecs_dmaap_https ##
+Send and recieve all API calls to the ECS over Dmaap via the MR using https.
+| arg list |
+|--|
+| None |
+
+## Function: set_ecs_debug ##
+Configure the ECS log on debug level. The ECS must be running.
+| arg list |
+|--|
+| None |
+
+## Function: set_ecs_trace ##
+Configure the ECS log on trace level. The ECS must be running.
+| arg list |
+|--|
+| None |
+
+## Function: check_policy_agent_logs ##
 Check the Policy Agent log for any warnings and errors and print the count of each.
 | arg list |
 |--|
 | None |
 
-#### Function: check_control_panel_logs ####
+## Function: check_ecs_logs ##
+Check the ECS log for any warnings and errors and print the count of each.
+| arg list |
+|--|
+| None |
+
+## Function: check_control_panel_logs ##
 Check the Control Panel log for any warnings and errors and print the count of each.
 | arg list |
 |--|
 | None |
 
-#### Function: store_logs ####
+## Function: check_sdnc_logs ##
+Check the SDNC log for any warnings and errors and print the count of each.
+| arg list |
+|--|
+| None |
+
+## Function: store_logs ##
 Take a snap-shot of all logs for all running containers and stores them in `./logs/<ATC-id>`. All logs will get the specified prefix in the file name. In general, one of the last steps in an auto-test script shall be to call this function. If logs shall be taken several times during a test script, different prefixes shall be used each time.
 | arg list |
 |--|
@@ -334,22 +423,7 @@ Take a snap-shot of all logs for all running containers and stores them in `./lo
 | `<logfile-prefix>` | Log file prefix  |
 
 
-#### Function: cr_equal ####
-Tests if a variable value in the Callback Receiver (CR) simulator is equal to a target value.
-Without the timeout, the test sets pass or fail immediately depending on if the variable is equal to the target or not.
-With the timeout, the test waits up to the timeout seconds before setting pass or fail depending on if the variable value becomes equal to the target value or not.
-See the 'cr' dir for more details.
-| arg list |
-|--|
-| `<variable-name> <target-value> [ <timeout-in-sec> ]` |
-
-| parameter | description |
-| --------- | ----------- |
-| `<variable-name>` | Variable name in the CR  |
-| `<target-value>` | Target value for the variable  |
-| `<timeout-in-sec>` | Max time to wait for the variable to reach the target value  |
-
-#### Function: mr_equal ####
+## Function: mr_equal ##
 Tests if a variable value in the Message Router (MR) simulator is equal to a target value.
 Without the timeout, the test sets pass or fail immediately depending on if the variable is equal to the target or not.
 With the timeout, the test waits up to the timeout seconds before setting pass or fail depending on if the variable value becomes equal to the target value or not.
@@ -364,7 +438,7 @@ See the 'mrstub' dir for more details.
 | `<target-value>` | Target value for the variable  |
 | `<timeout-in-sec>` | Max time to wait for the variable to reach the target value  |
 
-#### Function: mr_greater ####
+## Function: mr_greater ##
 Tests if a variable value in the Message Router (MR) simulator is greater than a target value.
 Without the timeout, the test sets pass or fail immediately depending on if the variable is greater than the target or not.
 With the timeout, the test waits up to the timeout seconds before setting pass or fail depending on if the variable value becomes greater than the target value or not.
@@ -379,7 +453,7 @@ See the 'mrstub' dir for more details.
 | `<target-value>` | Target value for the variable  |
 | `<timeout-in-sec>` | Max time to wait for the variable to become grater than the target value  |
 
-#### Function: mr_read ####
+## Function: mr_read ##
 Reads the value of a variable in the Message Router (MR) simulator. The value is intended to be passed to a env variable in the test script.
 See the 'mrstub' dir for more details.
 | arg list |
@@ -390,7 +464,7 @@ See the 'mrstub' dir for more details.
 | --------- | ----------- |
 | `<variable-name>` | Variable name in the MR  |
 
-#### Function: mr_print ####
+## Function: mr_print ##
 Prints the value of a variable in the Message Router (MR) simulator.
 See the 'mrstub' dir for more details.
 | arg list |
@@ -401,26 +475,44 @@ See the 'mrstub' dir for more details.
 | --------- | ----------- |
 | `<variable-name>` | Variable name in the MR  |
 
-## Descriptions of functions in testsuite_common.sh ##
-#### Function: suite_setup ####
+## Function: indent1 ##
+Indent every line of a command output with one space char.
+| arg list |
+|--|
+| None |
+
+## Function: indent2 ##
+Indent every line of a command output with two space chars.
+| arg list |
+|--|
+| None |
+
+# Description of functions in testsuite_common.sh #
+
+## Function: suite_setup ##
 Sets up the test suite and prints out a heading.
 | arg list |
 |--|
 | None |
 
-#### suite_complete ####
+## suite_complete ##
 Print out the overall result of the executed test cases.
 | arg list |
 |--|
 | None |
 
-## Descriptions of functions in agent_api_function.sh ##
-#### Function: api_equal() ####
+# Description of functions in agent_api_function.sh #
+
+## General ##
+Both PMS version 1 and 2 are supported. The version is controlled by the env variable `$PMS_VERSION` set in the test env file.
+
+## Function: api_equal() ##
 
 Tests if the array length of a json array in the Policy Agent simulator is equal to a target value.
 Without the timeout, the test sets pass or fail immediately depending on if the array length is equal to the target or not.
 With the timeout, the test waits up to the timeout seconds before setting pass or fail depending on if the array length becomes equal to the target value or not.
 See the 'cr' dir for more details.
+
 | arg list |
 |--|
 | `<variable-name> <target-value> [ <timeout-in-sec> ]` |
@@ -431,14 +523,19 @@ See the 'cr' dir for more details.
 | `<target-value>` | Target value for the length  |
 | `<timeout-in-sec>` | Max time to wait for the length to reach the target value  |
 
-#### Function: api_get_policies() ####
-Test of GET '/policies' and optional check of the array of returned policies.
+## Function: api_get_policies() ##
+Test of GET '/policies' or V2 GET '/v2/policy-instances' and optional check of the array of returned policies.
 To test the response code only, provide the response code parameter as well as the following three parameters.
-To also test the response payload add the 'NOID' for an expected empty array or repeat the last five parameters for each expected policy.
+To also test the response payload add the 'NOID' for an expected empty array or repeat the last five/seven parameters for each expected policy.
+
 | arg list |
 |--|
 | `<response-code> <ric-id>|NORIC <service-id>|NOSERVICE <policy-type-id>|NOTYPE [ NOID | [<policy-id> <ric-id> <service-id> EMPTY|<policy-type-id> <template-file>]*]` |
 
+| arg list V2 |
+|--|
+| `<response-code> <ric-id>|NORIC <service-id>|NOSERVICE <policy-type-id>|NOTYPE [ NOID | [<policy-id> <ric-id> <service-id> EMPTY|<policy-type-id> <transient> <notification-url> <template-file>]*]` |
+
 | parameter | description |
 | --------- | ----------- |
 | `<response-code>` | Expected http response code |
@@ -451,31 +548,48 @@ To also test the response payload add the 'NOID' for an expected empty array or
 | `NOID` |  Indicator that no policy id is provided - indicate empty list of policies|
 | `<policy-id>` |  Id of the policy |
 | `EMPTY` |  Indicate for the special empty policy type |
+| `transient` |  Transient, true or false |
+| `notification-url` |  Url for notifications |
 | `<template-file>` |  Path to the template file for the policy (same template used when creating the policy) |
 
 
-#### Function: api_get_policy() ####
-Test of GET /policy and optional check of the returned json payload.
+## Function: api_get_policy() ##
+Test of GET '/policy' or V2 GET '/v2/policies/{policy_id}' and optional check of the returned json payload.
 To test the the response code only, provide the expected response code and policy id.
 To test the contents of the returned json payload, add a path to the template file used when creating the policy.
+
 | arg list |
 |--|
 | `<response-code>  <policy-id> [<template-file>]` |
 
+| arg list V2|
+|--|
+| `<response-code> <policy-id> [ <template-file> <service-name> <ric-id> <policytype-id>|NOTYPE <transient> <notification-url>|NOURL ]` |
+
 | parameter | description |
 | --------- | ----------- |
 | `<response-code>` | Expected http response code |
 | `<policy-id>` |  Id of the policy |
 | `<template-file>` |  Path to the template file for the policy (same template used when creating the policy) |
+| `<service-id>` | Id of the service  |
+| `<ric-id>` | Id of the ric  |
+| `<policy-type-id>` |  Id of the policy type |
+| `NOTYPE` | Indicator that no type id is provided  |
+| `transient` |  Transient, true or false |
+| `notification-url` |  Url for notifications |
+
+## Function: api_put_policy() ##
+Test of PUT '/policy' or V2 PUT '/policies'.
+If more than one policy shall be created, add a count value to indicate the number of policies to create. Note that if more than one policy shall be created the provided policy-id must be numerical (will be used as the starting id).
 
-#### Function: api_put_policy() ####
-Test of PUT '/policy'.
-To test the response code only, provide the response code parameter as well as the following three parameters.
-To also test the response payload add the 'NOID' for an expected empty array or repeat the last five parameters for each expected policy.
 | arg list |
 |--|
 | `<response-code> <service-name> <ric-id> <policytype-id> <policy-id> <transient> <template-file> [<count>]` |
 
+| arg list V2 |
+|--|
+| `<response-code> <service-name> <ric-id> <policytype-id>|NOTYPE <policy-id> <transient>|NOTRANSIENT <notification-url>|NOURL <template-file> [<count>]` |
+
 | parameter | description |
 | --------- | ----------- |
 | `<response-code>` | Expected http response code |
@@ -484,20 +598,29 @@ To also test the response payload add the 'NOID' for an expected empty array or
 | `<policy-type-id>` |  Id of the policy type |
 | `<policy-id>` |  Id of the policy. This value shall be a numeric value if more than one policy shall be created |
 | `transient>` |  Transient 'true' or 'false'. 'NOTRANSIENT' can be used to indicate using the default value (no transient value provided) |
+| `notification-url` |  Url for notifications |
+|`NOURL`| Indicator for no url |
 | `<template-file>` |  Path to the template file for the policy |
 | `<count>` |  An optional count (default is 1). If a value greater than 1 is given, the policy ids will use the given policy id as the first id and add 1 to that id for each new policy |
 
-#### Function: api_put_policy_batch() ####
+## Function: api_put_policy_batch() ##
 This tests the same as function 'api_put_policy' except that all put requests are sent to dmaap in one go and then the responses are polled one by one.
 If the agent api is not configured to use dmaap (see 'use_agent_dmaap', 'use_agent_rest_http' and 'use_agent_rest_https'), an error message is printed.
 For arg list and parameters, see 'api_put_policy'.
 
-#### Function: api_put_policy_parallel() ####
+## Function: api_put_policy_parallel() ##
 This tests the same as function 'api_put_policy' except that the policy create is spread out over a number of processes and it only uses the agent rest API. The total number of policies created is determined by the product of the parameters 'number-of-rics' and 'count'. The parameter 'number-of-threads' shall be selected to be not evenly divisible by the product of the parameters 'number-of-rics' and 'count' - this is to ensure that one process does not handle the creation of all the policies in one ric.
+
 | arg list |
 |--|
 | `<response-code> <service-name> <ric-id-base> <number-of-rics> <policytype-id> <policy-start-id> <transient> <template-file> <count-per-ric> <number-of-threads>`
 
+| arg list |
+|--|
+| `<response-code> <service-name> <ric-id-base> <number-of-rics> <policytype-id> <policy-start-id> <transient> <notification-url>|NOURL <template-file> <count-per-ric> <number-of-threads>`
+
+| parameter | description |
+| --------- | ----------- |
 | `<response-code>` | Expected http response code |
 | `<service-id>` | Id of the service  |
 | `<ric-id-base>` | The base id of the rics, ie ric id without the sequence number. The sequence number is added during processing  |
@@ -505,12 +628,14 @@ This tests the same as function 'api_put_policy' except that the policy create i
 | `<policy-type-id>` |  Id of the policy type |
 | `<policy-start-id>` |  Id of the policy. This value shall be a numeric value and will be the id of the first policy |
 | `transient>` |  Transient 'true' or 'false'. 'NOTRANSIENT' can be used to indicate using the default value (no transient value provide) |
+| `notification-url` |  Url for notifications |
 | `<template-file>` |  Path to the template file for the policy |
 | `<count-per-ric>` |  Number of policies per ric |
 | `<number-of-threads>` |  Number of threads (processes) to run in parallel |
 
-#### Function: api_delete_policy() ####
-This tests the DELETE /policy. Removes the indicated policy or a 'count' number of policies starting with 'policy-id' as the first id.
+## Function: api_delete_policy() ##
+This tests the DELETE '/policy' or V2 DELETE '/v2/policies/{policy_id}'. Removes the indicated policy or a 'count' number of policies starting with 'policy-id' as the first id.
+
 | arg list |
 |--|
 | `<response-code> <policy-id> [<count>]`
@@ -521,17 +646,20 @@ This tests the DELETE /policy. Removes the indicated policy or a 'count' number
 | `<policy-id>` |  Id of the policy |
 | `<count>` |  An optional count of policies to delete. The 'policy-id' will be the first id to be deleted. |
 
-#### Function: api_delete_policy_batch() ####
+## Function: api_delete_policy_batch() ##
 This tests the same as function 'api_delete_policy' except that all delete requests are sent to dmaap in one go and then the responses are polled one by one.
 If the agent api is not configured to used dmaap (see 'use_agent_dmaap', 'use_agent_rest_http' and 'use_agent_rest_https'), an error message is printed.
 For arg list and parameters, see 'api_delete_policy'.
 
-#### Function: api_delete_policy_parallel() ####
+## Function: api_delete_policy_parallel() ##
 This tests the same as function 'api_delete_policy' except that the policy delete is spread out over a number of processes and it only uses the agent rest API. The total number of policies deleted is determined by the product of the parameters 'number-of-rics' and 'count'. The parameter 'number-of-threads' shall be selected to be not evenly divisible by the product of the parameters 'number-of-rics' and 'count' - this is to ensure that one process does not handle the deletion of all the policies in one ric.
+
 | arg list |
 |--|
 | `<response-code> <ric-id-base> <number-of-rics> <policy-start-id> <count-per-ric> <number-of-threads>`
 
+| parameter | description |
+| --------- | ----------- |
 | `<response-code>` | Expected http response code |
 | `<ric-id-base>` | The base id of the rics, ie ric id without the sequence number. The sequence number is added during processing  |
 | `<number-of-rics>` | The number of rics, assuming the first index is '1'  |
@@ -540,11 +668,12 @@ This tests the same as function 'api_delete_policy' except that the policy delet
 | `<number-of-threads>` |  Number of threads (processes) to run in parallel |
 
 
-#### Function: api_get_policy_ids() ####
+## Function: api_get_policy_ids() ##
 
-Test of GET '/policy_ids'.
+Test of GET '/policy_ids' or V2 GET '/v2/policies'.
 To test response code only, provide the response code parameter as well as the following three parameters.
 To also test the response payload add the 'NOID' for an expected empty array or repeat the 'policy-instance-id' for each expected policy id.
+
 | arg list |
 |--|
 | `<response-code> <ric-id>|NORIC <service-id>|NOSERVICE <type-id>|NOTYPE ([<policy-instance-id]*|NOID)` |
@@ -561,10 +690,26 @@ To also test the response payload add the 'NOID' for an expected empty array or
 | `NOID` |  Indicator that no policy id is provided - indicate empty list of policies|
 | `<policy-instance-id>` |  Id of the policy |
 
-#### Function: api_get_policy_schema() ####
-Test of GET /policy_schema and optional check of the returned json schema.
+## Function: api_get_policy_schema() ##
+Test of V2 GET '/v2/policy-types/{policyTypeId}' and optional check of the returned json schema.
+To test the response code only, provide the expected response code and policy type id.
+To test the contents of the returned json schema, add a path to a schema file to compare with.
+
+| arg list |
+|--|
+| `<response-code> <policy-type-id> [<schema-file>]` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<response-code>` | Expected http response code |
+| `<policy-type-id>` |  Id of the policy type |
+| `<schema-file>` |  Path to the schema file for the policy type |
+
+## Function: api_get_policy_schema() ##
+Test of GET '/policy_schema' and optional check of the returned json schema.
 To test the response code only, provide the expected response code and policy type id.
 To test the contents of the returned json schema, add a path to a schema file to compare with.
+
 | arg list |
 |--|
 | `<response-code> <policy-type-id> [<schema-file>]` |
@@ -575,10 +720,11 @@ To test the contents of the returned json schema, add a path to a schema file to
 | `<policy-type-id>` |  Id of the policy type |
 | `<schema-file>` |  Path to the schema file for the policy type |
 
-#### Function: api_get_policy_schemas() ####
-Test of GET /policy_schemas and optional check of the returned json schemas.
+## Function: api_get_policy_schemas() ##
+Test of GET '/policy_schemas' and optional check of the returned json schemas.
 To test the response code only, provide the expected response code and ric id (or NORIC if no ric is given).
 To test the contents of the returned json schema, add a path to a schema file to compare with (or NOFILE to represent an empty '{}' type)
+
 | arg list |
 |--|
 | `<response-code>  <ric-id>|NORIC [<schema-file>|NOFILE]*` |
@@ -591,8 +737,9 @@ To test the contents of the returned json schema, add a path to a schema file to
 | `<schema-file>` |  Path to the schema file for the policy type |
 | `NOFILE` |  Indicate the template for an empty type |
 
-#### Function: api_get_policy_status() ####
-Test of GET /policy_status.
+## Function: api_get_policy_status() ##
+Test of GET '/policy_status' or V2 GET '/policies/{policy_id}/status'.
+
 | arg list |
 |--|
 | `<response-code> <policy-id> (STD <enforce-status> [<reason>])|(OSC <instance-status> <has-been-deleted>)` |
@@ -608,8 +755,8 @@ Test of GET /policy_status.
 | `<instance-status>` |  Instance status |
 | `<has-been-deleted>` |  Deleted status, true or false |
 
-#### Function: api_get_policy_types() ####
-Test of GET /policy_types and optional check of the returned ids.
+## Function: api_get_policy_types() ##
+Test of GET '/policy_types' or  V2 GET '/v2/policy-types' and optional check of the returned ids.
 To test the response code only, provide the expected response code and ric id (or NORIC if no ric is given).
 To test the contents of the returned json payload, add the list of expected policy type id (or 'EMPTY' for the '{}' type)
 
@@ -625,8 +772,9 @@ To test the contents of the returned json payload, add the list of expected poli
 | `<policy-type-id>` |  Id of the policy type |
 | `EMPTY` |  Indicate the empty type |
 
-#### Function: api_get_status() ####
-Test of GET /status
+## Function: api_get_status() ##
+Test of GET /status or V2 GET /status
+
 | arg list |
 |--|
 | `<response-code>` |
@@ -635,26 +783,35 @@ Test of GET /status
 | --------- | ----------- |
 | `<response-code>` | Expected http response code |
 
-#### Function: api_get_ric() ####
-Test of GET /ric
+## Function: api_get_ric() ##
+Test of GET '/ric' or V2 GET '/v2/rics/ric'
 To test the response code only, provide the expected response code and managed element id.
 To test the returned ric id, provide the expected ric id.
+
 | arg list |
 |--|
 | `<reponse-code> <managed-element-id> [<ric-id>]` |
 
+| arg list V2 |
+|--|
+| `<reponse-code> <management-element-id>|NOME <ric-id>|<NORIC> [<string-of-ricinfo>]` |
+
 | parameter | description |
 | --------- | ----------- |
 | `<response-code>` | Expected http response code |
 | `<managed-element-id>` |  Id of the managed element |
-| `<ric-id>` |  Id of the ric |
+| `NOME` |  Indicator for no ME |
+| `ric-id` |  Id of the ric |
+| `NORIC` |  Indicator no RIC |
+| `string-of-ricinfo` |  String of ric info |
 
-#### Function: api_get_rics() ####
-Test of GET /rics and optional check of the returned json payload (ricinfo).
+## Function: api_get_rics() ##
+Test of GET '/rics' or V2 GET '/v2/rics' and optional check of the returned json payload (ricinfo).
 To test the response code only, provide the expected response code and policy type id (or NOTYPE if no type is given).
 To test also the returned payload, add the formatted string of info in the returned payload.
 Format of ricinfo: '<ric-id>:<list-of-mes>:<list-of-policy-type-ids>'
 Example `<space-separate-string-of-ricinfo> = "ricsim_g1_1:me1_ricsim_g1_1,me2_ricsim_g1_1:1,2,4 ricsim_g1_1:me2_........."`
+
 | arg list |
 |--|
 | `<reponse-code> <policy-type-id>|NOTYPE [<space-separate-string-of-ricinfo>]` |
@@ -666,8 +823,8 @@ Example `<space-separate-string-of-ricinfo> = "ricsim_g1_1:me1_ricsim_g1_1,me2_r
 | `NOTYPE>` |  No type given |
 | `<space-separate-string-of-ricinfo>` |  A space separated string of ric info - needs to be quoted |
 
-#### Function: api_put_service() ####
-Test of PUT /service
+## Function: api_put_service() ##
+Test of PUT '/service' or V2 PUT '/service'.
 | arg list |
 |--|
 | `<response-code>  <service-name> <keepalive-timeout> <callbackurl>` |
@@ -679,10 +836,11 @@ Test of PUT /service
 | `<keepalive-timeout>` |  Timeout value |
 | `<callbackurl>` |  Callback url |
 
-#### Function: api_get_services() ####
-Test of GET /service and optional check of the returned json payload.
+## Function: api_get_services() ##
+Test of GET '/service' or V2 GET '/v2/services' and optional check of the returned json payload.
 To test only the response code, omit all parameters except the expected response code.
 To test the returned json, provide the parameters after the response code.
+
 | arg list |
 |--|
 | `<response-code> [ (<query-service-name> <target-service-name> <keepalive-timeout> <callbackurl>) | (NOSERVICE <target-service-name> <keepalive-timeout> <callbackurl> [<target-service-name> <keepalive-timeout> <callbackurl>]* )]` |
@@ -696,8 +854,9 @@ To test the returned json, provide the parameters after the response code.
 | `<callbackurl>` |  Callback url |
 | `NOSERVICE` |  Indicator of no target service name |
 
-#### Function: api_get_service_ids() ####
-Test of GET /services
+## Function: api_get_service_ids() ##
+Test of GET '/services' or V2 GET /'v2/services'. Only check of service ids.
+
 | arg list |
 |--|
 | `<response-code> [<service-name>]*` |
@@ -707,8 +866,9 @@ Test of GET /services
 | `<response-code>` | Expected http response code |
 | `<service-name>` |  Service name |
 
-#### Function: api_delete_services() ####
-Test of DELETE /services
+## Function: api_delete_services() ##
+Test of DELETE '/services' or V2 DELETE '/v2/services/{serviceId}'
+
 | arg list |
 |--|
 | `<response-code> [<service-name>]*` |
@@ -718,8 +878,9 @@ Test of DELETE /services
 | `<response-code>` | Expected http response code |
 | `<service-name>` |  Service name |
 
-#### Function: api_put_services_keepalive() ####
-Test of PUT /services/keepalive
+## Function: api_put_services_keepalive() ##
+Test of PUT '/services/keepalive' or V2 PUT '/v2/services/{service_id}/keepalive'
+
 | arg list |
 |--|
 | <response-code> <service-name>` |
@@ -729,14 +890,15 @@ Test of PUT /services/keepalive
 | `<response-code>` | Expected http response code |
 | `<service-name>` |  Service name |
 
-## Descriptions of functions in ricsimulator_api_functions.sh ##
+# Description of functions in ricsimulator_api_functions.sh #
 The functions below only use the admin interface of the simulator, no usage of the A1 interface.
 
-#### Function: sim_equal ####
+## Function: sim_equal ##
 Tests if a variable value in the RIC simulator is equal to a target value.
 Without the timeout, the test sets pass or fail immediately depending on if the variable is equal to the target or not.
 With the timeout, the test waits up to the timeout seconds before setting pass or fail depending on if the variable value becomes equal to the target value or not.
 See the 'a1-interface' repo for more details.
+
 | arg list |
 |--|
 | `<variable-name> <target-value> [ <timeout-in-sec> ]` |
@@ -747,9 +909,10 @@ See the 'a1-interface' repo for more details.
 | `<target-value>` | Target value for the variable  |
 | `<timeout-in-sec>` | Max time to wait for the variable to reach the target value  |
 
-#### Function: sim_print ####
+## Function: sim_print ##
 Prints the value of a variable in the RIC simulator.
 See the 'a1-interface' repo for more details.
+
 | arg list |
 |--|
 | `<variable-name>` |
@@ -759,11 +922,12 @@ See the 'a1-interface' repo for more details.
 | `<variable-name>` | Variable name in the RIC simulator  |
 
 
-#### Function: sim_contains_str ####
+## Function: sim_contains_str ##
 Tests if a variable value in the RIC simulator contains a target string.
 Without the timeout, the test sets pass or fail immediately depending on if the variable contains the target string or not.
 With the timeout, the test waits up to the timeout seconds before setting pass or fail depending on if the variable value contains the target string or not.
 See the 'a1-interface' repo for more details.
+
 | arg list |
 |--|
 | `<variable-name> <target-value> [ <timeout-in-sec> ]` |
@@ -774,8 +938,9 @@ See the 'a1-interface' repo for more details.
 | `<target-value>` | Target substring for the variable  |
 | `<timeout-in-sec>` | Max time to wait for the variable to reach the target value  |
 
-#### Function: sim_put_policy_type ####
+## Function: sim_put_policy_type ##
 Loads a policy type to the simulator
+
 | arg list |
 |--|
 | `<response-code> <ric-id> <policy-type-id> <policy-type-file>` |
@@ -787,8 +952,9 @@ Loads a policy type to the simulator
 | `<policy-type-id>` |  Id of the policy type |
 | `<policy-type-file>` |  Path to the schema file of the policy type |
 
-#### Function: sim_delete_policy_type ####
+## Function: sim_delete_policy_type ##
 Deletes a policy type from the simulator
+
 | arg list |
 |--|
 | `<response-code> <ric-id> <policy_type_id>` |
@@ -799,8 +965,9 @@ Deletes a policy type from the simulator
 | `<ric-id>` |  Id of the ric |
 | `<policy-type-id>` |  Id of the policy type |
 
-#### Function: sim_post_delete_instances ####
+## Function: sim_post_delete_instances ##
 Deletes all instances (and status), for one ric
+
 | arg list |
 |--|
 | `<response-code> <ric-id>` |
@@ -811,8 +978,9 @@ Deletes all instances (and status), for one ric
 | `<ric-id>` |  Id of the ric |
 
 
-#### Function: sim_post_delete_all ####
+## Function: sim_post_delete_all ##
 Deletes all types, instances (and status), for one ric
+
 | arg list |
 |--|
 | `<response-code> <ric-id>` |
@@ -822,9 +990,10 @@ Deletes all types, instances (and status), for one ric
 | `<response-code>` | Expected http response code |
 | `<ric-id>` |  Id of the ric |
 
-#### Function: sim_post_forcedresponse ####
+## Function: sim_post_forcedresponse ##
 Sets (or resets) response code for next (one) A1 message, for one ric.
 The intention is to simulate error response on the A1 interface.
+
 | arg list |
 |--|
 | `<response-code> <ric-id> [<forced_response_code>]`|
@@ -835,9 +1004,10 @@ The intention is to simulate error response on the A1 interface.
 | `<ric-id>` |  Id of the ric |
 | `<forced_response_code>` |  Http response code to send |
 
-#### Function: sim_post_forcedelay ####
+## Function: sim_post_forcedelay ##
 Sets (or resets) A1 response delay, for one ric
 The intention is to delay responses on the A1 interface. Setting remains until removed.
+
 | arg list |
 |--|
 | `<response-code> <ric-id> [<delay-in-seconds>]`|
@@ -849,13 +1019,14 @@ The intention is to delay responses on the A1 interface. Setting remains until r
 | `<delay-in-seconds>` |  Delay in seconds. If omitted, the delay is removed |
 
 
-## Descriptions of functions in controller_api_functions.sh ##
+# Description of functions in controller_api_functions.sh #
 The file contains a selection of the possible API tests towards the a1-controller
 
-#### Function: controller_api_get_A1_policy_ids ####
+## Function: controller_api_get_A1_policy_ids ##
 Test of GET policy ids towards OSC or STD type simulator.
 To test response code only, provide the response code, 'OSC' + policy type or 'STD'
 To test the response payload, include the ids of the expexted response.
+
 | arg list |
 |--|
 | `<response-code> (OSC <ric-id> <policy-type-id> [ <policy-id> [<policy-id>]* ]) | ( STD <ric-id> [ <policy-id> [<policy-id>]* ]` |
@@ -870,8 +1041,9 @@ To test the response payload, include the ids of the expexted response.
 | `STD` |  Indicator of status of Standarized A1 |
 
 
-#### Function: controller_api_get_A1_policy_type ####
+## Function: controller_api_get_A1_policy_type ##
 Test of GET a policy type (OSC only)
+
 | arg list |
 |--|
 | `<response-code> OSC <ric-id> <policy-type-id> [<policy-type-file>]` |
@@ -884,8 +1056,9 @@ Test of GET a policy type (OSC only)
 | `policy-type-id>` |  Id of the policy type |
 | `policy-type-file>` |  Optional schema file to compare the returned type with |
 
-#### Function: controller_api_delete_A1_policy ####
+## Function: controller_api_delete_A1_policy ##
 Deletes a policy instance
+
 | arg list |
 |--|
 | `(STD <ric-id> <policy-id>) | (OSC <ric-id> <policy-type-id> <policy-id>)` |
@@ -900,8 +1073,9 @@ Deletes a policy instance
 | `OSC` |  Indicator of status of Non-Standarized OSC A1 |
 | `policy-type-file>` |  Optional schema file to compare the returned type with |
 
-#### Function: controller_api_put_A1_policy ####
+## Function: controller_api_put_A1_policy ##
 Creates a policy instance
+
 | arg list |
 |--|
 | `<response-code> (STD <ric-id> <policy-id> <template-file> ) | (OSC <ric-id> <policy-type-id> <policy-id> <template-file>)` |
@@ -916,8 +1090,9 @@ Creates a policy instance
 | `OSC` |  Indicator of status of Non-Standarized OSC A1 |
 | `<policy-type-id>` |  Id of the policy type |
 
-#### Function: controller_api_get_A1_policy_status ####
+## Function: controller_api_get_A1_policy_status ##
 Checks the status of a policy
+
  arg list |
 |--|
 | `<response-code> (STD <ric-id> <policy-id> <enforce-status> [<reason>]) | (OSC <ric-id> <policy-type-id> <policy-id> <instance-status> <has-been-deleted>)` |
@@ -935,6 +1110,401 @@ Checks the status of a policy
 | `<instance-status>` |  Instance status |
 | `<has-been-deleted>` |  Deleted status, true or false |
 
+
+
+
+# Description of functions in ecs_api_function.sh #
+
+## Function: ecs_api_a1_get_job_ids() ##
+Test of GET '/A1-EI​/v1​/eitypes​/{eiTypeId}​/eijobs' and optional check of the array of returned job ids.
+To test the response code only, provide the response code parameter as well as a type id and an owner id.
+To also test the response payload add the 'EMPTY' for an expected empty array or repeat the last parameter for each expected job id.
+
+| arg list |
+|--|
+| `<response-code> <type-id>  <owner-id>|NOOWNER [ EMPTY | <job-id>+ ]` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<response-code>` | Expected http response code |
+| `<type-id>` | Id of the EI type  |
+| `<owner-id>` | Id of the job owner  |
+| `NOOWNER` | No owner is given  |
+| `<job-id>` | Id of the expected job  |
+| `EMPTY` | The expected list of job id shall be empty  |
+
+## Function: ecs_api_a1_get_type() ##
+Test of GET '/A1-EI​/v1​/eitypes​/{eiTypeId}' and optional check of the returned schema.
+To test the response code only, provide the response code parameter as well as the type-id.
+To also test the response payload add a path to the expected schema file.
+
+| arg list |
+|--|
+| `<response-code> <type-id> [<schema-file>]` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<response-code>` | Expected http response code |
+| `<type-id>` | Id of the EI type  |
+| `<schema-file>` | Path to a schema file to compare with the returned schema  |
+
+## Function: ecs_api_a1_get_type_ids() ##
+Test of GET '/A1-EI​/v1​/eitypes' and optional check of returned list of type ids.
+To test the response code only, provide the response only.
+To also test the response payload add the list of expected type ids (or EMPTY if the list is expected to be empty).
+
+| arg list |
+|--|
+| `<response-code> [ (EMPTY | [<type-id>]+) ]` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<response-code>` | Expected http response code |
+| `EMPTY` | The expected list of type ids shall be empty  |
+| `<type-id>` | Id of the EI type  |
+
+## Function: ecs_api_a1_get_job_status() ##
+Test of GET '/A1-EI​/v1​/eitypes​/{eiTypeId}​/eijobs​/{eiJobId}​/status' and optional check of the returned status.
+To test the response code only, provide the response code, type id and job id.
+To also test the response payload add the expected status.
+
+| arg list |
+|--|
+| `<response-code> <type-id> <job-id> [<status>]` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<response-code>` | Expected http response code |
+| `<type-id>` | Id of the EI type  |
+| `<job-id>` | Id of the job  |
+| `<status>` | Expected status  |
+
+## Function: ecs_api_a1_get_job() ##
+Test of GET '/A1-EI​/v1​/eitypes​/{eiTypeId}​/eijobs​/{eiJobId}' and optional check of the returned job.
+To test the response code only, provide the response code, type id and job id.
+To also test the response payload add the remaining parameters.
+
+| arg list |
+|--|
+| `<response-code> <type-id> <job-id> [<target-url> <owner-id> <template-job-file>]` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<response-code>` | Expected http response code |
+| `<type-id>` | Id of the EI type  |
+| `<job-id>` | Id of the job  |
+| `<target-url>` | Expected target url for the job  |
+| `<owner-id>` | Expected owner for the job  |
+| `<template-job-file>` | Path to a job template for job parameters of the job  |
+
+## Function: ecs_api_a1_delete_job() ##
+Test of DELETE '/A1-EI​/v1​/eitypes​/{eiTypeId}​/eijobs​/{eiJobId}'.
+To test, provide all the specified parameters.
+
+| arg list |
+|--|
+| `<response-code> <type-id> <job-id> |
+
+| parameter | description |
+| --------- | ----------- |
+| `<response-code>` | Expected http response code |
+| `<type-id>` | Id of the EI type  |
+| `<job-id>` | Id of the job  |
+
+## Function: ecs_api_a1_put_job() ##
+Test of PUT '/A1-EI​/v1​/eitypes​/{eiTypeId}​/eijobs​/{eiJobId}'.
+To test, provide all the specified parameters.
+
+| arg list |
+|--|
+| `<response-code> <type-id> <job-id> <target-url> <owner-id> <template-job-file>` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<response-code>` | Expected http response code |
+| `<type-id>` | Id of the EI type  |
+| `<job-id>` | Id of the job  |
+| `<target-url>` | Target url for the job  |
+| `<owner-id>` | Owner of the job  |
+| `<template-job-file>` | Path to a job template for job parameters of the job  |
+
+## Function: ecs_api_edp_get_type_ids() ##
+Test of GET '/ei-producer/v1/eitypes' and an optional check of the returned list of type ids.
+To test the response code only, provide the response code.
+To also test the response payload add list of expected type ids (or EMPTY if the list is expected to be empty).
+
+| arg list |
+|--|
+| `<response-code> [ EMPTY | <type-id>+]` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<response-code>` | Expected http response code |
+| `<type-id>` | Id of the EI type  |
+| `EMPTY` | The expected list of type ids shall be empty  |
+
+## Function: ecs_api_edp_get_producer_status() ##
+Test of GET '/ei-producer/v1/eiproducers/{eiProducerId}/status' and optional check of the returned status.
+To test the response code only, provide the response code and producer id.
+To also test the response payload add the expected status.
+
+| arg list |
+|--|
+| `<response-code> <producer-id> [<status>]` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<response-code>` | Expected http response code |
+| `<producer-id>` | Id of the producer  |
+| `<status>` | The expected status string  |
+
+## Function: ecs_api_edp_get_producer_ids() ##
+Test of GET '/ei-producer/v1/eiproducers' and optional check of the returned producer ids.
+To test the response code only, provide the response.
+To also test the response payload add the list of expected producer-ids (or EMPTY if the list of ids is expected to be empty).
+
+| arg list |
+|--|
+| `<response-code> [ EMPTY | <producer-id>+]` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<response-code>` | Expected http response code |
+| `<producer-id>` | Id of the producer  |
+| `EMPTY` | The expected list of type ids shall be empty  |
+
+## Function: ecs_api_edp_get_type() ##
+Test of GET '/ei-producer/v1/eitypes/{eiTypeId}' and optional check of the returned type.
+To test the response code only, provide the response and the type-id.
+To also test the response payload add a path to a job schema file and a list expected producer-id (or EMPTY if the list of ids is expected to be empty).
+
+| arg list |
+|--|
+| `<response-code> <type-id> [<job-schema-file> (EMPTY | [<producer-id>]+)]` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<response-code>` | Expected http response code |
+| `<type-id>` | Id of the EI type  |
+| `<job-schema-file>` | Path to a job schema file  |
+| `<producer-id>` | Id of the producer  |
+| `EMPTY` | The expected list of type ids shall be empty  |
+
+## Function: ecs_api_edp_get_producer() ##
+Test of GET '/ei-producer/v1/eiproducers/{eiProducerId}' and optional check of the returned producer.
+To test the response code only, provide the response and the producer-id.
+To also test the response payload add the remaining parameters defining thee producer.
+
+| arg list |
+|--|
+| `<response-code> <producer-id> [<create-callback> <delete-callback> <supervision-callback> (EMPTY | [<type-id> <schema-file>]+) ]` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<response-code>` | Expected http response code |
+| `<producer-id>` | Id of the producer  |
+| `<create-callback>` | Callback for create job  |
+| `<delete-callback>` | Callback for delete job  |
+| `<supervision-callback>` | Callback for producer supervision  |
+| `<type-id>` | Id of the EI type  |
+| `<schema-file>` | Path to a schema file  |
+| `EMPTY` | The expected list of type schema pairs shall be empty  |
+
+## Function: ecs_api_edp_delete_producer() ##
+Test of DELETE '/ei-producer/v1/eiproducers/{eiProducerId}'.
+To test, provide all parameters.
+
+| arg list |
+|--|
+| `<response-code> <producer-id>` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<response-code>` | Expected http response code |
+| `<producer-id>` | Id of the producer  |
+
+## Function: ecs_api_edp_put_producer() ##
+Test of PUT '/ei-producer/v1/eiproducers/{eiProducerId}'.
+To test, provide all parameters. The list of type/schema pair may be empty.
+
+| arg list |
+|--|
+| `<response-code> <producer-id> <create-callback> <delete-callback> <supervision-callback> (EMPTY | [<type-id> <schema-file>]+)` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<response-code>` | Expected http response code |
+| `<producer-id>` | Id of the producer  |
+| `<create-callback>` | Callback for create job  |
+| `<delete-callback>` | Callback for delete job  |
+| `<supervision-callback>` | Callback for producer supervision  |
+| `<type-id>` | Id of the EI type  |
+| `<schema-file>` | Path to a schema file  |
+| `EMPTY` | The list of type/schema pairs is empty  |
+
+## Function: ecs_api_edp_get_producer_jobs() ##
+Test of GET '/ei-producer/v1/eiproducers/{eiProducerId}/eijobs' and optional check of the returned producer job.
+To test the response code only, provide the response and the producer-id.
+To also test the response payload add the remaining parameters.
+
+| arg list |
+|--|
+| `<response-code> <producer-id> (EMPTY | [<job-id> <type-id> <target-url> <template-job-file>]+)` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<response-code>` | Expected http response code |
+| `<producer-id>` | Id of the producer  |
+| `<job-id>` | Id of the job  |
+| `<type-id>` | Id of the EI type  |
+| `<target-url>` | Target url for data delivery  |
+| `<template-job-file>` | Path to a job template file  |
+| `EMPTY` | The list of job/type/target/job-file tuples is empty  |
+
+## Function: ecs_api_service_status() ##
+Test of GET '/status'.
+
+| arg list |
+|--|
+| `<response-code>` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<response-code>` | Expected http response code |
+
+
+# Description of functions in prodstub_api_function.sh #
+
+## Function: prodstub_arm_producer() ##
+Preconfigure the prodstub with a producer. The producer supervision response code is optional, if not given the response code will be set to 200.
+
+| arg list |
+|--|
+| `<response-code> <producer-id> [<forced_response_code>]` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<response-code>` | Expected http response code |
+| `<producer-id>` | Id of the producer  |
+| `<forced_response_code>` | Forced response code for the producer callback url |
+
+## Function: prodstub_arm_job_create() ##
+Preconfigure the prodstub with a job or update an existing job. Optional create/update job response code, if not given the response code will be set to 200/201 depending on if the job has been previously created or not.
+
+| arg list |
+|--|
+| `<response-code> <job-id> [<forced_response_code>]` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<response-code>` | Expected http response code |
+| `<job-id>` | Id of the job  |
+| `<forced_response_code>` | Forced response code for the create callback url |
+
+## Function: prodstub_arm_job_delete() ##
+Preconfigure the prodstub with a job. Optional delete job response code, if not given the response code will be set to 204/404 depending on if the job exists or not.
+
+| arg list |
+|--|
+| `<response-code> <job-id> [<forced_response_code>]` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<response-code>` | Expected http response code |
+| `<job-id>` | Id of the job  |
+| `<forced_response_code>` | Forced response code for the delete callback url |
+
+## Function: prodstub_arm_type() ##
+Preconfigure the prodstub with a type for a producer. Can be called multiple times to add more types.
+
+| arg list |
+|--|
+| `<response-code> <producer-id> <type-id>` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<response-code>` | Expected http response code |
+| `<producer-id>` | Id of the producer  |
+| `<type-id>` | Id of the type  |
+
+## Function: prodstub_disarm_type() ##
+Remove a type for the producer in the rodstub. Can be called multiple times to remove more types.
+
+| arg list |
+|--|
+| `<response-code> <producer-id> <type-id>` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<response-code>` | Expected http response code |
+| `<producer-id>` | Id of the producer  |
+| `<type-id>` | Id of the type  |
+
+## Function: prodstub_check_jobdata() ##
+Check a job in the prodstub towards the list of provided parameters.
+
+| arg list |
+|--|
+| `<response-code> <producer-id> <job-id> <type-id> <target-url> <template-job-file>` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<response-code>` | Expected http response code |
+| `<producer-id>` | Id of the producer  |
+| `<job-id>` | Id of the job  |
+| `<type-id>` | Id of the type  |
+| `<target-url>` | Target url for data delivery  |
+| `<template-job-file>` | Path to a job template file  |
+
+## Function: prodstub_equal ##
+Tests if a variable value in the prodstub is equal to a target value.
+Without the timeout, the test sets pass or fail immediately depending on if the variable is equal to the target or not.
+With the timeout, the test waits up to the timeout seconds before setting pass or fail depending on if the variable value becomes equal to the target value or not.
+
+| arg list |
+|--|
+| `<variable-name> <target-value> [ <timeout-in-sec> ]` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<variable-name>` | Variable name in the prostub  |
+| `<target-value>` | Target value for the variable  |
+| `<timeout-in-sec>` | Max time to wait for the variable to reach the target value  |
+
+# Description of functions in cr_api_function.sh #
+
+
+
+## Function: cr_equal ##
+Tests if a variable value in the Callback Receiver (CR) simulator is equal to a target value.
+Without the timeout, the test sets pass or fail immediately depending on if the variable is equal to the target or not.
+With the timeout, the test waits up to the timeout seconds before setting pass or fail depending on if the variable value becomes equal to the target value or not.
+See the 'cr' dir for more details.
+| arg list |
+|--|
+| `<variable-name> <target-value> [ <timeout-in-sec> ]` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<variable-name>` | Variable name in the CR  |
+| `<target-value>` | Target value for the variable  |
+| `<timeout-in-sec>` | Max time to wait for the variable to reach the target value  |
+
+## Function: cr_api_check_all_sync_events() ##
+Check the contents of all ric events received for a callback id.
+
+| arg list |
+|--|
+| `<response-code> <id> [ EMPTY | ( <ric-id> )+ ]` |
+
+| parameter | description |
+| --------- | ----------- |
+| `<response-code>` | Expected http response code |
+| `<id>` | Id of the callback destination  |
+| `EMPTY` | Indicator for an empty list  |
+| `<ric-id>` | Id of the ric  |
+
+
 ## License
 
 Copyright (C) 2020 Nordix Foundation. All rights reserved.
index 29e1bf1..5f5a2c6 100644 (file)
@@ -35,7 +35,11 @@ api_equal() {
     echo "(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
        if [ $# -eq 2 ] || [ $# -eq 3 ]; then
                if [[ $1 == "json:"* ]]; then
-                       __var_test "Policy Agent" $LOCALHOST$POLICY_AGENT_EXTERNAL_PORT"/" $1 "=" $2 $3
+                       if [ "$PMS_VERSION" == "V2" ]; then
+                               __var_test "Policy Agent" $LOCALHOST$POLICY_AGENT_EXTERNAL_PORT"/v2/" $1 "=" $2 $3
+                       else
+                               __var_test "Policy Agent" $LOCALHOST$POLICY_AGENT_EXTERNAL_PORT"/" $1 "=" $2 $3
+                       fi
                        return 0
                fi
        fi
@@ -45,92 +49,184 @@ api_equal() {
        return 1
 }
 
-# API Test function: GET /policies
-# args: <response-code> <ric-id>|NORIC <service-id>|NOSERVICE <policy-ype-id>|NOTYPE [ NOID | [<policy-id> <ric-id> <service-id> EMPTY|<policy-type-id> <template-file>]*]
+# API Test function: GET /policies and V2 GET /v2/policy-instances
+# args: <response-code> <ric-id>|NORIC <service-id>|NOSERVICE <policy-type-id>|NOTYPE [ NOID | [<policy-id> <ric-id> <service-id> EMPTY|<policy-type-id> <template-file>]*]
+# args(V2): <response-code> <ric-id>|NORIC <service-id>|NOSERVICE <policy-type-id>|NOTYPE [ NOID | [<policy-id> <ric-id> <service-id> EMPTY|<policy-type-id> <transient> <notification-url> <template-file>]*]
 # (Function for test scripts)
 api_get_policies() {
        echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
     echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
        ((RES_TEST++))
-       paramError=0
-       if [ $# -lt 4 ]; then
-               paramError=1
-       elif [ $# -eq 5 ] && [ $5 != "NOID" ]; then
-               paramError=1
-       elif [ $# -gt 4 ] && [ $(($#%5)) -ne 4 ]; then
-               paramError=1
+
+       if [ "$PMS_VERSION" == "V2" ]; then
+               paramError=0
+               variableParams=$(($#-4))
+               if [ $# -lt 4 ]; then
+                       paramError=1
+               elif [ $# -eq 5 ] && [ $5 != "NOID" ]; then
+                       paramError=1
+               elif [ $# -gt 5 ] && [ $(($variableParams%7)) -ne 0 ]; then
+                       paramError=1
+               fi
+
+               if [ $paramError -ne 0 ]; then
+                       __print_err "<response-code> <ric-id>|NORIC <service-id>|NOSERVICE <policy-type-id>|NOTYPE [ NOID | [<policy-id> <ric-id> <service-id> EMPTY|<policy-type-id> <transient> <notification-url> <template-file>]*]" $@
+                       return 1
+               fi
+       else
+               paramError=0
+               variableParams=$(($#-4))
+               if [ $# -lt 4 ]; then
+                       paramError=1
+               elif [ $# -eq 5 ] && [ $5 != "NOID" ]; then
+                       paramError=1
+               elif [ $# -gt 5 ] && [ $(($variableParams%5)) -ne 0 ]; then
+                       paramError=1
+               fi
+
+               if [ $paramError -ne 0 ]; then
+                       __print_err "<response-code> <ric-id>|NORIC <service-id>|NOSERVICE <policy-type-id>|NOTYPE [ NOID | [<policy-id> <ric-id> <service-id> EMPTY|<policy-type-id> <template-file>]*]" $@
+                       return 1
+               fi
        fi
 
-    if [ $paramError -ne 0 ]; then
-        __print_err "<response-code> <ric-id>|NORIC <service-id>|NOSERVICE <policy-type-id>|NOTYPE [ NOID | [<policy-id> <ric-id> <service-id> EMPTY|<policy-type-id> <template-file>]*]" $@
-        return 1
-    fi
        queryparams=""
-       if [ $2 != "NORIC" ]; then
-               queryparams="?ric="$2
-       fi
-       if [ $3 != "NOSERVICE" ]; then
-               if [ -z $queryparams ]; then
-                       queryparams="?service="$3
-               else
-                       queryparams=$queryparams"&service="$3
+       if [ "$PMS_VERSION" == "V2" ]; then
+               if [ $2 != "NORIC" ]; then
+                       queryparams="?ric_id="$2
                fi
-       fi
-       if [ $4 != "NOTYPE" ]; then
-               if [ -z $queryparams ]; then
-                       queryparams="?type="$4
-               else
-                       queryparams=$queryparams"&type="$4
+               if [ $3 != "NOSERVICE" ]; then
+                       if [ -z $queryparams ]; then
+                               queryparams="?service_id="$3
+                       else
+                               queryparams=$queryparams"&service_id="$3
+                       fi
+               fi
+               if [ $4 != "NOTYPE" ]; then
+                       if [ -z $queryparams ]; then
+                               queryparams="?policytype_id="$4
+                       else
+                               queryparams=$queryparams"&policytype_id="$4
+                       fi
                fi
-       fi
 
-       query="/policies"$queryparams
-    res="$(__do_curl_to_api PA GET $query)"
-    status=${res:${#res}-3}
+               query="/v2/policy-instances"$queryparams
+               res="$(__do_curl_to_api PA GET $query)"
+               status=${res:${#res}-3}
 
-       if [ $status -ne $1 ]; then
-               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
-               ((RES_FAIL++))
-               __check_stop_at_error
-               return 1
-       fi
+               if [ $status -ne $1 ]; then
+                       echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+                       ((RES_FAIL++))
+                       __check_stop_at_error
+                       return 1
+               fi
 
-       if [ $# -gt 4 ]; then
-               if [ $# -eq 5 ] && [ $5 == "NOID" ]; then
-                       targetJson="["
-               else
+               if [ $# -gt 4 ]; then
                        body=${res:0:${#res}-3}
-                       targetJson="["
-                       arr=(${@:5})
-
-                       for ((i=0; i<$(($#-4)); i=i+5)); do
-
-                               if [ "$targetJson" != "[" ]; then
-                                       targetJson=$targetJson","
-                               fi
-                               targetJson=$targetJson"{\"id\":\"$UUID${arr[$i]}\",\"lastModified\":\"????\",\"ric\":\"${arr[$i+1]}\",\"service\":\"${arr[$i+2]}\",\"type\":"
-                               if [ "${arr[$i+3]}" == "EMPTY" ]; then
-                                       targetJson=$targetJson"\"\","
-                               else
-                                       targetJson=$targetJson"\"${arr[$i+3]}\","
-                               fi
-                               file="./tmp/.p.json"
-                               sed 's/XXX/'${arr[$i]}'/g' ${arr[$i+4]} > $file
-                               json=$(cat $file)
-                               targetJson=$targetJson"\"json\":"$json"}"
-                       done
+                       if [ $# -eq 5 ] && [ $5 == "NOID" ]; then
+                               targetJson="["
+                       else
+                               targetJson="["
+                               arr=(${@:5})
+
+                               for ((i=0; i<$(($#-4)); i=i+7)); do
+
+                                       if [ "$targetJson" != "[" ]; then
+                                               targetJson=$targetJson","
+                                       fi
+                                       targetJson=$targetJson"{\"policy_id\":\"$UUID${arr[$i]}\",\"ric_id\":\"${arr[$i+1]}\",\"service_id\":\"${arr[$i+2]}\",\"policytype_id\":"
+                                       if [ "${arr[$i+3]}" == "EMPTY" ]; then
+                                               targetJson=$targetJson"\"\","
+                                       else
+                                               targetJson=$targetJson"\"${arr[$i+3]}\","
+                                       fi
+                                       targetJson=$targetJson"\"transient\":${arr[$i+4]},\"status_notification_uri\":\"${arr[$i+5]}\","
+                                       file="./tmp/.p.json"
+                                       sed 's/XXX/'${arr[$i]}'/g' ${arr[$i+6]} > $file
+                                       json=$(cat $file)
+                                       targetJson=$targetJson"\"policy_data\":"$json"}"
+                               done
+                       fi
+
+                       targetJson=$targetJson"]"
+                       targetJson="{\"policies\": $targetJson}"
+                       echo "TARGET JSON: $targetJson" >> $HTTPLOG
+                       res=$(python3 ../common/compare_json.py "$targetJson" "$body")
+
+                       if [ $res -ne 0 ]; then
+                               echo -e $RED" FAIL, returned body not correct"$ERED
+                               ((RES_FAIL++))
+                               __check_stop_at_error
+                               return 1
+                       fi
+               fi
+       else
+               if [ $2 != "NORIC" ]; then
+                       queryparams="?ric="$2
+               fi
+               if [ $3 != "NOSERVICE" ]; then
+                       if [ -z $queryparams ]; then
+                               queryparams="?service="$3
+                       else
+                               queryparams=$queryparams"&service="$3
+                       fi
+               fi
+               if [ $4 != "NOTYPE" ]; then
+                       if [ -z $queryparams ]; then
+                               queryparams="?type="$4
+                       else
+                               queryparams=$queryparams"&type="$4
+                       fi
                fi
 
-               targetJson=$targetJson"]"
-               echo "TARGET JSON: $targetJson" >> $HTTPLOG
-               res=$(python3 ../common/compare_json.py "$targetJson" "$body")
+               query="/policies"$queryparams
+               res="$(__do_curl_to_api PA GET $query)"
+               status=${res:${#res}-3}
 
-               if [ $res -ne 0 ]; then
-                       echo -e $RED" FAIL, returned body not correct"$ERED
+               if [ $status -ne $1 ]; then
+                       echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
                        ((RES_FAIL++))
                        __check_stop_at_error
                        return 1
                fi
+
+               if [ $# -gt 4 ]; then
+                       if [ $# -eq 5 ] && [ $5 == "NOID" ]; then
+                               targetJson="["
+                       else
+                               body=${res:0:${#res}-3}
+                               targetJson="["
+                               arr=(${@:5})
+
+                               for ((i=0; i<$(($#-4)); i=i+5)); do
+
+                                       if [ "$targetJson" != "[" ]; then
+                                               targetJson=$targetJson","
+                                       fi
+                                       targetJson=$targetJson"{\"id\":\"$UUID${arr[$i]}\",\"lastModified\":\"????\",\"ric\":\"${arr[$i+1]}\",\"service\":\"${arr[$i+2]}\",\"type\":"
+                                       if [ "${arr[$i+3]}" == "EMPTY" ]; then
+                                               targetJson=$targetJson"\"\","
+                                       else
+                                               targetJson=$targetJson"\"${arr[$i+3]}\","
+                                       fi
+                                       file="./tmp/.p.json"
+                                       sed 's/XXX/'${arr[$i]}'/g' ${arr[$i+4]} > $file
+                                       json=$(cat $file)
+                                       targetJson=$targetJson"\"json\":"$json"}"
+                               done
+                       fi
+
+                       targetJson=$targetJson"]"
+                       echo "TARGET JSON: $targetJson" >> $HTTPLOG
+                       res=$(python3 ../common/compare_json.py "$targetJson" "$body")
+
+                       if [ $res -ne 0 ]; then
+                               echo -e $RED" FAIL, returned body not correct"$ERED
+                               ((RES_FAIL++))
+                               __check_stop_at_error
+                               return 1
+                       fi
+               fi
        fi
 
        ((RES_PASS++))
@@ -139,20 +235,31 @@ api_get_policies() {
 
 }
 
-# API Test function: GET /policy
-#args: <response-code>  <policy-id> [<template-file>]
+
+# API Test function: GET /policy and V2 GET /v2/policies/{policy_id}
+# args: <response-code>  <policy-id> [<template-file>]
+# args(V2): <response-code> <policy-id> [ <template-file> <service-name> <ric-id> <policytype-id>|NOTYPE <transient> <notification-url>|NOURL ]
+
 # (Function for test scripts)
 api_get_policy() {
        echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
     echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
        ((RES_TEST++))
 
-    if [ $# -lt 2 ] || [ $# -gt 3 ]; then
-        __print_err "<response-code>  <policy-id> [<template-file>] " $@
-        return 1
-    fi
 
-       query="/policy?id=$UUID$2"
+       if [ "$PMS_VERSION" == "V2" ]; then
+               if [ $# -ne 2 ] && [ $# -ne 8 ]; then
+                       __print_err "<response-code> <policy-id> [ <template-file> <service-name> <ric-id> <policytype-id>|NOTYPE <transient> <notification-url>|NOURL ]" $@
+                       return 1
+               fi
+               query="/v2/policies/$UUID$2"
+       else
+               if [ $# -lt 2 ] || [ $# -gt 3 ]; then
+                       __print_err "<response-code>  <policy-id> [<template-file>] " $@
+                       return 1
+               fi
+               query="/policy?id=$UUID$2"
+       fi
        res="$(__do_curl_to_api PA GET $query)"
        status=${res:${#res}-3}
 
@@ -163,19 +270,54 @@ api_get_policy() {
                return 1
        fi
 
-       if [ $# -eq 3 ]; then
-               #Create a policy json to compare with
-               body=${res:0:${#res}-3}
-               file="./tmp/.p.json"
-               sed 's/XXX/'${2}'/g' $3 > $file
-               targetJson=$(< $file)
-               echo "TARGET JSON: $targetJson" >> $HTTPLOG
-               res=$(python3 ../common/compare_json.py "$targetJson" "$body")
-               if [ $res -ne 0 ]; then
-                       echo -e $RED" FAIL, returned body not correct"$ERED
-                       ((RES_FAIL++))
-                       __check_stop_at_error
-                       return 1
+       if [ "$PMS_VERSION" == "V2" ]; then
+               if [ $# -eq 8 ]; then
+
+                       #Create a policy json to compare with
+                       body=${res:0:${#res}-3}
+                       file="./tmp/.p.json"
+
+                       targetJson="\"ric_id\":\"$5\",\"policy_id\":\"$UUID$2\",\"service_id\":\"$4\""
+                       if [ $7 != "NOTRANSIENT" ]; then
+                               targetJson=$targetJson", \"transient\":$7"
+                       fi
+                       if [ $6 != "NOTYPE" ]; then
+                               targetJson=$targetJson", \"policytype_id\":\"$6\""
+                       else
+                               targetJson=$targetJson", \"policytype_id\":\"\""
+                       fi
+                       if [ $8 != "NOURL" ]; then
+                               targetJson=$targetJson", \"status_notification_uri\":\"$8\""
+                       fi
+
+                       data=$(sed 's/XXX/'${2}'/g' $temp)
+                       targetJson=$targetJson", \"policy_data\":$data"
+                       targetJson="{$targetJson}"
+
+                       echo "TARGET JSON: $targetJson" >> $HTTPLOG
+                       res=$(python3 ../common/compare_json.py "$targetJson" "$body")
+                       if [ $res -ne 0 ]; then
+                               echo -e $RED" FAIL, returned body not correct"$ERED
+                               ((RES_FAIL++))
+                               __check_stop_at_error
+                               return 1
+                       fi
+               fi
+       else
+               if [ $# -eq 3 ]; then
+                       #Create a policy json to compare with
+                       body=${res:0:${#res}-3}
+                       file="./tmp/.p.json"
+                       sed 's/XXX/'${2}'/g' $3 > $file
+                       targetJson=$(< $file)
+                       echo "TARGET JSON: $targetJson" >> $HTTPLOG
+                       res=$(python3 ../common/compare_json.py "$targetJson" "$body")
+                       if [ $res -ne 0 ]; then
+                               echo -e $RED" FAIL, returned body not correct"$ERED
+                               ((RES_FAIL++))
+                               __check_stop_at_error
+                               return 1
+                       fi
                fi
        fi
 
@@ -184,43 +326,84 @@ api_get_policy() {
        return 0
 }
 
-# API Test function: PUT /policy
-# args: <response-code> <service-name> <ric-id> <policytype-id> <policy-id> <transient> <template-file> [<count>]
+# API Test function: PUT /policy and V2 PUT /policies
+# args: <response-code> <service-name> <ric-id> <policytype-id>|NOTYPE <policy-id> <transient>|NOTRANSIENT <template-file> [<count>]
+# args(V2): <response-code> <service-name> <ric-id> <policytype-id>|NOTYPE <policy-id> <transient>|NOTRANSIENT <notification-url>|NOURL <template-file> [<count>]
 # (Function for test scripts)
 api_put_policy() {
        echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
     echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
        ((RES_TEST++))
 
-    if [ $# -lt 7 ] || [ $# -gt 8 ]; then
-        __print_err "<response-code> <service-name> <ric-id> <policytype-id> <policy-id> <transient>|NOTRANSIENT <template-file> [<count>]" $@
-        return 1
-    fi
+       if [ "$PMS_VERSION" == "V2" ]; then
+               if [ $# -lt 8 ] || [ $# -gt 9 ]; then
+                       __print_err "<response-code> <service-name> <ric-id> <policytype-id>|NOTYPE <policy-id> <transient>|NOTRANSIENT <notification-url>|NOURL <template-file> [<count>]" $@
+                       return 1
+               fi
+       else
+               if [ $# -lt 7 ] || [ $# -gt 8 ]; then
+                       __print_err "<response-code> <service-name> <ric-id> <policytype-id>|NOTYPE <policy-id> <transient>|NOTRANSIENT <template-file> [<count>]" $@
+                       return 1
+               fi
+       fi
 
-       ric=$3
        count=0
        max=1
+       serv=$2
+       ric=$3
+       pt=$4
+       pid=$5
+       trans=$6
 
-       if [ $# -eq 8 ]; then
-               max=$8
+       if [ "$PMS_VERSION" == "V2" ]; then
+               noti=$7
+               temp=$8
+               if [ $# -eq 9 ]; then
+                       max=$9
+               fi
+       else
+               temp=$7
+               if [ $# -eq 8 ]; then
+                       max=$8
+               fi
        fi
 
-       pid=$5
-       file=$7
-
        while [ $count -lt $max ]; do
-               query="/policy?id=$UUID$pid&ric=$ric&service=$2"
+               if [ "$PMS_VERSION" == "V2" ]; then
 
-               if [ $4 != "NOTYPE" ]; then
-                       query=$query"&type=$4"
-               fi
+                       query="/v2/policies"
 
-               if [ $6 != NOTRANSIENT ]; then
-                       query=$query"&transient=$6"
-               fi
+                       inputJson="\"ric_id\":\"$ric\",\"policy_id\":\"$UUID$pid\",\"service_id\":\"$serv\""
+                       if [ $trans != "NOTRANSIENT" ]; then
+                               inputJson=$inputJson", \"transient\":$trans"
+                       fi
+                       if [ $pt != "NOTYPE" ]; then
+                               inputJson=$inputJson", \"policytype_id\":\"$pt\""
+                       else
+                               inputJson=$inputJson", \"policytype_id\":\"\""
+                       fi
+                       if [ $noti != "NOURL" ]; then
+                               inputJson=$inputJson", \"status_notification_uri\":\"$noti\""
+                       fi
+                       file="./tmp/.p.json"
+                       data=$(sed 's/XXX/'${pid}'/g' $temp)
+                       inputJson=$inputJson", \"policy_data\":$data"
+                       inputJson="{$inputJson}"
+                       echo $inputJson > $file
+               else
+                       query="/policy?id=$UUID$pid&ric=$ric&service=$serv"
 
-               file="./tmp/.p.json"
-               sed 's/XXX/'${pid}'/g' $7 > $file
+                       if [ $pt != "NOTYPE" ]; then
+                               query=$query"&type=$pt"
+                       fi
+
+                       if [ $trans != NOTRANSIENT ]; then
+                               query=$query"&transient=$trans"
+                       fi
+
+                       file="./tmp/.p.json"
+                       sed 's/XXX/'${pid}'/g' $temp > $file
+               fi
        res="$(__do_curl_to_api PA PUT $query $file)"
        status=${res:${#res}-3}
                echo -ne " Executing "$count"("$max")${SAMELINE}"
@@ -243,43 +426,83 @@ api_put_policy() {
        return 0
 }
 
-# API Test function: PUT /policy to run in batch
-# args: <response-code> <service-name> <ric-id> <policytype-id> <policy-id> <transient> <template-file> [<count>]
+# API Test function: PUT /policy and V2 PUT /policies, to run in batch
+# args: <response-code> <service-name> <ric-id> <policytype-id>|NOTYPE <policy-id> <transient> <template-file> [<count>]
+# args(V2): <response-code> <service-name> <ric-id> <policytype-id>|NOTYPE <policy-id> <transient> <notification-url>|NOURL <template-file> [<count>]
 # (Function for test scripts)
+
 api_put_policy_batch() {
        echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
     echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
        ((RES_TEST++))
 
-    if [ $# -lt 7 ] || [ $# -gt 8 ]; then
-        __print_err "<response-code> <service-name> <ric-id> <policytype-id> <policy-id> <transient> <template-file> [<count>]" $@
-        return 1
-    fi
+       if [ "$PMS_VERSION" == "V2" ]; then
+               if [ $# -lt 8 ] || [ $# -gt 9 ]; then
+                       __print_err "<response-code> <service-name> <ric-id> <policytype-id>|NOTYPE <policy-id> <transient> <notification-url>|NOURL <template-file> [<count>]" $@
+                       return 1
+               fi
+       else
+               if [ $# -lt 7 ] || [ $# -gt 8 ]; then
+                       __print_err "<response-code> <service-name> <ric-id> <policytype-id>|NOTYPE <policy-id> <transient> <template-file> [<count>]" $@
+                       return 1
+               fi
+       fi
 
-       ric=$3
        count=0
        max=1
-
-       if [ $# -eq 8 ]; then
-               max=$8
+       serv=$2
+       ric=$3
+       pt=$4
+       pid=$5
+       trans=$6
+       if [ "$PMS_VERSION" == "V2" ]; then
+               noti=$7
+               temp=$8
+               if [ $# -eq 9 ]; then
+                       max=$9
+               fi
+       else
+               temp=$7
+               if [ $# -eq 8 ]; then
+                       max=$8
+               fi
        fi
 
-       pid=$5
-       file=$7
        ARR=""
        while [ $count -lt $max ]; do
-               query="/policy?id=$UUID$pid&ric=$ric&service=$2"
+               if [ "$PMS_VERSION" == "V2" ]; then
+                       query="/v2/policies"
 
-               if [ $4 != "NOTYPE" ]; then
-                       query=$query"&type=$4"
-               fi
+                       inputJson="\"ric_id\":\"$ric\",\"policy_id\":\"$UUID$pid\",\"service_id\":\"$serv\""
+                       if [ $trans != "NOTRANSIENT" ]; then
+                               inputJson=$inputJson", \"transient\":$trans"
+                       fi
+                       if [ $pt != "NOTYPE" ]; then
+                               inputJson=$inputJson", \"policytype_id\":\"$pt\""
+                       else
+                               inputJson=$inputJson", \"policytype_id\":\"\""
+                       fi
+                       if [ $noti != "NOURL" ]; then
+                               inputJson=$inputJson", \"status_notification_uri\":\"$noti\""
+                       fi
+                       file="./tmp/.p.json"
+                       data=$(sed 's/XXX/'${pid}'/g' $temp)
+                       inputJson=$inputJson", \"policy_data\":$data"
+                       inputJson="{$inputJson}"
+                       echo $inputJson > $file
+               else
+                       query="/policy?id=$UUID$pid&ric=$ric&service=$serv"
 
-               if [ $6 != NOTRANSIENT ]; then
-                       query=$query"&transient=$6"
-               fi
+                       if [ $pt != "NOTYPE" ]; then
+                               query=$query"&type=$pt"
+                       fi
 
-               file="./tmp/.p.json"
-               sed 's/XXX/'${pid}'/g' $7 > $file
+                       if [ $trans != NOTRANSIENT ]; then
+                               query=$query"&transient=$trans"
+                       fi
+                       file="./tmp/.p.json"
+                       sed 's/XXX/'${pid}'/g' $temp > $file
+               fi
        res="$(__do_curl_to_api PA PUT_BATCH $query $file)"
        status=${res:${#res}-3}
                echo -ne " Requesting(batch) "$count"("$max")${SAMELINE}"
@@ -304,10 +527,10 @@ api_put_policy_batch() {
 
        res="$(__do_curl_to_api PA RESPONSE $cid)"
        status=${res:${#res}-3}
-               echo -ne " Requesting(batch) "$count"("$max")${SAMELINE}"
+               echo -ne " Accepting(batch) "$count"("$max")${SAMELINE}"
 
                if [ $status -ne $1 ]; then
-                       echo " Requested(batch) "$count"?("$max")"
+                       echo " Accepted(batch) "$count"?("$max")"
                        echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
                        ((RES_FAIL++))
                        __check_stop_at_error
@@ -315,7 +538,7 @@ api_put_policy_batch() {
                fi
 
                let count=$count+1
-               echo -ne " Requested(batch)  "$count"("$max")${SAMELINE}"
+               echo -ne " Accepted(batch)  "$count"("$max")${SAMELINE}"
        done
 
        echo ""
@@ -325,18 +548,26 @@ api_put_policy_batch() {
        return 0
 }
 
-# API Test function: PUT /policy to run in i parallel for a number of rics
+# API Test function: PUT /policy and V2 PUT /policies, to run in i parallel for a number of rics
 # args: <response-code> <service-name> <ric-id-base> <number-of-rics> <policytype-id> <policy-start-id> <transient> <template-file> <count-per-ric> <number-of-threads>
+# args(V2): <response-code> <service-name> <ric-id-base> <number-of-rics> <policytype-id> <policy-start-id> <transient> <notification-url>|NOURL <template-file> <count-per-ric> <number-of-threads>
 # (Function for test scripts)
 api_put_policy_parallel() {
        echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
     echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
        ((RES_TEST++))
 
-    if [ $# -ne 10 ]; then
-        __print_err " <response-code> <service-name> <ric-id-base> <number-of-rics> <policytype-id> <policy-start-id> <transient> <template-file> <count-per-ric> <number-of-threads>" $@
-        return 1
-    fi
+       if [ "$PMS_VERSION" == "V2" ]; then
+               if [ $# -ne 11 ]; then
+                       __print_err "<response-code> <service-name> <ric-id-base> <number-of-rics> <policytype-id> <policy-start-id> <transient> <notification-url>|NOURL <template-file> <count-per-ric> <number-of-threads>" $@
+                       return 1
+               fi
+       else
+               if [ $# -ne 10 ]; then
+                       __print_err " <response-code> <service-name> <ric-id-base> <number-of-rics> <policytype-id> <policy-start-id> <transient> <template-file> <count-per-ric> <number-of-threads>" $@
+                       return 1
+               fi
+       fi
        resp_code=$1; shift;
        serv=$1; shift
        ric_base=$1; shift;
@@ -344,6 +575,11 @@ api_put_policy_parallel() {
        type=$1; shift;
        start_id=$1; shift;
        transient=$1; shift;
+       if [ "$PMS_VERSION" == "V2" ]; then
+               noti=$1; shift;
+       else
+               noti=""
+       fi
        template=$1; shift;
        count=$1; shift;
        pids=$1; shift;
@@ -352,18 +588,24 @@ api_put_policy_parallel() {
                echo " Info - api_put_policy_parallel uses only the agent REST interface - create over dmaap in parallel is not supported"
                echo " Info - will execute over agent REST"
        fi
+       if [ "$PMS_VERSION" == "V2" ]; then
+               if [ $serv == "NOSERVICE" ]; then
+                       serv=""
+               fi
+               query="/v2/policies"
+       else
+               if [ $serv == "NOSERVICE" ]; then
+                       serv=""
+               fi
+               query="/policy?service=$serv"
 
-       if [ $serv == "NOSERVICE" ]; then
-               serv=""
-       fi
-       query="/policy?service=$serv"
-
-       if [ $type != "NOTYPE" ]; then
-               query=$query"&type=$type"
-       fi
+               if [ $type != "NOTYPE" ]; then
+                       query=$query"&type=$type"
+               fi
 
-       if [ $transient != NOTRANSIENT ]; then
-               query=$query"&transient=$transient"
+               if [ $transient != NOTRANSIENT ]; then
+                       query=$query"&transient=$transient"
+               fi
        fi
 
        urlbase=${ADAPTER}${query}
@@ -375,7 +617,11 @@ api_put_policy_parallel() {
                        uuid="NOUUID"
                fi
                echo "" > "./tmp/.pid${i}.res.txt"
-               echo $resp_code $urlbase $ric_base $num_rics $uuid $start_id $template $count $pids $i > "./tmp/.pid${i}.txt"
+               if [ "$PMS_VERSION" == "V2" ]; then
+                       echo $resp_code $urlbase $ric_base $num_rics $uuid $start_id $serv $type $transient $noti $template $count $pids $i > "./tmp/.pid${i}.txt"
+               else
+                       echo $resp_code $urlbase $ric_base $num_rics $uuid $start_id $template $count $pids $i > "./tmp/.pid${i}.txt"
+               fi
                echo $i
        done  | xargs -n 1 -I{} -P $pids bash -c '{
                arg=$(echo {})
@@ -394,7 +640,7 @@ api_put_policy_parallel() {
                else
                        res=${tmp:0:1}
                        if [ $res == "0" ]; then
-                               echo " Process $i : OK"
+                               echo " Process $i : OK - "${tmp:1}
                        else
                                echo " Process $i : failed - "${tmp:1}
                                msg="failed"
@@ -414,7 +660,7 @@ api_put_policy_parallel() {
        return 1
 }
 
-# API Test function: DELETE /policy
+# API Test function: DELETE /policy and V2 DELETE /v2/policies/{policy_id}
 # args: <response-code> <policy-id> [count]
 # (Function for test scripts)
 api_delete_policy() {
@@ -437,7 +683,11 @@ api_delete_policy() {
        pid=$2
 
        while [ $count -lt $max ]; do
-               query="/policy?id="$UUID$pid
+               if [ "$PMS_VERSION" == "V2" ]; then
+                       query="/v2/policies/"$UUID$pid
+               else
+                       query="/policy?id="$UUID$pid
+               fi
                res="$(__do_curl_to_api PA DELETE $query)"
                status=${res:${#res}-3}
                echo -ne " Executing "$count"("$max")${SAMELINE}"
@@ -460,7 +710,7 @@ api_delete_policy() {
        return 0
 }
 
-# API Test function: DELETE /policy to run in batch
+# API Test function: DELETE /policy and V2 DELETE /v2/policies/{policy_id}, to run in batch
 # args: <response-code> <policy-id> [count]
 # (Function for test scripts)
 api_delete_policy_batch() {
@@ -483,7 +733,11 @@ api_delete_policy_batch() {
        pid=$2
        ARR=""
        while [ $count -lt $max ]; do
-               query="/policy?id="$UUID$pid
+               if [ "$PMS_VERSION" == "V2" ]; then
+                       query="/v2/policies/"$UUID$pid
+               else
+                       query="/policy?id="$UUID$pid
+               fi
                res="$(__do_curl_to_api PA DELETE_BATCH $query)"
                status=${res:${#res}-3}
                echo -ne " Requesting(batch) "$count"("$max")${SAMELINE}"
@@ -509,7 +763,7 @@ api_delete_policy_batch() {
 
        res="$(__do_curl_to_api PA RESPONSE $cid)"
        status=${res:${#res}-3}
-               echo -ne " Deleted(batch) "$count"("$max")${SAMELINE}"
+               echo -ne " Deleting(batch) "$count"("$max")${SAMELINE}"
 
                if [ $status -ne $1 ]; then
                        echo " Deleted(batch) "$count"?("$max")"
@@ -523,12 +777,14 @@ api_delete_policy_batch() {
                echo -ne " Deleted(batch)  "$count"("$max")${SAMELINE}"
        done
 
+       echo ""
+
        ((RES_PASS++))
        echo -e $GREEN" PASS"$EGREEN
        return 0
 }
 
-# API Test function: DELETE /policy to run in i parallel for a number of rics
+# API Test function: DELETE /policy and V2 DELETE /v2/policies/{policy_id}, to run in i parallel for a number of rics
 # args: <response-code> <number-of-rics> <policy-start-id> <count-per-ric> <number-of-threads>
 # (Function for test scripts)
 api_delete_policy_parallel() {
@@ -551,7 +807,11 @@ api_delete_policy_parallel() {
                echo " Info - will execute over agent REST"
        fi
 
-       query="/policy"
+       if [ "$PMS_VERSION" == "V2" ]; then
+               query="/v2/policies/"
+       else
+               query="/policy"
+       fi
 
        urlbase=${ADAPTER}${query}
 
@@ -567,8 +827,8 @@ api_delete_policy_parallel() {
        done  | xargs -n 1 -I{} -P $pids bash -c '{
                arg=$(echo {})
                echo " Parallel process $arg started"
-               tmp=$(< "./tmp/pid${arg}.del.txt")
-               python3 ../common/delete_policies_process.py $tmp > ./tmp/pid${arg}.del.res.txt
+               tmp=$(< "./tmp/.pid${arg}.del.txt")
+               python3 ../common/delete_policies_process.py $tmp > ./tmp/.pid${arg}.del.res.txt
        }'
        msg=""
        for ((i=1; i<=$pids; i++))
@@ -581,7 +841,7 @@ api_delete_policy_parallel() {
                else
                        res=${tmp:0:1}
                        if [ $res == "0" ]; then
-                               echo " Process $i : OK"
+                               echo " Process $i : OK - "${tmp:1}
                        else
                                echo " Process $i : failed - "${tmp:1}
                                msg="failed"
@@ -601,7 +861,7 @@ api_delete_policy_parallel() {
        return 1
 }
 
-# API Test function: GET /policy_ids
+# API Test function: GET /policy_ids and V2 GET /v2/policies
 # args: <response-code> <ric-id>|NORIC <service-id>|NOSERVICE <type-id>|NOTYPE ([<policy-instance-id]*|NOID)
 # (Function for test scripts)
 api_get_policy_ids() {
@@ -616,26 +876,50 @@ api_get_policy_ids() {
 
        queryparams=""
 
-       if [ $2 != "NORIC" ]; then
-               queryparams="?ric="$2
-       fi
+       if [ "$PMS_VERSION" == "V2" ]; then
+               if [ $2 != "NORIC" ]; then
+                       queryparams="?ric_id="$2
+               fi
 
-       if [ $3 != "NOSERVICE" ]; then
-               if [ -z $queryparams ]; then
-                       queryparams="?service="$3
-               else
-                       queryparams=$queryparams"&service="$3
+               if [ $3 != "NOSERVICE" ]; then
+                       if [ -z $queryparams ]; then
+                               queryparams="?service_id="$3
+                       else
+                               queryparams=$queryparams"&service_id="$3
+                       fi
                fi
-       fi
-       if [ $4 != "NOTYPE" ]; then
-               if [ -z $queryparams ]; then
-                       queryparams="?type="$4
-               else
-                       queryparams=$queryparams"&type="$4
+               if [ $4 != "NOTYPE" ]; then
+                       if [ -z $queryparams ]; then
+                               queryparams="?policytype_id="$4
+                       else
+                               queryparams=$queryparams"&policytype_id="$4
+                       fi
+               fi
+
+               query="/v2/policies"$queryparams
+       else
+               if [ $2 != "NORIC" ]; then
+                       queryparams="?ric="$2
                fi
+
+               if [ $3 != "NOSERVICE" ]; then
+                       if [ -z $queryparams ]; then
+                               queryparams="?service="$3
+                       else
+                               queryparams=$queryparams"&service="$3
+                       fi
+               fi
+               if [ $4 != "NOTYPE" ]; then
+                       if [ -z $queryparams ]; then
+                               queryparams="?type="$4
+                       else
+                               queryparams=$queryparams"&type="$4
+                       fi
+               fi
+
+               query="/policy_ids"$queryparams
        fi
 
-       query="/policy_ids"$queryparams
     res="$(__do_curl_to_api PA GET $query)"
     status=${res:${#res}-3}
 
@@ -660,6 +944,62 @@ api_get_policy_ids() {
                done
 
                targetJson=$targetJson"]"
+               if [ "$PMS_VERSION" == "V2" ]; then
+                       targetJson="{\"policy_ids\": $targetJson}"
+               fi
+               echo "TARGET JSON: $targetJson" >> $HTTPLOG
+               res=$(python3 ../common/compare_json.py "$targetJson" "$body")
+
+               if [ $res -ne 0 ]; then
+                       echo -e $RED" FAIL, returned body not correct"$ERED
+                       ((RES_FAIL++))
+                       __check_stop_at_error
+                       return 1
+               fi
+       fi
+
+       ((RES_PASS++))
+       echo -e $GREEN" PASS"$EGREEN
+       return 0
+}
+
+# API Test function: V2 GET /v2/policy-types/{policyTypeId}
+# args(V2): <response-code> <policy-type-id> [<schema-file>]
+# (Function for test scripts)
+api_get_policy_type() {
+       echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       ((RES_TEST++))
+
+       if [ "$PMS_VERSION" != "V2" ]; then
+               echo -e $RED" FAIL, function not supported"$ERED
+               ((RES_FAIL++))
+               __check_stop_at_error
+               return 1
+       fi
+
+    if [ $# -lt 2 ] || [ $# -gt 3 ]; then
+        __print_err "<response-code> <policy-type-id> [<schema-file>]" $@
+        return 1
+    fi
+       query="/v2/policy-types/$2"
+
+       res="$(__do_curl_to_api PA GET $query)"
+       status=${res:${#res}-3}
+
+       if [ $status -ne $1 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+               ((RES_FAIL++))
+               __check_stop_at_error
+               return 1
+       fi
+
+       if [ $# -eq 3 ]; then
+
+               body=${res:0:${#res}-3}
+
+               targetJson=$(< $3)
+               targetJson="{\"policy_schema\":$targetJson}"
                echo "TARGET JSON: $targetJson" >> $HTTPLOG
                res=$(python3 ../common/compare_json.py "$targetJson" "$body")
 
@@ -684,11 +1024,17 @@ api_get_policy_schema() {
     echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
        ((RES_TEST++))
 
+       if [ "$PMS_VERSION" == "V2" ]; then
+               echo -e $RED" FAIL, function not supported"$ERED
+               ((RES_FAIL++))
+               __check_stop_at_error
+               return 1
+       fi
+
     if [ $# -lt 2 ] || [ $# -gt 3 ]; then
         __print_err "<response-code> <policy-type-id> [<schema-file>]" $@
         return 1
     fi
-
        query="/policy_schema?id=$2"
        res="$(__do_curl_to_api PA GET $query)"
        status=${res:${#res}-3}
@@ -705,6 +1051,7 @@ api_get_policy_schema() {
                body=${res:0:${#res}-3}
 
                targetJson=$(< $3)
+
                echo "TARGET JSON: $targetJson" >> $HTTPLOG
                res=$(python3 ../common/compare_json.py "$targetJson" "$body")
 
@@ -723,20 +1070,31 @@ api_get_policy_schema() {
 
 # API Test function: GET /policy_schemas
 # args: <response-code>  <ric-id>|NORIC [<schema-file>|NOFILE]*
+# args(V2): <response-code>
 # (Function for test scripts)
 api_get_policy_schemas() {
        echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
     echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
        ((RES_TEST++))
 
-    if [ $# -lt 2 ]; then
-        __print_err "<response-code> <ric-id>|NORIC [<schema-file>|NOFILE]*" $@
-        return 1
-    fi
-
-       query="/policy_schemas"
-       if [ $2 != "NORIC" ]; then
-               query=$query"?ric="$2
+       if [ "$PMS_VERSION" == "V2" ]; then
+               if [ $# -ne 1 ]; then
+                       __print_err "<response-code>" $@
+                       return 1
+               fi
+       else
+               if [ $# -lt 2 ]; then
+                       __print_err "<response-code> <ric-id>|NORIC [<schema-file>|NOFILE]*" $@
+                       return 1
+               fi
+       fi
+       if [ "$PMS_VERSION" == "V2" ]; then
+               query="/v2/policy-schemas"
+       else
+               query="/policy_schemas"
+               if [ $2 != "NORIC" ]; then
+                       query=$query"?ric="$2
+               fi
        fi
 
        res="$(__do_curl_to_api PA GET $query)"
@@ -765,6 +1123,9 @@ api_get_policy_schemas() {
                done
 
                targetJson=$targetJson"]"
+               if [ "$PMS_VERSION" == "V2" ]; then
+                       targetJson="{\"policy_schemas\": $targetJson }"
+               fi
                echo "TARGET JSON: $targetJson" >> $HTTPLOG
                res=$(python3 ../common/compare_json.py "$targetJson" "$body")
 
@@ -781,13 +1142,14 @@ api_get_policy_schemas() {
        return 0
 }
 
-# API Test function: GET /policy_status
+# API Test function: GET /policy_status and V2 GET /policies/{policy_id}/status
 # arg: <response-code> <policy-id> (STD <enforce-status> [<reason>])|(OSC <instance-status> <has-been-deleted>)
 # (Function for test scripts)
 api_get_policy_status() {
        echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
     echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
        ((RES_TEST++))
+
     if [ $# -lt 4 ] || [ $# -gt 5 ]; then
                __print_err "<response-code> <policy-id> (STD <enforce-status> [<reason>])|(OSC <instance-status> <has-been-deleted>)" $@
                return 1
@@ -812,7 +1174,12 @@ api_get_policy_status() {
                return 1
        fi
 
-       query="/policy_status?id="$UUID$2
+       if [ "$PMS_VERSION" == "V2" ]; then
+               query="/v2/policies/$UUID$2/status"
+               targetJson="{\"last_modified\":\"????\",\"status\":$targetJson}"
+       else
+               query="/policy_status?id="$UUID$2
+       fi
 
        res="$(__do_curl_to_api PA GET $query)"
     status=${res:${#res}-3}
@@ -840,7 +1207,7 @@ api_get_policy_status() {
        return 0
 }
 
-# API Test function: GET /policy_types
+# API Test function: GET /policy_types and V2 GET /v2/policy-types
 # args: <response-code> [<ric-id>|NORIC [<policy-type-id>|EMPTY [<policy-type-id>]*]]
 # (Function for test scripts)
 api_get_policy_types() {
@@ -853,12 +1220,22 @@ api_get_policy_types() {
                return 1
        fi
 
-       if [ $# -eq 1 ]; then
-               query="/policy_types"
-       elif [ $2 == "NORIC" ]; then
-               query="/policy_types"
+       if [ "$PMS_VERSION" == "V2" ]; then
+               if [ $# -eq 1 ]; then
+                       query="/v2/policy-types"
+               elif [ $2 == "NORIC" ]; then
+                       query="/v2/policy-types"
+               else
+                       query="/v2/policy-types?ric_id=$2"
+               fi
        else
-               query="/policy_types?ric=$2"
+               if [ $# -eq 1 ]; then
+                       query="/policy_types"
+               elif [ $2 == "NORIC" ]; then
+                       query="/policy_types"
+               else
+                       query="/policy_types?ric=$2"
+               fi
        fi
 
     res="$(__do_curl_to_api PA GET $query)"
@@ -886,6 +1263,9 @@ api_get_policy_types() {
                done
 
                targetJson=$targetJson"]"
+               if [ "$PMS_VERSION" == "V2" ]; then
+                       targetJson="{\"policytype_ids\": $targetJson }"
+               fi
                echo "TARGET JSON: $targetJson" >> $HTTPLOG
                res=$(python3 ../common/compare_json.py "$targetJson" "$body")
 
@@ -906,7 +1286,7 @@ api_get_policy_types() {
 #### Test case functions Health check
 #########################################################
 
-# API Test function: GET /status
+# API Test function: GET /status and V2 GET /status
 # args: <response-code>
 # (Function for test scripts)
 api_get_status() {
@@ -917,7 +1297,11 @@ api_get_status() {
                __print_err "<response-code>" $@
                return 1
        fi
-    query="/status"
+       if [ "$PMS_VERSION" == "V2" ]; then
+               query="/v2/status"
+       else
+               query="/status"
+       fi
     res="$(__do_curl_to_api PA GET $query)"
     status=${res:${#res}-3}
 
@@ -937,46 +1321,102 @@ api_get_status() {
 #### Test case functions RIC Repository
 #########################################################
 
-# API Test function: GET /ric
+# API Test function: GET /ric and V2 GET /v2/rics/ric
 # args: <reponse-code> <management-element-id> [<ric-id>]
+# (V2) args: <reponse-code> <management-element-id>|NOME <ric-id>|<NORIC> [<string-of-ricinfo>]
+# (V2) example of <string-of-ricinfo> = "ricsim_g1_1:me1_ricsim_g1_1,me2_ricsim_g1_1:1,2,4"
+# (V2) format of ric-info:  <ric-id>:<list-of-mes>:<list-of-policy-type-ids>
+
+
 # (Function for test scripts)
 api_get_ric() {
        echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
     echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
        ((RES_TEST++))
-    if [ $# -lt 2 ] || [ $# -gt 3 ]; then
-               __print_err "<reponse-code> <management-element-id> [<ric-id>]" $@
-               return 1
-       fi
 
-       query="/ric?managedElementId="$2
+       if [ "$PMS_VERSION" == "V2" ]; then
+               if [ $# -lt 3 ]; then
+                       __print_err "<reponse-code> <management-element-id>|NOME <ric-id>|<NORIC> [string-of-ricinfo>]" $@
+                       return 1
+               fi
+               search=""
+               if [ $2 != "NOME" ]; then
+                       search="?managed_element_id="$2
+               fi
+               if [ $3 != "NORIC" ]; then
+                       if [ -z $search ]; then
+                               search="?ric_id="$3
+                       else
+                               search=$search"&ric_id="$3
+                       fi
+               fi
+               query="/v2/rics/ric"$search
 
-    res="$(__do_curl_to_api PA GET $query)"
-    status=${res:${#res}-3}
+               res="$(__do_curl_to_api PA GET $query)"
+               status=${res:${#res}-3}
 
-       if [ $status -ne $1 ]; then
-               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
-               ((RES_FAIL++))
-               __check_stop_at_error
-               return 1
-       fi
+               if [ $status -ne $1 ]; then
+                       echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+                       ((RES_FAIL++))
+                       __check_stop_at_error
+                       return 1
+               fi
 
-       if [ $# -eq 3 ]; then
-               body=${res:0:${#res}-3}
-               if [ "$body" != "$3" ]; then
-                       echo -e $RED" FAIL, returned body not correct"$ERED
+               if [ $# -gt 3 ]; then
+                       body=${res:0:${#res}-3}
+                       res=$(python3 ../common/create_rics_json.py "./tmp/.tmp_rics.json" "V2" "$4" )
+                       if [ $res -ne 0 ]; then
+                               echo -e $RED" FAIL, could not create target ric info json"$ERED
+                               ((RES_FAIL++))
+                               __check_stop_at_error
+                               return 1
+                       fi
+
+                       targetJson=$(<./tmp/.tmp_rics.json)
+                       targetJson=${targetJson:1:${#targetJson}-2} #remove array brackets
+                       echo " TARGET JSON: $targetJson" >> $HTTPLOG
+                       res=$(python3 ../common/compare_json.py "$targetJson" "$body")
+                       if [ $res -ne 0 ]; then
+                               echo -e $RED" FAIL, returned body not correct"$ERED
+                               ((RES_FAIL++))
+                               __check_stop_at_error
+                               return 1
+                       fi
+               fi
+       else
+               if [ $# -lt 2 ] || [ $# -gt 3 ]; then
+                       __print_err "<reponse-code> <management-element-id> [<ric-id>]" $@
+                       return 1
+               fi
+
+               query="/ric?managedElementId="$2
+
+               res="$(__do_curl_to_api PA GET $query)"
+               status=${res:${#res}-3}
+
+               if [ $status -ne $1 ]; then
+                       echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
                        ((RES_FAIL++))
                        __check_stop_at_error
                        return 1
                fi
-       fi
 
+               if [ $# -eq 3 ]; then
+                       body=${res:0:${#res}-3}
+                       if [ "$body" != "$3" ]; then
+                               echo -e $RED" FAIL, returned body not correct"$ERED
+                               ((RES_FAIL++))
+                               __check_stop_at_error
+                               return 1
+                       fi
+               fi
+       fi
        ((RES_PASS++))
        echo -e $GREEN" PASS"$EGREEN
        return 0
 }
 
-# API test function: GET /rics
+# API test function: GET /rics and V2 GET /v2/rics
 # args: <reponse-code> <policy-type-id>|NOTYPE [<space-separate-string-of-ricinfo>]
 # example of <space-separate-string-of-ricinfo> = "ricsim_g1_1:me1_ricsim_g1_1,me2_ricsim_g1_1:1,2,4 ricsim_g1_1:me2_........."
 # format of ric-info:  <ric-id>:<list-of-mes>:<list-of-policy-type-ids>
@@ -991,9 +1431,16 @@ api_get_rics() {
                return 1
        fi
 
-       query="/rics"
-       if [ $2 != "NOTYPE" ]; then
-       query="/rics?policyType="$2
+       if [ "$PMS_VERSION" == "V2" ]; then
+               query="/v2/rics"
+               if [ $2 != "NOTYPE" ]; then
+                       query="/v2/rics?policytype_id="$2
+               fi
+       else
+               query="/rics"
+               if [ $2 != "NOTYPE" ]; then
+                       query="/rics?policyType="$2
+               fi
        fi
 
     res="$(__do_curl_to_api PA GET $query)"
@@ -1008,7 +1455,11 @@ api_get_rics() {
 
        if [ $# -gt 2 ]; then
                body=${res:0:${#res}-3}
-               res=$(python3 ../common/create_rics_json.py "./tmp/.tmp_rics.json" "$3" )
+               if [ "$PMS_VERSION" == "V2" ]; then
+                       res=$(python3 ../common/create_rics_json.py "./tmp/.tmp_rics.json" "V2" "$3" )
+               else
+                       res=$(python3 ../common/create_rics_json.py "./tmp/.tmp_rics.json" "V1" "$3" )
+               fi
                if [ $res -ne 0 ]; then
                        echo -e $RED" FAIL, could not create target ric info json"$ERED
                        ((RES_FAIL++))
@@ -1017,6 +1468,9 @@ api_get_rics() {
                fi
 
                targetJson=$(<./tmp/.tmp_rics.json)
+               if [ "$PMS_VERSION" == "V2" ]; then
+                       targetJson="{\"rics\": $targetJson }"
+               fi
        echo "TARGET JSON: $targetJson" >> $HTTPLOG
                res=$(python3 ../common/compare_json.py "$targetJson" "$body")
                if [ $res -ne 0 ]; then
@@ -1036,7 +1490,7 @@ api_get_rics() {
 #### API Test case functions Service registry and supervision ####
 ##################################################################
 
-# API test function: PUT /service
+# API test function: PUT /service and V2 PUT /service
 # args: <response-code>  <service-name> <keepalive-timeout> <callbackurl>
 # (Function for test scripts)
 api_put_service() {
@@ -1048,8 +1502,13 @@ api_put_service() {
         return 1
     fi
 
-    query="/service"
-    json="{\"callbackUrl\": \""$4"\",\"keepAliveIntervalSeconds\": \""$3"\",\"serviceName\": \""$2"\"}"
+       if [ "$PMS_VERSION" == "V2" ]; then
+               query="/v2/services"
+               json="{\"callback_url\": \""$4"\",\"keep_alive_interval_seconds\": \""$3"\",\"service_id\": \""$2"\"}"
+       else
+               query="/service"
+               json="{\"callbackUrl\": \""$4"\",\"keepAliveIntervalSeconds\": \""$3"\",\"serviceName\": \""$2"\"}"
+       fi
     file="./tmp/.tmp.json"
        echo "$json" > $file
 
@@ -1068,7 +1527,7 @@ api_put_service() {
        return 0
 }
 
-# API test function: GET /services
+# API test function: GET /services and V2 GET /v2/services
 #args: <response-code> [ (<query-service-name> <target-service-name> <keepalive-timeout> <callbackurl>) | (NOSERVICE <target-service-name> <keepalive-timeout> <callbackurl> [<target-service-name> <keepalive-timeout> <callbackurl>]* )]
 # (Function for test scripts)
 api_get_services() {
@@ -1095,12 +1554,19 @@ api_get_services() {
                return 1
        fi
 
-    query="/services"
+       if [ "$PMS_VERSION" == "V2" ]; then
+               query="/v2/services"
 
-    if [ $# -gt 1 ] && [ $2 != "NOSERVICE" ]; then
-       query="/services?name="$2
-       fi
+               if [ $# -gt 1 ] && [ $2 != "NOSERVICE" ]; then
+                       query="/v2/services?service_id="$2
+               fi
+       else
+               query="/services"
 
+               if [ $# -gt 1 ] && [ $2 != "NOSERVICE" ]; then
+                       query="/services?name="$2
+               fi
+       fi
     res="$(__do_curl_to_api PA GET $query)"
     status=${res:${#res}-3}
 
@@ -1125,10 +1591,17 @@ api_get_services() {
                                targetJson=$targetJson","
                        fi
                        # timeSinceLastActivitySeconds value cannot be checked since value varies
-                       targetJson=$targetJson"{\"serviceName\": \""$servicename"\",\"keepAliveIntervalSeconds\": "$timeout",\"timeSinceLastActivitySeconds\":\"????\",\"callbackUrl\": \""$callback"\"}"
+                       if [ "$PMS_VERSION" == "V2" ]; then
+                               targetJson=$targetJson"{\"service_id\": \""$servicename"\",\"keep_alive_interval_seconds\": "$timeout",\"time_since_last_activity_seconds\":\"????\",\"callback_url\": \""$callback"\"}"
+                       else
+                               targetJson=$targetJson"{\"serviceName\": \""$servicename"\",\"keepAliveIntervalSeconds\": "$timeout",\"timeSinceLastActivitySeconds\":\"????\",\"callbackUrl\": \""$callback"\"}"
+                       fi
                        let cntr=cntr+3
                done
                targetJson=$targetJson"]"
+               if [ "$PMS_VERSION" == "V2" ]; then
+                       targetJson="{\"service_list\": $targetJson }"
+               fi
                echo "TARGET JSON: $targetJson" >> $HTTPLOG
                res=$(python3 ../common/compare_json.py "$targetJson" "$body")
                if [ $res -ne 0 ]; then
@@ -1144,7 +1617,7 @@ api_get_services() {
        return 0
 }
 
-# API test function: GET /services  (only checking service names)
+# API test function: GET /services V2 GET /v2/services -  (only checking service names)
 # args: <response-code> [<service-name>]*"
 # (Function for test scripts)
 api_get_service_ids() {
@@ -1157,7 +1630,11 @@ api_get_service_ids() {
                return 1
        fi
 
-    query="/services"
+       if [ "$PMS_VERSION" == "V2" ]; then
+           query="/v2/services"
+       else
+       query="/services"
+       fi
     res="$(__do_curl_to_api PA GET $query)"
     status=${res:${#res}-3}
 
@@ -1174,10 +1651,17 @@ api_get_service_ids() {
                if [ "$targetJson" != "[" ]; then
                        targetJson=$targetJson","
                fi
-               targetJson=$targetJson"{\"callbackUrl\":\"????\",\"keepAliveIntervalSeconds\":\"????\",\"serviceName\":\""$rapp"\",\"timeSinceLastActivitySeconds\":\"????\"}"
+               if [ "$PMS_VERSION" == "V2" ]; then
+                       targetJson=$targetJson"{\"callback_url\":\"????\",\"keep_alive_interval_seconds\":\"????\",\"service_id\":\""$rapp"\",\"time_since_last_activity_seconds\":\"????\"}"
+               else
+                       targetJson=$targetJson"{\"callbackUrl\":\"????\",\"keepAliveIntervalSeconds\":\"????\",\"serviceName\":\""$rapp"\",\"timeSinceLastActivitySeconds\":\"????\"}"
+               fi
        done
 
        targetJson=$targetJson"]"
+       if [ "$PMS_VERSION" == "V2" ]; then
+               targetJson="{\"service_list\": $targetJson }"
+       fi
        echo "TARGET JSON: $targetJson" >> $HTTPLOG
        res=$(python3 ../common/compare_json.py "$targetJson" "$body")
 
@@ -1193,7 +1677,7 @@ api_get_service_ids() {
        return 0
 }
 
-# API test function: DELETE /services
+# API test function: DELETE /services and V2 DELETE /v2/services/{serviceId}
 # args: <response-code> <service-name>
 # (Function for test scripts)
 api_delete_services() {
@@ -1205,8 +1689,11 @@ api_delete_services() {
                __print_err "<response-code> <service-name>" $@
                return 1
        fi
-
-    query="/services?name="$2
+       if [ "$PMS_VERSION" == "V2" ]; then
+               query="/v2/services/"$2
+       else
+               query="/services?name="$2
+       fi
     res="$(__do_curl_to_api PA DELETE $query)"
     status=${res:${#res}-3}
 
@@ -1222,7 +1709,7 @@ api_delete_services() {
        return 0
 }
 
-# API test function: PUT /services/keepalive
+# API test function: PUT /services/keepalive and V2 PUT /v2/services/{service_id}/keepalive
 # args: <response-code> <service-name>
 # (Function for test scripts)
 api_put_services_keepalive() {
@@ -1234,8 +1721,12 @@ api_put_services_keepalive() {
                __print_err "<response-code> <service-name>" $@
                return 1
        fi
+       if [ "$PMS_VERSION" == "V2" ]; then
+               query="/v2/services/$2/keepalive"
+       else
+       query="/services/keepalive?name="$2
+       fi
 
-    query="/services/keepalive?name="$2
     res="$(__do_curl_to_api PA PUT $query)"
     status=${res:${#res}-3}
 
index 2aff131..611fc4d 100644 (file)
@@ -40,6 +40,11 @@ __do_curl_to_api() {
             __RESTBASE=$ECS_RESTBASE
             __RESTBASE_SECURE=$ECS_RESTBASE_SECURE
             __RETRY_CODES=$ECS_RETRY_CODES
+               elif [ $1 == "CR" ]; then
+                   __ADAPTER=$CR_ADAPTER
+            __RESTBASE=$CR_RESTBASE
+            __RESTBASE_SECURE=$CR_RESTBASE_SECURE
+            __RETRY_CODES=""
         else
             paramError=1
         fi
@@ -97,7 +102,7 @@ __do_curl_to_api() {
 
     if [ $paramError -eq 1 ]; then
                ((RES_CONF_FAIL++))
-        echo "-Incorrect number of parameters to __do_curl_agent " $@ >> $HTTPLOG
+        echo "-Incorrect number of parameters to __do_curl_to_api " $@ >> $HTTPLOG
         echo "-Expected: (PA|ECS GET|PUT|POST|DELETE|GET_BATCH|PUT_BATCH|POST_BATCH|DELETE_BATCH <url> [<file>]) | (PA|ECS RESPONSE <correlation-id>)" >> $HTTPLOG
         echo "-Returning response 000" >> $HTTPLOG
         echo "-000"
@@ -150,6 +155,8 @@ __do_curl_to_api() {
                                payload="$(cat $4 | tr -d '\n' | tr -d ' ' )"
                                echo "payload: "$payload >> $HTTPLOG
                                file=" --data-binary "$payload
+                       elif [ $# -eq 4 ]; then
+                               echo " FILE: $(cat $4)" >> $HTTPLOG
                        fi
                        #urlencode the request url since it will be carried by send-request url
                        requestUrl=$(python3 -c "from __future__ import print_function; import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1]))"  "$3")
index 936e3f8..65e32c7 100644 (file)
@@ -20,16 +20,24 @@ import json
 import sys
 
 # Print the length of json array, -1 will be printed in any problem is encountered
+# Assumes the top level json is an array.
+# If not (and the number of keys on top level is 1) then assumes that key contains the array.
 
+arr_len=-1
 try:
     with open(sys.argv[1]) as json_file:
         jsonarray = json.load(json_file)
-
         if isinstance(jsonarray, list):
-            print(len(jsonarray))
-        else:
-            print(-1)
+            arr_len=len(jsonarray)
+        elif isinstance(jsonarray, dict) and len(jsonarray) == 1:
+            key=next(iter(jsonarray))
+            jsonarray=jsonarray[key]
+            if isinstance(jsonarray, list):
+                arr_len = len(jsonarray)
 
 except Exception as e:
-    print(-1)
+    print(arr_len)
+    sys.exit()
+
+print(arr_len)
 sys.exit()
\ No newline at end of file
diff --git a/test/common/cr_api_functions.sh b/test/common/cr_api_functions.sh
new file mode 100644 (file)
index 0000000..fe4b1fd
--- /dev/null
@@ -0,0 +1,127 @@
+#!/bin/bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 Nordix Foundation. All rights reserved.
+#  ========================================================================
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#  ============LICENSE_END=================================================
+#
+
+. ../common/api_curl.sh
+
+### Admin API functions for the Callback Reciver
+
+
+# Excute a curl cmd towards a Callback Reciver admin interface and check the response code.
+# args: <expected-response-code> <curl-cmd-string>
+__execute_curl_to_cr() {
+       echo ${FUNCNAME[1]} "line: "${BASH_LINENO[1]} >> $HTTPLOG
+       echo " CMD: $2" >> $HTTPLOG
+       res="$($2)"
+       echo " RESP: $res" >> $HTTPLOG
+       retcode=$?
+    if [ $retcode -ne 0 ]; then
+               ((RES_CONF_FAIL++))
+               echo " RETCODE: "$retcode
+        echo -e $RED" FAIL - fatal error when executing curl."$ERED
+        return 1
+    fi
+    status=${res:${#res}-3}
+    if [ $status -eq $1 ]; then
+        echo -e $GREEN" OK"$EGREEN
+        return 0
+    fi
+    echo -e $RED" FAIL - expected http response: "$1" but got http response: "$status $ERED
+       ((RES_CONF_FAIL++))
+    return 1
+}
+
+# Tests if a variable value in the CR is equal to a target value and and optional timeout.
+# Arg: <variable-name> <target-value> - This test set pass or fail depending on if the variable is
+# equal to the target or not.
+# Arg: <variable-name> <target-value> <timeout-in-sec>  - This test waits up to the timeout seconds
+# before setting pass or fail depending on if the variable value becomes equal to the target
+# value or not.
+# (Function for test scripts)
+cr_equal() {
+       if [ $# -eq 2 ] || [ $# -eq 3 ]; then
+               __var_test "CR" "$LOCALHOST$CR_EXTERNAL_PORT/counter/" $1 "=" $2 $3
+       else
+               ((RES_CONF_FAIL++))
+               __print_err "Wrong args to cr_equal, needs two or three args: <sim-param> <target-value> [ timeout ]" $@
+       fi
+}
+
+# CR API: Check the contents of all current ric sync events from PMS
+# <response-code> <id> [ EMPTY | ( <ric-id> )+ ]
+# (Function for test scripts)
+cr_api_check_all_sync_events() {
+       echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
+    echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
+       ((RES_TEST++))
+
+       if [ "$PMS_VERSION" != "V2" ]; then
+               echo -e $RED" FAIL, function not supported"$ERED
+               ((RES_FAIL++))
+               __check_stop_at_error
+               return 1
+       fi
+
+    if [ $# -lt 2 ]; then
+        __print_err "<response-code> <id> [ EMPTY | ( <ric-id> )+ ]" $@
+        return 1
+    fi
+
+       query="/get-all-events/"$2
+       res="$(__do_curl_to_api CR GET $query)"
+       status=${res:${#res}-3}
+
+       if [ $status -ne $1 ]; then
+               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+               ((RES_FAIL++))
+               __check_stop_at_error
+               return 1
+       fi
+
+       if [ $# -gt 2 ]; then
+               body=${res:0:${#res}-3}
+               if [ $# -eq 3 ] && [ $3 == "EMPTY" ]; then
+                       targetJson="["
+               else
+                       targetJson="["
+                       arr=(${@:3})
+
+                       for ((i=0; i<$(($#-2)); i=i+1)); do
+
+                               if [ "$targetJson" != "[" ]; then
+                                       targetJson=$targetJson","
+                               fi
+                               targetJson=$targetJson"{\"ric_id\":\"${arr[$i]}\",\"event_type\":\"AVAILABLE\"}"
+                       done
+               fi
+
+               targetJson=$targetJson"]"
+               echo "TARGET JSON: $targetJson" >> $HTTPLOG
+               res=$(python3 ../common/compare_json.py "$targetJson" "$body")
+
+               if [ $res -ne 0 ]; then
+                       echo -e $RED" FAIL, returned body not correct"$ERED
+                       ((RES_FAIL++))
+                       __check_stop_at_error
+                       return 1
+               fi
+       fi
+       ((RES_PASS++))
+       echo -e $GREEN" PASS"$EGREEN
+       return 0
+}
\ No newline at end of file
index 8d37678..89bfde8 100644 (file)
@@ -24,6 +24,7 @@ import json
 import sys
 import requests
 import traceback
+from time import sleep
 
 # disable warning about unverified https requests
 from requests.packages import urllib3
@@ -31,21 +32,44 @@ from requests.packages import urllib3
 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
 
 #arg responsecode baseurl ric_base num_rics uuid startid templatepath count pids pid_id
+data_out=""
+url_out=""
 try:
-    if len(sys.argv) != 11:
-        print("1Expected 10 args, got "+str(len(sys.argv)-1)+ ". Args: responsecode baseurl ric_base num_rics uuid startid templatepath count pids pid_id")
-        sys.exit()
 
+    if len(sys.argv) < 11:
+        print("1Expected 11/14 args, got "+str(len(sys.argv)-1))
+        print (sys.argv[1:])
+        sys.exit()
     responsecode=int(sys.argv[1])
-    baseurl=sys.argv[2]
-    ric_base=sys.argv[3]
+    baseurl=str(sys.argv[2])
+    ric_base=str(sys.argv[3])
     num_rics=int(sys.argv[4])
-    uuid=sys.argv[5]
+    uuid=str(sys.argv[5])
     start=int(sys.argv[6])
-    templatepath=sys.argv[7]
-    count=int(sys.argv[8])
-    pids=int(sys.argv[9])
-    pid_id=int(sys.argv[10])
+    if ("/v2/" in baseurl):
+        if len(sys.argv) != 15:
+            print("1Expected 14 args, got "+str(len(sys.argv)-1)+ ". Args: responsecode baseurl ric_base num_rics uuid startid service type transient notification-url templatepath count pids pid_id")
+            print (sys.argv[1:])
+            sys.exit()
+
+        serv=str(sys.argv[7])
+        pt=str(sys.argv[8])
+        trans=str(sys.argv[9])
+        noti=str(sys.argv[10])
+        templatepath=str(sys.argv[11])
+        count=int(sys.argv[12])
+        pids=int(sys.argv[13])
+        pid_id=int(sys.argv[14])
+    else:
+        if len(sys.argv) != 11:
+            print("1Expected 10 args, got "+str(len(sys.argv)-1)+ ". Args: responsecode baseurl ric_base num_rics uuid startid templatepath count pids pid_id")
+            print (sys.argv[1:])
+            sys.exit()
+
+        templatepath=str(sys.argv[7])
+        count=int(sys.argv[8])
+        pids=int(sys.argv[9])
+        pid_id=int(sys.argv[10])
 
     if uuid == "NOUUID":
         uuid=""
@@ -56,28 +80,72 @@ try:
         start=start
         stop=count*num_rics+start
 
+        total_retry_count=0
+
         for i in range(start,stop):
             if (i%pids == (pid_id-1)):
                 payload=template.replace("XXX",str(i))
                 ric_id=(i%num_rics)+1
                 ric=ric_base+str(ric_id)
-                url=baseurl+"&id="+uuid+str(i)+"&ric="+str(ric)
-                try:
-                    headers = {'Content-type': 'application/json'}
-                    resp=requests.put(url, json.dumps(json.loads(payload)), headers=headers, verify=False, timeout=90)
-                except Exception as e1:
-                    print("1Put failed for id:"+uuid+str(i)+ ", "+str(e1) + " "+traceback.format_exc())
-                    sys.exit()
-                if (resp.status_code == None):
-                    print("1Put failed for id:"+uuid+str(i)+ ", expected response code: "+responsecode+", got: None")
-                    sys.exit()
-                if (resp.status_code != responsecode):
-                    print("1Put failed for id:"+uuid+str(i)+ ", expected response code: "+responsecode+", got: "+str(resp.status_code))
-                    sys.exit()
-
-    print("0")
+
+                retry_cnt=5
+                while(retry_cnt>0):
+                    try:
+                        headers = {'Content-type': 'application/json'}
+                        if ("/v2/" in baseurl):
+                            url=baseurl
+
+                            data={}
+                            data["ric_id"]=ric
+                            data["policy_id"]=uuid+str(i)
+                            data["service_id"]=serv
+                            if (trans != "NOTRANSIENT"):
+                                data["transient"]=trans
+                            if (pt != "NOTYPE"):
+                                data["policytype_id"]=pt
+                            else:
+                                data["policytype_id"]=""
+                            if (noti != "NOURL"):
+                                data["status_notification_uri"]=noti
+                            data["policy_data"]=json.loads(payload)
+
+                            url_out=url
+                            data_out=json.dumps(data)
+                        else:
+                            url=baseurl+"&id="+uuid+str(i)+"&ric="+str(ric)
+                            url_out=url
+                            data_out=json.dumps(json.loads(payload))
+
+                        resp=requests.put(url, data_out, headers=headers, verify=False, timeout=90)
+                    except Exception as e1:
+                        print("1Put failed for id:"+uuid+str(i)+ ", "+str(e1) + " "+traceback.format_exc())
+                        sys.exit()
+
+                    if (resp.status_code == None):
+                        print("1Put failed for id:"+uuid+str(i)+ ", expected response code: "+str(responsecode)+", got: None")
+                        sys.exit()
+
+                    if (resp.status_code != responsecode):
+                        if (resp.status_code == 503 ) and (retry_cnt > 1):
+                            sleep(0.1)
+                            retry_cnt -= 1
+                            total_retry_count += 1
+                        else:
+                            print("1Put failed for id:"+uuid+str(i)+ ", expected response code: "+str(responsecode)+", got: "+str(resp.status_code))
+                            print(url_out)
+                            print(str(data_out))
+                            sys.exit()
+                    else:
+                        retry_cnt=-1
+
+    if (total_retry_count > 0):
+        print("0 retries:"+str(total_retry_count))
+    else:
+        print("0")
     sys.exit()
 
 except Exception as e:
     print("1"+str(e))
+    traceback.print_exc()
+    print(str(data_out))
 sys.exit()
\ No newline at end of file
index d6a095b..5f2fe69 100644 (file)
@@ -28,28 +28,41 @@ import re
 #To indicate that special STD zero length name type, use 'EMPTYTYPE'. Ex. ricsim_g1_1:kista_ricsim_g1_1,stockholm_ricsim_g1_1:EMPTYTYPE
 #Save in indicated file
 
+#arg: <file-name-for-result> <api-version> <list-ric-info>
 try:
     file_name = sys.argv[1]
-    ric_string = sys.argv[2]
+    api_version=sys.argv[2]
+    ric_string = sys.argv[3]
     ric_string=ric_string.strip()
     ric_string = re.sub(' +',' ',ric_string)
     ric_arr=[]
     rics=ric_string.split(' ')
+    if (api_version == "V2"):
+        param_ric='ric_id'
+        param_me='managed_element_ids'
+        param_policy_type='policytype_ids'
+        param_state='state'
+    else:
+        param_ric='ricName'
+        param_me='managedElementIds'
+        param_policy_type='policyTypes'
+        param_state='state'
+
     for i in range(len(rics)):
         ricDict={}
         items=rics[i].split(':')
-        ricDict['ricName']=items[0]
-        ricDict['managedElementIds']=items[1].split(',')
+        ricDict[param_ric]=items[0]
+        ricDict[param_me]=items[1].split(',')
         if (items[2] == "EMPTYTYPE"):
             empty_arr=[]
             empty_arr.append("")
-            ricDict['policyTypes']=empty_arr
+            ricDict[param_policy_type]=empty_arr
         elif (items[2] == "NOTYPE"):
             empty_arr=[]
-            ricDict['policyTypes']=empty_arr
+            ricDict[param_policy_type]=empty_arr
         else:
-            ricDict['policyTypes']=items[2].split(',')
-        ricDict['state']=items[3]
+            ricDict[param_policy_type]=items[2].split(',')
+        ricDict[param_state]=items[3]
         ric_arr.append(ricDict)
 
     with open(file_name, 'w') as f:
index e647118..febb3cc 100644 (file)
@@ -38,9 +38,9 @@ try:
         sys.exit()
 
     responsecode=int(sys.argv[1])
-    baseurl=sys.argv[2]
+    baseurl=str(sys.argv[2])
     num_rics=int(sys.argv[3])
-    uuid=sys.argv[4]
+    uuid=str(sys.argv[4])
     start=int(sys.argv[5])
     count=int(sys.argv[6])
     pids=int(sys.argv[7])
@@ -49,25 +49,43 @@ try:
     if uuid == "NOUUID":
         uuid=""
 
+    total_retry_count=0
+
     stop=count*num_rics+start
     for i in range(start,stop):
         if (i%pids == (pid_id-1)):
-            url=str(baseurl+"?id="+uuid+str(i))
-            try:
-                resp=requests.delete(url, verify=False, timeout=90)
-            except Exception as e1:
-                print("1Delete failed for id:"+uuid+str(i)+ ", "+str(e1) + " "+traceback.format_exc())
-                sys.exit()
-            if (resp.status_code == None):
-                print("1Delete failed for id:"+uuid+str(i)+ ", expected response code: "+responsecode+", got: None")
-                sys.exit()
-            if (resp.status_code != responsecode):
-                print("1Delete failed for id:"+uuid+str(i)+ ", expected response code: "+responsecode+", got: "+str(resp.status_code))
-                sys.exit()
+            retry_cnt=5
+            while(retry_cnt>0):
+                if ("/v2/policies/" in baseurl):
+                    url=str(baseurl+uuid+str(i))
+                else:
+                    url=str(baseurl+"?id="+uuid+str(i))
+                try:
+                    resp=requests.delete(url, verify=False, timeout=90)
+                except Exception as e1:
+                    print("1Delete failed for id:"+uuid+str(i)+ ", "+str(e1) + " "+traceback.format_exc())
+                    sys.exit()
+                if (resp.status_code == None):
+                    print("1Delete failed for id:"+uuid+str(i)+ ", expected response code: "+str(responsecode)+", got: None")
+                    sys.exit()
+                if (resp.status_code != responsecode):
+                    if (resp.status_code == 503 ) and (retry_cnt > 1):
+                        sleep(0.1)
+                        retry_cnt -= 1
+                        total_retry_count += 1
+                    else:
+                        print("1Delete failed for id:"+uuid+str(i)+ ", expected response code: "+str(responsecode)+", got: "+str(resp.status_code))
+                        sys.exit()
+                else:
+                    retry_cnt=-1
 
-    print("0")
+    if (total_retry_count > 0):
+        print("0 retries:"+str(total_retry_count))
+    else:
+        print("0")
     sys.exit()
 
 except Exception as e:
     print("1"+str(e))
+    traceback.print_exc()
 sys.exit()
\ No newline at end of file
index 6c726b9..b76d43b 100644 (file)
 
 # API Test function: GET /A1-EI​/v1​/eitypes​/{eiTypeId}​/eijobs
 # args: <response-code> <type-id>  <owner-id>|NOOWNER [ EMPTY | <job-id>+ ]
+# args (flat uri structure): <response-code> <type-id>|NOTYPE  <owner-id>|NOOWNER [ EMPTY | <job-id>+ ]
 # (Function for test scripts)
 ecs_api_a1_get_job_ids() {
        echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
     echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
        ((RES_TEST++))
 
-       # Valid number of parameters 3,4,5,6 etc
-    if [ $# -lt 1 ]; then
-               __print_err "<response-code> <type-id>  <owner-id>|NOOWNER [ EMPTY | <job-id>+ ]" $@
-               return 1
+       if [ -z "$FLAT_A1_EI" ]; then
+               # Valid number of parameters 4,5,6 etc
+       if [ $# -lt 3 ]; then
+                       __print_err "<response-code> <type-id>  <owner-id>|NOOWNER [ EMPTY | <job-id>+ ]" $@
+                       return 1
+               fi
+       else
+               echo -e $YELLOW"USING NOT CONFIRMED INTERFACE - FLAT URI STRUCTURE"$EYELLOW
+               # Valid number of parameters 4,5,6 etc
+       if [ $# -lt 3 ]; then
+                       __print_err "<response-code> <type-id>|NOTYPE  <owner-id>|NOOWNER [ EMPTY | <job-id>+ ]" $@
+                       return 1
+               fi
        fi
-       owner=""
+       search=""
        if [ $3 != "NOWNER" ]; then
-               owner="?owner="$3
+               search="?owner="$3
        fi
 
-       query="/A1-EI/v1/eitypes/$2/eijobs$owner"
+       if [  -z "$FLAT_A1_EI" ]; then
+               query="/A1-EI/v1/eitypes/$2/eijobs$search"
+       else
+               if [ $2 != "NOTYPE" ]; then
+                       if [ -z "$search" ]; then
+                               search="?eiTypeId="$2
+                       else
+                               search=$search"&eiTypeId="$2
+                       fi
+               fi
+               query="/A1-EI/v1/eijobs$search"
+       fi
     res="$(__do_curl_to_api ECS GET $query)"
     status=${res:${#res}-3}
 
@@ -125,7 +146,11 @@ ecs_api_a1_get_type() {
                        __check_stop_at_error
                        return 1
                fi
-               targetJson="{\"eiJobParametersSchema\":$schema}"
+               if [ -z "$FLAT_A1_EI" ]; then
+                       targetJson="{\"eiJobParametersSchema\":$schema}"
+               else
+                       targetJson=$schema
+               fi
                echo " TARGET JSON: $targetJson" >> $HTTPLOG
                res=$(python3 ../common/compare_json.py "$targetJson" "$body")
 
@@ -137,22 +162,21 @@ ecs_api_a1_get_type() {
                fi
        fi
 
-
        ((RES_PASS++))
        echo -e $GREEN" PASS"$EGREEN
        return 0
 }
 
-# API Test function: GET â€‹/A1-EI​/v1​/eitypes
-# args: <response-code> (EMPTY | [<type-id>]+)
+# API Test function: GET /A1-EI/v1/eitypes
+# args: <response-code> [ (EMPTY | [<type-id>]+) ]
 # (Function for test scripts)
 ecs_api_a1_get_type_ids() {
        echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
     echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
        ((RES_TEST++))
 
-    if [ $# -lt 2 ]; then
-               __print_err "<response-code> (EMPTY | [<type-id>]+)" $@
+    if [ $# -lt 1 ]; then
+               __print_err "<response-code> [ (EMPTY | [<type-id>]+) ]" $@
                return 1
        fi
 
@@ -166,25 +190,27 @@ ecs_api_a1_get_type_ids() {
                __check_stop_at_error
                return 1
        fi
-       body=${res:0:${#res}-3}
-       targetJson="["
-       if [ $2 != "EMPTY" ]; then
-               for pid in ${@:2} ; do
-                       if [ "$targetJson" != "[" ]; then
-                               targetJson=$targetJson","
-                       fi
-                       targetJson=$targetJson"\"$pid\""
-               done
-       fi
-       targetJson=$targetJson"]"
-       echo " TARGET JSON: $targetJson" >> $HTTPLOG
-       res=$(python3 ../common/compare_json.py "$targetJson" "$body")
+       if [ $# -gt 1 ]; then
+               body=${res:0:${#res}-3}
+               targetJson="["
+               if [ $2 != "EMPTY" ]; then
+                       for pid in ${@:2} ; do
+                               if [ "$targetJson" != "[" ]; then
+                                       targetJson=$targetJson","
+                               fi
+                               targetJson=$targetJson"\"$pid\""
+                       done
+               fi
+               targetJson=$targetJson"]"
+               echo " TARGET JSON: $targetJson" >> $HTTPLOG
+               res=$(python3 ../common/compare_json.py "$targetJson" "$body")
 
-       if [ $res -ne 0 ]; then
-               echo -e $RED" FAIL, returned body not correct"$ERED
-               ((RES_FAIL++))
-               __check_stop_at_error
-               return 1
+               if [ $res -ne 0 ]; then
+                       echo -e $RED" FAIL, returned body not correct"$ERED
+                       ((RES_FAIL++))
+                       __check_stop_at_error
+                       return 1
+               fi
        fi
 
        ((RES_PASS++))
@@ -194,39 +220,74 @@ ecs_api_a1_get_type_ids() {
 
 # API Test function: GET â€‹/A1-EI​/v1​/eitypes​/{eiTypeId}​/eijobs​/{eiJobId}​/status
 # args: <response-code> <type-id> <job-id> [<status>]
+# args (flat uri structure): <response-code> <job-id> [<status>]
 # (Function for test scripts)
 ecs_api_a1_get_job_status() {
        echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
     echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
        ((RES_TEST++))
 
-    if [ $# -ne 3 ] && [ $# -ne 4 ]; then
-               __print_err "<response-code> <type-id> <job-id>" $@
-               return 1
-       fi
+       if [ -z "$FLAT_A1_EI" ]; then
+               if [ $# -ne 3 ] && [ $# -ne 4 ]; then
+                       __print_err "<response-code> <type-id> <job-id> [<status>]" $@
+                       return 1
+               fi
 
-       query="/A1-EI/v1/eitypes/$2/eijobs/$3/status"
-    res="$(__do_curl_to_api ECS GET $query)"
-    status=${res:${#res}-3}
+               query="/A1-EI/v1/eitypes/$2/eijobs/$3/status"
 
-       if [ $status -ne $1 ]; then
-               echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
-               ((RES_FAIL++))
-               __check_stop_at_error
-               return 1
-       fi
-       if [ $# -eq 4 ]; then
-               body=${res:0:${#res}-3}
-               targetJson="{\"operationalState\": \"$4\"}"
-               echo " TARGET JSON: $targetJson" >> $HTTPLOG
-               res=$(python3 ../common/compare_json.py "$targetJson" "$body")
+               res="$(__do_curl_to_api ECS GET $query)"
+               status=${res:${#res}-3}
 
-               if [ $res -ne 0 ]; then
-                       echo -e $RED" FAIL, returned body not correct"$ERED
+               if [ $status -ne $1 ]; then
+                       echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
                        ((RES_FAIL++))
                        __check_stop_at_error
                        return 1
                fi
+               if [ $# -eq 4 ]; then
+                       body=${res:0:${#res}-3}
+                       targetJson="{\"operationalState\": \"$4\"}"
+                       echo " TARGET JSON: $targetJson" >> $HTTPLOG
+                       res=$(python3 ../common/compare_json.py "$targetJson" "$body")
+
+                       if [ $res -ne 0 ]; then
+                               echo -e $RED" FAIL, returned body not correct"$ERED
+                               ((RES_FAIL++))
+                               __check_stop_at_error
+                               return 1
+                       fi
+               fi
+       else
+               echo -e $YELLOW"USING NOT CONFIRMED INTERFACE - FLAT URI STRUCTURE"$EYELLOW
+               if [ $# -ne 2 ] && [ $# -ne 3 ]; then
+                       __print_err "<response-code> <job-id> [<status>]" $@
+                       return 1
+               fi
+
+               query="/A1-EI/v1/eijobs/$2/status"
+
+               res="$(__do_curl_to_api ECS GET $query)"
+               status=${res:${#res}-3}
+
+               if [ $status -ne $1 ]; then
+                       echo -e $RED" FAIL. Exepected status "$1", got "$status $ERED
+                       ((RES_FAIL++))
+                       __check_stop_at_error
+                       return 1
+               fi
+               if [ $# -eq 3 ]; then
+                       body=${res:0:${#res}-3}
+                       targetJson="{\"eiJobStatus\": \"$3\"}"
+                       echo " TARGET JSON: $targetJson" >> $HTTPLOG
+                       res=$(python3 ../common/compare_json.py "$targetJson" "$body")
+
+                       if [ $res -ne 0 ]; then
+                               echo -e $RED" FAIL, returned body not correct"$ERED
+                               ((RES_FAIL++))
+                               __check_stop_at_error
+                               return 1
+                       fi
+               fi
        fi
 
        ((RES_PASS++))
@@ -236,18 +297,27 @@ ecs_api_a1_get_job_status() {
 
 # API Test function: GET â€‹/A1-EI​/v1​/eitypes​/{eiTypeId}​/eijobs​/{eiJobId}
 # args: <response-code> <type-id> <job-id> [<target-url> <owner-id> <template-job-file>]
+# args (flat uri structure): <response-code> <job-id> [<type-id> <target-url> <owner-id> <template-job-file>]
 # (Function for test scripts)
 ecs_api_a1_get_job() {
        echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
     echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
        ((RES_TEST++))
 
-    if [ $# -ne 3 ] && [ $# -ne 6 ]; then
-               __print_err "<response-code> <type-id> <job-id> [<target-url> <owner-id> <template-job-file>]" $@
-               return 1
+       if [  -z "$FLAT_A1_EI" ]; then
+               if [ $# -ne 3 ] && [ $# -ne 6 ]; then
+                       __print_err "<response-code> <type-id> <job-id> [<target-url> <owner-id> <template-job-file>]" $@
+                       return 1
+               fi
+               query="/A1-EI/v1/eitypes/$2/eijobs/$3"
+       else
+               echo -e $YELLOW"USING NOT CONFIRMED INTERFACE - FLAT URI STRUCTURE"$EYELLOW
+               if [ $# -ne 2 ] && [ $# -ne 7 ]; then
+                       __print_err "<response-code> <job-id> [<type-id> <target-url> <owner-id> <notification-url> <template-job-file>]" $@
+                       return 1
+               fi
+               query="/A1-EI/v1/eijobs/$2"
        fi
-
-       query="/A1-EI/v1/eitypes/$2/eijobs/$3"
     res="$(__do_curl_to_api ECS GET $query)"
     status=${res:${#res}-3}
 
@@ -258,27 +328,53 @@ ecs_api_a1_get_job() {
                return 1
        fi
 
-       if [ $# -eq 6 ]; then
-               body=${res:0:${#res}-3}
+       if [  -z "$FLAT_A1_EI" ]; then
+               if [ $# -eq 6 ]; then
+                       body=${res:0:${#res}-3}
 
-               if [ -f $6 ]; then
-                       jobfile=$(cat $6)
-                       jobfile=$(echo "$jobfile" | sed "s/XXXX/$3/g")
-               else
-                       echo -e $RED" FAIL. Job template file "$6", does not exist"$ERED
-                       ((RES_FAIL++))
-                       __check_stop_at_error
-                       return 1
+                       if [ -f $6 ]; then
+                               jobfile=$(cat $6)
+                               jobfile=$(echo "$jobfile" | sed "s/XXXX/$3/g")
+                       else
+                               echo -e $RED" FAIL. Job template file "$6", does not exist"$ERED
+                               ((RES_FAIL++))
+                               __check_stop_at_error
+                               return 1
+                       fi
+                       targetJson="{\"targetUri\": \"$4\",\"jobOwner\": \"$5\",\"jobParameters\": $jobfile}"
+                       echo " TARGET JSON: $targetJson" >> $HTTPLOG
+                       res=$(python3 ../common/compare_json.py "$targetJson" "$body")
+
+                       if [ $res -ne 0 ]; then
+                               echo -e $RED" FAIL, returned body not correct"$ERED
+                               ((RES_FAIL++))
+                               __check_stop_at_error
+                               return 1
+                       fi
                fi
-               targetJson="{\"targetUri\": \"$4\",\"jobOwner\": \"$5\",\"jobParameters\": $jobfile}"
-               echo " TARGET JSON: $targetJson" >> $HTTPLOG
-               res=$(python3 ../common/compare_json.py "$targetJson" "$body")
+       else
+               if [ $# -eq 7 ]; then
+                       body=${res:0:${#res}-3}
 
-               if [ $res -ne 0 ]; then
-                       echo -e $RED" FAIL, returned body not correct"$ERED
-                       ((RES_FAIL++))
-                       __check_stop_at_error
-                       return 1
+                       if [ -f $7 ]; then
+                               jobfile=$(cat $7)
+                               jobfile=$(echo "$jobfile" | sed "s/XXXX/$2/g")
+                       else
+                               echo -e $RED" FAIL. Job template file "$6", does not exist"$ERED
+                               ((RES_FAIL++))
+                               __check_stop_at_error
+                               return 1
+                       fi
+                       targetJson="{\"eiTypeId\": \"$3\", \"targetUri\": \"$4\",\"jobOwner\": \"$5\",\"jobStatusNotificationUri\": \"$6\",\"jobDefinition\": $jobfile}"
+                       echo " TARGET JSON: $targetJson" >> $HTTPLOG
+                       res=$(python3 ../common/compare_json.py "$targetJson" "$body")
+
+                       if [ $res -ne 0 ]; then
+                               echo -e $RED" FAIL, returned body not correct"$ERED
+                               ((RES_FAIL++))
+                               __check_stop_at_error
+                               return 1
+                       fi
                fi
        fi
 
@@ -289,18 +385,28 @@ ecs_api_a1_get_job() {
 
 # API Test function: DELETE â€‹/A1-EI​/v1​/eitypes​/{eiTypeId}​/eijobs​/{eiJobId}
 # args: <response-code> <type-id> <job-id>
+# args (flat uri structure): <response-code> <job-id>
 # (Function for test scripts)
 ecs_api_a1_delete_job() {
        echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
     echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
        ((RES_TEST++))
 
-    if [ $# -lt 3 ]; then
-               __print_err "<response-code> <type-id> <job-id>" $@
-               return 1
-       fi
+       if [  -z "$FLAT_A1_EI" ]; then
+               if [ $# -ne 3 ]; then
+                       __print_err "<response-code> <type-id> <job-id>" $@
+                       return 1
+               fi
 
-       query="/A1-EI/v1/eitypes/$2/eijobs/$3"
+               query="/A1-EI/v1/eitypes/$2/eijobs/$3"
+       else
+               echo -e $YELLOW"USING NOT CONFIRMED INTERFACE - FLAT URI STRUCTURE"$EYELLOW
+               if [ $# -ne 2 ]; then
+                       __print_err "<response-code> <job-id>" $@
+                       return 1
+               fi
+               query="/A1-EI/v1/eijobs/$2"
+       fi
     res="$(__do_curl_to_api ECS DELETE $query)"
     status=${res:${#res}-3}
 
@@ -318,31 +424,56 @@ ecs_api_a1_delete_job() {
 
 # API Test function: PUT â€‹/A1-EI​/v1​/eitypes​/{eiTypeId}​/eijobs​/{eiJobId}
 # args: <response-code> <type-id> <job-id> <target-url> <owner-id> <template-job-file>
+# args (flat uri structure): <response-code> <job-id> <type-id> <target-url> <owner-id> <notification-url> <template-job-file>
 # (Function for test scripts)
 ecs_api_a1_put_job() {
        echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
     echo "TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ >> $HTTPLOG
        ((RES_TEST++))
 
-    if [ $# -lt 6 ]; then
-               __print_err "<response-code> <type-id> <job-id> <target-url> <owner-id> <template-job-file>" $@
-               return 1
-       fi
-       if [ -f $6 ]; then
-               jobfile=$(cat $6)
-               jobfile=$(echo "$jobfile" | sed "s/XXXX/$3/g")
+       if [  -z "$FLAT_A1_EI" ]; then
+               if [ $# -lt 6 ]; then
+                       __print_err "<response-code> <type-id> <job-id> <target-url> <owner-id> <template-job-file>" $@
+                       return 1
+               fi
+               if [ -f $6 ]; then
+                       jobfile=$(cat $6)
+                       jobfile=$(echo "$jobfile" | sed "s/XXXX/$3/g")
+               else
+                       echo -e $RED" FAIL. Job template file "$6", does not exist"$ERED
+                       ((RES_FAIL++))
+                       __check_stop_at_error
+                       return 1
+               fi
+
+               inputJson="{\"targetUri\": \"$4\",\"jobOwner\": \"$5\",\"jobParameters\": $jobfile}"
+               file="./tmp/.p.json"
+               echo "$inputJson" > $file
+
+               query="/A1-EI/v1/eitypes/$2/eijobs/$3"
        else
-               echo -e $RED" FAIL. Job template file "$6", does not exist"$ERED
-               ((RES_FAIL++))
-               __check_stop_at_error
-               return 1
-       fi
+               echo -e $YELLOW"USING NOT CONFIRMED INTERFACE - FLAT URI STRUCTURE"$EYELLOW
+               if [ $# -lt 7 ]; then
+                       __print_err "<response-code> <job-id> <type-id> <target-url> <owner-id> <notification-url> <template-job-file>" $@
+                       return 1
+               fi
+               if [ -f $7 ]; then
+                       jobfile=$(cat $7)
+                       jobfile=$(echo "$jobfile" | sed "s/XXXX/$2/g")
+               else
+                       echo -e $RED" FAIL. Job template file "$7", does not exist"$ERED
+                       ((RES_FAIL++))
+                       __check_stop_at_error
+                       return 1
+               fi
 
-       inputJson="{\"targetUri\": \"$4\",\"jobOwner\": \"$5\",\"jobParameters\": $jobfile}"
-       file="./tmp/.p.json"
-       echo "$inputJson" > $file
+               inputJson="{\"eiTypeId\": \"$3\", \"jobResultUri\": \"$4\",\"jobOwner\": \"$5\",\"jobStatusNotificationUri\": \"$6\",\"jobDefinition\": $jobfile}"
+               file="./tmp/.p.json"
+               echo "$inputJson" > $file
+
+               query="/A1-EI/v1/eijobs/$2"
+       fi
 
-       query="/A1-EI/v1/eitypes/$2/eijobs/$3"
     res="$(__do_curl_to_api ECS PUT $query $file)"
     status=${res:${#res}-3}
 
@@ -425,7 +556,7 @@ ecs_api_edp_get_producer_status() {
        ((RES_TEST++))
 
     if [ $# -lt 2 ] || [ $# -gt 3 ]; then
-               __print_err "<response-code> <producer-id> <status>" $@
+               __print_err "<response-code> <producer-id> [<status>]" $@
                return 1
        fi
 
@@ -514,7 +645,7 @@ ecs_api_edp_get_producer_ids() {
 }
 
 # API Test function: GET /ei-producer/v1/eitypes/{eiTypeId}
-# args: <response-code> <type-id> [<job-schema-file> (NOID | [<producer-id>]+)]
+# args: <response-code> <type-id> [<job-schema-file> (EMPTY | [<producer-id>]+)]
 # (Function for test scripts)
 ecs_api_edp_get_type() {
        echo -e $BOLD"TEST(${BASH_LINENO[0]}): ${FUNCNAME[0]}" $@ $EBOLD
@@ -529,7 +660,7 @@ ecs_api_edp_get_type() {
                paramError=0
        fi
     if [ $paramError -ne 0 ]; then
-               __print_err "<response-code> <type-id> [<job-schema-file> NOID | ([<producer-id>]+)]" $@
+               __print_err "<response-code> <type-id> [<job-schema-file> 'EMPTY' | ([<producer-id>]+)]" $@
                return 1
        fi
 
index b41c79b..f30b876 100644 (file)
@@ -61,7 +61,7 @@ __execute_curl_to_prodstub() {
 # Prodstub API: Set (or reset) response code for producer supervision
 # <response-code> <producer-id> [<forced_response_code>]
 # (Function for test scripts)
-prodstub_arm_supervision() {
+prodstub_arm_producer() {
        echo -e $BOLD"CONF(${BASH_LINENO[0]}): "${FUNCNAME[0]} $@ $EBOLD
     echo "CONF(${BASH_LINENO[0]}): "${FUNCNAME[0]} $@  >> $HTTPLOG
        if [ $# -ne 2 ] && [ $# -ne 3 ]; then
@@ -86,7 +86,7 @@ prodstub_arm_supervision() {
 # Prodstub API: Set (or reset) response code job create
 # <response-code> <producer-id> <job-id> [<forced_response_code>]
 # (Function for test scripts)
-prodstub_arm_create() {
+prodstub_arm_job_create() {
        echo -e $BOLD"CONF(${BASH_LINENO[0]}): "${FUNCNAME[0]} $@ $EBOLD
     echo "CONF(${BASH_LINENO[0]}): "${FUNCNAME[0]} $@  >> $HTTPLOG
        if [ $# -ne 3 ] && [ $# -ne 4 ]; then
@@ -111,7 +111,7 @@ prodstub_arm_create() {
 # Prodstub API: Set (or reset) response code job delete
 # <response-code> <producer-id> <job-id> [<forced_response_code>]
 # (Function for test scripts)
-prodstub_arm_delete() {
+prodstub_arm_job_delete() {
        echo -e $BOLD"CONF(${BASH_LINENO[0]}): "${FUNCNAME[0]} $@ $EBOLD
     echo "CONF(${BASH_LINENO[0]}): "${FUNCNAME[0]} $@  >> $HTTPLOG
        if [ $# -ne 3 ] && [ $# -ne 4 ]; then
@@ -207,4 +207,20 @@ prodstub_check_jobdata() {
         ((RES_FAIL++))
     fi
        return $retcode
+}
+
+# Tests if a variable value in the prod stub is equal to a target value and and optional timeout.
+# Arg: <variable-name> <target-value> - This test set pass or fail depending on if the variable is
+# equal to the target or not.
+# Arg: <variable-name> <target-value> <timeout-in-sec>  - This test waits up to the timeout seconds
+# before setting pass or fail depending on if the variable value becomes equal to the target
+# value or not.
+# (Function for test scripts)
+prodstub_equal() {
+       if [ $# -eq 2 ] || [ $# -eq 3 ]; then
+               __var_test "PRODSTUB" "$LOCALHOST$PROD_STUB_EXTERNAL_PORT/counter/" $1 "=" $2 $3
+       else
+               ((RES_CONF_FAIL++))
+               __print_err "Wrong args to prodstub_equal, needs two or three args: <sim-param> <target-value> [ timeout ]" $@
+       fi
 }
\ No newline at end of file
index 67a398e..56f968e 100644 (file)
@@ -30,6 +30,7 @@ __execute_curl_to_sim() {
        echo " RESP: $res" >> $HTTPLOG
        retcode=$?
     if [ $retcode -ne 0 ]; then
+               ((RES_CONF_FAIL++))
                echo " RETCODE: "$retcode
         echo -e $RED" FAIL - fatal error when executing curl."$ERED
         return 1
@@ -40,6 +41,7 @@ __execute_curl_to_sim() {
         return 0
     fi
     echo -e $RED" FAIL - expected http response: "$1" but got http response: "$status $ERED
+       ((RES_CONF_FAIL++))
     return 1
 }
 
@@ -119,7 +121,7 @@ sim_put_policy_type() {
        return $?
 }
 
-# DSimulator API: Delete a policy type in a ric
+# Simulator API: Delete a policy type in a ric
 # <response-code> <ric-id> <policy-type-id>
 # (Function for test scripts)
 sim_delete_policy_type() {
diff --git a/test/common/test_env-onap-guilin.sh b/test/common/test_env-onap-guilin.sh
new file mode 100644 (file)
index 0000000..51eab69
--- /dev/null
@@ -0,0 +1,150 @@
+#!/bin/bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 Nordix Foundation. All rights reserved.
+#  ========================================================================
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#  ============LICENSE_END=================================================
+#
+
+TEST_ENV_PROFILE="ONAP-GUILIN"
+
+# Set up the image and tags for the test. Do not add the image tag to the image names.
+
+# NOTE: A env var for each container is created by the test script.
+# This var will point to the local or remote var depending on how
+# the test script is started. The name format is <container-name>_IMAGE, ie with 'LOCAL' or 'REMOTE'.
+
+# Tag for guilin branch
+# Remote Policy Agent image and tag
+POLICY_AGENT_REMOTE_IMAGE="nexus3.onap.org:10003/onap/ccsdk-oran-a1policymanagementservice"
+POLICY_AGENT_REMOTE_IMAGE_TAG="1.0.1-SNAPSHOT"
+
+
+# Control Panel remote image and tag
+CONTROL_PANEL_REMOTE_IMAGE="nexus3.o-ran-sc.org:10004/o-ran-sc/nonrtric-controlpanel"
+CONTROL_PANEL_REMOTE_IMAGE_TAG="2.0.0"
+
+# Tag for guilin branch
+# SDNC A1 Controller remote image and tag
+SDNC_A1_CONTROLLER_REMOTE_IMAGE="nexus3.onap.org:10003/onap/sdnc-image"
+SDNC_A1_CONTROLLER_REMOTE_IMAGE_TAG="2.0.2-STAGING-latest"
+
+
+#SDNC DB remote image and tag
+SDNC_DB_REMOTE_IMAGE="mysql/mysql-server"
+SDNC_DB_REMOTE_IMAGE_TAG="5.6"
+#No local image for DB, remote image always used
+
+
+# Near RT RIC Simulator remote image and tag
+RIC_SIM_REMOTE_IMAGE="nexus3.o-ran-sc.org:10004/o-ran-sc/a1-simulator"
+RIC_SIM_REMOTE_IMAGE_TAG="2.0.0"
+
+
+#Consul remote image and tag
+CONSUL_REMOTE_IMAGE="consul"
+CONSUL_REMOTE_IMAGE_TAG="1.7.2"
+#No local image for Consul, remote image always used
+
+
+#CBS remote image and tag
+CBS_REMOTE_IMAGE="nexus3.onap.org:10001/onap/org.onap.dcaegen2.platform.configbinding.app-app"
+CBS_REMOTE_IMAGE_TAG="2.3.0"
+#No local image for CBS, remote image always used
+
+
+#MR stub image and tag
+MRSTUB_LOCAL_IMAGE="mrstub"
+MRSTUB_LOCAL_IMAGE_TAG="latest"
+#No remote image for MR stub, local image always used
+
+#Callback receiver image and tag
+CR_LOCAL_IMAGE="callback-receiver"
+CR_LOCAL_IMAGE_TAG="latest"
+#No remote image for CR, local image always used
+
+# Common env var for auto-test. Vars used by docker-compose need to be exported
+export DOCKER_SIM_NWNAME="nonrtric-docker-net"                  # Name of docker private network
+
+export POLICY_AGENT_EXTERNAL_PORT=8081                          # Policy Agent container external port (host -> container)
+export POLICY_AGENT_INTERNAL_PORT=8081                          # Policy Agent container internal port (container -> container)
+export POLICY_AGENT_EXTERNAL_SECURE_PORT=8433                   # Policy Agent container external secure port (host -> container)
+export POLICY_AGENT_INTERNAL_SECURE_PORT=8433                   # Policy Agent container internal secure port (container -> container)
+export POLICY_AGENT_APIS="V1"                                   # Supported northbound api versions
+
+export POLICY_AGENT_APP_NAME="policy-agent"                     # Name for Policy Agent container
+POLICY_AGENT_LOGPATH="/var/log/policy-agent/application.log"    # Path the application log in the Policy Agent container
+export POLICY_AGENT_APP_NAME_ALIAS="policy-agent-container"     # Alias name, name used by the control panel
+
+export MR_EXTERNAL_PORT=3905                                    # MR stub container external port (host -> container)
+export MR_INTERNAL_PORT=3905                                    # MR stub container internal port (container -> container)
+export MR_EXTERNAL_SECURE_PORT=3906                             # MR stub container external secure port (host -> container)
+export MR_INTERNAL_SECURE_PORT=3906                             # MR stub container internal secure port (container -> container)
+export MR_APP_NAME="message-router"                             # Name for the MR
+export MR_READ_URL="/events/A1-POLICY-AGENT-READ/users/policy-agent?timeout=15000&limit=100" # Path to read messages from MR
+export MR_WRITE_URL="/events/A1-POLICY-AGENT-WRITE"             # Path write messages to MR
+
+export CR_EXTERNAL_PORT=8090                                    # Callback receiver container external port (host -> container)
+export CR_INTERNAL_PORT=8090                                    # Callback receiver container internal port (container -> container)
+export CR_EXTERNAL_SECURE_PORT=8091                             # Callback receiver container external secure port (host -> container)
+export CR_INTERNAL_SECURE_PORT=8091                             # Callback receiver container internal secure port (container -> container)
+export CR_APP_NAME="callback-receiver"                          # Name for the Callback receiver
+
+export CONSUL_HOST="consul-server"                              # Host name of consul
+export CONSUL_EXTERNAL_PORT=8500                                # Consul container external port (host -> container)
+export CONSUL_INTERNAL_PORT=8500                                # Consul container internal port (container -> container)
+export CONSUL_APP_NAME="polman-consul"                          # Name for consul container
+
+export CBS_APP_NAME="polman-cbs"                                # Name for CBS container
+export CBS_EXTERNAL_PORT=10000                                  # CBS container external port (host -> container)
+export CBS_INTERNAL_PORT=10000                                  # CBS container internal port (container -> container)
+export CONFIG_BINDING_SERVICE="config-binding-service"          # Host name of CBS
+
+export RIC_SIM_BASE="g"                                         # Base name of the RIC Simulator container, shall be the group code
+                                                                # Note, a prefix is added to each container name by the .env file in the 'ric' dir
+RIC_SIM_PREFIX="ricsim"                                         # Prefix added to ric container name, added in the .env file in the 'ric' dir
+                                                                # This prefix can be changed from the command line
+export RIC_SIM_INTERNAL_PORT=8085                               # RIC Simulator container internal port (container -> container).
+                                                                # (external ports allocated by docker)
+export RIC_SIM_INTERNAL_SECURE_PORT=8185                        # RIC Simulator container internal secure port (container -> container).
+                                                                # (external ports allocated by docker)
+
+export SDNC_APP_NAME="a1-controller"                            # Name of the SNDC A1 Controller container
+export SDNC_EXTERNAL_PORT=8282                                  # SNDC A1 Controller container external port (host -> container)
+export SDNC_INTERNAL_PORT=8181                                  # SNDC A1 Controller container internal port (container -> container)
+export SDNC_EXTERNAL_SECURE_PORT=8443                           # SNDC A1 Controller container external securee port (host -> container)
+export SDNC_INTERNAL_SECURE_PORT=8443                           # SNDC A1 Controller container internal secure port (container -> container)
+export SDNC_DB_APP_NAME="sdnc-db"                               # Name of the SDNC DB container
+export SDNC_A1_TRUSTSTORE_PASSWORD="a1adapter"                  # SDNC truststore password
+SDNC_USER="admin"                                               # SDNC username
+SDNC_PWD="Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U"          # SNDC PWD
+SDNC_API_URL="/restconf/operations/A1-ADAPTER-API:"             # Base url path for SNDC API
+SDNC_ALIVE_URL="/apidoc/explorer/"                              # Base url path for SNDC API docs (for alive check)
+SDNC_KARAF_LOG="/opt/opendaylight/data/log/karaf.log"           # Path to karaf log
+
+
+export CONTROL_PANEL_APP_NAME="control-panel"                   # Name of the Control Panel container
+export CONTROL_PANEL_EXTERNAL_PORT=8080                         # Control Panel container external port (host -> container)
+export CONTROL_PANEL_INTERNAL_PORT=8080                         # Control Panel container external port (host -> container)
+CONTROL_PANEL_LOGPATH="/logs/nonrtric-controlpanel.log"         # Path the application log in the Control Panel container
+
+UUID=""                                                         # UUID used as prefix to the policy id to simulate a real UUID
+                                                                # Testscript need to set the UUID to use other this empty prefix is used
+
+RESTBASE="http://localhost:"$POLICY_AGENT_EXTERNAL_PORT         # Base url to the Agent NB REST interface
+RESTBASE_SECURE="https://localhost:"$POLICY_AGENT_EXTERNAL_SECURE_PORT # Base url to the secure Agent NB REST interface
+DMAAPBASE="http://localhost:"$MR_EXTERNAL_PORT                  # Base url to the Dmaap adapter, http
+DMAAPBASE_SECURE="https://localhost:"$MR_EXTERNAL_SECURE_PORT   # Base url to the Dmaap adapter, https
+ADAPTER=$RESTBASE                                               # Adapter holds the address the agent R-APP interface (REST OR DMAAP)
+                                                                # The values of this var is swiched between the two base url when needed
diff --git a/test/common/test_env-onap-master.sh b/test/common/test_env-onap-master.sh
new file mode 100644 (file)
index 0000000..f97309c
--- /dev/null
@@ -0,0 +1,200 @@
+#!/bin/bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 Nordix Foundation. All rights reserved.
+#  ========================================================================
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#  ============LICENSE_END=================================================
+#
+
+TEST_ENV_PROFILE="ONAP-MASTER"
+
+# Set up the image and tags for the test. Do not add the image tag to the image names.
+
+# NOTE: A env var for each container is created by the test script.
+# This var will point to the local or remote var depending on how
+# the test script is started. The name format is <container-name>_IMAGE, ie with 'LOCAL' or 'REMOTE'.
+
+# Local Policy Agent image and tag
+POLICY_AGENT_LOCAL_IMAGE="onap/ccsdk-oran-a1policymanagementservice"
+POLICY_AGENT_LOCAL_IMAGE_TAG="1.1.0-SNAPSHOT"
+# Remote Policy Agent image and tag
+POLICY_AGENT_REMOTE_IMAGE="nexus3.onap.org:10003/onap/ccsdk-oran-a1policymanagementservice"
+POLICY_AGENT_REMOTE_IMAGE_TAG="1.1.0-SNAPSHOT"
+
+# Local ECS image and tag
+ECS_LOCAL_IMAGE="o-ran-sc/nonrtric-enrichment-coordinator-service"
+ECS_LOCAL_IMAGE_TAG="1.0.0-SNAPSHOT"
+# Remote ECS image and tag
+ECS_REMOTE_IMAGE="nexus3.o-ran-sc.org:10003/o-ran-sc/nonrtric-enrichment-coordinator-service"
+ECS_REMOTE_IMAGE_TAG="1.0.0-SNAPSHOT"
+
+# Control Panel local image and tag
+CONTROL_PANEL_LOCAL_IMAGE="o-ran-sc/nonrtric-controlpanel"
+CONTROL_PANEL_LOCAL_IMAGE_TAG="2.0.0-SNAPSHOT"
+# Control Panel remote image and tag
+CONTROL_PANEL_REMOTE_IMAGE="nexus3.o-ran-sc.org:10004/o-ran-sc/nonrtric-controlpanel"
+CONTROL_PANEL_REMOTE_IMAGE_TAG="2.0.0"
+
+
+# SDNC A1 Controller remote image and tag
+SDNC_A1_CONTROLLER_REMOTE_IMAGE="nexus3.onap.org:10003/onap/sdnc-image"
+SDNC_A1_CONTROLLER_REMOTE_IMAGE_TAG="2.1.0-STAGING-latest"
+
+
+#SDNC DB remote image and tag
+SDNC_DB_REMOTE_IMAGE="mysql/mysql-server"
+SDNC_DB_REMOTE_IMAGE_TAG="5.6"
+#No local image for DB, remote image always used
+
+# Near RT RIC Simulator local image and tag
+RIC_SIM_LOCAL_IMAGE="o-ran-sc/a1-simulator"
+RIC_SIM_LOCAL_IMAGE_TAG="latest"
+# Near RT RIC Simulator remote image and tag
+RIC_SIM_REMOTE_IMAGE="nexus3.o-ran-sc.org:10004/o-ran-sc/a1-simulator"
+RIC_SIM_REMOTE_IMAGE_TAG="2.1.0"
+
+
+#Consul remote image and tag
+CONSUL_REMOTE_IMAGE="consul"
+CONSUL_REMOTE_IMAGE_TAG="1.7.2"
+#No local image for Consul, remote image always used
+
+
+#CBS remote image and tag
+CBS_REMOTE_IMAGE="nexus3.onap.org:10001/onap/org.onap.dcaegen2.platform.configbinding.app-app"
+CBS_REMOTE_IMAGE_TAG="2.3.0"
+#No local image for CBS, remote image always used
+
+
+#MR stub image and tag
+MRSTUB_LOCAL_IMAGE="mrstub"
+MRSTUB_LOCAL_IMAGE_TAG="latest"
+#No remote image for MR stub, local image always used
+
+#Callback receiver image and tag
+CR_LOCAL_IMAGE="callback-receiver"
+CR_LOCAL_IMAGE_TAG="latest"
+#No remote image for CR, local image always used
+
+#Producer stub image and tag
+PROD_STUB_LOCAL_IMAGE="producer-stub"
+PROD_STUB_LOCAL_IMAGE_TAG="latest"
+#No remote image for producer stub, local image always used
+
+# Common env var for auto-test. Vars used by docker-compose need to be exported
+export DOCKER_SIM_NWNAME="nonrtric-docker-net"                  # Name of docker private network
+
+export POLICY_AGENT_EXTERNAL_PORT=8081                          # Policy Agent container external port (host -> container)
+export POLICY_AGENT_INTERNAL_PORT=8081                          # Policy Agent container internal port (container -> container)
+export POLICY_AGENT_EXTERNAL_SECURE_PORT=8433                   # Policy Agent container external secure port (host -> container)
+export POLICY_AGENT_INTERNAL_SECURE_PORT=8433                   # Policy Agent container internal secure port (container -> container)
+export POLICY_AGENT_APIS="V1 V2"                                # Supported northbound api versions
+export PMS_VERSION="V2"
+
+export POLICY_AGENT_APP_NAME="policy-agent"                     # Name for Policy Agent container
+POLICY_AGENT_LOGPATH="/var/log/policy-agent/application.log"    # Path the application log in the Policy Agent container
+export POLICY_AGENT_APP_NAME_ALIAS="policy-agent-container"     # Alias name, name used by the control panel
+
+export ECS_EXTERNAL_PORT=8083                                   # ECS container external port (host -> container)
+export ECS_INTERNAL_PORT=8083                                   # ECS container internal port (container -> container)
+export ECS_EXTERNAL_SECURE_PORT=8434                            # ECS container external secure port (host -> container)
+export ECS_INTERNAL_SECURE_PORT=8434                            # ECS container internal secure port (container -> container)
+
+export ECS_APP_NAME="ecs"                                       # Name for ECS container
+ECS_LOGPATH="/var/log/enrichment-coordinator-service/application.log" # Path the application log in the ECS container
+export ECS_APP_NAME_ALIAS="enrichment-service-container"        # Alias name, name used by the control panel
+export ECS_HOST_MNT_DIR="./mnt"                                 # Mounted dir, relative to compose file, on the host
+export ECS_CONTAINER_MNT_DIR="/var/enrichment-coordinator-service" # Mounted dir in the container
+
+export MR_EXTERNAL_PORT=3905                                    # MR stub container external port (host -> container)
+export MR_INTERNAL_PORT=3905                                    # MR stub container internal port (container -> container)
+export MR_EXTERNAL_SECURE_PORT=3906                             # MR stub container external secure port (host -> container)
+export MR_INTERNAL_SECURE_PORT=3906                             # MR stub container internal secure port (container -> container)
+export MR_APP_NAME="message-router"                             # Name for the MR
+export MR_READ_URL="/events/A1-POLICY-AGENT-READ/users/policy-agent?timeout=15000&limit=100" # Path to read messages from MR
+export MR_WRITE_URL="/events/A1-POLICY-AGENT-WRITE"             # Path write messages to MR
+
+export CR_EXTERNAL_PORT=8090                                    # Callback receiver container external port (host -> container)
+export CR_INTERNAL_PORT=8090                                    # Callback receiver container internal port (container -> container)
+export CR_EXTERNAL_SECURE_PORT=8091                             # Callback receiver container external secure port (host -> container)
+export CR_INTERNAL_SECURE_PORT=8091                             # Callback receiver container internal secure port (container -> container)
+export CR_APP_NAME="callback-receiver"                          # Name for the Callback receiver
+export CR_APP_CALLBACK="/callbacks"                             # Url for callbacks
+
+export PROD_STUB_EXTERNAL_PORT=8092                             # Producer stub container external port (host -> container)
+export PROD_STUB_INTERNAL_PORT=8092                             # Producer stub container internal port (container -> container)
+export PROD_STUB_EXTERNAL_SECURE_PORT=8093                      # Producer stub container external secure port (host -> container)
+export PROD_STUB_INTERNAL_SECURE_PORT=8093                      # Producer stub container internal secure port (container -> container)
+export PROD_STUB_APP_NAME="producer-stub"                       # Name for the Producer stub
+
+export CONSUL_HOST="consul-server"                              # Host name of consul
+export CONSUL_EXTERNAL_PORT=8500                                # Consul container external port (host -> container)
+export CONSUL_INTERNAL_PORT=8500                                # Consul container internal port (container -> container)
+export CONSUL_APP_NAME="polman-consul"                          # Name for consul container
+
+export CBS_APP_NAME="polman-cbs"                                # Name for CBS container
+export CBS_EXTERNAL_PORT=10000                                  # CBS container external port (host -> container)
+export CBS_INTERNAL_PORT=10000                                  # CBS container internal port (container -> container)
+export CONFIG_BINDING_SERVICE="config-binding-service"          # Host name of CBS
+
+export RIC_SIM_BASE="g"                                         # Base name of the RIC Simulator container, shall be the group code
+                                                                # Note, a prefix is added to each container name by the .env file in the 'ric' dir
+RIC_SIM_PREFIX="ricsim"                                         # Prefix added to ric container name, added in the .env file in the 'ric' dir
+                                                                # This prefix can be changed from the command line
+export RIC_SIM_INTERNAL_PORT=8085                               # RIC Simulator container internal port (container -> container).
+                                                                # (external ports allocated by docker)
+export RIC_SIM_INTERNAL_SECURE_PORT=8185                        # RIC Simulator container internal secure port (container -> container).
+                                                                # (external ports allocated by docker)
+
+export SDNC_APP_NAME="a1-controller"                            # Name of the SNDC A1 Controller container
+export SDNC_EXTERNAL_PORT=8282                                  # SNDC A1 Controller container external port (host -> container)
+export SDNC_INTERNAL_PORT=8181                                  # SNDC A1 Controller container internal port (container -> container)
+export SDNC_EXTERNAL_SECURE_PORT=8443                           # SNDC A1 Controller container external securee port (host -> container)
+export SDNC_INTERNAL_SECURE_PORT=8443                           # SNDC A1 Controller container internal secure port (container -> container)
+export SDNC_DB_APP_NAME="sdnc-db"                               # Name of the SDNC DB container
+export SDNC_A1_TRUSTSTORE_PASSWORD="a1adapter"                  # SDNC truststore password
+SDNC_USER="admin"                                               # SDNC username
+SDNC_PWD="Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U"          # SNDC PWD
+SDNC_API_URL="/restconf/operations/A1-ADAPTER-API:"             # Base url path for SNDC API
+SDNC_ALIVE_URL="/apidoc/explorer/"                              # Base url path for SNDC API docs (for alive check)
+SDNC_KARAF_LOG="/opt/opendaylight/data/log/karaf.log"           # Path to karaf log
+
+
+export CONTROL_PANEL_APP_NAME="control-panel"                   # Name of the Control Panel container
+export CONTROL_PANEL_EXTERNAL_PORT=8080                         # Control Panel container external port (host -> container)
+export CONTROL_PANEL_INTERNAL_PORT=8080                         # Control Panel container external port (host -> container)
+CONTROL_PANEL_LOGPATH="/logs/nonrtric-controlpanel.log"         # Path the application log in the Control Panel container
+
+UUID=""                                                         # UUID used as prefix to the policy id to simulate a real UUID
+                                                                # Testscript need to set the UUID to use other this empty prefix is used
+
+RESTBASE="http://localhost:"$POLICY_AGENT_EXTERNAL_PORT         # Base url to the Agent NB REST interface
+RESTBASE_SECURE="https://localhost:"$POLICY_AGENT_EXTERNAL_SECURE_PORT # Base url to the secure Agent NB REST interface
+DMAAPBASE="http://localhost:"$MR_EXTERNAL_PORT                  # Base url to the Dmaap adapter, http
+DMAAPBASE_SECURE="https://localhost:"$MR_EXTERNAL_SECURE_PORT   # Base url to the Dmaap adapter, https
+ADAPTER=$RESTBASE                                               # Adapter holds the address the agent R-APP interface (REST OR DMAAP)
+                                                                # The values of this var is swiched between the two base url when needed
+                                                                # The values of this var is swiched between the four base url when needed
+
+ECS_RESTBASE="http://localhost:"$ECS_EXTERNAL_PORT              # Base url to the ECS NB REST interface
+ECS_RESTBASE_SECURE="https://localhost:"$ECS_EXTERNAL_SECURE_PORT # Base url to the secure ECS NB REST interface
+ECS_DMAAPBASE="http://localhost:"$MR_EXTERNAL_PORT              # Base url to the Dmaap adapter, http
+ECS_DMAAPBASE_SECURE="https://localhost:"$MR_EXTERNAL_SECURE_PORT   # Base url to the Dmaap adapter, https
+ECS_ADAPTER=$ECS_RESTBASE                                       # Adapter holds the address the ECS R-APP interface (REST OR DMAAP)
+                                                                # The values of this var is swiched between the four base url when needed
+
+CR_RESTBASE="http://localhost:"$CR_EXTERNAL_PORT                # Base url to the Callback receiver REST interface
+CR_RESTBASE_SECURE="https://localhost:"$CR_EXTERNAL_SECURE_PORT # Base url to the secure Callback receiver REST interface
+CR_ADAPTER=$CR_RESTBASE                                         # Adapter holds the address the CR admin interface (REST only)
+                                                                # The values of this var is swiched between the two base url when needed
\ No newline at end of file
diff --git a/test/common/test_env-oran-master.sh b/test/common/test_env-oran-master.sh
new file mode 100755 (executable)
index 0000000..0077ef0
--- /dev/null
@@ -0,0 +1,201 @@
+#!/bin/bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2020 Nordix Foundation. All rights reserved.
+#  ========================================================================
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#  ============LICENSE_END=================================================
+#
+
+TEST_ENV_PROFILE="ORAN-MASTER"
+
+# Set up the image and tags for the test. Do not add the image tag to the image names.
+
+# NOTE: A env var for each container is created by the test script.
+# This var will point to the local or remote var depending on how
+# the test script is started. The name format is <container-name>_IMAGE, ie with 'LOCAL' or 'REMOTE'.
+
+# Local Policy Agent image and tag
+POLICY_AGENT_LOCAL_IMAGE="o-ran-sc/nonrtric-policy-agent"
+POLICY_AGENT_LOCAL_IMAGE_TAG="2.1.0-SNAPSHOT"
+# Remote Policy Agent image and tag
+POLICY_AGENT_REMOTE_IMAGE="nexus3.o-ran-sc.org:10004/o-ran-sc/nonrtric-policy-agent"
+POLICY_AGENT_REMOTE_IMAGE_TAG="2.1.0"
+
+# Local ECS image and tag
+ECS_LOCAL_IMAGE="o-ran-sc/nonrtric-enrichment-coordinator-service"
+ECS_LOCAL_IMAGE_TAG="1.0.0-SNAPSHOT"
+# Remote ECS image and tag
+ECS_REMOTE_IMAGE="nexus3.o-ran-sc.org:10003/o-ran-sc/nonrtric-enrichment-coordinator-service"
+ECS_REMOTE_IMAGE_TAG="1.0.0-SNAPSHOT"
+
+# Control Panel local image and tag
+CONTROL_PANEL_LOCAL_IMAGE="o-ran-sc/nonrtric-controlpanel"
+CONTROL_PANEL_LOCAL_IMAGE_TAG="2.0.0-SNAPSHOT"
+# Control Panel remote image and tag
+CONTROL_PANEL_REMOTE_IMAGE="nexus3.o-ran-sc.org:10004/o-ran-sc/nonrtric-controlpanel"
+CONTROL_PANEL_REMOTE_IMAGE_TAG="2.0.0"
+
+
+# SDNC A1 Controller local image and tag
+SDNC_A1_CONTROLLER_LOCAL_IMAGE="o-ran-sc/nonrtric-a1-controller"
+SDNC_A1_CONTROLLER_LOCAL_IMAGE_TAG="2.1.0-SNAPSHOT"
+# SDNC A1 Controller remote image and tag
+SDNC_A1_CONTROLLER_REMOTE_IMAGE="nexus3.o-ran-sc.org:10004/o-ran-sc/nonrtric-a1-controller"
+SDNC_A1_CONTROLLER_REMOTE_IMAGE_TAG="2.1.0"
+
+
+#SDNC DB remote image and tag
+SDNC_DB_REMOTE_IMAGE="mysql/mysql-server"
+SDNC_DB_REMOTE_IMAGE_TAG="5.6"
+#No local image for DB, remote image always used
+
+
+# Near RT RIC Simulator local image and tag
+RIC_SIM_LOCAL_IMAGE="o-ran-sc/a1-simulator"
+RIC_SIM_LOCAL_IMAGE_TAG="latest"
+# Near RT RIC Simulator remote image and tag
+RIC_SIM_REMOTE_IMAGE="nexus3.o-ran-sc.org:10004/o-ran-sc/a1-simulator"
+RIC_SIM_REMOTE_IMAGE_TAG="2.0.0"
+
+
+#Consul remote image and tag
+CONSUL_REMOTE_IMAGE="consul"
+CONSUL_REMOTE_IMAGE_TAG="1.7.2"
+#No local image for Consul, remote image always used
+
+
+#CBS remote image and tag
+CBS_REMOTE_IMAGE="nexus3.onap.org:10001/onap/org.onap.dcaegen2.platform.configbinding.app-app"
+CBS_REMOTE_IMAGE_TAG="2.3.0"
+#No local image for CBS, remote image always used
+
+
+#MR stub image and tag
+MRSTUB_LOCAL_IMAGE="mrstub"
+MRSTUB_LOCAL_IMAGE_TAG="latest"
+#No remote image for MR stub, local image always used
+
+#Callback receiver image and tag
+CR_LOCAL_IMAGE="callback-receiver"
+CR_LOCAL_IMAGE_TAG="latest"
+#No remote image for CR, local image always used
+
+#Producer stub image and tag
+PROD_STUB_LOCAL_IMAGE="producer-stub"
+PROD_STUB_LOCAL_IMAGE_TAG="latest"
+#No remote image for producer stub, local image always used
+
+# Common env var for auto-test. Vars used by docker-compose need to be exported
+export DOCKER_SIM_NWNAME="nonrtric-docker-net"                  # Name of docker private network
+
+export POLICY_AGENT_EXTERNAL_PORT=8081                          # Policy Agent container external port (host -> container)
+export POLICY_AGENT_INTERNAL_PORT=8081                          # Policy Agent container internal port (container -> container)
+export POLICY_AGENT_EXTERNAL_SECURE_PORT=8433                   # Policy Agent container external secure port (host -> container)
+export POLICY_AGENT_INTERNAL_SECURE_PORT=8433                   # Policy Agent container internal secure port (container -> container)
+export POLICY_AGENT_APIS="V1"                                   # Supported northbound api versions
+
+export POLICY_AGENT_APP_NAME="policy-agent"                     # Name for Policy Agent container
+POLICY_AGENT_LOGPATH="/var/log/policy-agent/application.log"    # Path the application log in the Policy Agent container
+export POLICY_AGENT_APP_NAME_ALIAS="policy-agent-container"     # Alias name, name used by the control panel
+
+export ECS_EXTERNAL_PORT=8083                                   # ECS container external port (host -> container)
+export ECS_INTERNAL_PORT=8083                                   # ECS container internal port (container -> container)
+export ECS_EXTERNAL_SECURE_PORT=8434                            # ECS container external secure port (host -> container)
+export ECS_INTERNAL_SECURE_PORT=8434                            # ECS container internal secure port (container -> container)
+
+export ECS_APP_NAME="ecs"                                       # Name for ECS container
+ECS_LOGPATH="/var/log/enrichment-coordinator-service/application.log" # Path the application log in the ECS container
+export ECS_APP_NAME_ALIAS="enrichment-service-container"        # Alias name, name used by the control panel
+export ECS_HOST_MNT_DIR="./mnt"                                 # Mounted dir, relative to compose file, on the host
+export ECS_CONTAINER_MNT_DIR="/var/enrichment-coordinator-service" # Mounted dir in the container
+
+export MR_EXTERNAL_PORT=3905                                    # MR stub container external port (host -> container)
+export MR_INTERNAL_PORT=3905                                    # MR stub container internal port (container -> container)
+export MR_EXTERNAL_SECURE_PORT=3906                             # MR stub container external secure port (host -> container)
+export MR_INTERNAL_SECURE_PORT=3906                             # MR stub container internal secure port (container -> container)
+export MR_APP_NAME="message-router"                             # Name for the MR
+export MR_READ_URL="/events/A1-POLICY-AGENT-READ/users/policy-agent?timeout=15000&limit=100" # Path to read messages from MR
+export MR_WRITE_URL="/events/A1-POLICY-AGENT-WRITE"             # Path write messages to MR
+
+export CR_EXTERNAL_PORT=8090                                    # Callback receiver container external port (host -> container)
+export CR_INTERNAL_PORT=8090                                    # Callback receiver container internal port (container -> container)
+export CR_EXTERNAL_SECURE_PORT=8091                             # Callback receiver container external secure port (host -> container)
+export CR_INTERNAL_SECURE_PORT=8091                             # Callback receiver container internal secure port (container -> container)
+export CR_APP_NAME="callback-receiver"                          # Name for the Callback receiver
+export CR_APP_CALLBACK="/callbacks"                             # Url for callbacks
+
+export PROD_STUB_EXTERNAL_PORT=8092                             # Producer stub container external port (host -> container)
+export PROD_STUB_INTERNAL_PORT=8092                             # Producer stub container internal port (container -> container)
+export PROD_STUB_EXTERNAL_SECURE_PORT=8093                      # Producer stub container external secure port (host -> container)
+export PROD_STUB_INTERNAL_SECURE_PORT=8093                      # Producer stub container internal secure port (container -> container)
+export PROD_STUB_APP_NAME="producer-stub"                       # Name for the Producer stub
+
+export CONSUL_HOST="consul-server"                              # Host name of consul
+export CONSUL_EXTERNAL_PORT=8500                                # Consul container external port (host -> container)
+export CONSUL_INTERNAL_PORT=8500                                # Consul container internal port (container -> container)
+export CONSUL_APP_NAME="polman-consul"                          # Name for consul container
+
+export CBS_APP_NAME="polman-cbs"                                # Name for CBS container
+export CBS_EXTERNAL_PORT=10000                                  # CBS container external port (host -> container)
+export CBS_INTERNAL_PORT=10000                                  # CBS container internal port (container -> container)
+export CONFIG_BINDING_SERVICE="config-binding-service"          # Host name of CBS
+
+export RIC_SIM_BASE="g"                                         # Base name of the RIC Simulator container, shall be the group code
+                                                                # Note, a prefix is added to each container name by the .env file in the 'ric' dir
+RIC_SIM_PREFIX="ricsim"                                         # Prefix added to ric container name, added in the .env file in the 'ric' dir
+                                                                # This prefix can be changed from the command line
+export RIC_SIM_INTERNAL_PORT=8085                               # RIC Simulator container internal port (container -> container).
+                                                                # (external ports allocated by docker)
+export RIC_SIM_INTERNAL_SECURE_PORT=8185                        # RIC Simulator container internal secure port (container -> container).
+                                                                # (external ports allocated by docker)
+
+export SDNC_APP_NAME="a1-controller"                            # Name of the SNDC A1 Controller container
+export SDNC_EXTERNAL_PORT=8282                                  # SNDC A1 Controller container external port (host -> container)
+export SDNC_INTERNAL_PORT=8181                                  # SNDC A1 Controller container internal port (container -> container)
+export SDNC_EXTERNAL_SECURE_PORT=8443                           # SNDC A1 Controller container external securee port (host -> container)
+export SDNC_INTERNAL_SECURE_PORT=8443                           # SNDC A1 Controller container internal secure port (container -> container)
+export SDNC_DB_APP_NAME="sdnc-db"                               # Name of the SDNC DB container
+export SDNC_A1_TRUSTSTORE_PASSWORD=""                           # SDNC truststore password
+SDNC_USER="admin"                                               # SDNC username
+SDNC_PWD="Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U"          # SNDC PWD
+SDNC_API_URL="/restconf/operations/A1-ADAPTER-API:"             # Base url path for SNDC API
+SDNC_ALIVE_URL="/apidoc/explorer/"                              # Base url path for SNDC API docs (for alive check)
+SDNC_KARAF_LOG="/opt/opendaylight/data/log/karaf.log"           # Path to karaf log
+
+export CONTROL_PANEL_APP_NAME="control-panel"                   # Name of the Control Panel container
+export CONTROL_PANEL_EXTERNAL_PORT=8080                         # Control Panel container external port (host -> container)
+export CONTROL_PANEL_INTERNAL_PORT=8080                         # Control Panel container external port (host -> container)
+CONTROL_PANEL_LOGPATH="/logs/nonrtric-controlpanel.log"         # Path the application log in the Control Panel container
+
+UUID=""                                                         # UUID used as prefix to the policy id to simulate a real UUID
+                                                                # Testscript need to set the UUID otherwise this empty prefix is used
+
+RESTBASE="http://localhost:"$POLICY_AGENT_EXTERNAL_PORT         # Base url to the Agent NB REST interface
+RESTBASE_SECURE="https://localhost:"$POLICY_AGENT_EXTERNAL_SECURE_PORT # Base url to the secure Agent NB REST interface
+DMAAPBASE="http://localhost:"$MR_EXTERNAL_PORT                  # Base url to the Dmaap adapter, http
+DMAAPBASE_SECURE="https://localhost:"$MR_EXTERNAL_SECURE_PORT   # Base url to the Dmaap adapter, https
+ADAPTER=$RESTBASE                                               # Adapter holds the address the agent R-APP interface (REST OR DMAAP)
+                                                                # The values of this var is swiched between the four base url when needed
+
+ECS_RESTBASE="http://localhost:"$ECS_EXTERNAL_PORT              # Base url to the ECS NB REST interface
+ECS_RESTBASE_SECURE="https://localhost:"$ECS_EXTERNAL_SECURE_PORT # Base url to the secure ECS NB REST interface
+ECS_DMAAPBASE="http://localhost:"$MR_EXTERNAL_PORT              # Base url to the Dmaap adapter, http
+ECS_DMAAPBASE_SECURE="https://localhost:"$MR_EXTERNAL_SECURE_PORT   # Base url to the Dmaap adapter, https
+ECS_ADAPTER=$ECS_RESTBASE                                       # Adapter holds the address the ECS R-APP interface (REST OR DMAAP)
+                                                                # The values of this var is swiched between the four base url when needed
+
+CR_RESTBASE="http://localhost:"$CR_EXTERNAL_PORT                # Base url to the Callback receiver REST interface
+CR_RESTBASE_SECURE="https://localhost:"$CR_EXTERNAL_SECURE_PORT # Base url to the secure Callback receiver REST interface
+CR_ADAPTER=$CR_RESTBASE                                         # Adapter holds the address the CR admin interface (REST only)
+                                                                # The values of this var is swiched between the two base url when needed
\ No newline at end of file
old mode 100755 (executable)
new mode 100644 (file)
index ac5cfa4..293e993
@@ -186,4 +186,4 @@ ECS_RESTBASE_SECURE="https://localhost:"$ECS_EXTERNAL_SECURE_PORT # Base url to
 ECS_DMAAPBASE="http://localhost:"$MR_EXTERNAL_PORT              # Base url to the Dmaap adapter, http
 ECS_DMAAPBASE_SECURE="https://localhost:"$MR_EXTERNAL_SECURE_PORT   # Base url to the Dmaap adapter, https
 ECS_ADAPTER=$ECS_RESTBASE                                       # Adapter holds the address the ECS R-APP interface (REST OR DMAAP)
-                                                                # The values of this var is swiched between the four base url when needed
\ No newline at end of file
+                                                                # The values of this var is swiched between the four base url when needed
index ed02c7b..3ed51c9 100755 (executable)
@@ -61,7 +61,7 @@ fi
 echo -ne $EBOLD
 
 # default test environment variables
-TEST_ENV_VAR_FILE="../common/test_env.sh"
+TEST_ENV_VAR_FILE=""
 
 echo "Test case started as: ${BASH_SOURCE[$i+1]} "$@
 
@@ -128,6 +128,17 @@ echo "" > $HTTPLOG
 # Create a log dir for the test case
 mkdir -p $TESTLOGS/$ATC
 
+# Save create for current logs
+mkdir -p $TESTLOGS/$ATC/previous
+
+rm $TESTLOGS/$ATC/previous/*.log &> /dev/null
+rm $TESTLOGS/$ATC/previous/*.txt &> /dev/null
+rm $TESTLOGS/$ATC/previous/*.json &> /dev/null
+
+mv  $TESTLOGS/$ATC/*.log $TESTLOGS/$ATC/previous &> /dev/null
+mv  $TESTLOGS/$ATC/*.txt $TESTLOGS/$ATC/previous &> /dev/null
+mv  $TESTLOGS/$ATC/*.txt $TESTLOGS/$ATC/previous &> /dev/null
+
 # Clear the log dir for the test case
 rm $TESTLOGS/$ATC/*.log &> /dev/null
 rm $TESTLOGS/$ATC/*.txt &> /dev/null
@@ -215,7 +226,7 @@ while [ $paramerror -eq 0 ] && [ $foundparm -eq 0 ]; do
                        if [ -z "$1" ]; then
                                paramerror=1
                        else
-                               echo "Option set - Overriding test_env.sh with: "$1
+                               echo "Option set - Reading test env from: "$1
                                shift;
                                foundparm=0
                        fi
@@ -257,8 +268,23 @@ fi
 if [ -f "$TEST_ENV_VAR_FILE" ]; then
        echo -e $BOLD"Sourcing env vars from: "$TEST_ENV_VAR_FILE$EBOLD
        . $TEST_ENV_VAR_FILE
+
+       if [ -z "$TEST_ENV_PROFILE" ] || [ -z "$SUPPORTED_PROFILES" ]; then
+               echo -e $YELLOW"This test case may no work with selected test env file. TEST_ENV_PROFILE is missing in test_env file or SUPPORTED_PROFILES is missing in test case file"$EYELLOW
+       else
+               if [[ "$SUPPORTED_PROFILES" == *"$TEST_ENV_PROFILE"* ]]; then
+                       echo -e $GREEN"Test case support the selected test env file"$EGREEN
+               else
+                       echo -e $RED"Test case does not support the selected test env file"$ERED
+                       echo -e $RED"Exiting...."$ERED
+                       exit 1
+               fi
+       fi
 else
        echo -e $RED"Selected env var file does not exist: "$TEST_ENV_VAR_FILE$ERED
+       echo " Select one of following env var file matching the intended target of the test"
+       echo " Restart the test using the flag '--env-file <path-to-env-file>"
+       ls ../common/test_env* | indent1
        exit 1
 fi
 
@@ -266,9 +292,13 @@ fi
 G1_A1_VERSION=""
 G2_A1_VERSION=""
 G3_A1_VERSION=""
+G4_A1_VERSION=""
+G5_A1_VERSION=""
 G1_COUNT=0
 G2_COUNT=0
 G3_COUNT=0
+G4_COUNT=0
+G5_COUNT=0
 
 # Vars to switch between http and https. Extra curl flag needed for https
 export RIC_SIM_HTTPX="http"
@@ -283,6 +313,7 @@ export MR_LOCAL_PORT=$MR_EXTERNAL_PORT #When agent is running outside the docker
 export CR_HTTPX="http"
 export CR_PORT=$CR_INTERNAL_PORT
 export CR_LOCAL_PORT=$CR_EXTERNAL_PORT #When CR is running outside the docker net
+export CR_PATH="$CR_HTTPX://$CR_APP_NAME:$CR_PORT$CR_APP_CALLBACK"
 
 export PROD_STUB_HTTPX="http"
 export PROD_STUB_PORT=$PROD_STUB_INTERNAL_PORT
@@ -321,7 +352,7 @@ __check_image_var() {
        tag="${!5}"
 
        if [ -z $image ]; then
-               echo -e $RED"\$"$4" not set in test_env"$ERED
+               echo -e $RED"\$"$4" not set in $TEST_ENV_VAR_FILE"$ERED
                ((IMAGE_ERR++))
                echo ""
                tmp=$tmp"<no-image>\t"
@@ -329,7 +360,7 @@ __check_image_var() {
                tmp=$tmp$image"\t"
        fi
        if [ -z $tag ]; then
-               echo -e $RED"\$"$5" not set in test_env"$ERED
+               echo -e $RED"\$"$5" not set in $TEST_ENV_VAR_FILE"$ERED
                ((IMAGE_ERR++))
                echo ""
                tmp=$tmp"<no-tag>\t"
@@ -464,13 +495,13 @@ if [ -z "$SIM_GROUP" ]; then
        SIM_GROUP=$PWD/../simulator-group
        if [ ! -d  $SIM_GROUP ]; then
                echo "Trying to set env var SIM_GROUP to dir 'simulator-group' in the nontrtric repo, but failed."
-               echo -e $RED"Please set the SIM_GROUP manually in the test_env.sh"$ERED
+               echo -e $RED"Please set the SIM_GROUP manually in the applicable $TEST_ENV_VAR_FILE"$ERED
                exit 1
        else
                echo " SIM_GROUP auto set to: " $SIM_GROUP
        fi
 elif [ $SIM_GROUP = *simulator_group ]; then
-       echo -e $RED"Env var SIM_GROUP does not seem to point to dir 'simulator-group' in the repo, check common/test_env.sh"$ERED
+       echo -e $RED"Env var SIM_GROUP does not seem to point to dir 'simulator-group' in the repo, check $TEST_ENV_VAR_FILE"$ERED
        exit 1
 else
        echo " SIM_GROUP env var already set to: " $SIM_GROUP
@@ -667,6 +698,8 @@ if [ $? -eq 0 ]; then
                echo -e $RED" Build Failed"$ERED
                ((RES_CONF_FAIL++))
                cat .dockererr
+               echo -e $RED"Exiting...."$ERED
+               exit 1
        fi
        cd $curdir
 else
@@ -684,6 +717,8 @@ if [ $? -eq 0 ]; then
                echo -e $RED" Build Failed"$ERED
                ((RES_CONF_FAIL++))
                cat .dockererr
+               echo -e $RED"Exiting...."$ERED
+               exit 1
        fi
        cd $curdir
 else
@@ -701,6 +736,8 @@ if [ $? -eq 0 ]; then
                echo -e $RED" Build Failed"$ERED
                ((RES_CONF_FAIL++))
                cat .dockererr
+               echo -e $RED"Exiting...."$ERED
+               exit 1
        fi
        cd $curdir
 else
@@ -780,6 +817,7 @@ print_result() {
        echo "-------------------------------------------------------------------------------------------------"
        echo "-- Description: "$TC_ONELINE_DESCR
        echo "-- Execution time: " $duration " seconds"
+       echo "-- Used env file: "$TEST_ENV_VAR_FILE
        echo "-------------------------------------------------------------------------------------------------"
        echo "-------------------------------------     RESULTS"
        echo ""
@@ -1147,7 +1185,8 @@ __check_container_start() {
                        ((RES_CONF_FAIL++))
                        echo ""
                        echo -e $RED" Container $BOLD${appname}$EBOLD could not be started"$ERED
-                       return 1
+                       echo -e $RED" Stopping script..."$ERED
+                       exit 1
                fi
                if [ $localport -eq 0 ]; then
                        while [ $localport -eq 0 ]; do
@@ -1182,7 +1221,7 @@ __check_container_start() {
                else
                        TS_TMP=$SECONDS
                        while [ $(($TS_TMP+$i)) -gt $SECONDS ]; do
-                               echo -ne " Waiting for container ${appname} service status...retrying in $(($TS_TMP+$i-$SECONDS)) seconds   ${SAMELINE}"
+                               echo -ne " Waiting for container ${appname} service status...$(($SECONDS-$TSTART)) seconds, retrying in $(($TS_TMP+$i-$SECONDS)) seconds   ${SAMELINE}"
                                sleep 1
                        done
                fi
@@ -1190,7 +1229,7 @@ __check_container_start() {
 
        if [ "$pa_st" = "false"  ]; then
                ((RES_CONF_FAIL++))
-               echo -e $RED" Container ${appname} did not respond to service status"$ERED
+               echo -e $RED" Container ${appname} did not respond to service status in $(($SECONDS-$TSTART)) seconds"$ERED
                return 0
        fi
 
@@ -1221,6 +1260,8 @@ __start_container() {
                if [ $? -ne 0 ]; then
                        echo -e $RED"Problem to launch container(s) with docker-compose"$ERED
                        cat .dockererr
+                       echo -e $RED"Stopping script...."$ERED
+                       exit 1
                fi
        elif [ "$2" == "STANDALONE" ]; then
                echo "Skipping docker-compose"
@@ -1229,6 +1270,8 @@ __start_container() {
                if [ $? -ne 0 ]; then
                        echo -e $RED"Problem to launch container(s) with docker-compose"$ERED
                        cat .dockererr
+                       echo -e $RED"Stopping script...."$ERED
+                       exit 1
                fi
        fi
        app_prefix=""
@@ -1454,9 +1497,9 @@ use_simulator_https() {
        echo ""
 }
 
-# Start one group (ricsim_g1, ricsim_g2 or ricsim_g3) with a number of RIC Simulators using a given A interface
+# Start one group (ricsim_g1, ricsim_g2 .. ricsim_g5) with a number of RIC Simulators using a given A interface
 # 'ricsim' may be set on command line to other prefix
-# args:  ricsim_g1|ricsim_g2|ricsim_g3 <count> <interface-id>
+# args:  ricsim_g1|ricsim_g2|ricsim_g3|ricsim_g4|ricsim_g5 <count> <interface-id>
 # (Function for test scripts)
 start_ric_simulators() {
 
@@ -1472,10 +1515,12 @@ start_ric_simulators() {
        RIC1=$RIC_SIM_PREFIX"_g1"
        RIC2=$RIC_SIM_PREFIX"_g2"
        RIC3=$RIC_SIM_PREFIX"_g3"
+       RIC4=$RIC_SIM_PREFIX"_g4"
+       RIC5=$RIC_SIM_PREFIX"_g5"
 
        if [ $# != 3 ]; then
                ((RES_CONF_FAIL++))
-       __print_err "need three args,  $RIC1|$RIC2|$RIC3 <count> <interface-id>" $@
+       __print_err "need three args,  $RIC1|$RIC2|$RIC3|$RIC4|$RIC5 <count> <interface-id>" $@
                exit 1
        fi
        echo " $2 simulators using basename: $1 on interface: $3"
@@ -1489,9 +1534,15 @@ start_ric_simulators() {
        elif [ $1 == "$RIC3" ]; then
                G3_COUNT=$2
                G3_A1_VERSION=$3
+       elif [ $1 == "$RIC4" ]; then
+               G4_COUNT=$2
+               G4_A1_VERSION=$3
+       elif [ $1 == "$RIC5" ]; then
+               G5_COUNT=$2
+               G5_A1_VERSION=$3
        else
                ((RES_CONF_FAIL++))
-       __print_err "need three args, $RIC1|$RIC2|$RIC3 <count> <interface-id>" $@
+       __print_err "need three args, $RIC1|$RIC2|$RIC3|$RIC4|$RIC5 <count> <interface-id>" $@
                exit 1
        fi
 
@@ -1501,8 +1552,10 @@ start_ric_simulators() {
        export G1_A1_VERSION
        export G2_A1_VERSION
        export G3_A1_VERSION
+       export G4_A1_VERSION
+       export G5_A1_VERSION
 
-       docker_args="--scale g1=$G1_COUNT --scale g2=$G2_COUNT --scale g3=$G3_COUNT"
+       docker_args="--scale g1=$G1_COUNT --scale g2=$G2_COUNT --scale g3=$G3_COUNT --scale g4=$G4_COUNT --scale g5=$G5_COUNT"
        app_data=""
        cntr=1
        while [ $cntr -le $2 ]; do
@@ -1635,6 +1688,7 @@ use_cr_http() {
        export CR_HTTPX="http"
        export CR_PORT=$CR_INTERNAL_PORT
        export CR_LOCAL_PORT=$CR_EXTERNAL_PORT
+       export CR_PATH="$CR_HTTPX://$CR_APP_NAME:$CR_PORT$CR_APP_CALLBACK"
        echo ""
 }
 
@@ -1643,6 +1697,7 @@ use_cr_https() {
        export CR_HTTPX="https"
        export CR_PORT=$CR_INTERNAL_SECURE_PORT
        export CR_LOCAL_PORT=$CR_EXTERNAL_SECURE_PORT
+       export CR_PATH="$CR_HTTPX://$CR_APP_NAME:$CR_PORT$CR_APP_CALLBACK"
        echo ""
 }
 
@@ -1754,7 +1809,7 @@ use_agent_dmaap_http() {
 # args: -
 # (Function for test scripts)
 use_agent_dmaap_https() {
-       echo -e "Using $BOLD https $EBOLD and $BOLD REST $EBOLD towards the agent"
+       echo -e "Using $BOLD https $EBOLD and $BOLD DMAAP $EBOLD towards the agent"
        export ADAPTER=$DMAAPBASE_SECURE
        echo ""
        return 0
@@ -1765,7 +1820,11 @@ use_agent_dmaap_https() {
 # (Function for test scripts)
 set_agent_debug() {
        echo -e $BOLD"Setting agent debug"$EBOLD
-       curlString="$LOCALHOST$POLICY_AGENT_EXTERNAL_PORT/actuator/loggers/org.oransc.policyagent -X POST  -H Content-Type:application/json -d {\"configuredLevel\":\"debug\"}"
+       actuator="/actuator/loggers/org.oransc.policyagent"
+       if [[ $POLICY_AGENT_IMAGE = *"onap"* ]]; then
+               actuator="/actuator/loggers/org.onap.ccsdk.oran.a1policymanagementservice"
+       fi
+       curlString="$LOCALHOST$POLICY_AGENT_EXTERNAL_PORT$actuator -X POST  -H Content-Type:application/json -d {\"configuredLevel\":\"debug\"}"
        result=$(__do_curl "$curlString")
        if [ $? -ne 0 ]; then
                __print_err "could not set debug mode" $@
@@ -1781,7 +1840,11 @@ set_agent_debug() {
 # (Function for test scripts)
 set_agent_trace() {
        echo -e $BOLD"Setting agent trace"$EBOLD
-       curlString="$LOCALHOST$POLICY_AGENT_EXTERNAL_PORT/actuator/loggers/org.oransc.policyagent -X POST  -H Content-Type:application/json -d {\"configuredLevel\":\"trace\"}"
+       actuator="/actuator/loggers/org.oransc.policyagent"
+       if [[ $POLICY_AGENT_IMAGE = *"onap"* ]]; then
+               actuator="/actuator/loggers/org.onap.ccsdk.oran.a1policymanagementservice"
+       fi
+       curlString="$LOCALHOST$POLICY_AGENT_EXTERNAL_PORT$actuator -X POST  -H Content-Type:application/json -d {\"configuredLevel\":\"trace\"}"
        result=$(__do_curl "$curlString")
        if [ $? -ne 0 ]; then
                __print_err "could not set trace mode" $@
@@ -1812,6 +1875,23 @@ use_agent_retries() {
 start_ecs() {
 
        echo -e $BOLD"Starting ECS"$EBOLD
+
+       curdir=$PWD
+       cd $SIM_GROUP
+       cd ecs
+       cd $ECS_HOST_MNT_DIR
+       if [ -d database ]; then
+               echo -e $BOLD" Cleaning files in mounted dir: $PWD/database"$EBOLD
+               rm database/* > /dev/null
+               if [ $? -ne 0 ]; then
+                       echo -e $RED" Cannot remove database files in: $PWD"$ERED
+                       exit 1
+               fi
+       else
+               echo " No files in mounted dir or dir does not exists"
+       fi
+       cd $curdir
+
        __check_included_image 'ECS'
        if [ $? -eq 1 ]; then
                echo -e $RED"The ECS image has not been checked for this test run due to arg to the test script"$ERED
@@ -1822,6 +1902,23 @@ start_ecs() {
        __start_container ecs NODOCKERARGS $ECS_APP_NAME $ECS_EXTERNAL_PORT "/status" "http"
 }
 
+# Restart ECS
+# args: -
+# (Function for test scripts)
+restart_ecs() {
+       docker restart $ECS_APP_NAME &> ./tmp/.dockererr
+       if [ $? -ne 0 ]; then
+               __print_err "Could restart $ECS_APP_NAME" $@
+               cat ./tmp/.dockererr
+               ((RES_CONF_FAIL++))
+               return 1
+       fi
+
+       __check_container_start $ECS_APP_NAME $ECS_EXTERNAL_PORT "/status" "http"
+       echo ""
+       return 0
+}
+
 # All calls to ECS will be directed to the ECS REST interface from now on
 # args: -
 # (Function for test scripts)
@@ -1975,7 +2072,7 @@ store_logs() {
        __print_err "need one arg, <file-prefix>" $@
                exit 1
        fi
-       echo -e $BOLD"Storing all container logs using prefix: "$1$EBOLD
+       echo -e $BOLD"Storing all container logs in $TESTLOGS/$ATC using prefix: "$1$EBOLD
 
        docker stats --no-stream > $TESTLOGS/$ATC/$1_docker_stats.log 2>&1
 
@@ -2031,6 +2128,11 @@ store_logs() {
                done
        fi
 
+       __check_included_image 'PRODSTUB'
+       if [ $? -eq 0 ]; then
+               docker logs $PROD_STUB_APP_NAME > $TESTLOGS/$ATC/$1_prodstub.log 2>&1
+       fi
+
        echo ""
 }
 
@@ -2196,22 +2298,6 @@ __var_test() {
 
 ### Generic test cases for varaible checking
 
-# Tests if a variable value in the CR is equal to a target value and and optional timeout.
-# Arg: <variable-name> <target-value> - This test set pass or fail depending on if the variable is
-# equal to the target or not.
-# Arg: <variable-name> <target-value> <timeout-in-sec>  - This test waits up to the timeout seconds
-# before setting pass or fail depending on if the variable value becomes equal to the target
-# value or not.
-# (Function for test scripts)
-cr_equal() {
-       if [ $# -eq 2 ] || [ $# -eq 3 ]; then
-               __var_test "CR" "$LOCALHOST$CR_EXTERNAL_PORT/counter/" $1 "=" $2 $3
-       else
-               ((RES_CONF_FAIL++))
-               __print_err "Wrong args to cr_equal, needs two or three args: <sim-param> <target-value> [ timeout ]" $@
-       fi
-}
-
 # Tests if a variable value in the MR stub is equal to a target value and and optional timeout.
 # Arg: <variable-name> <target-value> - This test set pass or fail depending on if the variable is
 # equal to the target or not.
index bdc3521..8349554 100644 (file)
 
 FROM python:3.8-slim-buster
 
+#install nginx
+RUN apt-get update
+RUN apt-get install -y nginx=1.14.*
+
 COPY app/ /usr/src/app/
 COPY cert/ /usr/src/app/cert/
 
@@ -26,8 +30,4 @@ RUN pip install -r requirements.txt
 
 RUN chmod +x start.sh
 
-#install nginx
-RUN apt-get update
-RUN apt-get install -y nginx=1.14.*
-
 CMD [ "./start.sh" ]
index 251f0b3..becace1 100644 (file)
@@ -2,7 +2,7 @@
 
 The callback receiver is intended for function tests to simulate a RAPP.
 The callback receiver exposes the read and write urls, used by the agent, as configured in service.
-The callback receiver receives notifications from PMS when synchronization happens between PMS and RICs.
+The callback receiver receives notifications from PMS when synchronization happens between PMS and RICs. However, the callback receiver can be uses to receive any json payload from any source.
 
 # Ports and certificates
 
@@ -24,14 +24,30 @@ The following REST operations are available:
 
 >Send a message to CR<br>
 This method puts a request message from PMS to notify that sychronization between PMS and certain RIC happens.<br>
-```URI and payload, (PUT or POST): /callbacks/<id> <json array of response messages>```<br><br>
+```URI and payload, (PUT or POST): /callbacks/<id> <json messages>```<br>
 ```response: OK 200 or 500 for other errors```
 
+>Fetch one message for an id from CR<br>
+This method fetches the oldes message for an id, and removes the message.<br>
+```URI and payload, (GET): /get-event/<id>```<br>
+```response:  <json messages> 200 or 500 for other errors```
+
+>Fetch all messages for an id from CR<br>
+This method fetches all message in an array for an id, and removes all messages.<br>
+```URI and payload, (GET): /get-all-events/<id>```<br>
+```response:  <json array of json messages> 200 or 500 for other errors```
+
+>Dump all currently wating callback messages in CR<br>
+This method fetches all message in an array for an id. Messages are left intact in the CR.<br>
+```URI and payload, (GET): /db```<br>
+```response:  <json> 200```
+
 >Metrics - counters<br>
 There are a number of counters that can be read to monitor the message processing. Do a http GET on any of the current counters and an integer value will be returned with http response code 200.
 ```/counter/received_callbacks``` - The total number of received callbacks<br>
 ```/counter/fetched_callbacks``` - The total number of fetched callbacks<br>
 ```/counter/current_messages``` - The current number of callback messages waiting to be fetched<br>
+All counters also support the query parameter "id" to fetch counter for one individual id, eg ```/counter/current_messages?id=my-id```
 
 
 ### Build and start ###
index bc6e28f..fe0fbe4 100644 (file)
 #  ============LICENSE_END=================================================
 #
 
-from flask import Flask, request
+from flask import Flask, request, Response
 from time import sleep
 import time
 import datetime
 import json
-from flask import Flask
-from flask import Response
 import traceback
 
 app = Flask(__name__)
@@ -37,10 +35,13 @@ HOST_PORT = 2222
 # Metrics vars
 cntr_msg_callbacks=0
 cntr_msg_fetched=0
+cntr_callbacks={}
 
 # Request and response constants
 CALLBACK_URL="/callbacks/<string:id>"
 APP_READ_URL="/get-event/<string:id>"
+APP_READ_ALL_URL="/get-all-events/<string:id>"
+DUMP_ALL_URL="/db"
 
 MIME_TEXT="text/plain"
 MIME_JSON="application/json"
@@ -57,7 +58,7 @@ def index():
 
 # Fetch the oldest callback message for an id
 # URI and parameter, (GET): /get-event/<id>
-# response: message + 200 or 204
+# response: message + 200 or just 204 or just 500(error)
 @app.route(APP_READ_URL,
     methods=['GET'])
 def receiveresponse(id):
@@ -67,19 +68,47 @@ def receiveresponse(id):
     try:
         if ((id in msg_callbacks.keys()) and (len(msg_callbacks[id]) > 0)):
             cntr_msg_fetched+=1
-            msg=str(msg_callbacks[id][0])
-            print("Fetching msg for id: "+id+", msg="+msg)
+            cntr_callbacks[id][1]+=1
+            msg=msg_callbacks[id][0]
+            print("Fetching msg for id: "+id+", msg="+str(msg))
             del msg_callbacks[id][0]
-            return msg,200
+            return json.dumps(msg),200
         print("No messages for id: "+id)
     except Exception as e:
         print(CAUGHT_EXCEPTION+str(e))
+        traceback.print_exc()
+        return "",500
 
     return "",204
 
+# Fetch all callback message for an id in an array
+# URI and parameter, (GET): /get-all-events/<id>
+# response: message + 200 or just 500(error)
+@app.route(APP_READ_ALL_URL,
+    methods=['GET'])
+def receiveresponse_all(id):
+    global msg_callbacks
+    global cntr_msg_fetched
+
+    try:
+        if ((id in msg_callbacks.keys()) and (len(msg_callbacks[id]) > 0)):
+            cntr_msg_fetched+=len(msg_callbacks[id])
+            cntr_callbacks[id][1]+=len(msg_callbacks[id])
+            msg=msg_callbacks[id]
+            print("Fetching all msgs for id: "+id+", msg="+str(msg))
+            del msg_callbacks[id]
+            return json.dumps(msg),200
+        print("No messages for id: "+id)
+    except Exception as e:
+        print(CAUGHT_EXCEPTION+str(e))
+        traceback.print_exc()
+        return "",500
+
+    msg=[]
+    return json.dumps(msg),200
 
 # Receive a callback message
-# URI and payload, (PUT or POST): /callbacks/<id> <json array of response messages>
+# URI and payload, (PUT or POST): /callbacks/<id> <json messages>
 # response: OK 200 or 500 for other errors
 @app.route(CALLBACK_URL,
     methods=['PUT','POST'])
@@ -91,17 +120,16 @@ def events_write(id):
         print("Received callback for id: "+id +", content-type="+request.content_type)
         try:
             if (request.content_type == MIME_JSON):
-                msg = request.json
+                data = request.data
+                msg = json.loads(data)
                 print("Payload(json): "+str(msg))
-            elif (request.content_type == MIME_TEXT):
-                msg= request.form
-                print("Payload(text): "+str(msg))
             else:
-                msg="\"\""
-                print("Payload(content-type="+request.content_type+"). Setting data to empty, quoted, string")
-        except:
-            msg="\"\""
-            print("(Exception) Payload does not contain any json or text data, setting empty string as payload")
+                msg={}
+                print("Payload(content-type="+request.content_type+"). Setting empty json as payload")
+        except Exception as e:
+            msg={}
+            print("(Exception) Payload does not contain any json, setting empty json as payload")
+            traceback.print_exc()
 
         cntr_msg_callbacks += 1
         if (id in msg_callbacks.keys()):
@@ -109,30 +137,68 @@ def events_write(id):
         else:
             msg_callbacks[id]=[]
             msg_callbacks[id].append(msg)
+
+        if (id in cntr_callbacks.keys()):
+            cntr_callbacks[id][0] += 1
+        else:
+            cntr_callbacks[id]=[]
+            cntr_callbacks[id].append(1)
+            cntr_callbacks[id].append(0)
+
     except Exception as e:
         print(CAUGHT_EXCEPTION+str(e))
-        return 'OK',500
+        traceback.print_exc()
+        return 'NOTOK',500
 
     return 'OK',200
 
+### Functions for test ###
+
+# Dump the whole db of current callbacks
+# URI and parameter, (GET): /db
+# response: message + 200
+@app.route(DUMP_ALL_URL,
+    methods=['GET'])
+def dump_db():
+    return json.dumps(msg_callbacks),200
 
 ### Functions for metrics read out ###
 
 @app.route('/counter/received_callbacks',
     methods=['GET'])
 def requests_submitted():
-    return Response(str(cntr_msg_callbacks), status=200, mimetype=MIME_TEXT)
+    req_id = request.args.get('id')
+    if (req_id is None):
+        return Response(str(cntr_msg_callbacks), status=200, mimetype=MIME_TEXT)
+
+    if (req_id in cntr_callbacks.keys()):
+        return Response(str(cntr_callbacks[req_id][0]), status=200, mimetype=MIME_TEXT)
+    else:
+        return Response(str("0"), status=200, mimetype=MIME_TEXT)
 
 @app.route('/counter/fetched_callbacks',
     methods=['GET'])
 def requests_fetched():
-    return Response(str(cntr_msg_fetched), status=200, mimetype=MIME_TEXT)
+    req_id = request.args.get('id')
+    if (req_id is None):
+        return Response(str(cntr_msg_fetched), status=200, mimetype=MIME_TEXT)
+
+    if (req_id in cntr_callbacks.keys()):
+        return Response(str(cntr_callbacks[req_id][1]), status=200, mimetype=MIME_TEXT)
+    else:
+        return Response(str("0"), status=200, mimetype=MIME_TEXT)
 
 @app.route('/counter/current_messages',
     methods=['GET'])
 def current_messages():
-    return Response(str(cntr_msg_callbacks-cntr_msg_fetched), status=200, mimetype=MIME_TEXT)
-
+    req_id = request.args.get('id')
+    if (req_id is None):
+        return Response(str(cntr_msg_callbacks-cntr_msg_fetched), status=200, mimetype=MIME_TEXT)
+
+    if (req_id in cntr_callbacks.keys()):
+        return Response(str(cntr_callbacks[req_id][0]-cntr_callbacks[req_id][1]), status=200, mimetype=MIME_TEXT)
+    else:
+        return Response(str("0"), status=200, mimetype=MIME_TEXT)
 
 
 ### Admin ###
index dbaca4f..d0bf25d 100755 (executable)
@@ -49,6 +49,9 @@ echo "=== CR hello world ==="
 RESULT="OK"
 do_curl GET / 200
 
+echo "=== Reset ==="
+RESULT="*"
+do_curl POST /reset 200
 
 echo "=== Get counter - callbacks ==="
 RESULT="0"
@@ -62,11 +65,16 @@ echo "=== Get counter - current events ==="
 RESULT="0"
 do_curl GET /counter/current_messages 200
 
+echo "=== Send a request non json ==="
+RESULT="*"
+#create payload
+echo "DATA" > .tmp.json
+do_curl POST '/callbacks/test' 200 .tmp.json
 
 echo "=== Send a request ==="
 RESULT="*"
 #create payload
-echo "\"DATA-MSG\"" > .tmp.json
+echo "{\"DATA-MSG\":\"msg\"}" > .tmp.json
 do_curl POST '/callbacks/test' 200 .tmp.json
 
 
@@ -74,9 +82,9 @@ echo "=== Fetch an event, wrong id==="
 RESULT="*"
 do_curl GET '/get-event/wrongid' 204
 
-
+# Test counters for all ids
 echo "=== Get counter - callbacks ==="
-RESULT="1"
+RESULT="2"
 do_curl GET /counter/received_callbacks 200
 
 echo "=== Get counter - fetched events ==="
@@ -84,12 +92,42 @@ RESULT="0"
 do_curl GET /counter/fetched_callbacks 200
 
 echo "=== Get counter - current events ==="
-RESULT="1"
+RESULT="2"
 do_curl GET /counter/current_messages 200
 
+# Test counter for one id
+echo "=== Get counter - callbacks ==="
+RESULT="2"
+do_curl GET /counter/received_callbacks?id=test 200
+
+echo "=== Get counter - fetched events ==="
+RESULT="0"
+do_curl GET /counter/fetched_callbacks?id=test 200
+
+echo "=== Get counter - current events ==="
+RESULT="2"
+do_curl GET /counter/current_messages?id=test 200
+
+# Test counter for dummy id
+echo "=== Get counter - callbacks ==="
+RESULT="0"
+do_curl GET /counter/received_callbacks?id=dummy 200
+
+echo "=== Get counter - fetched events ==="
+RESULT="0"
+do_curl GET /counter/fetched_callbacks?id=dummy 200
+
+echo "=== Get counter - current events ==="
+RESULT="0"
+do_curl GET /counter/current_messages?id=dummy 200
+
+
+echo "=== Fetch an event ==="
+RESULT="json:{}"
+do_curl GET '/get-event/test' 200
 
 echo "=== Fetch an event ==="
-RESULT="DATA-MSG"
+RESULT="json:{\"DATA-MSG\":\"msg\"}"
 do_curl GET '/get-event/test' 200
 
 echo "=== Fetch an event again ==="
@@ -97,15 +135,87 @@ RESULT="*"
 do_curl GET '/get-event/test' 204
 
 echo "=== Get counter - callbacks ==="
-RESULT="1"
+RESULT="2"
 do_curl GET /counter/received_callbacks 200
 
 echo "=== Get counter - fetched events ==="
-RESULT="1"
+RESULT="2"
+do_curl GET /counter/fetched_callbacks 200
+
+echo "=== Get counter - current events ==="
+RESULT="0"
+do_curl GET /counter/current_messages 200
+
+# Test counter for one id
+echo "=== Get counter - callbacks ==="
+RESULT="2"
+do_curl GET /counter/received_callbacks?id=test 200
+
+echo "=== Get counter - fetched events ==="
+RESULT="2"
+do_curl GET /counter/fetched_callbacks?id=test 200
+
+echo "=== Get counter - current events ==="
+RESULT="0"
+do_curl GET /counter/current_messages?id=test 200
+
+echo "=== Send a request ==="
+RESULT="*"
+#create payload
+echo "{\"DATA-MSG\":\"msg\"}" > .tmp.json
+do_curl POST '/callbacks/test' 200 .tmp.json
+
+echo "=== Send a request ==="
+RESULT="*"
+#create payload
+echo "{\"DATA-MSG2\":\"msg2\"}" > .tmp.json
+do_curl POST '/callbacks/test' 200 .tmp.json
+
+echo "=== Send a request ==="
+RESULT="*"
+#create payload
+echo "{\"DATA-MSG3\":\"msg3\"}" > .tmp.json
+do_curl POST '/callbacks/test1' 200 .tmp.json
+
+echo "=== Get counter - callbacks ==="
+RESULT="5"
+do_curl GET /counter/received_callbacks 200
+
+echo "=== Get counter - fetched events ==="
+RESULT="2"
 do_curl GET /counter/fetched_callbacks 200
 
 echo "=== Get counter - current events ==="
+RESULT="3"
+do_curl GET /counter/current_messages 200
+
+# Test counter for one id, test1
+echo "=== Get counter - callbacks ==="
+RESULT="1"
+do_curl GET /counter/received_callbacks?id=test1 200
+
+echo "=== Get counter - fetched events ==="
 RESULT="0"
+do_curl GET /counter/fetched_callbacks?id=test1 200
+
+echo "=== Get counter - current events ==="
+RESULT="1"
+do_curl GET /counter/current_messages?id=test1 200
+
+echo "=== Fetch all events ==="
+RESULT="json:[{\"DATA-MSG2\":\"msg2\"},{\"DATA-MSG\":\"msg\"}]"
+do_curl GET '/get-all-events/test' 200
+
+echo "=== Get counter - callbacks ==="
+RESULT="5"
+do_curl GET /counter/received_callbacks 200
+
+echo "=== Get counter - fetched events ==="
+RESULT="4"
+do_curl GET /counter/fetched_callbacks 200
+
+echo "=== Get counter - current events ==="
+RESULT="1"
 do_curl GET /counter/current_messages 200
 
 echo "=== CR reset ==="
index a971d68..2234679 100755 (executable)
@@ -21,4 +21,4 @@
 
 docker build -t callback-receiver .
 
-docker run -it -p 8090:8090 -p 8091:8091 callback-receiver
+docker run --rm -it -p 8090:8090 -p 8091:8091 callback-receiver
index e7262e4..3f000c7 100755 (executable)
@@ -33,7 +33,7 @@ clean_docker(){
 # Run auto-test scripts
 cd ../auto-test/
 clean_docker
-bash FTC10.sh remote auto-clean --use-local-image PA SDNC
+bash FTC10.sh remote auto-clean --env-file ../common/test_env-oran-master.sh --use-local-image PA SDNC
 
 echo "--> run_integration.sh END"
 
index 4aa3a7a..ab11497 100644 (file)
@@ -1,2 +1,3 @@
+.p.json
 .tmp.json
-.dockererr
\ No newline at end of file
+.dockererr
index c21a7ab..7323d3a 100644 (file)
 from flask import Flask
 from flask import request
 
+import requests
+
 import json
 from jsonschema import validate
 
+import threading
+import time
+import datetime
+
 app = Flask(__name__)
 
 # # list of callback messages
@@ -44,7 +50,6 @@ ARM_CREATE_RESPONSE="/arm/create/<string:producer_id>/<string:job_id>"
 ARM_DELETE_RESPONSE="/arm/delete/<string:producer_id>/<string:job_id>"
 ARM_SUPERVISION_RESPONSE="/arm/supervision/<string:producer_id>"
 ARM_TYPE="/arm/type/<string:producer_id>/<string:type_id>"
-
 COUNTER_SUPERVISION="/counter/supervision/<string:producer_id>"
 COUNTER_CREATE="/counter/create/<string:producer_id>/<string:job_id>"
 COUNTER_DELETE="/counter/delete/<string:producer_id>/<string:job_id>"
@@ -62,6 +67,8 @@ PRODUCER_OR_JOB_NOT_FOUND="producer or job not found"
 PRODUCER_NOT_FOUND="producer not found"
 TYPE_NOT_FOUND="type not found"
 TYPE_IN_USE="type is in use in a job"
+JOB_NOT_FOUND="job not found"
+JOB_DATA_NOT_FOUND="job data not found"
 JSON_CORRUPT="json in request is corrupt or missing"
 
 #Producer and job db, including armed responses
@@ -72,6 +79,7 @@ db={}
 #  supervision counter
 #  job
 #    job json
+#    target_type
 #    armed response for create
 #    armed response for delete
 #    create counter
@@ -109,6 +117,8 @@ def setup_callback_dict(producer_id, job_id):
         job_dict['json']=None
         job_dict['create_counter']=0
         job_dict['delete_counter']=0
+        job_dict['delivering']=False
+        job_dict['delivery_attempts']=0
     return job_dict
 
 
@@ -121,6 +131,9 @@ def get_callback_dict(producer_id, job_id):
     if (producer_id in db.keys()):
         producer_dict=db[producer_id]
 
+    if (producer_dict is None):
+        return None
+
     if (job_id is None):
         return producer_dict
 
@@ -141,6 +154,17 @@ def recursive_search(s_dict, s_key, s_id):
 
     return False
 
+# Helper function to find all job dicts
+def get_all_jobs():
+    job_dicts={}
+    for producer_key in db:
+        producer_dict = db[producer_key]
+        for job_key in producer_dict:
+            job_dict = producer_dict[job_key]
+            if (isinstance(job_dict, dict)):
+                job_dicts[job_key]=job_dict
+    return job_dicts
+
 # I'm alive function
 # response: always 200
 @app.route('/',
@@ -150,7 +174,7 @@ def index():
 
 # Arm the create callback with a response code
 # Omitting the query parameter switch to response back to the standard 200/201 response
-# URI and parameters (PUT): /arm/create/<producer_id>/<job-id>[?response=<resonsecode>]
+# URI and parameters (PUT): /arm/create/<producer_id>/<job_id>[?response=<resonsecode>]
 # Setting
 # response: 200 (400 if incorrect query params)
 @app.route(ARM_CREATE_RESPONSE,
@@ -166,6 +190,7 @@ def arm_create(producer_id, job_id):
         if (len(request.args) != 1):
             return UNKNOWN_QUERY_PARAMETERS,400
 
+
     print("Arm create received for producer: "+str(producer_id)+" and job: "+str(job_id)+" and response: "+str(arm_response))
 
     job_dict=setup_callback_dict(producer_id, job_id)
@@ -176,7 +201,7 @@ def arm_create(producer_id, job_id):
         else:
             job_dict['create_response']=200
     else:
-        job_dict['create_response']=arm_response
+        job_dict['create_response']=int(arm_response)
 
     return "",200
 
@@ -209,7 +234,7 @@ def arm_delete(producer_id, job_id):
         else:
             job_dict['delete_response']=204
     else:
-        job_dict['delete_response']=arm_response
+        job_dict['delete_response']=int(arm_response)
 
     return "",200
 
@@ -236,7 +261,7 @@ def arm_supervision(producer_id):
     if (arm_response is None):
         producer_dict['supervision_response']=200
     else:
-        producer_dict['supervision_response']=arm_response
+        producer_dict['supervision_response']=int(arm_response)
 
     return "",200
 
@@ -282,6 +307,7 @@ def disarm_type(producer_id, type_id):
 
     return "",200
 
+
 # Callback for create job
 # URI and parameters (POST): /callbacks/create/<producer_id>
 # response 201 at create, 200 at update or other configured response code
@@ -304,7 +330,7 @@ def callback_create(producer_id):
     type_list=producer_dict['types']
     type_id=req_json_dict['ei_type_identity']
     if (type_id not in type_list):
-        return TYPE_NOT_FOUND
+        return TYPE_NOT_FOUND, 400
 
     job_id=req_json_dict['ei_job_identity']
     job_dict=get_callback_dict(producer_id, job_id)
@@ -317,6 +343,7 @@ def callback_create(producer_id):
         return_code=job_dict['create_response']
         if ((job_dict['create_response'] == 200) or (job_dict['create_response'] == 201)):
             job_dict['json']=req_json_dict
+            job_dict['delivering']=True
             if (job_dict['create_response'] == 201): #Set up next response code if create was ok
                 job_dict['create_response'] = 200
             if (job_dict['delete_response'] == 404):
@@ -328,7 +355,7 @@ def callback_create(producer_id):
     else:
         return JOBID_NO_MATCH, 400
 
-    return return_msg,return_code
+    return return_msg, return_code
 
 # Callback for delete job
 # URI and parameters (POST): /callbacks/delete/<producer_id>
@@ -358,6 +385,7 @@ def callback_delete(producer_id):
         if (job_dict['delete_response'] == 204):
             job_dict['json']=None
             job_dict['delete_response']=404
+            job_dict['delivering']=False
             if (job_dict['create_response'] == 200):
                 job_dict['create_response'] = 201 # reset create response if delete was ok
         else:
@@ -390,7 +418,7 @@ def callback_supervision(producer_id):
 
     return return_msg,producer_dict['supervision_response']
 
-# Callback for supervision of producer
+# Get the job definition for a job
 # URI and parameters (GET): "/jobdata/<string:producer_id>/<string:job_id>"
 # response: 200 or 204
 @app.route(JOB_DATA,
@@ -399,12 +427,49 @@ def get_jobdata(producer_id, job_id):
 
     print("Get job data received for producer: "+str(producer_id)+" and job: "+str(job_id))
 
-    job_dict=setup_callback_dict(producer_id, job_id)
+    job_dict=get_callback_dict(producer_id, job_id)
+
+    if (job_dict is None):
+        return PRODUCER_OR_JOB_NOT_FOUND,400
+
     if (job_dict['json'] is None):
         return "",204
     else:
         return json.dumps(job_dict['json']), 200
 
+# Start data delivery for a job, action : START or STOP
+# URI and parameters (POST): "/jobdata/<string:producer_id>/<string:job_id>?action=action"
+# response: 200 or 204
+@app.route(JOB_DATA,
+     methods=['POST'])
+def start_jobdata(producer_id, job_id):
+
+    action=request.args.get('action')
+
+    if (action is None):
+        return UNKNOWN_QUERY_PARAMETERS,400
+    else:
+        if (len(request.args) != 1):
+            return UNKNOWN_QUERY_PARAMETERS,400
+        else:
+            if ((action != "START") and (action != "STOP")):
+                return UNKNOWN_QUERY_PARAMETERS,400
+
+    print("Job data action received for producer: "+str(producer_id)+" and job: "+str(job_id) + " action: " + action)
+
+    job_dict=get_callback_dict(producer_id, job_id)
+    if (job_dict is None):
+        return JOB_NOT_FOUND,404
+
+    if (job_dict['json'] is None):
+        return JOB_DATA_NOT_FOUND, 400
+    else:
+        if (action == "START"):
+            job_dict['delivering']=True
+        else:
+            job_dict['delivering']=False
+        return "",200
+
 
 # Counter for create calls for a job
 # URI and parameters (GET): "/counter/create/<string:producer_id>/<string:job_id>"
@@ -414,7 +479,7 @@ def get_jobdata(producer_id, job_id):
 def counter_create(producer_id, job_id):
     job_dict=get_callback_dict(producer_id, job_id)
     if (job_dict is None):
-        return -1,200
+        return "-1",200
     return str(job_dict['create_counter']),200
 
 # Counter for delete calls for a job
@@ -425,7 +490,7 @@ def counter_create(producer_id, job_id):
 def counter_delete(producer_id, job_id):
     job_dict=get_callback_dict(producer_id, job_id)
     if (job_dict is None):
-        return -1,200
+        return "-1",200
     return str(job_dict['delete_counter']),200
 
 # Counter for supervision calls for a producer
@@ -436,7 +501,7 @@ def counter_delete(producer_id, job_id):
 def counter_supervision(producer_id):
     producer_dict=get_callback_dict(producer_id, None)
     if (producer_dict is None):
-        return -1,200
+        return "-1",200
     return str(producer_dict['supervision_counter']),200
 
 # Get status info
@@ -457,7 +522,36 @@ def reset():
     db={}
     return "",200
 
+
+def datadelivery() :
+    while True:
+        try:
+            job_dicts=get_all_jobs()
+            for key in job_dicts:
+                job=job_dicts[key]
+                if (job['delivering'] == True and job['json'] != None):
+                    url=job['json']['target_uri']
+
+                    data={}
+                    data["date"]=str(datetime.datetime.now())
+                    data["job"]=""+key
+                    data["sequence_no"]=""+str(job['delivery_attempts'])
+                    data["value"]=str(100)
+                    print("Sending to "+url+" payload:"+json.dumps(data))
+
+                    requests.post(url, json=data, verify=False, timeout=2) #NOSONAR
+                    job['delivery_attempts'] += 1
+        except Exception as err:
+            print("Error during data delivery: "+ str(err))
+        time.sleep(1)
+
+
 ### Main function ###
 
+print("Starting data delivery thread")
+thread = threading.Thread(target=datadelivery, args=())
+thread.daemon = True
+thread.start()
+
 if __name__ == "__main__":
     app.run(port=HOST_PORT, host=HOST_IP)
index cc0dabf..d33cdac 100644 (file)
@@ -1,3 +1,3 @@
 Flask==1.1.1
 jsonschema==3.2.0
-
+requests==2.24.0
index c0af24e..a17c804 100755 (executable)
@@ -30,12 +30,12 @@ fi
 
 if [ $1 == "nonsecure" ]; then
     #Default http port for the simulator
-    PORT=8092
+    PORT=8992
     # Set http protocol
     HTTPX="http"
 else
     #Default https port for the simulator
-    PORT=8093
+    PORT=8993
     # Set https protocol
     HTTPX="https"
 fi
@@ -43,11 +43,229 @@ fi
 # source function to do curl and check result
 . ../common/do_curl_function.sh
 
-echo "===  hello world ==="
+echo "=== hello world ==="
 RESULT="OK"
 do_curl GET / 200
 
+echo "=== reset ==="
+RESULT=""
+do_curl GET /reset 200
 
+echo "=== status ==="
+RESULT="json:{}"
+do_curl GET /status 200
+
+# Basic admin
+
+echo "===  check supervision counter ==="
+RESULT="-1"
+do_curl GET /counter/supervision/prod-x 200
+
+echo "===  check create counter ==="
+RESULT="-1"
+do_curl GET /counter/create/prod-x/job-x 200
+
+echo "===  check delete counter ==="
+RESULT="-1"
+do_curl GET /counter/delete/prod-x/job-x 200
+
+## Create/update a producer
+
+echo "===  create producer ==="
+RESULT="Unknown query parameter(s)"
+do_curl PUT /arm/supervision/prod-x?test=201 400
+
+echo "===  create producer ==="
+RESULT=""
+do_curl PUT /arm/supervision/prod-x?response=201 200
+
+echo "===  update producer ==="
+RESULT=""
+do_curl PUT /arm/supervision/prod-x?response=400 200
+
+echo "===  update producer ==="
+RESULT=""
+do_curl PUT /arm/supervision/prod-x 200
+
+## Add types to a producere
+
+echo "===  add type 10 ==="
+RESULT=""
+do_curl PUT /arm/type/prod-x/10 200
+
+echo "===  add type 15 ==="
+RESULT=""
+do_curl PUT /arm/type/prod-x/15 200
+
+## check the db
+
+echo "=== status ==="
+RESULT="json:{\"prod-x\": {\"supervision_response\": 200, \"supervision_counter\": 0, \"types\": [\"10\", \"15\"]}}"
+do_curl GET /status 200
+
+## Add type
+echo "===  add type 20 ==="
+RESULT=""
+do_curl PUT /arm/type/prod-x/20 200
+
+echo "=== status ==="
+RESULT="json:{\"prod-x\": {\"supervision_response\": 200, \"supervision_counter\": 0, \"types\": [\"10\", \"15\", \"20\"]}}"
+do_curl GET /status 200
+
+## remove type
+echo "===  remove type 20 ==="
+RESULT=""
+do_curl DELETE /arm/type/prod-x/20 200
+
+echo "=== status ==="
+RESULT="json:{\"prod-x\": {\"supervision_response\": 200, \"supervision_counter\": 0, \"types\": [\"10\", \"15\"]}}"
+do_curl GET /status 200
+
+## producer supervision
+echo "===  check supervision counter ==="
+RESULT="0"
+do_curl GET /counter/supervision/prod-x 200
+
+echo "===  supervision producer ==="
+RESULT=""
+do_curl GET /callbacks/supervision/prod-x 200
+
+echo "===  update producer ==="
+RESULT=""
+do_curl PUT /arm/supervision/prod-x?response=400 200
+
+echo "===  callback supervision producer ==="
+RESULT="returning configured response code"
+do_curl GET /callbacks/supervision/prod-x 400
+
+## check the db
+
+echo "=== status ==="
+RESULT="json:{\"prod-x\": {\"supervision_response\": 400, \"supervision_counter\": 2, \"types\": [\"10\", \"15\"]}}"
+do_curl GET /status 200
+
+## create/update job
+
+echo "===  add job ==="
+RESULT=""
+do_curl PUT /arm/create/prod-x/job-y 200
+
+echo "===  update job ==="
+RESULT=""
+do_curl PUT /arm/create/prod-x/job-y?response=405 200
+
+## check the db
+
+echo "=== status ==="
+RESULT="json:{\"prod-x\": {\"supervision_response\": 400, \"supervision_counter\": 2, \"types\": [\"10\", \"15\"], \"job-y\": {\"create_response\": 405, \"delete_response\": 404, \"json\": null, \"create_counter\": 0, \"delete_counter\": 0, \"delivering\": false, \"delivery_attempts\": 0}}}"
+do_curl GET /status 200
+
+## add delete response for job
+
+echo "===  update job ==="
+RESULT=""
+do_curl PUT /arm/delete/prod-x/job-y?response=407 200
+
+## check the db
+
+echo "=== status ==="
+RESULT="json:{\"prod-x\": {\"supervision_response\": 400, \"supervision_counter\": 2, \"types\": [\"10\", \"15\"], \"job-y\": {\"create_response\": 405, \"delete_response\": 407, \"json\": null, \"create_counter\": 0, \"delete_counter\": 0, \"delivering\": false, \"delivery_attempts\": 0}}}"
+do_curl GET /status 200
+
+## Get jobdata
+echo "=== job data ==="
+RESULT=""
+do_curl GET /jobdata/prod-x/job-y 204
+
+##  callback create
+
+echo "===  add job ==="
+RESULT=""
+do_curl PUT /arm/create/prod-x/job-1 200
+RESULT=""
+do_curl PUT /arm/delete/prod-x/job-1 200
+
+echo "===  callback create job ==="
+RESULT=""
+echo "{\"ei_job_identity\": \"job-1\", \"ei_job_data\": {}, \"target_uri\": \"http://localhost:80\",\"ei_type_identity\": \"10\"}" > .p.json
+do_curl POST /callbacks/create/prod-x 201 .p.json
+
+echo "===  callback create job -update ==="
+RESULT=""
+echo "{\"ei_job_identity\": \"job-1\", \"ei_job_data\": {}, \"target_uri\": \"http://localhost:80\",\"ei_type_identity\": \"10\"}" > .p.json
+do_curl POST /callbacks/create/prod-x 200 .p.json
+
+## Get jobdata
+echo "=== job data ==="
+RESULT="json:{\"ei_job_identity\": \"job-1\", \"ei_job_data\": {}, \"target_uri\": \"http://localhost:80\", \"ei_type_identity\": \"10\"}"
+do_curl GET /jobdata/prod-x/job-1 200
+
+## check the db
+
+echo "=== status ==="
+RESULT="json:{\"prod-x\": {\"supervision_response\": 400, \"supervision_counter\": 2, \"types\": [\"10\", \"15\"], \"job-y\": {\"create_response\": 405, \"delete_response\": 407, \"json\": null, \"create_counter\": 0, \"delete_counter\": 0, \"delivering\": false, \"delivery_attempts\": 0}, \"job-1\": {\"create_response\": 200, \"delete_response\": 204, \"json\": {\"ei_job_identity\": \"job-1\", \"ei_job_data\": {}, \"target_uri\": \"http://localhost:80\", \"ei_type_identity\": \"10\"}, \"create_counter\": 2, \"delete_counter\": 0, \"delivering\": false, \"delivery_attempts\": 0}}}"
+do_curl GET /status 200
+
+# create and delete job tests
+echo "===  set job create response ==="
+RESULT=""
+do_curl PUT /arm/create/prod-x/job-1?response=404 200
+
+echo "===  callback create job -update ==="
+RESULT="returning configured response code"
+echo "{\"ei_job_identity\": \"job-1\", \"ei_job_data\": {}, \"target_uri\": \"http://localhost:80\",\"ei_type_identity\": \"10\"}" > .p.json
+do_curl POST /callbacks/create/prod-x 404 .p.json
+
+echo "===  set job delete response ==="
+RESULT=""
+do_curl PUT /arm/delete/prod-x/job-1?response=404 200
+
+echo "===  callback delete job==="
+RESULT="returning configured response code"
+echo "{\"ei_job_identity\": \"job-1\", \"ei_job_data\": {}, \"target_uri\": \"http://localhost:80\",\"ei_type_identity\": \"10\"}" > .p.json
+do_curl POST /callbacks/delete/prod-x 404 .p.json
+
+echo "===  set job delete response ==="
+RESULT=""
+do_curl PUT /arm/delete/prod-x/job-1 200
+
+echo "===  callback delete job==="
+RESULT=""
+echo "{\"ei_job_identity\": \"job-1\", \"ei_job_data\": {}, \"target_uri\": \"http://localhost:80\",\"ei_type_identity\": \"10\"}" > .p.json
+do_curl POST /callbacks/delete/prod-x 204 .p.json
+
+## check the db
+
+echo "=== status ==="
+RESULT="json:{\"prod-x\": {\"supervision_response\": 400, \"supervision_counter\": 2, \"types\": [\"10\", \"15\"], \"job-y\": {\"create_response\": 405, \"delete_response\": 407, \"json\": null, \"create_counter\": 0, \"delete_counter\": 0, \"delivering\": false, \"delivery_attempts\": 0}, \"job-1\": {\"create_response\": 404, \"delete_response\": 404, \"json\": null, \"create_counter\": 3, \"delete_counter\": 2, \"delivering\": false, \"delivery_attempts\": 0}}}"
+do_curl GET /status 200
+
+
+##  data delivery
+
+echo "===  update producer ==="
+RESULT=""
+do_curl PUT /arm/create/prod-x/job-1 200
+
+echo "===  callback create job ==="
+RESULT=""
+echo "{\"ei_job_identity\": \"job-1\", \"ei_job_data\": {}, \"target_uri\": \"http://localhost:80\",\"ei_type_identity\": \"10\"}" > .p.json
+do_curl POST /callbacks/create/prod-x 201 .p.json
+
+echo "=== data delivery start ==="
+RESULT="job not found"
+do_curl POST /jobdata/prod-x/job-x?action=START 404
+
+echo "=== data delivery start ==="
+RESULT=""
+do_curl POST /jobdata/prod-x/job-1?action=START 200
+
+echo "sleep 5"
+sleep 5
+
+echo "=== data delivery stop ==="
+RESULT=""
+do_curl POST /jobdata/prod-x/job-1?action=STOP 200
 
 echo "********************"
 echo "*** All tests ok ***"
index 7f111b6..b16e613 100755 (executable)
 
 #Builds the producer stub container and starts it in interactive mode
 
-docker build -t producer-stub .
+NAME="producer-stub-test"
+IMAGE_NAME="producer-stub-test-image"
 
-docker run -it -p 8092:8092 -p 8093:8093 --name producer-stub producer-stub
+docker build -t $IMAGE_NAME .
+
+docker stop $NAME
+docker rm -f $NAME
+docker run -it -p 8992:8092 -p 8993:8093 --name $NAME $IMAGE_NAME
index 17d3205..7d7ffdf 100644 (file)
@@ -24,9 +24,13 @@ var LOCALHOST="http://127.0.0.1:"
 var MRSTUB_PORT="3905"
 var AGENT_PORT="8081"
 var CR_PORT="8090"
+var ECS_PORT="8083"
+var PRODSTUB_PORT="8092"
+
 var http = require('http');
 
 var express = require('express');
+const { POINT_CONVERSION_HYBRID } = require('constants')
 var app = express();
 var fieldSize=32;
 
@@ -37,11 +41,10 @@ app.get("/",function(req, res){
        res.send("ok");
 })
 
-//Get parameter valuue from other server
+//Get parameter value from other server
 function getSimCtr(url, index, cb) {
     var data = '';
 
-    //console.log("URL: "+ url + " - ")
     try {
         http.get(url, (resp) => {
             // A chunk of data has been recieved.
@@ -162,6 +165,7 @@ var ag1=""
 var ag2=""
 var ag3=""
 var ag4=""
+var ag5=""
 
 //Status variables for callback receiver
 var cr1=""
@@ -179,21 +183,47 @@ var simvar2=[]
 var simvar3=[]
 var simvar4=[]
 var simvar5=[]
+var simvar6=[]
+
+//Status variables, for parameters values fetched from ecs
+var ecs1="", ecs2="", ecs3="", ecs4="", ecs_types="-", ecs_producers="-";
+var ecs_producer_arr=new Array(0)
+var ecs_producer_type_arr=new Array(0)
+var ecs_producer_jobs_arr=new Array(0)
+var ecs_producer_status_arr=new Array(0)
+
+//Status variables, for parameters values fetched from prodstub
+var ps2="", ps3="", ps4="", ps_types="-", ps_producers="-";
+var ps_producer_type_arr=new Array(0)
+var ps_producer_jobs_arr=new Array(0)
+var ps_producer_delivery_arr=new Array(0)
+
+//Full CR DB
+var cr_db={}
 
 //Counts the number of get request for the html page
 var getCtr=0
 
-var refreshInterval=4000
+var refreshCount_pol=-1
+
+var refreshCount_ecs=-1
+
+var refreshCount_cr=-1
 
 var ricbasename="ricsim"
 
-function fetchAllMetrics() {
+function fetchAllMetrics_pol() {
+
+    console.log("Fetching policy metrics " + refreshCount_pol)
+
+    if (refreshCount_pol < 0) {
+        refreshCount_pol = -1
+        return
+    } else {
+        refreshCount_pol = refreshCount_pol - 1
+    }
     setTimeout(() => {
 
-        console.log("Fetching all metics data")
-        if (refreshInterval < 20000) {
-            refreshInterval+=100
-        }
         if (getCtr%3 == 0) {
             //Extract the port numbers from the running simulators, for every 3 calls
             const { exec } = require('child_process');
@@ -250,6 +280,12 @@ function fetchAllMetrics() {
                     clearFlag("simvar5_"+index)
                 });
             }
+            if (checkFunctionFlag("simvar6_"+index)) {
+                getSimCtr(LOCALHOST+simports[index]+"/counter/datadelivery", index, function(data,index) {
+                    simvar6[index] = data;
+                    clearFlag("simvar6_"+index)
+                });
+            }
         }
 
         //MR - get metrics values from the MR stub
@@ -352,9 +388,9 @@ function fetchAllMetrics() {
                 clearFlag("ag3")
             });
         }
+
         if (checkFunctionFlag("ag4")) {
             getSimCtr(LOCALHOST+AGENT_PORT+"/policy_ids", 0, function(data, index) {
-                ag4=""
                 try {
                     var jd=JSON.parse(data);
                     ag4=""+jd.length
@@ -366,19 +402,401 @@ function fetchAllMetrics() {
             });
         }
 
+        if (checkFunctionFlag("ag5")) {
+            getSimCtr(LOCALHOST+AGENT_PORT+"/rics", 0, function(data, index) {
+                try {
+                    var jd=JSON.parse(data);
+                    ag5=""+jd.length
+                }
+                catch (err) {
+                    ag5=""
+                }
+                clearFlag("ag5")
+            });
+        }
+
+        fetchAllMetrics_pol();
+
+    }, 500)
+}
+
+function fetchAllMetrics_ecs() {
+
+    console.log("Fetching enrichment metrics - timer:" + refreshCount_ecs)
+
+    if (refreshCount_ecs < 0) {
+        refreshCount_ecs = -1
+        return
+    } else {
+        refreshCount_ecs = refreshCount_ecs - 1
+    }
+    setTimeout(() => {
+
+        if (checkFunctionFlag("ecs_stat")) {
+            getSimCtr(LOCALHOST+ECS_PORT+"/status", 0, function(data, index) {
+                ecs1=""
+                ecs2=""
+                ecs3=""
+                ecs4=""
+                try {
+                    var jd=JSON.parse(data);
+                    ecs1=jd["status"]
+                    ecs2=""+jd["no_of_producers"]
+                    ecs3=""+jd["no_of_types"]
+                    ecs4=""+jd["no_of_jobs"]
+                }
+                catch (err) {
+                    ecs1="error response"
+                    ecs2="error response"
+                    ecs3="error response"
+                    ecs4="error response"
+                }
+            });
+
+            getSimCtr(LOCALHOST+ECS_PORT+"/ei-producer/v1/eitypes", 0, function(data, index) {
+                ecs_types="-"
+                try {
+                    var jd=JSON.parse(data);
+                    for(var i=0;i<jd.length;i++) {
+                        if (ecs_types.length == 1) {
+                            ecs_types=""
+                        }
+                        ecs_types=""+ecs_types+jd[i]+" "
+                    }
+                }
+                catch (err) {
+                    ecs_types="error response"
+                }
+            });
+
+            getSimCtr(LOCALHOST+ECS_PORT+"/ei-producer/v1/eiproducers", 0, function(data, index) {
+                ecs_producers="-"
+                try {
+                    var jd=JSON.parse(data);
+                    var tmp_ecs_producer_arr=new Array(jd.length)
+                    for(var i=0;i<jd.length;i++) {
+                        if (ecs_producers.length == 1) {
+                            ecs_producers=""
+                        }
+                        ecs_producers=""+ecs_producers+jd[i]+" "
+                        tmp_ecs_producer_arr[i]=jd[i]
+                    }
+                    ecs_producer_arr = tmp_ecs_producer_arr
+                }
+                catch (err) {
+                    ecs_producers="error response"
+                    ecs_producer_arr=new Array(0)
+                }
+            });
+
+            ecs_producer_type_arr = JSON.parse(JSON.stringify(ecs_producer_arr))
+            for(var x=0;x<ecs_producer_type_arr.length;x++) {
+                getSimCtr(LOCALHOST+ECS_PORT+"/ei-producer/v1/eiproducers/"+ecs_producer_type_arr[x], x, function(data, x) {
+                    var row=""+ecs_producer_type_arr[x]+" : "
+                    try {
+                        var jd=JSON.parse(data);
+                        var jda=jd["supported_ei_types"]
+                        for(var j=0;j<jda.length;j++) {
+                            row=""+row+jda[j]["ei_type_identity"]+" "
+                        }
+                        ecs_producer_type_arr[x]=row
+                    }
+                    catch (err) {
+                        ecs_producer_type_arr=new Array(0)
+                    }
+                });
+            }
+
+            ecs_producer_jobs_arr = JSON.parse(JSON.stringify(ecs_producer_arr))
+            for(var x=0;x<ecs_producer_jobs_arr.length;x++) {
+                getSimCtr(LOCALHOST+ECS_PORT+"/ei-producer/v1/eiproducers/"+ecs_producer_jobs_arr[x]+"/eijobs", x, function(data, x) {
+                    var row=""+ecs_producer_jobs_arr[x]+" : "
+                    try {
+                        var jd=JSON.parse(data);
+                        for(var j=0;j<jd.length;j++) {
+                            var jda=jd[j]
+                            row=""+row+jda["ei_job_identity"]+"("+jda["ei_type_identity"]+") "
+                        }
+                        ecs_producer_jobs_arr[x]=row
+                    }
+                    catch (err) {
+                        ecs_producer_jobs_arr=new Array(0)
+                    }
+                });
+            }
+
+            ecs_producer_status_arr = JSON.parse(JSON.stringify(ecs_producer_arr))
+            for(var x=0;x<ecs_producer_status_arr.length;x++) {
+                getSimCtr(LOCALHOST+ECS_PORT+"/ei-producer/v1/eiproducers/"+ecs_producer_status_arr[x]+"/status", x, function(data, x) {
+                    var row=""+ecs_producer_status_arr[x]+" : "
+                    try {
+                        var jd=JSON.parse(data);
+                        row=""+row+jd["operational_state"]
+                        ecs_producer_status_arr[x]=row
+                    }
+                    catch (err) {
+                        ecs_producer_status_arr=new Array(0)
+                    }
+                });
+            }
+            clearFlag("ecs_stat")
+        }
+        if (checkFunctionFlag("prodstub_stat")) {
+            getSimCtr(LOCALHOST+PRODSTUB_PORT+"/status", x, function(data, x) {
+                var ctr2_map=new Map()
+                var ctr3_map=new Map()
+                var ctr2=0
+                var ctr4=0
+                ps_producers=""
+                ps_types=""
+                ps_producer_type_arr=new Array()
+                ps_producer_jobs_arr=new Array()
+                ps_producer_delivery_arr=new Array()
+                ps2=""
+                ps3=""
+                ps4=""
+                try {
+                    var jp=JSON.parse(data);
+                    for(var prod_name in jp) {
+                        ctr2_map.set(prod_name, prod_name)
+                        ctr2 += 1
+                        var jj=jp[prod_name]
+                        var row=""+prod_name+" : "
+                        var rowj=""+prod_name+" : "
+                        var rowd=""+prod_name+" : "
+                        ps_producers += prod_name + " "
+                        for(var ji in jj) {
+                            if (ji == "types") {
+                                var ta=jj[ji]
+                                for(var i=0;i<ta.length;i++) {
+                                    ctr3_map.set(ta[i], ta[i])
+                                    row += " "+ta[i]
+                                }
+                            } else if (ji == "supervision_response") {
+                            } else if (ji == "supervision_counter") {
+                            } else if (ji == "types") {
+                            } else {
+                                ctr4 += 1
+                                rowj += " "+ji
+                                rowd += " "+ji
+                                var job_data=jj[ji]["json"]
+                                if (job_data != undefined) {
+                                    rowj += "("+job_data["ei_type_identity"]+")"
+                                }
+                                rowd += "("+jj[ji]["delivery_attempts"]+")"
+                            }
+                        }
+                        ps_producer_type_arr[(ctr2-1)]=row
+                        ps_producer_jobs_arr[(ctr2-1)]=rowj
+                        ps_producer_delivery_arr[(ctr2-1)]=rowd
+                    }
+                    ps2=""+ctr2_map.size
+                    ps3=""+ctr3_map.size
+                    for(const [key, value] of ctr3_map.entries()) {
+                        ps_types += key + " "
+                    }
+                    ps4=""+ctr4
+                }
+                catch (err) {
+                    console.error(err);
+                    ps_producers="error response"
+                    ps_types="error response"
+                    ps_producer_type_arr=new Array()
+                    ps_producer_jobs_arr=new Array()
+                    ps_producer_delivery_arr=new Array()
+                    ps2="error response"
+                    ps3="error response"
+                    ps4="error response"
+                }
+            });
+            clearFlag("prodstub_stat")
+        }
+
+        fetchAllMetrics_ecs();
 
-        fetchAllMetrics();
-    }, refreshInterval)
+    }, 500)
 }
 
-fetchAllMetrics();
+function fetchAllMetrics_cr() {
+
+    console.log("Fetching CR DB - timer:" + refreshCount_ecs)
 
-setInterval(() => {
-    console.log("Setting interval "+refreshInterval+"ms")
-}, refreshInterval)
+    if (refreshCount_cr < 0) {
+        refreshCount_cr = -1
+        return
+    } else {
+        refreshCount_cr = refreshCount_cr - 1
+    }
+    setTimeout(() => {
+
+        if (checkFunctionFlag("cr_stat")) {
+            getSimCtr(LOCALHOST+CR_PORT+"/db", 0, function(data, index) {
+                ecs4=""
+                try {
+                    cr_db=JSON.parse(data);
+                }
+                catch (err) {
+                    cr_db={}
+                }
+            });
+            clearFlag("cr_stat")
+        }
+        fetchAllMetrics_cr();
+    }, 500)
+}
+
+// Monitor for CR db
+app.get("/mon3",function(req, res){
+
+    console.log("Creating CR DB page - timer: " + refreshCount_ecs)
+
+    if (refreshCount_cr < 0) {
+        refreshCount_cr=5
+        fetchAllMetrics_cr()
+    }
+    refreshCount_cr=5
+    var json_str=JSON.stringify(cr_db, null, 1)
+    var htmlStr = "<!DOCTYPE html>" +
+    "<html>" +
+    "<head>" +
+      "<meta http-equiv=\"refresh\" content=\"2\">"+  //2 sec auto refresh
+      "<title>CR DB dump</title>"+
+      "</head>" +
+      "<body style=\"white-space: pre-wrap\">" +
+      json_str +
+      "</body>" +
+      "</html>";
+    res.send(htmlStr);
+})
+
+// Monitor for ECS
+app.get("/mon2",function(req, res){
+
+    console.log("Creating enrichment metrics - timer: " + refreshCount_ecs)
+
+    if (refreshCount_ecs < 0) {
+        refreshCount_ecs=5
+        fetchAllMetrics_ecs()
+    }
+    refreshCount_ecs=5
+
+    var summary=req.query.summary
+
+    if (summary == undefined) {
+        return res.redirect('/mon2?summary=false');
+    }
+
+  //Build web page
+       var htmlStr = "<!DOCTYPE html>" +
+          "<html>" +
+          "<head>" +
+            "<meta http-equiv=\"refresh\" content=\"2\">"+  //2 sec auto refresh
+            "<title>Enrichment coordinator service and producer stub</title>"+
+            "</head>" +
+            "<body>" +
+            "<font size=\"-3\" face=\"summary\">"
+            if (summary == "false") {
+                htmlStr=htmlStr+"<p>Set query param '?summary' to true to only show summary statistics</p>"
+            } else {
+                htmlStr=htmlStr+"<p>Set query param '?summary' to false to only show full statistics</p>"
+            }
+            htmlStr=htmlStr+"</font>" +
+            "<h3>Enrichment Coordinator Service</h3>" +
+            "<font face=\"monospace\">" +
+            "Status:..........." + formatDataRow(ecs1) + "<br>" +
+            "Producers:........" + formatDataRow(ecs2) + "<br>" +
+            "Types:............" + formatDataRow(ecs3) + "<br>" +
+            "Jobs:............." + formatDataRow(ecs4) + "<br>" +
+            "</font>"
+            if (summary == "false") {
+                htmlStr=htmlStr+
+                "<h4>Details</h4>" +
+                "<font face=\"monospace\">" +
+                "Producer ids:....." + formatDataRow(ecs_producers) + "<br>" +
+                "Type ids:........." + formatDataRow(ecs_types) + "<br>" +
+                "<br>";
+                for(var i=0;i<ecs_producer_type_arr.length;i++) {
+                    var tmp=ecs_producer_type_arr[i]
+                    if (tmp != undefined) {
+                        var s = "Producer types...." + formatDataRow(ecs_producer_type_arr[i]) + "<br>"
+                        htmlStr=htmlStr+s
+                    }
+                }
+                htmlStr=htmlStr+"<br>";
+                for(var i=0;i<ecs_producer_jobs_arr.length;i++) {
+                    var tmp=ecs_producer_jobs_arr[i]
+                    if (tmp != undefined) {
+                        var s = "Producer jobs....." + formatDataRow(ecs_producer_jobs_arr[i]) + "<br>"
+                        htmlStr=htmlStr+s
+                    }
+                }
+                htmlStr=htmlStr+"<br>";
+                for(var i=0;i<ecs_producer_status_arr.length;i++) {
+                    var tmp=ecs_producer_status_arr[i]
+                    if (tmp != undefined) {
+                        var s = "Producer status..." + formatDataRow(ecs_producer_status_arr[i]) + "<br>"
+                        htmlStr=htmlStr+s
+                    }
+                }
+                htmlStr=htmlStr+"<br>"+"<br>" +
+                "</font>"
+            }
+            htmlStr=htmlStr+
+            "<h3>Producer stub</h3>" +
+            "<font face=\"monospace\">" +
+            "Producers:........" + formatDataRow(ps2) + "<br>" +
+            "Types:............" + formatDataRow(ps3) + "<br>" +
+            "Jobs:............." + formatDataRow(ps4) + "<br>" +
+            "</font>"
+            if (summary == "false") {
+                htmlStr=htmlStr+
+                "<h4>Details</h4>" +
+                "<font face=\"monospace\">" +
+                "Producer ids:....." + formatDataRow(ps_producers) + "<br>" +
+                "Type ids:........." + formatDataRow(ps_types) + "<br>" +
+                "<br>";
+                for(var i=0;i<ps_producer_type_arr.length;i++) {
+                    var tmp=ps_producer_type_arr[i]
+                    if (tmp != undefined) {
+                        var s = "Producer types...." + formatDataRow(ps_producer_type_arr[i]) + "<br>"
+                        htmlStr=htmlStr+s
+                    }
+                }
+                htmlStr=htmlStr+"<br>";
+                for(var i=0;i<ps_producer_jobs_arr.length;i++) {
+                    var tmp=ps_producer_jobs_arr[i]
+                    if (tmp != undefined) {
+                        var s = "Producer jobs....." + formatDataRow(ps_producer_jobs_arr[i]) + "<br>"
+                        htmlStr=htmlStr+s
+                    }
+                }
+                htmlStr=htmlStr+"<br>";
+                for(var i=0;i<ps_producer_delivery_arr.length;i++) {
+                    var tmp=ps_producer_delivery_arr[i]
+                    if (tmp != undefined) {
+                        var s = "Producer delivery." + formatDataRow(ps_producer_delivery_arr[i]) + "<br>"
+                        htmlStr=htmlStr+s
+                    }
+                }
+            }
+            htmlStr=htmlStr+
+            "</font>" +
+           "</body>" +
+          "</html>";
+       res.send(htmlStr);
+})
 
+// Monitor for policy management
 app.get("/mon",function(req, res){
 
+    console.log("Creating policy metrics page " + refreshCount_pol)
+
+    if (refreshCount_pol < 0) {
+        refreshCount_pol=5
+        fetchAllMetrics_pol()
+    }
+    refreshCount_pol=5
+
     var bn=req.query.basename
 
     if (bn == undefined) {
@@ -388,9 +806,7 @@ app.get("/mon",function(req, res){
         ricbasename=bn
     }
 
-    refreshInterval=2000
-
-  //Build web page
+    //Build web page
        var htmlStr = "<!DOCTYPE html>" +
           "<html>" +
           "<head>" +
@@ -407,6 +823,7 @@ app.get("/mon",function(req, res){
             "Services:............................." + formatIdRowCompact(ag2) + "<br>" +
             "Types:................................" + formatIdRowCompact(ag3) + "<br>" +
             "Number of instances:.................." + formatDataRow(ag4) + "<br>" +
+            "Near-RT RICs:........................." + formatDataRow(ag5) + "<br>" +
             "</font>" +
             "<h3>MR Stub interface</h3>" +
             "<font face=\"monospace\">"+
@@ -428,12 +845,14 @@ app.get("/mon",function(req, res){
 
             htmlStr=htmlStr+padding("Near-RT RIC Simulator name", 35,"&nbsp;")
             htmlStr=htmlStr+padding("Types", 10,"&nbsp;")
-            htmlStr=htmlStr+padding("Instances", 10,"&nbsp;")+"<br>"
-            htmlStr=htmlStr+padding("",55,"=")+"<br>"
+            htmlStr=htmlStr+padding("Instances", 12,"&nbsp;")
+            htmlStr=htmlStr+padding("Data delivery", 12,"&nbsp;")+"<br>"
+            htmlStr=htmlStr+padding("",70,"=")+"<br>"
             for(var simIndex=0;simIndex<simnames.length;simIndex++) {
                 htmlStr=htmlStr+padding(simnames[simIndex]+ " ("+simports[simIndex]+")",35,"&nbsp;");
                 htmlStr=htmlStr+padding(simvar2[simIndex],10,"&nbsp;")
-                htmlStr=htmlStr+padding(simvar1[simIndex],10,"&nbsp;")
+                htmlStr=htmlStr+padding(simvar1[simIndex],12    ,"&nbsp;")
+                htmlStr=htmlStr+padding(simvar6[simIndex],12,"&nbsp;")
                 htmlStr=htmlStr+"<br>";
             }
 
@@ -469,4 +888,6 @@ var httpServer = http.createServer(app);
 var httpPort=9999;
 httpServer.listen(httpPort);
 console.log("Simulator monitor listening (http) at "+httpPort);
-console.log("Open the web page on localhost:9999/mon to view the statistics page.")
\ No newline at end of file
+console.log("Open the web page on localhost:9999/mon to view the policy statistics page.")
+console.log("Open the web page on localhost:9999/mon2 to view the enrichment statistics page.")
+console.log("Open the web page on localhost:9999/mon3 to view CR DB in json.")
\ No newline at end of file
diff --git a/tox.ini b/tox.ini
index 4491722..2705e16 100644 (file)
--- a/tox.ini
+++ b/tox.ini
@@ -24,23 +24,14 @@ skipsdist = true
 
 [testenv:docs]
 basepython = python3
-deps =
-    sphinx
-    sphinx-rtd-theme
-    sphinxcontrib-httpdomain
-    recommonmark
-    lfdocs-conf
+deps = -r{toxinidir}/docs/requirements-docs.txt
 
 commands =
-    sphinx-build -W -b html -n -d {envtmpdir}/doctrees ./docs/ {toxinidir}/docs/_build/html
+    sphinx-build -W -b html -n -d {envtmpdir}/docs/doctrees ./docs/ {toxinidir}/docs/_build/html
     echo "Generated docs available in {toxinidir}/docs/_build/html"
 whitelist_externals = echo
 
 [testenv:docs-linkcheck]
 basepython = python3
-deps = sphinx
-       sphinx-rtd-theme
-       sphinxcontrib-httpdomain
-       recommonmark
-       lfdocs-conf
+deps = -r{toxinidir}/docs/requirements-docs.txt
 commands = sphinx-build -W -b linkcheck -d {envtmpdir}/doctrees ./docs/ {toxinidir}/docs/_build/linkcheck